localstack-core 4.4.1.dev61__py3-none-any.whl → 4.4.1.dev63__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- localstack/aws/api/ec2/__init__.py +70 -2
- localstack/aws/api/s3/__init__.py +2 -0
- localstack/services/cloudformation/engine/v2/change_set_model.py +102 -144
- localstack/services/cloudformation/engine/v2/change_set_model_describer.py +9 -7
- localstack/services/cloudformation/engine/v2/change_set_model_executor.py +7 -6
- localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +118 -118
- localstack/services/s3/provider.py +3 -2
- localstack/version.py +2 -2
- {localstack_core-4.4.1.dev61.dist-info → localstack_core-4.4.1.dev63.dist-info}/METADATA +3 -3
- {localstack_core-4.4.1.dev61.dist-info → localstack_core-4.4.1.dev63.dist-info}/RECORD +18 -18
- localstack_core-4.4.1.dev63.dist-info/plux.json +1 -0
- localstack_core-4.4.1.dev61.dist-info/plux.json +0 -1
- {localstack_core-4.4.1.dev61.data → localstack_core-4.4.1.dev63.data}/scripts/localstack +0 -0
- {localstack_core-4.4.1.dev61.data → localstack_core-4.4.1.dev63.data}/scripts/localstack-supervisor +0 -0
- {localstack_core-4.4.1.dev61.data → localstack_core-4.4.1.dev63.data}/scripts/localstack.bat +0 -0
- {localstack_core-4.4.1.dev61.dist-info → localstack_core-4.4.1.dev63.dist-info}/WHEEL +0 -0
- {localstack_core-4.4.1.dev61.dist-info → localstack_core-4.4.1.dev63.dist-info}/entry_points.txt +0 -0
- {localstack_core-4.4.1.dev61.dist-info → localstack_core-4.4.1.dev63.dist-info}/licenses/LICENSE.txt +0 -0
- {localstack_core-4.4.1.dev61.dist-info → localstack_core-4.4.1.dev63.dist-info}/top_level.txt +0 -0
@@ -8,7 +8,9 @@ from localstack.services.cloudformation.engine.v2.change_set_model import (
|
|
8
8
|
NodeIntrinsicFunction,
|
9
9
|
NodeProperty,
|
10
10
|
NodeResource,
|
11
|
+
Nothing,
|
11
12
|
PropertiesKey,
|
13
|
+
is_nothing,
|
12
14
|
)
|
13
15
|
from localstack.services.cloudformation.engine.v2.change_set_model_preproc import (
|
14
16
|
ChangeSetModelPreproc,
|
@@ -53,8 +55,8 @@ class ChangeSetModelDescriber(ChangeSetModelPreproc):
|
|
53
55
|
if isinstance(after_argument, str):
|
54
56
|
after_argument = after_argument.split(".")
|
55
57
|
|
56
|
-
before =
|
57
|
-
if before_argument:
|
58
|
+
before = Nothing
|
59
|
+
if not is_nothing(before_argument):
|
58
60
|
before_logical_name_of_resource = before_argument[0]
|
59
61
|
before_attribute_name = before_argument[1]
|
60
62
|
before_node_resource = self._get_node_resource_for(
|
@@ -72,8 +74,8 @@ class ChangeSetModelDescriber(ChangeSetModelPreproc):
|
|
72
74
|
property_name=before_attribute_name,
|
73
75
|
)
|
74
76
|
|
75
|
-
after =
|
76
|
-
if after_argument:
|
77
|
+
after = Nothing
|
78
|
+
if not is_nothing(after_argument):
|
77
79
|
after_logical_name_of_resource = after_argument[0]
|
78
80
|
after_attribute_name = after_argument[1]
|
79
81
|
after_node_resource = self._get_node_resource_for(
|
@@ -154,7 +156,7 @@ class ChangeSetModelDescriber(ChangeSetModelPreproc):
|
|
154
156
|
if before == after:
|
155
157
|
# unchanged: nothing to do.
|
156
158
|
return
|
157
|
-
if
|
159
|
+
if not is_nothing(before) and not is_nothing(after):
|
158
160
|
# Case: change on same type.
|
159
161
|
if before.resource_type == after.resource_type:
|
160
162
|
# Register a Modified if changed.
|
@@ -184,7 +186,7 @@ class ChangeSetModelDescriber(ChangeSetModelPreproc):
|
|
184
186
|
before_properties=None,
|
185
187
|
after_properties=after.properties,
|
186
188
|
)
|
187
|
-
elif
|
189
|
+
elif not is_nothing(before):
|
188
190
|
# Case: removal
|
189
191
|
self._register_resource_change(
|
190
192
|
logical_id=name,
|
@@ -193,7 +195,7 @@ class ChangeSetModelDescriber(ChangeSetModelPreproc):
|
|
193
195
|
before_properties=before.properties,
|
194
196
|
after_properties=None,
|
195
197
|
)
|
196
|
-
elif
|
198
|
+
elif not is_nothing(after):
|
197
199
|
# Case: addition
|
198
200
|
self._register_resource_change(
|
199
201
|
logical_id=name,
|
@@ -11,6 +11,7 @@ from localstack.services.cloudformation.engine.v2.change_set_model import (
|
|
11
11
|
NodeOutput,
|
12
12
|
NodeParameter,
|
13
13
|
NodeResource,
|
14
|
+
is_nothing,
|
14
15
|
)
|
15
16
|
from localstack.services.cloudformation.engine.v2.change_set_model_preproc import (
|
16
17
|
ChangeSetModelPreproc,
|
@@ -113,13 +114,13 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
|
|
113
114
|
# There are no updates for this resource; iff the resource was previously
|
114
115
|
# deployed, then the resolved details are copied in the current state for
|
115
116
|
# references or other downstream operations.
|
116
|
-
if
|
117
|
+
if not is_nothing(before):
|
117
118
|
before_logical_id = delta.before.logical_id
|
118
119
|
before_resource = self._before_resolved_resources.get(before_logical_id, dict())
|
119
120
|
self.resources[before_logical_id] = before_resource
|
120
121
|
|
121
122
|
# Update the latest version of this resource for downstream references.
|
122
|
-
if
|
123
|
+
if not is_nothing(after):
|
123
124
|
after_logical_id = after.logical_id
|
124
125
|
after_physical_id: str = self._after_resource_physical_id(
|
125
126
|
resource_logical_id=after_logical_id
|
@@ -132,7 +133,7 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
|
|
132
133
|
) -> PreprocEntityDelta[PreprocOutput, PreprocOutput]:
|
133
134
|
delta = super().visit_node_output(node_output=node_output)
|
134
135
|
after = delta.after
|
135
|
-
if after
|
136
|
+
if is_nothing(after) or (isinstance(after, PreprocOutput) and after.condition is False):
|
136
137
|
return delta
|
137
138
|
self.outputs[delta.after.name] = delta.after.value
|
138
139
|
return delta
|
@@ -142,7 +143,7 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
|
|
142
143
|
) -> None:
|
143
144
|
# Changes are to be made about this resource.
|
144
145
|
# TODO: this logic is a POC and should be revised.
|
145
|
-
if
|
146
|
+
if not is_nothing(before) and not is_nothing(after):
|
146
147
|
# Case: change on same type.
|
147
148
|
if before.resource_type == after.resource_type:
|
148
149
|
# Register a Modified if changed.
|
@@ -177,7 +178,7 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
|
|
177
178
|
before_properties=None,
|
178
179
|
after_properties=after.properties,
|
179
180
|
)
|
180
|
-
elif
|
181
|
+
elif not is_nothing(before):
|
181
182
|
# Case: removal
|
182
183
|
# XXX hacky, stick the previous resources' properties into the payload
|
183
184
|
# XXX hacky, stick the previous resources' properties into the payload
|
@@ -190,7 +191,7 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
|
|
190
191
|
before_properties=before_properties,
|
191
192
|
after_properties=None,
|
192
193
|
)
|
193
|
-
elif
|
194
|
+
elif not is_nothing(after):
|
194
195
|
# Case: addition
|
195
196
|
self._execute_resource_action(
|
196
197
|
action=ChangeAction.Add,
|
@@ -11,6 +11,7 @@ from localstack.services.cloudformation.engine.transformers import (
|
|
11
11
|
from localstack.services.cloudformation.engine.v2.change_set_model import (
|
12
12
|
ChangeSetEntity,
|
13
13
|
ChangeType,
|
14
|
+
Maybe,
|
14
15
|
NodeArray,
|
15
16
|
NodeCondition,
|
16
17
|
NodeDependsOn,
|
@@ -25,12 +26,14 @@ from localstack.services.cloudformation.engine.v2.change_set_model import (
|
|
25
26
|
NodeProperty,
|
26
27
|
NodeResource,
|
27
28
|
NodeTemplate,
|
29
|
+
Nothing,
|
28
30
|
Scope,
|
29
31
|
TerminalValue,
|
30
32
|
TerminalValueCreated,
|
31
33
|
TerminalValueModified,
|
32
34
|
TerminalValueRemoved,
|
33
35
|
TerminalValueUnchanged,
|
36
|
+
is_nothing,
|
34
37
|
)
|
35
38
|
from localstack.services.cloudformation.engine.v2.change_set_model_visitor import (
|
36
39
|
ChangeSetModelVisitor,
|
@@ -58,10 +61,10 @@ TAfter = TypeVar("TAfter")
|
|
58
61
|
|
59
62
|
|
60
63
|
class PreprocEntityDelta(Generic[TBefore, TAfter]):
|
61
|
-
before:
|
62
|
-
after:
|
64
|
+
before: Maybe[TBefore]
|
65
|
+
after: Maybe[TAfter]
|
63
66
|
|
64
|
-
def __init__(self, before:
|
67
|
+
def __init__(self, before: Maybe[TBefore] = Nothing, after: Maybe[TAfter] = Nothing):
|
65
68
|
self.before = before
|
66
69
|
self.after = after
|
67
70
|
|
@@ -200,7 +203,6 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
200
203
|
_ = self._get_node_resource_for(
|
201
204
|
resource_name=resource_logical_id, node_template=self._node_template
|
202
205
|
)
|
203
|
-
|
204
206
|
resolved_resource = resolved_resources.get(resource_logical_id)
|
205
207
|
if resolved_resource is None:
|
206
208
|
raise RuntimeError(
|
@@ -237,26 +239,25 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
237
239
|
if mapping.name == map_name:
|
238
240
|
self.visit(mapping)
|
239
241
|
return mapping
|
240
|
-
|
241
|
-
raise RuntimeError()
|
242
|
+
raise RuntimeError(f"Undefined '{map_name}' mapping")
|
242
243
|
|
243
|
-
def _get_node_parameter_if_exists(self, parameter_name: str) ->
|
244
|
+
def _get_node_parameter_if_exists(self, parameter_name: str) -> Maybe[NodeParameter]:
|
244
245
|
parameters: list[NodeParameter] = self._node_template.parameters.parameters
|
245
246
|
# TODO: another scenarios suggesting property lookups might be preferable.
|
246
247
|
for parameter in parameters:
|
247
248
|
if parameter.name == parameter_name:
|
248
249
|
self.visit(parameter)
|
249
250
|
return parameter
|
250
|
-
return
|
251
|
+
return Nothing
|
251
252
|
|
252
|
-
def _get_node_condition_if_exists(self, condition_name: str) ->
|
253
|
+
def _get_node_condition_if_exists(self, condition_name: str) -> Maybe[NodeCondition]:
|
253
254
|
conditions: list[NodeCondition] = self._node_template.conditions.conditions
|
254
255
|
# TODO: another scenarios suggesting property lookups might be preferable.
|
255
256
|
for condition in conditions:
|
256
257
|
if condition.name == condition_name:
|
257
258
|
self.visit(condition)
|
258
259
|
return condition
|
259
|
-
return
|
260
|
+
return Nothing
|
260
261
|
|
261
262
|
def _resolve_condition(self, logical_id: str) -> PreprocEntityDelta:
|
262
263
|
node_condition = self._get_node_condition_if_exists(condition_name=logical_id)
|
@@ -280,14 +281,9 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
280
281
|
case "AWS::URLSuffix":
|
281
282
|
return _AWS_URL_SUFFIX
|
282
283
|
case "AWS::NoValue":
|
283
|
-
|
284
|
-
raise NotImplementedError("The use of AWS:NoValue is currently unsupported")
|
285
|
-
case "AWS::NotificationARNs":
|
286
|
-
raise NotImplementedError(
|
287
|
-
"The use of AWS::NotificationARNs is currently unsupported"
|
288
|
-
)
|
284
|
+
return None
|
289
285
|
case _:
|
290
|
-
raise RuntimeError(f"
|
286
|
+
raise RuntimeError(f"The use of '{pseudo_parameter_name}' is currently unsupported")
|
291
287
|
|
292
288
|
def _resolve_reference(self, logical_id: str) -> PreprocEntityDelta:
|
293
289
|
if logical_id in _PSEUDO_PARAMETERS:
|
@@ -323,11 +319,12 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
323
319
|
return mapping_value_delta
|
324
320
|
|
325
321
|
def visit(self, change_set_entity: ChangeSetEntity) -> PreprocEntityDelta:
|
326
|
-
|
327
|
-
if
|
322
|
+
scope = change_set_entity.scope
|
323
|
+
if scope in self._processed:
|
324
|
+
delta = self._processed[scope]
|
328
325
|
return delta
|
329
326
|
delta = super().visit(change_set_entity=change_set_entity)
|
330
|
-
self._processed[
|
327
|
+
self._processed[scope] = delta
|
331
328
|
return delta
|
332
329
|
|
333
330
|
def visit_terminal_value_modified(
|
@@ -362,21 +359,17 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
362
359
|
return PreprocEntityDelta(before=before_delta.before, after=after_delta.after)
|
363
360
|
|
364
361
|
def visit_node_object(self, node_object: NodeObject) -> PreprocEntityDelta:
|
365
|
-
|
366
|
-
|
362
|
+
node_change_type = node_object.change_type
|
363
|
+
before = dict() if node_change_type != ChangeType.CREATED else Nothing
|
364
|
+
after = dict() if node_change_type != ChangeType.REMOVED else Nothing
|
367
365
|
for name, change_set_entity in node_object.bindings.items():
|
368
366
|
delta: PreprocEntityDelta = self.visit(change_set_entity=change_set_entity)
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
case ChangeType.REMOVED:
|
376
|
-
before[name] = delta.before
|
377
|
-
case ChangeType.UNCHANGED:
|
378
|
-
before[name] = delta.before
|
379
|
-
after[name] = delta.before
|
367
|
+
delta_before = delta.before
|
368
|
+
delta_after = delta.after
|
369
|
+
if not is_nothing(before) and not is_nothing(delta_before) and delta_before is not None:
|
370
|
+
before[name] = delta_before
|
371
|
+
if not is_nothing(after) and not is_nothing(delta_after) and delta_after is not None:
|
372
|
+
after[name] = delta_after
|
380
373
|
return PreprocEntityDelta(before=before, after=after)
|
381
374
|
|
382
375
|
def visit_node_intrinsic_function_fn_get_att(
|
@@ -384,14 +377,14 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
384
377
|
) -> PreprocEntityDelta:
|
385
378
|
# TODO: validate the return value according to the spec.
|
386
379
|
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
387
|
-
before_argument:
|
380
|
+
before_argument: Maybe[list[str]] = arguments_delta.before
|
388
381
|
if isinstance(before_argument, str):
|
389
382
|
before_argument = before_argument.split(".")
|
390
|
-
after_argument:
|
383
|
+
after_argument: Maybe[list[str]] = arguments_delta.after
|
391
384
|
if isinstance(after_argument, str):
|
392
385
|
after_argument = after_argument.split(".")
|
393
386
|
|
394
|
-
before =
|
387
|
+
before = Nothing
|
395
388
|
if before_argument:
|
396
389
|
before_logical_name_of_resource = before_argument[0]
|
397
390
|
before_attribute_name = before_argument[1]
|
@@ -414,7 +407,7 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
414
407
|
property_name=before_attribute_name,
|
415
408
|
)
|
416
409
|
|
417
|
-
after =
|
410
|
+
after = Nothing
|
418
411
|
if after_argument:
|
419
412
|
after_logical_name_of_resource = after_argument[0]
|
420
413
|
after_attribute_name = after_argument[1]
|
@@ -444,10 +437,10 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
444
437
|
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
445
438
|
before_values = arguments_delta.before
|
446
439
|
after_values = arguments_delta.after
|
447
|
-
before =
|
440
|
+
before = Nothing
|
448
441
|
if before_values:
|
449
442
|
before = before_values[0] == before_values[1]
|
450
|
-
after =
|
443
|
+
after = Nothing
|
451
444
|
if after_values:
|
452
445
|
after = after_values[0] == after_values[1]
|
453
446
|
return PreprocEntityDelta(before=before, after=after)
|
@@ -456,6 +449,8 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
456
449
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
457
450
|
) -> PreprocEntityDelta:
|
458
451
|
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
452
|
+
arguments_before = arguments_delta.before
|
453
|
+
arguments_after = arguments_delta.after
|
459
454
|
|
460
455
|
def _compute_delta_for_if_statement(args: list[Any]) -> PreprocEntityDelta:
|
461
456
|
condition_name = args[0]
|
@@ -466,13 +461,13 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
466
461
|
)
|
467
462
|
|
468
463
|
# TODO: add support for this being created or removed.
|
469
|
-
before =
|
470
|
-
if
|
471
|
-
before_outcome_delta = _compute_delta_for_if_statement(
|
464
|
+
before = Nothing
|
465
|
+
if not is_nothing(arguments_before):
|
466
|
+
before_outcome_delta = _compute_delta_for_if_statement(arguments_before)
|
472
467
|
before = before_outcome_delta.before
|
473
|
-
after =
|
474
|
-
if
|
475
|
-
after_outcome_delta = _compute_delta_for_if_statement(
|
468
|
+
after = Nothing
|
469
|
+
if not is_nothing(arguments_after):
|
470
|
+
after_outcome_delta = _compute_delta_for_if_statement(arguments_after)
|
476
471
|
after = after_outcome_delta.after
|
477
472
|
return PreprocEntityDelta(before=before, after=after)
|
478
473
|
|
@@ -482,17 +477,14 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
482
477
|
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
483
478
|
before_condition = arguments_delta.before
|
484
479
|
after_condition = arguments_delta.after
|
485
|
-
|
480
|
+
before = Nothing
|
481
|
+
if not is_nothing(before_condition):
|
486
482
|
before_condition_outcome = before_condition[0]
|
487
483
|
before = not before_condition_outcome
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
if after_condition:
|
484
|
+
after = Nothing
|
485
|
+
if not is_nothing(after_condition):
|
492
486
|
after_condition_outcome = after_condition[0]
|
493
487
|
after = not after_condition_outcome
|
494
|
-
else:
|
495
|
-
after = None
|
496
488
|
# Implicit change type computation.
|
497
489
|
return PreprocEntityDelta(before=before, after=after)
|
498
490
|
|
@@ -560,11 +552,11 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
560
552
|
# TODO: add tests to review the behaviour of CFN with changes to transformation
|
561
553
|
# function code and no changes to the template.
|
562
554
|
|
563
|
-
before =
|
564
|
-
if arguments_before:
|
555
|
+
before = Nothing
|
556
|
+
if not is_nothing(arguments_before):
|
565
557
|
before = self._compute_fn_transform(args=arguments_before)
|
566
|
-
after =
|
567
|
-
if arguments_after:
|
558
|
+
after = Nothing
|
559
|
+
if not is_nothing(arguments_after):
|
568
560
|
after = self._compute_fn_transform(args=arguments_after)
|
569
561
|
return PreprocEntityDelta(before=before, after=after)
|
570
562
|
|
@@ -606,9 +598,9 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
606
598
|
template_variable_value = sub_parameters[template_variable_name]
|
607
599
|
else:
|
608
600
|
try:
|
609
|
-
|
601
|
+
resource_delta = self._resolve_reference(logical_id=template_variable_name)
|
610
602
|
template_variable_value = (
|
611
|
-
|
603
|
+
resource_delta.before if select_before else resource_delta.after
|
612
604
|
)
|
613
605
|
if isinstance(template_variable_value, PreprocResource):
|
614
606
|
template_variable_value = template_variable_value.logical_id
|
@@ -621,19 +613,11 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
621
613
|
)
|
622
614
|
return sub_string
|
623
615
|
|
624
|
-
before =
|
625
|
-
if (
|
626
|
-
isinstance(arguments_before, str)
|
627
|
-
or isinstance(arguments_before, list)
|
628
|
-
and len(arguments_before) == 2
|
629
|
-
):
|
616
|
+
before = Nothing
|
617
|
+
if not is_nothing(arguments_before):
|
630
618
|
before = _compute_sub(args=arguments_before, select_before=True)
|
631
|
-
after =
|
632
|
-
if (
|
633
|
-
isinstance(arguments_after, str)
|
634
|
-
or isinstance(arguments_after, list)
|
635
|
-
and len(arguments_after) == 2
|
636
|
-
):
|
619
|
+
after = Nothing
|
620
|
+
if not is_nothing(arguments_after):
|
637
621
|
after = _compute_sub(args=arguments_after)
|
638
622
|
return PreprocEntityDelta(before=before, after=after)
|
639
623
|
|
@@ -654,10 +638,10 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
654
638
|
join_result = delimiter.join(map(str, values))
|
655
639
|
return join_result
|
656
640
|
|
657
|
-
before =
|
641
|
+
before = Nothing
|
658
642
|
if isinstance(arguments_before, list) and len(arguments_before) == 2:
|
659
643
|
before = _compute_join(arguments_before)
|
660
|
-
after =
|
644
|
+
after = Nothing
|
661
645
|
if isinstance(arguments_after, list) and len(arguments_after) == 2:
|
662
646
|
after = _compute_join(arguments_after)
|
663
647
|
return PreprocEntityDelta(before=before, after=after)
|
@@ -669,16 +653,14 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
669
653
|
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
670
654
|
before_arguments = arguments_delta.before
|
671
655
|
after_arguments = arguments_delta.after
|
656
|
+
before = Nothing
|
672
657
|
if before_arguments:
|
673
658
|
before_value_delta = self._resolve_mapping(*before_arguments)
|
674
659
|
before = before_value_delta.before
|
675
|
-
|
676
|
-
before = None
|
660
|
+
after = Nothing
|
677
661
|
if after_arguments:
|
678
662
|
after_value_delta = self._resolve_mapping(*after_arguments)
|
679
663
|
after = after_value_delta.after
|
680
|
-
else:
|
681
|
-
after = None
|
682
664
|
return PreprocEntityDelta(before=before, after=after)
|
683
665
|
|
684
666
|
def visit_node_mapping(self, node_mapping: NodeMapping) -> PreprocEntityDelta:
|
@@ -733,15 +715,15 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
733
715
|
after_logical_id = arguments_delta.after
|
734
716
|
|
735
717
|
# TODO: extend this to support references to other types.
|
736
|
-
before =
|
737
|
-
if
|
718
|
+
before = Nothing
|
719
|
+
if not is_nothing(before_logical_id):
|
738
720
|
before_delta = self._resolve_reference(logical_id=before_logical_id)
|
739
721
|
before = before_delta.before
|
740
722
|
if isinstance(before, PreprocResource):
|
741
723
|
before = before.physical_resource_id
|
742
724
|
|
743
|
-
after =
|
744
|
-
if
|
725
|
+
after = Nothing
|
726
|
+
if not is_nothing(after_logical_id):
|
745
727
|
after_delta = self._resolve_reference(logical_id=after_logical_id)
|
746
728
|
after = after_delta.after
|
747
729
|
if isinstance(after, PreprocResource):
|
@@ -750,14 +732,17 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
750
732
|
return PreprocEntityDelta(before=before, after=after)
|
751
733
|
|
752
734
|
def visit_node_array(self, node_array: NodeArray) -> PreprocEntityDelta:
|
753
|
-
|
754
|
-
|
735
|
+
node_change_type = node_array.change_type
|
736
|
+
before = list() if node_change_type != ChangeType.CREATED else Nothing
|
737
|
+
after = list() if node_change_type != ChangeType.REMOVED else Nothing
|
755
738
|
for change_set_entity in node_array.array:
|
756
739
|
delta: PreprocEntityDelta = self.visit(change_set_entity=change_set_entity)
|
757
|
-
|
758
|
-
|
759
|
-
if
|
760
|
-
|
740
|
+
delta_before = delta.before
|
741
|
+
delta_after = delta.after
|
742
|
+
if not is_nothing(before) and not is_nothing(delta_before):
|
743
|
+
before.append(delta_before)
|
744
|
+
if not is_nothing(after) and not is_nothing(delta_after):
|
745
|
+
after.append(delta_after)
|
761
746
|
return PreprocEntityDelta(before=before, after=after)
|
762
747
|
|
763
748
|
def visit_node_property(self, node_property: NodeProperty) -> PreprocEntityDelta:
|
@@ -766,29 +751,44 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
766
751
|
def visit_node_properties(
|
767
752
|
self, node_properties: NodeProperties
|
768
753
|
) -> PreprocEntityDelta[PreprocProperties, PreprocProperties]:
|
769
|
-
|
770
|
-
|
754
|
+
node_change_type = node_properties.change_type
|
755
|
+
before_bindings = dict() if node_change_type != ChangeType.CREATED else Nothing
|
756
|
+
after_bindings = dict() if node_change_type != ChangeType.REMOVED else Nothing
|
771
757
|
for node_property in node_properties.properties:
|
772
|
-
delta = self.visit(node_property)
|
773
758
|
property_name = node_property.name
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
759
|
+
delta = self.visit(node_property)
|
760
|
+
delta_before = delta.before
|
761
|
+
delta_after = delta.after
|
762
|
+
if (
|
763
|
+
not is_nothing(before_bindings)
|
764
|
+
and not is_nothing(delta_before)
|
765
|
+
and delta_before is not None
|
766
|
+
):
|
767
|
+
before_bindings[property_name] = delta_before
|
768
|
+
if (
|
769
|
+
not is_nothing(after_bindings)
|
770
|
+
and not is_nothing(delta_after)
|
771
|
+
and delta_after is not None
|
772
|
+
):
|
773
|
+
after_bindings[property_name] = delta_after
|
774
|
+
before = Nothing
|
775
|
+
if not is_nothing(before_bindings):
|
776
|
+
before = PreprocProperties(properties=before_bindings)
|
777
|
+
after = Nothing
|
778
|
+
if not is_nothing(after_bindings):
|
779
|
+
after = PreprocProperties(properties=after_bindings)
|
780
780
|
return PreprocEntityDelta(before=before, after=after)
|
781
781
|
|
782
782
|
def _resolve_resource_condition_reference(self, reference: TerminalValue) -> PreprocEntityDelta:
|
783
783
|
reference_delta = self.visit(reference)
|
784
784
|
before_reference = reference_delta.before
|
785
|
-
before =
|
786
|
-
if before_reference
|
785
|
+
before = Nothing
|
786
|
+
if isinstance(before_reference, str):
|
787
787
|
before_delta = self._resolve_condition(logical_id=before_reference)
|
788
788
|
before = before_delta.before
|
789
|
-
after =
|
789
|
+
after = Nothing
|
790
790
|
after_reference = reference_delta.after
|
791
|
-
if after_reference
|
791
|
+
if isinstance(after_reference, str):
|
792
792
|
after_delta = self._resolve_condition(logical_id=after_reference)
|
793
793
|
after = after_delta.after
|
794
794
|
return PreprocEntityDelta(before=before, after=after)
|
@@ -797,19 +797,19 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
797
797
|
self, node_resource: NodeResource
|
798
798
|
) -> PreprocEntityDelta[PreprocResource, PreprocResource]:
|
799
799
|
change_type = node_resource.change_type
|
800
|
-
condition_before =
|
801
|
-
condition_after =
|
802
|
-
if node_resource.condition_reference
|
800
|
+
condition_before = Nothing
|
801
|
+
condition_after = Nothing
|
802
|
+
if not is_nothing(node_resource.condition_reference):
|
803
803
|
condition_delta = self._resolve_resource_condition_reference(
|
804
804
|
node_resource.condition_reference
|
805
805
|
)
|
806
806
|
condition_before = condition_delta.before
|
807
807
|
condition_after = condition_delta.after
|
808
808
|
|
809
|
-
depends_on_before =
|
810
|
-
depends_on_after =
|
811
|
-
if node_resource.depends_on
|
812
|
-
depends_on_delta = self.
|
809
|
+
depends_on_before = Nothing
|
810
|
+
depends_on_after = Nothing
|
811
|
+
if not is_nothing(node_resource.depends_on):
|
812
|
+
depends_on_delta = self.visit(node_resource.depends_on)
|
813
813
|
depends_on_before = depends_on_delta.before
|
814
814
|
depends_on_after = depends_on_delta.after
|
815
815
|
|
@@ -818,9 +818,9 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
818
818
|
node_resource.properties
|
819
819
|
)
|
820
820
|
|
821
|
-
before =
|
822
|
-
after =
|
823
|
-
if change_type != ChangeType.CREATED and condition_before
|
821
|
+
before = Nothing
|
822
|
+
after = Nothing
|
823
|
+
if change_type != ChangeType.CREATED and is_nothing(condition_before) or condition_before:
|
824
824
|
logical_resource_id = node_resource.name
|
825
825
|
before_physical_resource_id = self._before_resource_physical_id(
|
826
826
|
resource_logical_id=logical_resource_id
|
@@ -833,7 +833,7 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
833
833
|
properties=properties_delta.before,
|
834
834
|
depends_on=depends_on_before,
|
835
835
|
)
|
836
|
-
if change_type != ChangeType.REMOVED and condition_after
|
836
|
+
if change_type != ChangeType.REMOVED and is_nothing(condition_after) or condition_after:
|
837
837
|
logical_resource_id = node_resource.name
|
838
838
|
try:
|
839
839
|
after_physical_resource_id = self._after_resource_physical_id(
|
@@ -857,8 +857,8 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
857
857
|
change_type = node_output.change_type
|
858
858
|
value_delta = self.visit(node_output.value)
|
859
859
|
|
860
|
-
condition_delta =
|
861
|
-
if node_output.condition_reference
|
860
|
+
condition_delta = Nothing
|
861
|
+
if not is_nothing(node_output.condition_reference):
|
862
862
|
condition_delta = self._resolve_resource_condition_reference(
|
863
863
|
node_output.condition_reference
|
864
864
|
)
|
@@ -869,11 +869,11 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
869
869
|
elif condition_before and not condition_after:
|
870
870
|
change_type = ChangeType.REMOVED
|
871
871
|
|
872
|
-
export_delta =
|
873
|
-
if node_output.export
|
872
|
+
export_delta = Nothing
|
873
|
+
if not is_nothing(node_output.export):
|
874
874
|
export_delta = self.visit(node_output.export)
|
875
875
|
|
876
|
-
before:
|
876
|
+
before: Maybe[PreprocOutput] = Nothing
|
877
877
|
if change_type != ChangeType.CREATED:
|
878
878
|
before = PreprocOutput(
|
879
879
|
name=node_output.name,
|
@@ -881,7 +881,7 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
881
881
|
export=export_delta.before if export_delta else None,
|
882
882
|
condition=condition_delta.before if condition_delta else None,
|
883
883
|
)
|
884
|
-
after:
|
884
|
+
after: Maybe[PreprocOutput] = Nothing
|
885
885
|
if change_type != ChangeType.REMOVED:
|
886
886
|
after = PreprocOutput(
|
887
887
|
name=node_output.name,
|
@@ -900,8 +900,8 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
900
900
|
output_delta: PreprocEntityDelta[PreprocOutput, PreprocOutput] = self.visit(node_output)
|
901
901
|
output_before = output_delta.before
|
902
902
|
output_after = output_delta.after
|
903
|
-
if output_before:
|
903
|
+
if not is_nothing(output_before):
|
904
904
|
before.append(output_before)
|
905
|
-
if output_after:
|
905
|
+
if not is_nothing(output_after):
|
906
906
|
after.append(output_after)
|
907
907
|
return PreprocEntityDelta(before=before, after=after)
|
@@ -3815,8 +3815,9 @@ class S3Provider(S3Api, ServiceLifecycleHook):
|
|
3815
3815
|
context: RequestContext,
|
3816
3816
|
bucket: BucketName,
|
3817
3817
|
ownership_controls: OwnershipControls,
|
3818
|
-
content_md5: ContentMD5 = None,
|
3819
|
-
expected_bucket_owner: AccountId = None,
|
3818
|
+
content_md5: ContentMD5 | None = None,
|
3819
|
+
expected_bucket_owner: AccountId | None = None,
|
3820
|
+
checksum_algorithm: ChecksumAlgorithm | None = None,
|
3820
3821
|
**kwargs,
|
3821
3822
|
) -> None:
|
3822
3823
|
# TODO: this currently only mock the operation, but its actual effect is not emulated
|
localstack/version.py
CHANGED
@@ -17,5 +17,5 @@ __version__: str
|
|
17
17
|
__version_tuple__: VERSION_TUPLE
|
18
18
|
version_tuple: VERSION_TUPLE
|
19
19
|
|
20
|
-
__version__ = version = '4.4.1.
|
21
|
-
__version_tuple__ = version_tuple = (4, 4, 1, '
|
20
|
+
__version__ = version = '4.4.1.dev63'
|
21
|
+
__version_tuple__ = version_tuple = (4, 4, 1, 'dev63')
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: localstack-core
|
3
|
-
Version: 4.4.1.
|
3
|
+
Version: 4.4.1.dev63
|
4
4
|
Summary: The core library and runtime of LocalStack
|
5
5
|
Author-email: LocalStack Contributors <info@localstack.cloud>
|
6
6
|
License-Expression: Apache-2.0
|
@@ -31,8 +31,8 @@ Requires-Dist: requests>=2.20.0
|
|
31
31
|
Requires-Dist: semver>=2.10
|
32
32
|
Requires-Dist: tailer>=0.4.1
|
33
33
|
Provides-Extra: base-runtime
|
34
|
-
Requires-Dist: boto3==1.38.
|
35
|
-
Requires-Dist: botocore==1.38.
|
34
|
+
Requires-Dist: boto3==1.38.27; extra == "base-runtime"
|
35
|
+
Requires-Dist: botocore==1.38.27; extra == "base-runtime"
|
36
36
|
Requires-Dist: awscrt!=0.27.1,>=0.13.14; extra == "base-runtime"
|
37
37
|
Requires-Dist: cbor2>=5.5.0; extra == "base-runtime"
|
38
38
|
Requires-Dist: dnspython>=1.16.0; extra == "base-runtime"
|