Skip to content

Commit eed879a

Browse files
authored
Fix: Replaced invalid AMQ managed policy by providing policy statements (#1891)
* Fix for invalid MQ event source managed policy * Fix for invalid managed policy for MQ, included support for new MQ event source property, updated test cases * Black reformatting * Test case changes * Changed policy name * Modified test cases with new policy name
1 parent 528f803 commit eed879a

File tree

13 files changed

+712
-214
lines changed

13 files changed

+712
-214
lines changed

samtranslator/model/eventsources/pull.py

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,17 @@ class PullEventSource(ResourceMacro):
3434
"Broker": PropertyType(False, is_str()),
3535
"Queues": PropertyType(False, is_type(list)),
3636
"SourceAccessConfigurations": PropertyType(False, is_type(list)),
37+
"SecretsManagerKmsKeyId": PropertyType(False, is_str()),
3738
"TumblingWindowInSeconds": PropertyType(False, is_type(int)),
3839
"FunctionResponseTypes": PropertyType(False, is_type(list)),
3940
}
4041

4142
def get_policy_arn(self):
4243
raise NotImplementedError("Subclass must implement this method")
4344

45+
def get_policy_statements(self):
46+
raise NotImplementedError("Subclass must implement this method")
47+
4448
def to_cloudformation(self, **kwargs):
4549
"""Returns the Lambda EventSourceMapping to which this pull event corresponds. Adds the appropriate managed
4650
policy to the function's execution role, if such a role is provided.
@@ -133,8 +137,17 @@ def _link_policy(self, role, destination_config_policy=None):
133137
:param model.iam.IAMRole role: the execution role generated for the function
134138
"""
135139
policy_arn = self.get_policy_arn()
136-
if role is not None and policy_arn not in role.ManagedPolicyArns:
137-
role.ManagedPolicyArns.append(policy_arn)
140+
policy_statements = self.get_policy_statements()
141+
if role is not None:
142+
if policy_arn is not None and policy_arn not in role.ManagedPolicyArns:
143+
role.ManagedPolicyArns.append(policy_arn)
144+
if policy_statements is not None:
145+
if role.Policies is None:
146+
role.Policies = []
147+
for policy in policy_statements:
148+
if policy not in role.Policies:
149+
if not policy.get("PolicyDocument") in [d["PolicyDocument"] for d in role.Policies]:
150+
role.Policies.append(policy)
138151
# add SQS or SNS policy only if role is present in kwargs
139152
if role is not None and destination_config_policy is not None and destination_config_policy:
140153
if role.Policies is None:
@@ -154,6 +167,9 @@ class Kinesis(PullEventSource):
154167
def get_policy_arn(self):
155168
return ArnGenerator.generate_aws_managed_policy_arn("service-role/AWSLambdaKinesisExecutionRole")
156169

170+
def get_policy_statements(self):
171+
return None
172+
157173

158174
class DynamoDB(PullEventSource):
159175
"""DynamoDB Streams event source."""
@@ -163,6 +179,9 @@ class DynamoDB(PullEventSource):
163179
def get_policy_arn(self):
164180
return ArnGenerator.generate_aws_managed_policy_arn("service-role/AWSLambdaDynamoDBExecutionRole")
165181

182+
def get_policy_statements(self):
183+
return None
184+
166185

167186
class SQS(PullEventSource):
168187
"""SQS Queue event source."""
@@ -172,6 +191,9 @@ class SQS(PullEventSource):
172191
def get_policy_arn(self):
173192
return ArnGenerator.generate_aws_managed_policy_arn("service-role/AWSLambdaSQSQueueExecutionRole")
174193

194+
def get_policy_statements(self):
195+
return None
196+
175197

176198
class MSK(PullEventSource):
177199
"""MSK event source."""
@@ -181,11 +203,69 @@ class MSK(PullEventSource):
181203
def get_policy_arn(self):
182204
return ArnGenerator.generate_aws_managed_policy_arn("service-role/AWSLambdaMSKExecutionRole")
183205

206+
def get_policy_statements(self):
207+
return None
208+
184209

185210
class MQ(PullEventSource):
186211
"""MQ event source."""
187212

188213
resource_type = "MQ"
189214

190215
def get_policy_arn(self):
191-
return ArnGenerator.generate_aws_managed_policy_arn("service-role/AWSLambdaAMQExecutionRole")
216+
return None
217+
218+
def get_policy_statements(self):
219+
if not self.SourceAccessConfigurations:
220+
raise InvalidEventException(
221+
self.relative_id,
222+
"No SourceAccessConfigurations for ActiveMQ provided.",
223+
)
224+
if not type(self.SourceAccessConfigurations) is list:
225+
raise InvalidEventException(
226+
self.relative_id,
227+
"Provided SourceAccessConfigurations cannot be parsed into a list.",
228+
)
229+
# MQ only supports SourceAccessConfigurations with list size of 1
230+
if not (len(self.SourceAccessConfigurations) == 1):
231+
raise InvalidEventException(
232+
self.relative_id,
233+
"SourceAccessConfigurations for ActiveMQ only supports single configuration entry.",
234+
)
235+
if not self.SourceAccessConfigurations[0].get("URI"):
236+
raise InvalidEventException(
237+
self.relative_id,
238+
"No URI property specified in SourceAccessConfigurations for ActiveMQ.",
239+
)
240+
document = {
241+
"PolicyName": "SamAutoGeneratedAMQPolicy",
242+
"PolicyDocument": {
243+
"Statement": [
244+
{
245+
"Action": [
246+
"secretsmanager:GetSecretValue",
247+
],
248+
"Effect": "Allow",
249+
"Resource": self.SourceAccessConfigurations[0].get("URI"),
250+
},
251+
{
252+
"Action": [
253+
"mq:DescribeBroker",
254+
],
255+
"Effect": "Allow",
256+
"Resource": self.Broker,
257+
},
258+
]
259+
},
260+
}
261+
if self.SecretsManagerKmsKeyId:
262+
kms_policy = {
263+
"Action": "kms:Decrypt",
264+
"Effect": "Allow",
265+
"Resource": {
266+
"Fn::Sub": "arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/"
267+
+ self.SecretsManagerKmsKeyId
268+
},
269+
}
270+
document["PolicyDocument"]["Statement"].append(kms_policy)
271+
return [document]
File renamed without changes.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Resources:
2+
MQFunction:
3+
Type: 'AWS::Serverless::Function'
4+
Properties:
5+
CodeUri: s3://sam-demo-bucket/queues.zip
6+
Handler: queue.mq_handler
7+
Runtime: python2.7
8+
Events:
9+
MyMQQueue:
10+
Type: MQ
11+
Properties:
12+
Broker: arn:aws:mq:us-east-2:123456789012:broker:MyBroker:b-1234a5b6-78cd-901e-2fgh-3i45j6k178l9
13+
Queues:
14+
- "Queue1"
15+
SourceAccessConfigurations:
16+
- Type: BASIC_AUTH
17+
URI: arn:aws:secretsmanager:us-west-2:123456789012:secret:my-path/my-secret-name-1a2b3c
18+
SecretsManagerKmsKeyId: 1abc23d4-567f-8ab9-cde0-1fab234c5d67

tests/translator/output/amq.json

Lines changed: 0 additions & 70 deletions
This file was deleted.

tests/translator/output/aws-cn/amq.json

Lines changed: 0 additions & 70 deletions
This file was deleted.

0 commit comments

Comments
 (0)