11import json
22from abc import ABCMeta
3- from typing import Any , Dict , Optional , cast
3+ from typing import Any , Dict , List , Optional , Union , cast
44
55from samtranslator .metrics .method_decorator import cw_timer
66from samtranslator .model import Property , PropertyType , Resource , ResourceMacro
1010from samtranslator .model .exceptions import InvalidEventException
1111from samtranslator .model .iam import IAMRole , IAMRolePolicies
1212from samtranslator .model .intrinsics import fnSub
13+ from samtranslator .model .stepfunctions .resources import StepFunctionsStateMachine
1314from samtranslator .model .types import IS_BOOL , IS_DICT , IS_STR , PassThrough
1415from samtranslator .swagger .swagger import SwaggerEditor
1516from samtranslator .translator import logical_id_generator
@@ -50,7 +51,13 @@ def _generate_logical_id(self, prefix, suffix, resource_type): # type: ignore[n
5051 generator = logical_id_generator .LogicalIdGenerator (prefix + resource_type , suffix )
5152 return generator .gen ()
5253
53- def _construct_role (self , resource , permissions_boundary = None , prefix = None , suffix = "" ): # type: ignore[no-untyped-def]
54+ def _construct_role (
55+ self ,
56+ resource : StepFunctionsStateMachine ,
57+ permissions_boundary : Optional [str ],
58+ prefix : Optional [str ],
59+ suffix : str = "" ,
60+ ) -> IAMRole :
5461 """Constructs the IAM Role resource allowing the event service to invoke
5562 the StartExecution API of the state machine resource it is associated with.
5663
@@ -93,6 +100,7 @@ class Schedule(EventSource):
93100 "DeadLetterConfig" : PropertyType (False , IS_DICT ),
94101 "RetryPolicy" : PropertyType (False , IS_DICT ),
95102 "Target" : Property (False , IS_DICT ),
103+ "RoleArn" : Property (False , IS_STR ),
96104 }
97105
98106 Schedule : PassThrough
@@ -104,6 +112,7 @@ class Schedule(EventSource):
104112 DeadLetterConfig : Optional [Dict [str , Any ]]
105113 RetryPolicy : Optional [PassThrough ]
106114 Target : Optional [PassThrough ]
115+ RoleArn : Optional [PassThrough ]
107116
108117 @cw_timer (prefix = SFN_EVETSOURCE_METRIC_PREFIX )
109118 def to_cloudformation (self , resource , ** kwargs ): # type: ignore[no-untyped-def]
@@ -113,7 +122,7 @@ def to_cloudformation(self, resource, **kwargs): # type: ignore[no-untyped-def]
113122 :returns: a list of vanilla CloudFormation Resources, to which this Schedule event expands
114123 :rtype: list
115124 """
116- resources = []
125+ resources : List [ Any ] = []
117126
118127 permissions_boundary = kwargs .get ("permissions_boundary" )
119128
@@ -135,8 +144,12 @@ def to_cloudformation(self, resource, **kwargs): # type: ignore[no-untyped-def]
135144 events_rule .Name = self .Name
136145 events_rule .Description = self .Description
137146
138- role = self ._construct_role (resource , permissions_boundary ) # type: ignore[no-untyped-call]
139- resources .append (role )
147+ role : Union [IAMRole , str , Dict [str , Any ]]
148+ if self .RoleArn is None :
149+ role = self ._construct_role (resource , permissions_boundary , prefix = None )
150+ resources .append (role )
151+ else :
152+ role = self .RoleArn
140153
141154 source_arn = events_rule .get_runtime_attr ("arn" )
142155 dlq_queue_arn = None
@@ -146,26 +159,44 @@ def to_cloudformation(self, resource, **kwargs): # type: ignore[no-untyped-def]
146159 self , source_arn , passthrough_resource_attributes
147160 )
148161 resources .extend (dlq_resources )
149- events_rule .Targets = [self ._construct_target (resource , role , dlq_queue_arn )] # type: ignore[no-untyped-call]
162+ events_rule .Targets = [self ._construct_target (resource , role , dlq_queue_arn )]
150163
151164 return resources
152165
153- def _construct_target (self , resource , role , dead_letter_queue_arn = None ): # type: ignore[no-untyped-def]
154- """Constructs the Target property for the EventBridge Rule.
155-
156- :returns: the Target property
157- :rtype: dict
166+ def _construct_target (
167+ self ,
168+ resource : StepFunctionsStateMachine ,
169+ role : Union [IAMRole , str , Dict [str , Any ]],
170+ dead_letter_queue_arn : Optional [str ],
171+ ) -> Dict [str , Any ]:
172+ """_summary_
173+
174+ Parameters
175+ ----------
176+ resource
177+ StepFunctionsState machine resource to be generated
178+ role
179+ The role to be used by the Schedule event resource either generated or user provides arn
180+ dead_letter_queue_arn
181+ Dead letter queue associated with the resource
182+
183+ Returns
184+ -------
185+ The Target property
158186 """
159187 target_id = (
160188 self .Target ["Id" ]
161189 if self .Target and "Id" in self .Target
162190 else generate_valid_target_id (self .logical_id , EVENT_RULE_SFN_TARGET_SUFFIX )
163191 )
192+
164193 target = {
165194 "Arn" : resource .get_runtime_attr ("arn" ),
166195 "Id" : target_id ,
167- "RoleArn" : role .get_runtime_attr ("arn" ),
168196 }
197+
198+ target ["RoleArn" ] = role .get_runtime_attr ("arn" ) if isinstance (role , IAMRole ) else role
199+
169200 if self .Input is not None :
170201 target ["Input" ] = self .Input
171202
@@ -216,7 +247,7 @@ def to_cloudformation(self, resource, **kwargs): # type: ignore[no-untyped-def]
216247 :returns: a list of vanilla CloudFormation Resources, to which this CloudWatch Events/EventBridge event expands
217248 :rtype: list
218249 """
219- resources = []
250+ resources : List [ Any ] = []
220251
221252 permissions_boundary = kwargs .get ("permissions_boundary" )
222253
@@ -231,7 +262,11 @@ def to_cloudformation(self, resource, **kwargs): # type: ignore[no-untyped-def]
231262
232263 resources .append (events_rule )
233264
234- role = self ._construct_role (resource , permissions_boundary ) # type: ignore[no-untyped-call]
265+ role = self ._construct_role (
266+ resource ,
267+ permissions_boundary ,
268+ prefix = None ,
269+ )
235270 resources .append (role )
236271
237272 source_arn = events_rule .get_runtime_attr ("arn" )
@@ -331,7 +366,7 @@ def to_cloudformation(self, resource, **kwargs): # type: ignore[no-untyped-def]
331366 :returns: a list of vanilla CloudFormation Resources, to which this Api event expands
332367 :rtype: list
333368 """
334- resources = []
369+ resources : List [ Any ] = []
335370
336371 intrinsics_resolver = kwargs .get ("intrinsics_resolver" )
337372 permissions_boundary = kwargs .get ("permissions_boundary" )
@@ -340,7 +375,7 @@ def to_cloudformation(self, resource, **kwargs): # type: ignore[no-untyped-def]
340375 # Convert to lower case so that user can specify either GET or get
341376 self .Method = self .Method .lower ()
342377
343- role = self ._construct_role (resource , permissions_boundary ) # type: ignore[no-untyped-call]
378+ role = self ._construct_role (resource , permissions_boundary , prefix = None )
344379 resources .append (role )
345380
346381 explicit_api = kwargs ["explicit_api" ]
0 commit comments