8000 Fix: CFn: support tags with ESMs (#11787) · localstack/localstack@f584a04 · GitHub
[go: up one dir, main page]

Skip to content

Commit f584a04

Browse files
simonrwgregfurman
authored andcommitted
Fix: CFn: support tags with ESMs (#11787)
< 8000 /span>Co-authored-by: Greg Furman <31275503+gregfurman@users.noreply.github.com>
1 parent 720f702 commit f584a04

File tree

5 files changed

+208
-1
lines changed

5 files changed

+208
-1
lines changed

localstack-core/localstack/services/lambda_/resource_providers/aws_lambda_eventsourcemapping.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# LocalStack Resource Provider Scaffolding v2
22
from __future__ import annotations
33

4+
import copy
45
from pathlib import Path
56
from typing import Optional, TypedDict
67

@@ -126,8 +127,16 @@ def create(
126127
model = request.desired_state
127128
lambda_client = request.aws_client_factory.lambda_
128129

129-
response = lambda_client.create_event_source_mapping(**model)
130+
params = copy.deepcopy(model)
131+
if tags := params.get("Tags"):
132+
transformed_tags = {}
133+
for tag_definition in tags:
134+
transformed_tags[tag_definition["Key"]] = tag_definition["Value"]
135+
params["Tags"] = transformed_tags
136+
137+
response = lambda_client.create_event_source_mapping(**params)
130138
model["Id"] = response["UUID"]
139+
model["EventSourceMappingArn"] = response["EventSourceMappingArn"]
131140

132141
return ProgressEvent(
133142
status=OperationStatus.SUCCESS,
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import json
2+
import os
3+
4+
import pytest
5+
6+
from localstack.testing.pytest import markers
7+
from localstack.testing.scenario.provisioning import cleanup_s3_bucket
8+
from localstack.utils.strings import short_uid
9+
from localstack.utils.sync import retry
10+
from tests.aws.services.lambda_.event_source_mapping.utils import is_old_esm
11+
12+
13+
@markers.aws.validated
14+
@pytest.mark.skipif(condition=is_old_esm(), reason="Not implemented in v1 provider")
15+
@markers.snapshot.skip_snapshot_verify(
16+
paths=[
17+
"$..Tags.'aws:cloudformation:logical-id'",
18+
"$..Tags.'aws:cloudformation:stack-id'",
19+
"$..Tags.'aws:cloudformation:stack-name'",
20+
]
21+
)
22+
def test_adding_tags(deploy_cfn_template, aws_client, snapshot, cleanups):
23+
template_path = os.path.join(
24+
os.path.join(os.path.dirname(__file__), "../../../templates/event_source_mapping_tags.yml")
25+
)
26+
assert os.path.isfile(template_path)
27+
28+
output_key = f"key-{short_uid()}"
29+
stack = deploy_cfn_template(
30+
template_path=template_path,
31+
parameters={"OutputKey": output_key},
32+
)
33+
# ensure the S3 bucket is empty so we can delete it
34+
cleanups.append(lambda: cleanup_s3_bucket(aws_client.s3, stack.outputs["OutputBucketName"]))
35+
36+
snapshot.add_transformer(snapshot.transform.regex(stack.stack_id, "<stack-id>"))
37+
snapshot.add_transformer(snapshot.transform.regex(stack.stack_name, "<stack-name>"))
38+
39+
event_source_mapping_arn = stack.outputs["EventSourceMappingArn"]
40+
tags_response = aws_client.lambda_.list_tags(Resource=event_source_mapping_arn)
41+
snapshot.match("event-source-mapping-tags", tags_response)
42+
43+
# check the mapping works
44+
queue_url = stack.outputs["QueueUrl"]
45+
aws_client.sqs.send_message(
46+
QueueUrl=queue_url,
47+
MessageBody=json.dumps({"body": "something"}),
48+
)
49+
50+
retry(
51+
lambda: aws_client.s3.head_object(Bucket=stack.outputs["OutputBucketName"], Key=output_key),
52+
retries=10,
53+
sleep=5.0,
54+
)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"tests/aws/services/lambda_/event_source_mapping/test_cfn_resource.py::test_adding_tags": {
3+
"recorded-date": "06-11-2024, 11:55:29",
4+
"recorded-content": {
5+
"event-source-mapping-tags": {
6+
"Tags": {
7+
"aws:cloudformation:logical-id": "EventSourceMapping",
8+
"aws:cloudformation:stack-id": "<stack-id>",
9 A93C +
"aws:cloudformation:stack-name": "<stack-name>",
10+
"my": "tag"
11+
},
12+
"ResponseMetadata": {
13+
"HTTPHeaders": {},
14+
"HTTPStatusCode": 200
15+
}
16+
}
17+
}
18+
}
19+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"tests/aws/services/lambda_/event_source_mapping/test_cfn_resource.py::test_adding_tags": {
3+
"last_validated_date": "2024-11-06T11:55:29+00:00"
4+
}
5+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
Parameters:
2+
OutputKey:
3+
Type: String
4+
5+
Resources:
6+
Queue:
7+
Type: AWS::SQS::Queue
8+
UpdateReplacePolicy: Delete
9+
DeletionPolicy: Delete
10+
11+
FunctionRole:
12+
Type: AWS::IAM::Role
13+
Properties:
14+
AssumeRolePolicyDocument:
15+
Statement:
16+
- Action: sts:AssumeRole
17+
Effect: Allow
18+
Principal:
19+
Service: lambda.amazonaws.com
20+
Version: '2012-10-17'
21+
ManagedPolicyArns:
22+
- Fn::Join:
23+
- ''
24+
- - 'arn:'
25+
- Ref: AWS::Partition
26+
- :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
27+
Tags:
28+
- Key: my
29+
Value: tag
30+
31+
FunctionRolePolicy:
32+
Type: AWS::IAM::Policy
33+
Properties:
34+
PolicyDocument:
35+
Statement:
36+
- Action:
37+
- sqs:ChangeMessageVisibility
38+
- sqs:DeleteMessage
39+
- sqs:GetQueueAttributes
40+
- sqs:GetQueueUrl
41+
- sqs:ReceiveMessage
42+
Effect: Allow
43+
Resource:
44+
Fn::GetAtt:
45+
- Queue
46+
- Arn
47+
- Action:
48+
- s3:PutObject
49+
Effect: Allow
50+
Resource:
51+
Fn::Sub:
52+
- "${bucketArn}/${key}"
53+
- bucketArn: !GetAtt OutputBucket.Arn
54+
key: !Ref OutputKey
55+
Version: '2012-10-17'
56+
PolicyName: FunctionRolePolicy
57+
Roles:
58+
- Ref: FunctionRole
59+
60+
OutputBucket:
61+
Type: AWS::S3::Bucket
62+
63+
Function:
64+
Type: AWS::Lambda::Function
65+
Properties:
66+
Code:
67+
ZipFile: |
68+
import os
69+
import boto3
70+
71+
BUCKET = os.environ["BUCKET"]
72+
KEY = os.environ["KEY"]
73+
74+
def handler(event, context):
75+
client = boto3.client("s3")
76+
client.put_object(Bucket=BUCKET, Key=KEY, Body=b"ok")
77+
return "ok"
78+
Handler: index.handler
79+
Environment:
80+
Variables:
81+
BUCKET: !Ref OutputBucket
82+
KEY: !Ref OutputKey
83+
84+
Role:
85+
Fn::GetAtt:
86+
- FunctionRole
87+
- Arn
88+
Runtime: python3.11
89+
Tags:
90+
- Key: my
91+
Value: tag
92+
DependsOn:
93+
- FunctionRolePolicy
94+
- FunctionRole
95+
96+
EventSourceMapping:
97+
Type: AWS::Lambda::EventSourceMapping
98+
Properties:
99+
EventSourceArn:
100+
Fn::GetAtt:
101+
- Queue
102+
- Arn
103+
FunctionName:
104+
Ref: Function
105+
Tags:
106+
- Key: my
107+
Value: tag
108+
109+
Outputs:
110+
QueueUrl:
111+
Value: !Ref Queue
112+
113+
EventSourceMappingArn:
114+
Value: !GetAtt EventSourceMapping.EventSourceMappingArn
115+
116+
FunctionName:
117+
Value: !Ref Function
118+
119+
OutputBucketName:
120+
Value: !Ref OutputBucket

0 commit comments

Comments
 (0)
0