5
5
select_parameters ,
6
6
)
7
7
from localstack .services .cloudformation .service_models import GenericBaseModel
8
- from localstack .utils .aws import aws_stack
9
8
from localstack .utils .collections import select_attributes
10
9
from localstack .utils .common import short_uid
11
10
@@ -17,7 +16,7 @@ def cloudformation_type():
17
16
18
17
def fetch_state (self , stack_name , resources ):
19
18
param_name = self .props .get ("Name" ) or self .logical_resource_id
20
- return aws_stack . connect_to_service ( "ssm" ) .get_parameter (Name = param_name )["Parameter" ]
19
+ return connect_to (). ssm .get_parameter (Name = param_name )["Parameter" ]
21
20
22
21
@staticmethod
23
22
def add_defaults (resource , stack_name : str ):
@@ -80,8 +79,7 @@ def update_resource(self, new_resource, stack_name, resources):
80
79
81
80
@staticmethod
82
81
def get_deploy_templates ():
83
- def _handle_result (result , resource_id , resources , resource_type ):
84
- resource = resources [resource_id ]
82
+ def _handle_result (result , logical_resource_id , resource ):
85
83
resource ["PhysicalResourceId" ] = resource ["Properties" ]["Name" ]
86
84
87
85
return {
@@ -104,3 +102,188 @@ def _handle_result(result, resource_id, resources, resource_type):
104
102
},
105
103
"delete" : {"function" : "delete_parameter" , "parameters" : ["Name" ]},
106
104
}
105
+
106
+
107
+ class SSMMaintenanceWindow (GenericBaseModel ):
108
+ @staticmethod
109
+ def cloudformation_type ():
110
+ return "AWS::SSM::MaintenanceWindow"
111
+
112
+ def fetch_state (self , stack_name , resources ):
113
+ if not self .physical_resource_id :
114
+ return None
115
+ maintenance_windows = connect_to ().ssm .describe_maintenance_windows ()["WindowIdentities" ]
116
+ for maintenance_window in maintenance_windows :
117
+ if maintenance_window ["WindowId" ] == self .physical_resource_id :
118
+ return maintenance_window
119
+
120
+ @staticmethod
121
+ def get_deploy_templates ():
122
+ def _delete_window (logical_resource_id , resource , stack_name ):
123
+ connect_to ().ssm .delete_maintenance_window (WindowId = resource ["PhysicalResourceId" ])
124
+
125
+ def _handle_result (result , logical_resource_id , resource ):
126
+ resource ["PhysicalResourceId" ] = result ["WindowId" ]
127
+
128
+ return {
129
+ "create" : {
130
+ "function" : "create_maintenance_window" ,
131
+ "parameters" : select_parameters (
132
+ "AllowUnassociatedTargets" ,
133
+ "Cutoff" ,
134
+ "Duration" ,
135
+ "Name" ,
136
+ "Schedule" ,
137
+ "ScheduleOffset" ,
138
+ "ScheduleTimezone" ,
139
+ "StartDate" ,
140
+ "EndDate" ,
141
+ "Description" ,
142
+ "Tags" ,
143
+ ),
144
+ "result_handler" : _handle_result ,
145
+ },
146
+ "delete" : {"function" : _delete_window },
147
+ }
148
+
149
+
57AE
150
+ class SSMMaintenanceWindowTarget (GenericBaseModel ):
151
+ @staticmethod
152
+ def cloudformation_type ():
153
+ return "AWS::SSM::MaintenanceWindowTarget"
154
+
155
+ def fetch_state (self , stack_name , resources ):
156
+ targets = connect_to ().ssm .describe_maintenance_window_targets (
157
+ WindowTargetId = self .props .get ("WindowTargetId" )
158
+ )["Targets" ]
159
+ targets = [
160
+ target for target in targets if target ["WindowTargetId" ] == self .physical_resource_id
161
+ ]
162
+ return targets [0 ] if targets else None
163
+
164
B41A
+ @staticmethod
165
+ def get_deploy_templates ():
166
+ def _delete_window_target (logical_resource_id , resource , stack_name ):
167
+ connect_to ().ssm .deregister_target_from_maintenance_window (
168
+ WindowId = resource ["Properties" ]["WindowId" ],
169
+ WindowTargetId = resource ["PhysicalResourceId" ],
170
+ )
171
+
172
+ def _handle_result (result , logical_resource_id , resource ):
173
+ resource ["PhysicalResourceId" ] = result ["WindowTargetId" ]
174
+
175
+ return {
176
+ "create" : {
177
+ "function" : "register_target_with_maintenance_window" ,
178
+ "parameters" : select_parameters (
179
+ "Description" ,
180
+ "Name" ,
181
+ "OwnerInformation" ,
182
+ "ResourceType" ,
183
+ "Targets" ,
184
+ "WindowId" ,
185
+ ),
186
+ "result_handler" : _handle_result ,
187
+ },
188
+ "delete" : {"function" : _delete_window_target },
189
+ }
190
+
191
+
192
+ class SSMMaintenanceTask (GenericBaseModel ):
193
+ @staticmethod
194
+ def cloudformation_type ():
195
+ return "AWS::SSM::MaintenanceWindowTask"
196
+
197
+ def fetch_state (self , stack_name , resources ):
198
+ return connect_to ().ssm .describe_maintenance_window_task (
199
+ WindowTaskId = self .props .get ("WindowTaskId" )
200
+ )["WindowTaskId" ]
201
+
202
+ @staticmethod
203
+ def get_deploy_templates ():
204
+ def _delete_window_task (logical_resource_id , resource , stack_name ):
205
+ connect_to ().ssm .deregister_task_from_maintenance_window (
206
+ WindowId = resource ["Properties" ]["WindowId" ],
207
+ WindowTaskId = resource ["PhysicalResourceId" ],
208
+ )
209
+
210
+ def _handle_result (result , logical_resource_id , resource ):
211
+ resource ["PhysicalResourceId" ] = result ["WindowTaskId" ]
212
+
213
+ def _params (properties , logical_resource_id , resource_def , stack_name ):
214
+ kwargs = {
215
+ "Description" : properties .get ("Description" ),
216
+ "Name" : properties .get ("Name" ),
217
+ "OwnerInformation" : properties .get ("OwnerInformation" ),
218
+ "Priority" : properties .get ("Priority" ),
219
+ "ServiceRoleArn" : properties .get ("ServiceRoleArn" ),
220
+ "Targets" : properties .get ("Targets" ),
221
+ "TaskArn" : properties .get ("TaskArn" ),
222
+ "TaskParameters" : properties .get ("TaskParameters" ),
223
+ "TaskType" : properties .get ("TaskType" ),
224
+ "WindowId" : properties .get ("WindowId" ),
225
+ }
226
+
227
+ if invocation_params := properties .get ("TaskInvocationParameters" ):
228
+ task_type_map = {
229
+ "MaintenanceWindowAutomationParameters" : "Automation" ,
230
+ "MaintenanceWindowLambdaParameters" : "Lambda" ,
231
+ "MaintenanceWindowRunCommandParameters" : "RunCommand" ,
232
+ "MaintenanceWindowStepFunctionsParameters" : "StepFunctions" ,
233
+ }
234
+ kwargs ["TaskInvocationParameters" ] = {
235
+ task_type_map [k ]: v for k , v in invocation_params .items ()
236
+ }
237
+
238
+ return kwargs
239
+
240
+ return {
241
+ "create" : {
242
+ "function" : "register_task_with_maintenance_window" ,
243
+ "parameters" : _params ,
244
+ "result_handler" : _handle_result ,
245
+ },
246
+ "delete" : {"function" : _delete_window_task },
247
+ }
248
+
249
+
250
+ class SSMPatchBaseline (GenericBaseModel ):
251
+ @staticmethod
252
+ def cloudformation_type ():
253
+ return "AWS::SSM::PatchBaseline"
254
+
255
+ def fetch_state (self , stack_name , resources ):
256
+ return connect_to ().ssm .describe_patch_baselines (BaselineId = self .props .get ("BaselineId" ))[
257
+ "BaselineId"
258
+ ]
259
+
260
+ @staticmethod
261
+ def get_deploy_templates ():
262
+ def _delete_patch_baseline (logical_resource_id , resource , stack_name ):
263
+ connect_to ().ssm .delete_patch_baseline (BaselineId = resource ["PhysicalResourceId" ])
264
+
265
+ def _handle_result (result , logical_resource_id , resource ):
266
+ resource ["PhysicalResourceId" ] = result ["BaselineId" ]
267
+
268
+ return {
269
+ "create" : {
270
+ "function" : "create_patch_baseline" ,
271
+ "parameters" : select_parameters (
272
+ "OperatingSystem" ,
273
+ "Name" ,
274
+ "GlobalFilters" ,
275
+ "ApprovalRules" ,
276
+ "ApprovedPatches" ,
277
+ "ApprovedPatchesComplianceLevel" ,
278
+ "ApprovedPatchesEnableNonSecurity" ,
279
+ "RejectedPatches" ,
280
+ "RejectedPatchesAction" ,
281
+ "Description" ,
282
+ "Sources" ,
283
+ "ClientToken" ,
284
+ "Tags" ,
285
+ ),
286
+ "result_handler" : _handle_result ,
287
+ },
288
+ "delete" : {"function" : _delete_patch_baseline },
289
+ }
0 commit comments