localstack-core 4.5.1.dev62__py3-none-any.whl → 4.5.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/services/cloudformation/engine/v2/change_set_model.py +22 -6
- localstack/services/cloudformation/engine/v2/change_set_model_describer.py +24 -4
- localstack/services/cloudformation/engine/v2/change_set_model_executor.py +2 -1
- localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +223 -210
- localstack/services/cloudformation/engine/v2/change_set_model_transform.py +33 -18
- localstack/services/cloudformation/v2/entities.py +3 -3
- localstack/services/cloudformation/v2/provider.py +39 -3
- localstack/version.py +2 -2
- {localstack_core-4.5.1.dev62.dist-info → localstack_core-4.5.1.dev63.dist-info}/METADATA +1 -1
- {localstack_core-4.5.1.dev62.dist-info → localstack_core-4.5.1.dev63.dist-info}/RECORD +18 -18
- localstack_core-4.5.1.dev63.dist-info/plux.json +1 -0
- localstack_core-4.5.1.dev62.dist-info/plux.json +0 -1
- {localstack_core-4.5.1.dev62.data → localstack_core-4.5.1.dev63.data}/scripts/localstack +0 -0
- {localstack_core-4.5.1.dev62.data → localstack_core-4.5.1.dev63.data}/scripts/localstack-supervisor +0 -0
- {localstack_core-4.5.1.dev62.data → localstack_core-4.5.1.dev63.data}/scripts/localstack.bat +0 -0
- {localstack_core-4.5.1.dev62.dist-info → localstack_core-4.5.1.dev63.dist-info}/WHEEL +0 -0
- {localstack_core-4.5.1.dev62.dist-info → localstack_core-4.5.1.dev63.dist-info}/entry_points.txt +0 -0
- {localstack_core-4.5.1.dev62.dist-info → localstack_core-4.5.1.dev63.dist-info}/licenses/LICENSE.txt +0 -0
- {localstack_core-4.5.1.dev62.dist-info → localstack_core-4.5.1.dev63.dist-info}/top_level.txt +0 -0
@@ -147,6 +147,22 @@ class ChangeSetNode(ChangeSetEntity, abc.ABC): ...
|
|
147
147
|
class ChangeSetTerminal(ChangeSetEntity, abc.ABC): ...
|
148
148
|
|
149
149
|
|
150
|
+
class UpdateModel:
|
151
|
+
# TODO: may be expanded to keep track of other runtime values such as resolved_parameters.
|
152
|
+
|
153
|
+
node_template: Final[NodeTemplate]
|
154
|
+
before_runtime_cache: Final[dict]
|
155
|
+
after_runtime_cache: Final[dict]
|
156
|
+
|
157
|
+
def __init__(
|
158
|
+
self,
|
159
|
+
node_template: NodeTemplate,
|
160
|
+
):
|
161
|
+
self.node_template = node_template
|
162
|
+
self.before_runtime_cache = dict()
|
163
|
+
self.after_runtime_cache = dict()
|
164
|
+
|
165
|
+
|
150
166
|
class NodeTemplate(ChangeSetNode):
|
151
167
|
transform: Final[NodeTransform]
|
152
168
|
mappings: Final[NodeMappings]
|
@@ -515,9 +531,8 @@ class ChangeSetModel:
|
|
515
531
|
)
|
516
532
|
# TODO: need to do template preprocessing e.g. parameter resolution, conditions etc.
|
517
533
|
|
518
|
-
def get_update_model(self) ->
|
519
|
-
|
520
|
-
return self._node_template
|
534
|
+
def get_update_model(self) -> UpdateModel:
|
535
|
+
return UpdateModel(node_template=self._node_template)
|
521
536
|
|
522
537
|
def _visit_terminal_value(
|
523
538
|
self, scope: Scope, before_value: Maybe[Any], after_value: Maybe[Any]
|
@@ -548,8 +563,9 @@ class ChangeSetModel:
|
|
548
563
|
node_intrinsic_function = self._visited_scopes.get(scope)
|
549
564
|
if isinstance(node_intrinsic_function, NodeIntrinsicFunction):
|
550
565
|
return node_intrinsic_function
|
566
|
+
arguments_scope = scope.open_scope("args")
|
551
567
|
arguments = self._visit_value(
|
552
|
-
scope=
|
568
|
+
scope=arguments_scope, before_value=before_arguments, after_value=after_arguments
|
553
569
|
)
|
554
570
|
if is_created(before=before_arguments, after=after_arguments):
|
555
571
|
change_type = ChangeType.CREATED
|
@@ -777,7 +793,7 @@ class ChangeSetModel:
|
|
777
793
|
self._safe_access_in(scope, dominant_type_name, before_value, after_value)
|
778
794
|
)
|
779
795
|
value = self._visit_intrinsic_function(
|
780
|
-
scope=
|
796
|
+
scope=intrinsic_function_scope,
|
781
797
|
intrinsic_function=dominant_type_name,
|
782
798
|
before_arguments=before_arguments,
|
783
799
|
after_arguments=after_arguments,
|
@@ -937,7 +953,7 @@ class ChangeSetModel:
|
|
937
953
|
scope, mapping_name, before_mappings, after_mappings
|
938
954
|
)
|
939
955
|
mapping = self._visit_mapping(
|
940
|
-
scope=
|
956
|
+
scope=scope_mapping,
|
941
957
|
name=mapping_name,
|
942
958
|
before_mapping=before_mapping,
|
943
959
|
after_mapping=after_mapping,
|
@@ -8,6 +8,7 @@ from localstack.services.cloudformation.engine.v2.change_set_model import (
|
|
8
8
|
NodeIntrinsicFunction,
|
9
9
|
NodeProperty,
|
10
10
|
NodeResource,
|
11
|
+
NodeResources,
|
11
12
|
PropertiesKey,
|
12
13
|
is_nothing,
|
13
14
|
)
|
@@ -40,6 +41,20 @@ class ChangeSetModelDescriber(ChangeSetModelPreproc):
|
|
40
41
|
self.process()
|
41
42
|
return self._changes
|
42
43
|
|
44
|
+
def _setup_runtime_cache(self) -> None:
|
45
|
+
# The describer can output {{changeSet:KNOWN_AFTER_APPLY}} values as not every field
|
46
|
+
# is computable at describe time. Until a filtering logic or executor override logic
|
47
|
+
# is available, the describer cannot benefit of previous evaluations to compute
|
48
|
+
# change set resource changes.
|
49
|
+
pass
|
50
|
+
|
51
|
+
def _save_runtime_cache(self) -> None:
|
52
|
+
# The describer can output {{changeSet:KNOWN_AFTER_APPLY}} values as not every field
|
53
|
+
# is computable at describe time. Until a filtering logic or executor override logic
|
54
|
+
# is available, there are no benefits in having the describer saving its runtime cache
|
55
|
+
# for future changes chains.
|
56
|
+
pass
|
57
|
+
|
43
58
|
def _resolve_attribute(self, arguments: str | list[str], select_before: bool) -> str:
|
44
59
|
if select_before:
|
45
60
|
return super()._resolve_attribute(arguments=arguments, select_before=select_before)
|
@@ -57,7 +72,8 @@ class ChangeSetModelDescriber(ChangeSetModelPreproc):
|
|
57
72
|
attribute_name = arguments_list[1]
|
58
73
|
|
59
74
|
node_resource = self._get_node_resource_for(
|
60
|
-
resource_name=logical_name_of_resource,
|
75
|
+
resource_name=logical_name_of_resource,
|
76
|
+
node_template=self._change_set.update_model.node_template,
|
61
77
|
)
|
62
78
|
node_property: Optional[NodeProperty] = self._get_node_property_for(
|
63
79
|
property_name=attribute_name, node_resource=node_resource
|
@@ -182,6 +198,13 @@ class ChangeSetModelDescriber(ChangeSetModelPreproc):
|
|
182
198
|
after_properties=after.properties,
|
183
199
|
)
|
184
200
|
|
201
|
+
def visit_node_resources(self, node_resources: NodeResources) -> None:
|
202
|
+
for node_resource in node_resources.resources:
|
203
|
+
delta_resource = self.visit(node_resource)
|
204
|
+
self._describe_resource_change(
|
205
|
+
name=node_resource.name, before=delta_resource.before, after=delta_resource.after
|
206
|
+
)
|
207
|
+
|
185
208
|
def visit_node_resource(
|
186
209
|
self, node_resource: NodeResource
|
187
210
|
) -> PreprocEntityDelta[PreprocResource, PreprocResource]:
|
@@ -189,7 +212,4 @@ class ChangeSetModelDescriber(ChangeSetModelPreproc):
|
|
189
212
|
after_resource = delta.after
|
190
213
|
if not is_nothing(after_resource) and after_resource.physical_resource_id is None:
|
191
214
|
after_resource.physical_resource_id = CHANGESET_KNOWN_AFTER_APPLY
|
192
|
-
self._describe_resource_change(
|
193
|
-
name=node_resource.name, before=delta.before, after=delta.after
|
194
|
-
)
|
195
215
|
return delta
|
@@ -159,7 +159,8 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
|
|
159
159
|
depends_on_resource_logical_ids.update(array_identifiers_delta.after)
|
160
160
|
for depends_on_resource_logical_id in depends_on_resource_logical_ids:
|
161
161
|
node_resource = self._get_node_resource_for(
|
162
|
-
resource_name=depends_on_resource_logical_id,
|
162
|
+
resource_name=depends_on_resource_logical_id,
|
163
|
+
node_template=self._change_set.update_model.node_template,
|
163
164
|
)
|
164
165
|
self.visit(node_resource)
|
165
166
|
|
@@ -1,8 +1,9 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import base64
|
4
|
+
import copy
|
4
5
|
import re
|
5
|
-
from typing import Any, Final, Generic, Optional, TypeVar
|
6
|
+
from typing import Any, Callable, Final, Generic, Optional, TypeVar
|
6
7
|
|
7
8
|
from botocore.exceptions import ClientError
|
8
9
|
|
@@ -33,6 +34,7 @@ from localstack.services.cloudformation.engine.v2.change_set_model import (
|
|
33
34
|
NodeResource,
|
34
35
|
NodeTemplate,
|
35
36
|
Nothing,
|
37
|
+
NothingType,
|
36
38
|
Scope,
|
37
39
|
TerminalValue,
|
38
40
|
TerminalValueCreated,
|
@@ -165,19 +167,44 @@ class PreprocOutput:
|
|
165
167
|
|
166
168
|
class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
167
169
|
_change_set: Final[ChangeSet]
|
168
|
-
_node_template: Final[NodeTemplate]
|
169
170
|
_before_resolved_resources: Final[dict]
|
170
|
-
|
171
|
+
_before_cache: Final[dict[Scope, Any]]
|
172
|
+
_after_cache: Final[dict[Scope, Any]]
|
171
173
|
|
172
174
|
def __init__(self, change_set: ChangeSet):
|
173
175
|
self._change_set = change_set
|
174
|
-
self._node_template = change_set.update_model
|
175
176
|
self._before_resolved_resources = change_set.stack.resolved_resources
|
176
|
-
self.
|
177
|
+
self._before_cache = dict()
|
178
|
+
self._after_cache = dict()
|
179
|
+
|
180
|
+
def _setup_runtime_cache(self) -> None:
|
181
|
+
runtime_cache_key = self.__class__.__name__
|
182
|
+
|
183
|
+
self._before_cache.clear()
|
184
|
+
self._after_cache.clear()
|
185
|
+
|
186
|
+
before_runtime_cache = self._change_set.update_model.before_runtime_cache
|
187
|
+
if cache := before_runtime_cache.get(runtime_cache_key):
|
188
|
+
self._before_cache.update(cache)
|
189
|
+
|
190
|
+
after_runtime_cache = self._change_set.update_model.after_runtime_cache
|
191
|
+
if cache := after_runtime_cache.get(runtime_cache_key):
|
192
|
+
self._after_cache.update(cache)
|
193
|
+
|
194
|
+
def _save_runtime_cache(self) -> None:
|
195
|
+
runtime_cache_key = self.__class__.__name__
|
196
|
+
|
197
|
+
before_runtime_cache = self._change_set.update_model.before_runtime_cache
|
198
|
+
before_runtime_cache[runtime_cache_key] = copy.deepcopy(self._before_cache)
|
199
|
+
|
200
|
+
after_runtime_cache = self._change_set.update_model.after_runtime_cache
|
201
|
+
after_runtime_cache[runtime_cache_key] = copy.deepcopy(self._after_cache)
|
177
202
|
|
178
203
|
def process(self) -> None:
|
179
|
-
self.
|
180
|
-
self.
|
204
|
+
self._setup_runtime_cache()
|
205
|
+
node_template = self._change_set.update_model.node_template
|
206
|
+
self.visit(node_template)
|
207
|
+
self._save_runtime_cache()
|
181
208
|
|
182
209
|
def _get_node_resource_for(
|
183
210
|
self, resource_name: str, node_template: NodeTemplate
|
@@ -209,7 +236,8 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
209
236
|
# be accessible through delta objects, to ensure computation is always complete at
|
210
237
|
# every level.
|
211
238
|
_ = self._get_node_resource_for(
|
212
|
-
resource_name=resource_logical_id,
|
239
|
+
resource_name=resource_logical_id,
|
240
|
+
node_template=self._change_set.update_model.node_template,
|
213
241
|
)
|
214
242
|
resolved_resource = resolved_resources.get(resource_logical_id)
|
215
243
|
if resolved_resource is None:
|
@@ -241,7 +269,7 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
241
269
|
)
|
242
270
|
|
243
271
|
def _get_node_mapping(self, map_name: str) -> NodeMapping:
|
244
|
-
mappings: list[NodeMapping] = self.
|
272
|
+
mappings: list[NodeMapping] = self._change_set.update_model.node_template.mappings.mappings
|
245
273
|
# TODO: another scenarios suggesting property lookups might be preferable.
|
246
274
|
for mapping in mappings:
|
247
275
|
if mapping.name == map_name:
|
@@ -250,7 +278,9 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
250
278
|
raise RuntimeError(f"Undefined '{map_name}' mapping")
|
251
279
|
|
252
280
|
def _get_node_parameter_if_exists(self, parameter_name: str) -> Maybe[NodeParameter]:
|
253
|
-
parameters: list[NodeParameter] =
|
281
|
+
parameters: list[NodeParameter] = (
|
282
|
+
self._change_set.update_model.node_template.parameters.parameters
|
283
|
+
)
|
254
284
|
# TODO: another scenarios suggesting property lookups might be preferable.
|
255
285
|
for parameter in parameters:
|
256
286
|
if parameter.name == parameter_name:
|
@@ -259,7 +289,9 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
259
289
|
return Nothing
|
260
290
|
|
261
291
|
def _get_node_condition_if_exists(self, condition_name: str) -> Maybe[NodeCondition]:
|
262
|
-
conditions: list[NodeCondition] =
|
292
|
+
conditions: list[NodeCondition] = (
|
293
|
+
self._change_set.update_model.node_template.conditions.conditions
|
294
|
+
)
|
263
295
|
# TODO: another scenarios suggesting property lookups might be preferable.
|
264
296
|
for condition in conditions:
|
265
297
|
if condition.name == condition_name:
|
@@ -307,7 +339,7 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
307
339
|
return parameter_delta
|
308
340
|
|
309
341
|
node_resource = self._get_node_resource_for(
|
310
|
-
resource_name=logical_id, node_template=self.
|
342
|
+
resource_name=logical_id, node_template=self._change_set.update_model.node_template
|
311
343
|
)
|
312
344
|
resource_delta = self.visit(node_resource)
|
313
345
|
before = resource_delta.before
|
@@ -327,14 +359,65 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
327
359
|
return mapping_value_delta
|
328
360
|
|
329
361
|
def visit(self, change_set_entity: ChangeSetEntity) -> PreprocEntityDelta:
|
330
|
-
|
331
|
-
if
|
332
|
-
|
333
|
-
|
362
|
+
entity_scope = change_set_entity.scope
|
363
|
+
if entity_scope in self._before_cache and entity_scope in self._after_cache:
|
364
|
+
before = self._before_cache[entity_scope]
|
365
|
+
after = self._after_cache[entity_scope]
|
366
|
+
return PreprocEntityDelta(before=before, after=after)
|
334
367
|
delta = super().visit(change_set_entity=change_set_entity)
|
335
|
-
|
368
|
+
if isinstance(delta, PreprocEntityDelta):
|
369
|
+
self._before_cache[entity_scope] = delta.before
|
370
|
+
self._after_cache[entity_scope] = delta.after
|
336
371
|
return delta
|
337
372
|
|
373
|
+
def _cached_apply(
|
374
|
+
self, scope: Scope, arguments_delta: PreprocEntityDelta, resolver: Callable[[Any], Any]
|
375
|
+
) -> PreprocEntityDelta:
|
376
|
+
"""
|
377
|
+
Applies the resolver function to the given input delta if and only if the required
|
378
|
+
values are not already present in the runtime caches. This function handles both
|
379
|
+
the 'before' and 'after' components of the delta independently.
|
380
|
+
|
381
|
+
The resolver function receives either the 'before' or 'after' value from the input
|
382
|
+
delta and returns a resolved value. If the result returned by the resolver is
|
383
|
+
itself a PreprocEntityDelta, the function automatically extracts the appropriate
|
384
|
+
component from it: the 'before' value if the input was 'before', and the 'after'
|
385
|
+
value if the input was 'after'.
|
386
|
+
|
387
|
+
This function only reads from the cache and does not update it. It is the caller's
|
388
|
+
responsibility to handle caching, either manually or via the upstream visit method
|
389
|
+
of this class.
|
390
|
+
|
391
|
+
Args:
|
392
|
+
scope (Scope): The current scope used as a key for cache lookup.
|
393
|
+
arguments_delta (PreprocEntityDelta): The delta containing 'before' and 'after' values to resolve.
|
394
|
+
resolver (Callable[[Any], Any]): Function to apply on uncached 'before' or 'after' argument values.
|
395
|
+
|
396
|
+
Returns:
|
397
|
+
PreprocEntityDelta: A new delta with resolved 'before' and 'after' values.
|
398
|
+
"""
|
399
|
+
|
400
|
+
# TODO: Update all visit_* methods in this class and its subclasses to use this function.
|
401
|
+
# This ensures maximal reuse of precomputed 'before' (and 'after') values from
|
402
|
+
# prior runtimes on the change sets template, thus avoiding unnecessary recomputation.
|
403
|
+
|
404
|
+
arguments_before = arguments_delta.before
|
405
|
+
arguments_after = arguments_delta.after
|
406
|
+
|
407
|
+
before = self._before_cache.get(scope, Nothing)
|
408
|
+
if is_nothing(before) and not is_nothing(arguments_before):
|
409
|
+
before = resolver(arguments_before)
|
410
|
+
if isinstance(before, PreprocEntityDelta):
|
411
|
+
before = before.before
|
412
|
+
|
413
|
+
after = self._after_cache.get(scope, Nothing)
|
414
|
+
if is_nothing(after) and not is_nothing(arguments_after):
|
415
|
+
after = resolver(arguments_after)
|
416
|
+
if isinstance(after, PreprocEntityDelta):
|
417
|
+
after = after.after
|
418
|
+
|
419
|
+
return PreprocEntityDelta(before=before, after=after)
|
420
|
+
|
338
421
|
def visit_terminal_value_modified(
|
339
422
|
self, terminal_value_modified: TerminalValueModified
|
340
423
|
) -> PreprocEntityDelta:
|
@@ -391,7 +474,8 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
391
474
|
attribute_name = arguments_list[1]
|
392
475
|
|
393
476
|
node_resource = self._get_node_resource_for(
|
394
|
-
resource_name=logical_name_of_resource,
|
477
|
+
resource_name=logical_name_of_resource,
|
478
|
+
node_template=self._change_set.update_model.node_template,
|
395
479
|
)
|
396
480
|
node_property: Optional[NodeProperty] = self._get_node_property_for(
|
397
481
|
property_name=attribute_name, node_resource=node_resource
|
@@ -423,12 +507,12 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
423
507
|
before_arguments: Maybe[str | list[str]] = arguments_delta.before
|
424
508
|
after_arguments: Maybe[str | list[str]] = arguments_delta.after
|
425
509
|
|
426
|
-
before = Nothing
|
427
|
-
if not is_nothing(before_arguments):
|
510
|
+
before = self._before_cache.get(node_intrinsic_function.scope, Nothing)
|
511
|
+
if is_nothing(before) and not is_nothing(before_arguments):
|
428
512
|
before = self._resolve_attribute(arguments=before_arguments, select_before=True)
|
429
513
|
|
430
|
-
after = Nothing
|
431
|
-
if not is_nothing(after_arguments):
|
514
|
+
after = self._after_cache.get(node_intrinsic_function.scope, Nothing)
|
515
|
+
if is_nothing(after) and not is_nothing(after_arguments):
|
432
516
|
after = self._resolve_attribute(arguments=after_arguments, select_before=False)
|
433
517
|
|
434
518
|
return PreprocEntityDelta(before=before, after=after)
|
@@ -436,24 +520,21 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
436
520
|
def visit_node_intrinsic_function_fn_equals(
|
437
521
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
438
522
|
) -> PreprocEntityDelta:
|
523
|
+
# TODO: add argument shape validation.
|
524
|
+
def _compute_fn_equals(args: list[Any]) -> bool:
|
525
|
+
return args[0] == args[1]
|
526
|
+
|
439
527
|
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
if after_values:
|
447
|
-
after = after_values[0] == after_values[1]
|
448
|
-
return PreprocEntityDelta(before=before, after=after)
|
528
|
+
delta = self._cached_apply(
|
529
|
+
scope=node_intrinsic_function.scope,
|
530
|
+
arguments_delta=arguments_delta,
|
531
|
+
resolver=_compute_fn_equals,
|
532
|
+
)
|
533
|
+
return delta
|
449
534
|
|
450
535
|
def visit_node_intrinsic_function_fn_if(
|
451
536
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
452
537
|
) -> PreprocEntityDelta:
|
453
|
-
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
454
|
-
arguments_before = arguments_delta.before
|
455
|
-
arguments_after = arguments_delta.after
|
456
|
-
|
457
538
|
def _compute_delta_for_if_statement(args: list[Any]) -> PreprocEntityDelta:
|
458
539
|
condition_name = args[0]
|
459
540
|
boolean_expression_delta = self._resolve_condition(logical_id=condition_name)
|
@@ -462,74 +543,57 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
462
543
|
after=args[1] if boolean_expression_delta.after else args[2],
|
463
544
|
)
|
464
545
|
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
after_outcome_delta = _compute_delta_for_if_statement(arguments_after)
|
473
|
-
after = after_outcome_delta.after
|
474
|
-
return PreprocEntityDelta(before=before, after=after)
|
546
|
+
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
547
|
+
delta = self._cached_apply(
|
548
|
+
scope=node_intrinsic_function.scope,
|
549
|
+
arguments_delta=arguments_delta,
|
550
|
+
resolver=_compute_delta_for_if_statement,
|
551
|
+
)
|
552
|
+
return delta
|
475
553
|
|
476
554
|
def visit_node_intrinsic_function_fn_and(
|
477
555
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
478
556
|
) -> PreprocEntityDelta:
|
479
|
-
|
480
|
-
arguments_before = arguments_delta.before
|
481
|
-
arguments_after = arguments_delta.after
|
482
|
-
|
483
|
-
def _compute_fn_and(args: list[bool]):
|
557
|
+
def _compute_fn_and(args: list[bool]) -> bool:
|
484
558
|
result = all(args)
|
485
559
|
return result
|
486
560
|
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
return PreprocEntityDelta(before=before, after=after)
|
561
|
+
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
562
|
+
delta = self._cached_apply(
|
563
|
+
scope=node_intrinsic_function.scope,
|
564
|
+
arguments_delta=arguments_delta,
|
565
|
+
resolver=_compute_fn_and,
|
566
|
+
)
|
567
|
+
return delta
|
496
568
|
|
497
569
|
def visit_node_intrinsic_function_fn_or(
|
498
570
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
499
571
|
) -> PreprocEntityDelta:
|
500
|
-
|
501
|
-
arguments_before = arguments_delta.before
|
502
|
-
arguments_after = arguments_delta.after
|
503
|
-
|
504
|
-
def _compute_fn_and(args: list[bool]):
|
572
|
+
def _compute_fn_or(args: list[bool]):
|
505
573
|
result = any(args)
|
506
574
|
return result
|
507
575
|
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
return PreprocEntityDelta(before=before, after=after)
|
576
|
+
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
577
|
+
delta = self._cached_apply(
|
578
|
+
scope=node_intrinsic_function.scope,
|
579
|
+
arguments_delta=arguments_delta,
|
580
|
+
resolver=_compute_fn_or,
|
581
|
+
)
|
582
|
+
return delta
|
516
583
|
|
517
584
|
def visit_node_intrinsic_function_fn_not(
|
518
585
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
519
586
|
) -> PreprocEntityDelta:
|
587
|
+
def _compute_fn_not(arg: bool) -> bool:
|
588
|
+
return not arg
|
589
|
+
|
520
590
|
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
after = Nothing
|
528
|
-
if not is_nothing(after_condition):
|
529
|
-
after_condition_outcome = after_condition[0]
|
530
|
-
after = not after_condition_outcome
|
531
|
-
# Implicit change type computation.
|
532
|
-
return PreprocEntityDelta(before=before, after=after)
|
591
|
+
delta = self._cached_apply(
|
592
|
+
scope=node_intrinsic_function.scope,
|
593
|
+
arguments_delta=arguments_delta,
|
594
|
+
resolver=_compute_fn_not,
|
595
|
+
)
|
596
|
+
return delta
|
533
597
|
|
534
598
|
def _compute_fn_transform(self, args: dict[str, Any]) -> Any:
|
535
599
|
# TODO: add typing to arguments before this level.
|
@@ -583,33 +647,16 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
583
647
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
584
648
|
) -> PreprocEntityDelta:
|
585
649
|
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
# though for this transformation before==after). Another options may be to
|
593
|
-
# have specialised caching for transformations.
|
594
|
-
|
595
|
-
# TODO: add tests to review the behaviour of CFN with changes to transformation
|
596
|
-
# function code and no changes to the template.
|
597
|
-
|
598
|
-
before = Nothing
|
599
|
-
if not is_nothing(arguments_before):
|
600
|
-
before = self._compute_fn_transform(args=arguments_before)
|
601
|
-
after = Nothing
|
602
|
-
if not is_nothing(arguments_after):
|
603
|
-
after = self._compute_fn_transform(args=arguments_after)
|
604
|
-
return PreprocEntityDelta(before=before, after=after)
|
650
|
+
delta = self._cached_apply(
|
651
|
+
scope=node_intrinsic_function.scope,
|
652
|
+
arguments_delta=arguments_delta,
|
653
|
+
resolver=self._compute_fn_transform,
|
654
|
+
)
|
655
|
+
return delta
|
605
656
|
|
606
657
|
def visit_node_intrinsic_function_fn_sub(
|
607
658
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
608
659
|
) -> PreprocEntityDelta:
|
609
|
-
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
610
|
-
arguments_before = arguments_delta.before
|
611
|
-
arguments_after = arguments_delta.after
|
612
|
-
|
613
660
|
def _compute_sub(args: str | list[Any], select_before: bool) -> str:
|
614
661
|
# TODO: add further schema validation.
|
615
662
|
string_template: str
|
@@ -695,24 +742,25 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
695
742
|
result = sub_string
|
696
743
|
return result
|
697
744
|
|
698
|
-
|
699
|
-
|
745
|
+
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
746
|
+
arguments_before = arguments_delta.before
|
747
|
+
arguments_after = arguments_delta.after
|
748
|
+
before = self._before_cache.get(node_intrinsic_function.scope, Nothing)
|
749
|
+
if is_nothing(before) and not is_nothing(arguments_before):
|
700
750
|
before = _compute_sub(args=arguments_before, select_before=True)
|
701
|
-
after = Nothing
|
702
|
-
if not is_nothing(arguments_after):
|
751
|
+
after = self._after_cache.get(node_intrinsic_function.scope, Nothing)
|
752
|
+
if is_nothing(after) and not is_nothing(arguments_after):
|
703
753
|
after = _compute_sub(args=arguments_after, select_before=False)
|
704
754
|
return PreprocEntityDelta(before=before, after=after)
|
705
755
|
|
706
756
|
def visit_node_intrinsic_function_fn_join(
|
707
757
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
708
758
|
) -> PreprocEntityDelta:
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
# TODO: add support for schema validation.
|
715
|
-
# TODO: add tests for joining non string values.
|
759
|
+
# TODO: add support for schema validation.
|
760
|
+
# TODO: add tests for joining non string values.
|
761
|
+
def _compute_fn_join(args: list[Any]) -> str | NothingType:
|
762
|
+
if not (isinstance(args, list) and len(args) == 2):
|
763
|
+
return Nothing
|
716
764
|
delimiter: str = str(args[0])
|
717
765
|
values: list[Any] = args[1]
|
718
766
|
if not isinstance(values, list):
|
@@ -731,22 +779,18 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
731
779
|
join_result = delimiter.join(str_values)
|
732
780
|
return join_result
|
733
781
|
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
return
|
782
|
+
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
783
|
+
delta = self._cached_apply(
|
784
|
+
scope=node_intrinsic_function.scope,
|
785
|
+
arguments_delta=arguments_delta,
|
786
|
+
resolver=_compute_fn_join,
|
787
|
+
)
|
788
|
+
return delta
|
741
789
|
|
742
790
|
def visit_node_intrinsic_function_fn_select(
|
743
791
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
744
792
|
):
|
745
793
|
# TODO: add further support for schema validation
|
746
|
-
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
747
|
-
arguments_before = arguments_delta.before
|
748
|
-
arguments_after = arguments_delta.after
|
749
|
-
|
750
794
|
def _compute_fn_select(args: list[Any]) -> Any:
|
751
795
|
values: list[Any] = args[1]
|
752
796
|
if not isinstance(values, list) or not values:
|
@@ -758,24 +802,18 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
758
802
|
selection = values[index]
|
759
803
|
return selection
|
760
804
|
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
return PreprocEntityDelta(before=before, after=after)
|
805
|
+
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
806
|
+
delta = self._cached_apply(
|
807
|
+
scope=node_intrinsic_function.scope,
|
808
|
+
arguments_delta=arguments_delta,
|
809
|
+
resolver=_compute_fn_select,
|
810
|
+
)
|
811
|
+
return delta
|
770
812
|
|
771
813
|
def visit_node_intrinsic_function_fn_split(
|
772
814
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
773
815
|
):
|
774
816
|
# TODO: add further support for schema validation
|
775
|
-
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
776
|
-
arguments_before = arguments_delta.before
|
777
|
-
arguments_after = arguments_delta.after
|
778
|
-
|
779
817
|
def _compute_fn_split(args: list[Any]) -> Any:
|
780
818
|
delimiter = args[0]
|
781
819
|
if not isinstance(delimiter, str) or not delimiter:
|
@@ -786,23 +824,18 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
786
824
|
split_string = source_string.split(delimiter)
|
787
825
|
return split_string
|
788
826
|
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
return PreprocEntityDelta(before=before, after=after)
|
827
|
+
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
828
|
+
delta = self._cached_apply(
|
829
|
+
scope=node_intrinsic_function.scope,
|
830
|
+
arguments_delta=arguments_delta,
|
831
|
+
resolver=_compute_fn_split,
|
832
|
+
)
|
833
|
+
return delta
|
798
834
|
|
799
835
|
def visit_node_intrinsic_function_fn_get_a_zs(
|
800
836
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
801
837
|
) -> PreprocEntityDelta:
|
802
838
|
# TODO: add further support for schema validation
|
803
|
-
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
804
|
-
arguments_before = arguments_delta.before
|
805
|
-
arguments_after = arguments_delta.after
|
806
839
|
|
807
840
|
def _compute_fn_get_a_zs(region) -> Any:
|
808
841
|
if not isinstance(region, str):
|
@@ -827,24 +860,18 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
827
860
|
azs = [az["ZoneName"] for az in availability_zones]
|
828
861
|
return azs
|
829
862
|
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
return PreprocEntityDelta(before=before, after=after)
|
863
|
+
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
864
|
+
delta = self._cached_apply(
|
865
|
+
scope=node_intrinsic_function.scope,
|
866
|
+
arguments_delta=arguments_delta,
|
867
|
+
resolver=_compute_fn_get_a_zs,
|
868
|
+
)
|
869
|
+
return delta
|
839
870
|
|
840
871
|
def visit_node_intrinsic_function_fn_base64(
|
841
872
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
842
873
|
) -> PreprocEntityDelta:
|
843
874
|
# TODO: add further support for schema validation
|
844
|
-
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
845
|
-
arguments_before = arguments_delta.before
|
846
|
-
arguments_after = arguments_delta.after
|
847
|
-
|
848
875
|
def _compute_fn_base_64(string) -> Any:
|
849
876
|
if not isinstance(string, str):
|
850
877
|
raise RuntimeError(f"Invalid valueToEncode for Fn::Base64: '{string}'")
|
@@ -852,15 +879,13 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
852
879
|
base64_string = to_str(base64.b64encode(to_bytes(string)))
|
853
880
|
return base64_string
|
854
881
|
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
return PreprocEntityDelta(before=before, after=after)
|
882
|
+
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
883
|
+
delta = self._cached_apply(
|
884
|
+
scope=node_intrinsic_function.scope,
|
885
|
+
arguments_delta=arguments_delta,
|
886
|
+
resolver=_compute_fn_base_64,
|
887
|
+
)
|
888
|
+
return delta
|
864
889
|
|
865
890
|
def visit_node_intrinsic_function_fn_find_in_map(
|
866
891
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
@@ -941,52 +966,40 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
|
|
941
966
|
def visit_node_intrinsic_function_ref(
|
942
967
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
943
968
|
) -> PreprocEntityDelta:
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
before_delta = self._resolve_reference(logical_id=before_logical_id)
|
952
|
-
before = before_delta.before
|
953
|
-
if isinstance(before, PreprocResource):
|
954
|
-
before = before.physical_resource_id
|
955
|
-
|
956
|
-
after = Nothing
|
957
|
-
if not is_nothing(after_logical_id):
|
958
|
-
after_delta = self._resolve_reference(logical_id=after_logical_id)
|
959
|
-
after = after_delta.after
|
960
|
-
if isinstance(after, PreprocResource):
|
961
|
-
after = after.physical_resource_id
|
969
|
+
def _compute_fn_ref(logical_id: str) -> PreprocEntityDelta:
|
970
|
+
reference_delta: PreprocEntityDelta = self._resolve_reference(logical_id=logical_id)
|
971
|
+
if isinstance(before := reference_delta.before, PreprocResource):
|
972
|
+
reference_delta.before = before.physical_resource_id
|
973
|
+
if isinstance(after := reference_delta.after, PreprocResource):
|
974
|
+
reference_delta.after = after.physical_resource_id
|
975
|
+
return reference_delta
|
962
976
|
|
963
|
-
|
977
|
+
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
978
|
+
delta = self._cached_apply(
|
979
|
+
scope=node_intrinsic_function.scope,
|
980
|
+
arguments_delta=arguments_delta,
|
981
|
+
resolver=_compute_fn_ref,
|
982
|
+
)
|
983
|
+
return delta
|
964
984
|
|
965
985
|
def visit_node_intrinsic_function_condition(
|
966
986
|
self, node_intrinsic_function: NodeIntrinsicFunction
|
967
987
|
) -> PreprocEntityDelta:
|
968
988
|
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
969
|
-
before_condition_name = arguments_delta.before
|
970
|
-
after_condition_name = arguments_delta.after
|
971
989
|
|
972
990
|
def _delta_of_condition(name: str) -> PreprocEntityDelta:
|
973
991
|
node_condition = self._get_node_condition_if_exists(condition_name=name)
|
974
992
|
if is_nothing(node_condition):
|
975
993
|
raise RuntimeError(f"Undefined condition '{name}'")
|
976
|
-
|
977
|
-
return
|
978
|
-
|
979
|
-
before = Nothing
|
980
|
-
if not is_nothing(before_condition_name):
|
981
|
-
before_delta = _delta_of_condition(before_condition_name)
|
982
|
-
before = before_delta.before
|
983
|
-
|
984
|
-
after = Nothing
|
985
|
-
if not is_nothing(after_condition_name):
|
986
|
-
after_delta = _delta_of_condition(after_condition_name)
|
987
|
-
after = after_delta.after
|
994
|
+
condition_delta = self.visit(node_condition)
|
995
|
+
return condition_delta
|
988
996
|
|
989
|
-
|
997
|
+
delta = self._cached_apply(
|
998
|
+
resolver=_delta_of_condition,
|
999
|
+
scope=node_intrinsic_function.scope,
|
1000
|
+
arguments_delta=arguments_delta,
|
1001
|
+
)
|
1002
|
+
return delta
|
990
1003
|
|
991
1004
|
def visit_node_array(self, node_array: NodeArray) -> PreprocEntityDelta:
|
992
1005
|
node_change_type = node_array.change_type
|
@@ -18,6 +18,7 @@ from localstack.services.cloudformation.engine.v2.change_set_model import (
|
|
18
18
|
NodeParameter,
|
19
19
|
NodeTransform,
|
20
20
|
Nothing,
|
21
|
+
Scope,
|
21
22
|
is_nothing,
|
22
23
|
)
|
23
24
|
from localstack.services.cloudformation.engine.v2.change_set_model_preproc import (
|
@@ -33,6 +34,8 @@ SERVERLESS_TRANSFORM = "AWS::Serverless-2016-10-31"
|
|
33
34
|
EXTENSIONS_TRANSFORM = "AWS::LanguageExtensions"
|
34
35
|
SECRETSMANAGER_TRANSFORM = "AWS::SecretsManager-2020-07-23"
|
35
36
|
|
37
|
+
_SCOPE_TRANSFORM_TEMPLATE_OUTCOME: Final[Scope] = Scope("TRANSFORM_TEMPLATE_OUTCOME")
|
38
|
+
|
36
39
|
|
37
40
|
# TODO: evaluate the use of subtypes to represent and validate types of transforms
|
38
41
|
class GlobalTransform:
|
@@ -190,35 +193,47 @@ class ChangeSetModelTransform(ChangeSetModelPreproc):
|
|
190
193
|
return transformed_template
|
191
194
|
|
192
195
|
def transform(self) -> tuple[dict, dict]:
|
193
|
-
|
196
|
+
self._setup_runtime_cache()
|
197
|
+
|
198
|
+
node_template = self._change_set.update_model.node_template
|
199
|
+
|
200
|
+
parameters_delta = self.visit_node_parameters(node_template.parameters)
|
194
201
|
parameters_before = parameters_delta.before
|
195
202
|
parameters_after = parameters_delta.after
|
196
203
|
|
197
204
|
transform_delta: PreprocEntityDelta[list[GlobalTransform], list[GlobalTransform]] = (
|
198
|
-
self.visit_node_transform(
|
205
|
+
self.visit_node_transform(node_template.transform)
|
199
206
|
)
|
200
207
|
transform_before: Maybe[list[GlobalTransform]] = transform_delta.before
|
201
208
|
transform_after: Maybe[list[GlobalTransform]] = transform_delta.after
|
202
209
|
|
203
210
|
transformed_before_template = self._before_template
|
204
|
-
if
|
205
|
-
transformed_before_template = self.
|
206
|
-
|
207
|
-
transformed_before_template = self.
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
211
|
+
if transform_before and not is_nothing(self._before_template):
|
212
|
+
transformed_before_template = self._before_cache.get(_SCOPE_TRANSFORM_TEMPLATE_OUTCOME)
|
213
|
+
if not transformed_before_template:
|
214
|
+
transformed_before_template = self._before_template
|
215
|
+
for before_global_transform in transform_before:
|
216
|
+
transformed_before_template = self._apply_global_transform(
|
217
|
+
global_transform=before_global_transform,
|
218
|
+
parameters=parameters_before,
|
219
|
+
template=transformed_before_template,
|
220
|
+
)
|
221
|
+
self._before_cache[_SCOPE_TRANSFORM_TEMPLATE_OUTCOME] = transformed_before_template
|
212
222
|
|
213
223
|
transformed_after_template = self._after_template
|
214
|
-
if
|
215
|
-
transformed_after_template = self.
|
216
|
-
|
217
|
-
transformed_after_template = self.
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
224
|
+
if transform_after and not is_nothing(self._after_template):
|
225
|
+
transformed_after_template = self._after_cache.get(_SCOPE_TRANSFORM_TEMPLATE_OUTCOME)
|
226
|
+
if not transformed_after_template:
|
227
|
+
transformed_after_template = self._after_template
|
228
|
+
for after_global_transform in transform_after:
|
229
|
+
transformed_after_template = self._apply_global_transform(
|
230
|
+
global_transform=after_global_transform,
|
231
|
+
parameters=parameters_after,
|
232
|
+
template=transformed_after_template,
|
233
|
+
)
|
234
|
+
self._after_cache[_SCOPE_TRANSFORM_TEMPLATE_OUTCOME] = transformed_after_template
|
235
|
+
|
236
|
+
self._save_runtime_cache()
|
222
237
|
|
223
238
|
return transformed_before_template, transformed_after_template
|
224
239
|
|
@@ -24,7 +24,7 @@ from localstack.services.cloudformation.engine.entities import (
|
|
24
24
|
StackIdentifier,
|
25
25
|
)
|
26
26
|
from localstack.services.cloudformation.engine.v2.change_set_model import (
|
27
|
-
|
27
|
+
UpdateModel,
|
28
28
|
)
|
29
29
|
from localstack.utils.aws import arns
|
30
30
|
from localstack.utils.strings import long_uid, short_uid
|
@@ -204,7 +204,7 @@ class ChangeSet:
|
|
204
204
|
change_set_name: str
|
205
205
|
change_set_id: str
|
206
206
|
change_set_type: ChangeSetType
|
207
|
-
update_model: Optional[
|
207
|
+
update_model: Optional[UpdateModel]
|
208
208
|
status: ChangeSetStatus
|
209
209
|
execution_status: ExecutionStatus
|
210
210
|
creation_time: datetime
|
@@ -231,7 +231,7 @@ class ChangeSet:
|
|
231
231
|
region_name=self.stack.region_name,
|
232
232
|
)
|
233
233
|
|
234
|
-
def set_update_model(self, update_model:
|
234
|
+
def set_update_model(self, update_model: UpdateModel) -> None:
|
235
235
|
self.update_model = update_model
|
236
236
|
|
237
237
|
def set_change_set_status(self, status: ChangeSetStatus):
|
@@ -47,7 +47,7 @@ from localstack.services.cloudformation.engine import template_preparer
|
|
47
47
|
from localstack.services.cloudformation.engine.v2.change_set_model import (
|
48
48
|
ChangeSetModel,
|
49
49
|
ChangeType,
|
50
|
-
|
50
|
+
UpdateModel,
|
51
51
|
)
|
52
52
|
from localstack.services.cloudformation.engine.v2.change_set_model_describer import (
|
53
53
|
ChangeSetModelDescriber,
|
@@ -133,6 +133,7 @@ class CloudformationProviderV2(CloudformationProvider):
|
|
133
133
|
after_template: Optional[dict],
|
134
134
|
before_parameters: Optional[dict],
|
135
135
|
after_parameters: Optional[dict],
|
136
|
+
previous_update_model: Optional[UpdateModel],
|
136
137
|
):
|
137
138
|
# Create and preprocess the update graph for this template update.
|
138
139
|
change_set_model = ChangeSetModel(
|
@@ -141,7 +142,12 @@ class CloudformationProviderV2(CloudformationProvider):
|
|
141
142
|
before_parameters=before_parameters,
|
142
143
|
after_parameters=after_parameters,
|
143
144
|
)
|
144
|
-
raw_update_model:
|
145
|
+
raw_update_model: UpdateModel = change_set_model.get_update_model()
|
146
|
+
# If there exists an update model which operated in the 'before' version of this change set,
|
147
|
+
# port the runtime values computed for the before version into this latest update model.
|
148
|
+
if previous_update_model:
|
149
|
+
raw_update_model.before_runtime_cache.clear()
|
150
|
+
raw_update_model.before_runtime_cache.update(previous_update_model.after_runtime_cache)
|
145
151
|
change_set.set_update_model(raw_update_model)
|
146
152
|
|
147
153
|
# Apply global transforms.
|
@@ -165,6 +171,12 @@ class CloudformationProviderV2(CloudformationProvider):
|
|
165
171
|
after_parameters=after_parameters,
|
166
172
|
)
|
167
173
|
update_model = change_set_model.get_update_model()
|
174
|
+
# Bring the cache for the previous operations forward in the update graph for this version
|
175
|
+
# of the templates. This enables downstream update graph visitors to access runtime
|
176
|
+
# information computed whilst evaluating the previous version of this template, and during
|
177
|
+
# the transformations.
|
178
|
+
update_model.before_runtime_cache.update(raw_update_model.before_runtime_cache)
|
179
|
+
update_model.after_runtime_cache.update(raw_update_model.after_runtime_cache)
|
168
180
|
change_set.set_update_model(update_model)
|
169
181
|
|
170
182
|
@handler("CreateChangeSet", expand=False)
|
@@ -284,6 +296,15 @@ class CloudformationProviderV2(CloudformationProvider):
|
|
284
296
|
before_template = stack.template
|
285
297
|
after_template = structured_template
|
286
298
|
|
299
|
+
previous_update_model = None
|
300
|
+
try:
|
301
|
+
# FIXME: 'change_set_id' for 'stack' objects is dynamically attributed
|
302
|
+
if previous_change_set := find_change_set_v2(state, stack.change_set_id):
|
303
|
+
previous_update_model = previous_change_set.update_model
|
304
|
+
except Exception:
|
305
|
+
# No change set available on this stack.
|
306
|
+
pass
|
307
|
+
|
287
308
|
# create change set for the stack and apply changes
|
288
309
|
change_set = ChangeSet(stack, request, template=after_template)
|
289
310
|
self._setup_change_set_model(
|
@@ -292,6 +313,7 @@ class CloudformationProviderV2(CloudformationProvider):
|
|
292
313
|
after_template=after_template,
|
293
314
|
before_parameters=before_parameters,
|
294
315
|
after_parameters=after_parameters,
|
316
|
+
previous_update_model=previous_update_model,
|
295
317
|
)
|
296
318
|
|
297
319
|
change_set.set_change_set_status(ChangeSetStatus.CREATE_COMPLETE)
|
@@ -488,6 +510,7 @@ class CloudformationProviderV2(CloudformationProvider):
|
|
488
510
|
after_template=after_template,
|
489
511
|
before_parameters=None,
|
490
512
|
after_parameters=after_parameters,
|
513
|
+
previous_update_model=None,
|
491
514
|
)
|
492
515
|
|
493
516
|
# deployment process
|
@@ -695,6 +718,10 @@ class CloudformationProviderV2(CloudformationProvider):
|
|
695
718
|
before_template = stack.template
|
696
719
|
after_template = structured_template
|
697
720
|
|
721
|
+
previous_update_model = None
|
722
|
+
if previous_change_set := find_change_set_v2(state, stack.change_set_id):
|
723
|
+
previous_update_model = previous_change_set.update_model
|
724
|
+
|
698
725
|
change_set = ChangeSet(
|
699
726
|
stack,
|
700
727
|
{"ChangeSetName": f"cs-{stack_name}-create", "ChangeSetType": ChangeSetType.CREATE},
|
@@ -706,9 +733,13 @@ class CloudformationProviderV2(CloudformationProvider):
|
|
706
733
|
after_template=after_template,
|
707
734
|
before_parameters=before_parameters,
|
708
735
|
after_parameters=after_parameters,
|
736
|
+
previous_update_model=previous_update_model,
|
709
737
|
)
|
710
738
|
|
711
|
-
|
739
|
+
# TODO: some changes are only detectable at runtime; consider using
|
740
|
+
# the ChangeSetModelDescriber, or a new custom visitors, to
|
741
|
+
# pick-up on runtime changes.
|
742
|
+
if change_set.update_model.node_template.change_type == ChangeType.UNCHANGED:
|
712
743
|
raise ValidationError("No updates are to be performed.")
|
713
744
|
|
714
745
|
stack.set_stack_status(StackStatus.UPDATE_IN_PROGRESS)
|
@@ -757,6 +788,10 @@ class CloudformationProviderV2(CloudformationProvider):
|
|
757
788
|
stack.deletion_time = datetime.now(tz=timezone.utc)
|
758
789
|
return
|
759
790
|
|
791
|
+
previous_update_model = None
|
792
|
+
if previous_change_set := find_change_set_v2(state, stack.change_set_id):
|
793
|
+
previous_update_model = previous_change_set.update_model
|
794
|
+
|
760
795
|
# create a dummy change set
|
761
796
|
change_set = ChangeSet(stack, {"ChangeSetName": f"delete-stack_{stack.stack_name}"}) # noqa
|
762
797
|
self._setup_change_set_model(
|
@@ -765,6 +800,7 @@ class CloudformationProviderV2(CloudformationProvider):
|
|
765
800
|
after_template=None,
|
766
801
|
before_parameters=stack.resolved_parameters,
|
767
802
|
after_parameters=None,
|
803
|
+
previous_update_model=previous_update_model,
|
768
804
|
)
|
769
805
|
|
770
806
|
change_set_executor = ChangeSetModelExecutor(change_set)
|
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.5.1.
|
21
|
-
__version_tuple__ = version_tuple = (4, 5, 1, '
|
20
|
+
__version__ = version = '4.5.1.dev63'
|
21
|
+
__version_tuple__ = version_tuple = (4, 5, 1, 'dev63')
|
@@ -4,7 +4,7 @@ localstack/deprecations.py,sha256=mNXTebZ8kSbQjFKz0LbT-g1Kdr0CE8bhEgZfHV3IX0s,15
|
|
4
4
|
localstack/openapi.yaml,sha256=B803NmpwsxG8PHpHrdZYBrUYjnrRh7B_JX0XuNynuFs,30237
|
5
5
|
localstack/plugins.py,sha256=BIJC9dlo0WbP7lLKkCiGtd_2q5oeqiHZohvoRTcejXM,2457
|
6
6
|
localstack/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
-
localstack/version.py,sha256=
|
7
|
+
localstack/version.py,sha256=LTxjfcRuowkt-GVcLE40v8qA0zkkDM-GYlAiR90qrJE,526
|
8
8
|
localstack/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
9
|
localstack/aws/accounts.py,sha256=102zpGowOxo0S6UGMpfjw14QW7WCLVAGsnFK5xFMLoo,3043
|
10
10
|
localstack/aws/app.py,sha256=n9bJCfJRuMz_gLGAH430c3bIQXgUXeWO5NPfcdL2MV8,5145
|
@@ -311,11 +311,11 @@ localstack/services/cloudformation/engine/types.py,sha256=YIhmTrO__obIviYvzzCovK
|
|
311
311
|
localstack/services/cloudformation/engine/validations.py,sha256=brq7s8O8exA5kvnfzR9ulOtQ7i4konrWQs07-0h_ByE,2847
|
312
312
|
localstack/services/cloudformation/engine/yaml_parser.py,sha256=LQpAVq9Syze9jXUGen9Mz8SjosBuodpV5XvsCSn9bDg,2164
|
313
313
|
localstack/services/cloudformation/engine/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
314
|
-
localstack/services/cloudformation/engine/v2/change_set_model.py,sha256=
|
315
|
-
localstack/services/cloudformation/engine/v2/change_set_model_describer.py,sha256=
|
316
|
-
localstack/services/cloudformation/engine/v2/change_set_model_executor.py,sha256=
|
317
|
-
localstack/services/cloudformation/engine/v2/change_set_model_preproc.py,sha256=
|
318
|
-
localstack/services/cloudformation/engine/v2/change_set_model_transform.py,sha256=
|
314
|
+
localstack/services/cloudformation/engine/v2/change_set_model.py,sha256=9JK6YySuJehfP_IJTwrwRfQRaPMmyh3qH3RFJ1GsnOA,55108
|
315
|
+
localstack/services/cloudformation/engine/v2/change_set_model_describer.py,sha256=Y1mvD57gBCSQ4VjVTwebDGeaDv9_a8dNCqOEZq5u5Fg,9075
|
316
|
+
localstack/services/cloudformation/engine/v2/change_set_model_executor.py,sha256=7uKu7GLARY15s3J5_HCUti4K_KPMz4RqdunRpVn_n-A,19984
|
317
|
+
localstack/services/cloudformation/engine/v2/change_set_model_preproc.py,sha256=zdHDjYUJBo53pdgida0TPsyVjELu4MifLpQFvFYtVAE,50713
|
318
|
+
localstack/services/cloudformation/engine/v2/change_set_model_transform.py,sha256=P3iJhAJd2w2E4WevqifAgdBs8tPqk5BuSJYxXs5HpOY,11398
|
319
319
|
localstack/services/cloudformation/engine/v2/change_set_model_visitor.py,sha256=JERT55YkPF-UHzG-sk958mpyEq2Gxz4smY8xwDbhIRQ,7666
|
320
320
|
localstack/services/cloudformation/models/__init__.py,sha256=da1PTClDMl-IBkrSvq6JC1lnS-K_BASzCvxVhNxN5Ls,13
|
321
321
|
localstack/services/cloudformation/resource_providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -334,8 +334,8 @@ localstack/services/cloudformation/resource_providers/aws_cloudformation_waitcon
|
|
334
334
|
localstack/services/cloudformation/scaffolding/__main__.py,sha256=zjedOdqvnfN99WzQ43gxtGZxLDitSnbFGA-zpWbyMQ0,30960
|
335
335
|
localstack/services/cloudformation/scaffolding/propgen.py,sha256=9YsSCkDegcU_Yp8Sfw8eNV26N5ibOlLC6Hg6lxPeBBM,7949
|
336
336
|
localstack/services/cloudformation/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
337
|
-
localstack/services/cloudformation/v2/entities.py,sha256=
|
338
|
-
localstack/services/cloudformation/v2/provider.py,sha256=
|
337
|
+
localstack/services/cloudformation/v2/entities.py,sha256=34Xb2ZoLusyZB0WkSJfMhCEydyY7GpDlxOFqA86s6o4,8031
|
338
|
+
localstack/services/cloudformation/v2/provider.py,sha256=QN9T_fIMi7zptVlR6FJ5RTLP7VtL1_uK-qQnaasO3S0,35226
|
339
339
|
localstack/services/cloudformation/v2/utils.py,sha256=xy4Lcp4X8XGJ0OKfnsE7pnfMcFrtIH0Chw35qwjhZuw,148
|
340
340
|
localstack/services/cloudwatch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
341
341
|
localstack/services/cloudwatch/alarm_scheduler.py,sha256=XFllg0gI_WNV7cNxOcgXifzmbNA07OPpuEUuf37keP4,15663
|
@@ -1286,13 +1286,13 @@ localstack/utils/server/tcp_proxy.py,sha256=rR6d5jR0ozDvIlpHiqW0cfyY9a2fRGdOzyA8
|
|
1286
1286
|
localstack/utils/xray/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1287
1287
|
localstack/utils/xray/trace_header.py,sha256=ahXk9eonq7LpeENwlqUEPj3jDOCiVRixhntQuxNor-Q,6209
|
1288
1288
|
localstack/utils/xray/traceid.py,sha256=SQSsMV2rhbTNK6ceIoozZYuGU7Fg687EXcgqxoDl1Fw,1106
|
1289
|
-
localstack_core-4.5.1.
|
1290
|
-
localstack_core-4.5.1.
|
1291
|
-
localstack_core-4.5.1.
|
1292
|
-
localstack_core-4.5.1.
|
1293
|
-
localstack_core-4.5.1.
|
1294
|
-
localstack_core-4.5.1.
|
1295
|
-
localstack_core-4.5.1.
|
1296
|
-
localstack_core-4.5.1.
|
1297
|
-
localstack_core-4.5.1.
|
1298
|
-
localstack_core-4.5.1.
|
1289
|
+
localstack_core-4.5.1.dev63.data/scripts/localstack,sha256=WyL11vp5CkuP79iIR-L8XT7Cj8nvmxX7XRAgxhbmXNE,529
|
1290
|
+
localstack_core-4.5.1.dev63.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
|
1291
|
+
localstack_core-4.5.1.dev63.data/scripts/localstack.bat,sha256=tlzZTXtveHkMX_s_fa7VDfvdNdS8iVpEz2ER3uk9B_c,29
|
1292
|
+
localstack_core-4.5.1.dev63.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
|
1293
|
+
localstack_core-4.5.1.dev63.dist-info/METADATA,sha256=nd0S0X_zyxnGAkuGycaqLBX0J5AnnvPIEElGAAlzYzU,5539
|
1294
|
+
localstack_core-4.5.1.dev63.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
1295
|
+
localstack_core-4.5.1.dev63.dist-info/entry_points.txt,sha256=-GFtw80qM_1GQIDUcyqXojJvnqvP_8lK1Vc-M9ShaJE,20668
|
1296
|
+
localstack_core-4.5.1.dev63.dist-info/plux.json,sha256=SrBYCxHG_jbVHlfE9Kl6TsUmFfVQEREHJRBd3jECTqQ,20891
|
1297
|
+
localstack_core-4.5.1.dev63.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
|
1298
|
+
localstack_core-4.5.1.dev63.dist-info/RECORD,,
|
@@ -0,0 +1 @@
|
|
1
|
+
{"localstack.cloudformation.resource_providers": ["AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "AWS::ApiGateway::Deployment=localstack.services.apigateway.resource_providers.aws_apigateway_deployment_plugin:ApiGatewayDeploymentProviderPlugin", "AWS::Route53::HealthCheck=localstack.services.route53.resource_providers.aws_route53_healthcheck_plugin:Route53HealthCheckProviderPlugin", "AWS::EC2::RouteTable=localstack.services.ec2.resource_providers.aws_ec2_routetable_plugin:EC2RouteTableProviderPlugin", "AWS::IAM::ServerCertificate=localstack.services.iam.resource_providers.aws_iam_servercertificate_plugin:IAMServerCertificateProviderPlugin", "AWS::ApiGateway::RestApi=localstack.services.apigateway.resource_providers.aws_apigateway_restapi_plugin:ApiGatewayRestApiProviderPlugin", "AWS::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::EC2::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::Lambda::Permission=localstack.services.lambda_.resource_providers.aws_lambda_permission_plugin:LambdaPermissionProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::Kinesis::StreamConsumer=localstack.services.kinesis.resource_providers.aws_kinesis_streamconsumer_plugin:KinesisStreamConsumerProviderPlugin", "AWS::Lambda::Function=localstack.services.lambda_.resource_providers.aws_lambda_function_plugin:LambdaFunctionProviderPlugin", "AWS::DynamoDB::GlobalTable=localstack.services.dynamodb.resource_providers.aws_dynamodb_globaltable_plugin:DynamoDBGlobalTableProviderPlugin", "AWS::SecretsManager::SecretTargetAttachment=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment_plugin:SecretsManagerSecretTargetAttachmentProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::ApiGateway::DomainName=localstack.services.apigateway.resource_providers.aws_apigateway_domainname_plugin:ApiGatewayDomainNameProviderPlugin", "AWS::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "AWS::EC2::NetworkAcl=localstack.services.ec2.resource_providers.aws_ec2_networkacl_plugin:EC2NetworkAclProviderPlugin", "AWS::Lambda::LayerVersionPermission=localstack.services.lambda_.resource_providers.aws_lambda_layerversionpermission_plugin:LambdaLayerVersionPermissionProviderPlugin", "AWS::EC2::Route=localstack.services.ec2.resource_providers.aws_ec2_route_plugin:EC2RouteProviderPlugin", "AWS::Lambda::EventSourceMapping=localstack.services.lambda_.resource_providers.aws_lambda_eventsourcemapping_plugin:LambdaEventSourceMappingProviderPlugin", "AWS::Events::EventBusPolicy=localstack.services.events.resource_providers.aws_events_eventbuspolicy_plugin:EventsEventBusPolicyProviderPlugin", "AWS::Lambda::Version=localstack.services.lambda_.resource_providers.aws_lambda_version_plugin:LambdaVersionProviderPlugin", "AWS::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::ApiGateway::Method=localstack.services.apigateway.resource_providers.aws_apigateway_method_plugin:ApiGatewayMethodProviderPlugin", "AWS::SNS::Subscription=localstack.services.sns.resource_providers.aws_sns_subscription_plugin:SNSSubscriptionProviderPlugin", "AWS::ApiGateway::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::EC2::PrefixList=localstack.services.ec2.resource_providers.aws_ec2_prefixlist_plugin:EC2PrefixListProviderPlugin", "AWS::SQS::QueuePolicy=localstack.services.sqs.resource_providers.aws_sqs_queuepolicy_plugin:SQSQueuePolicyProviderPlugin", "AWS::ApiGateway::ApiKey=localstack.services.apigateway.resource_providers.aws_apigateway_apikey_plugin:ApiGatewayApiKeyProviderPlugin", "AWS::Lambda::Alias=localstack.services.lambda_.resource_providers.lambda_alias_plugin:LambdaAliasProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::CertificateManager::Certificate=localstack.services.certificatemanager.resource_providers.aws_certificatemanager_certificate_plugin:CertificateManagerCertificateProviderPlugin", "AWS::EC2::Subnet=localstack.services.ec2.resource_providers.aws_ec2_subnet_plugin:EC2SubnetProviderPlugin", "AWS::IAM::ManagedPolicy=localstack.services.iam.resource_providers.aws_iam_managedpolicy_plugin:IAMManagedPolicyProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin", "AWS::IAM::Policy=localstack.services.iam.resource_providers.aws_iam_policy_plugin:IAMPolicyProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::Route53::RecordSet=localstack.services.route53.resource_providers.aws_route53_recordset_plugin:Route53RecordSetProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::KMS::Alias=localstack.services.kms.resource_providers.aws_kms_alias_plugin:KMSAliasProviderPlugin", "AWS::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin", "AWS::Events::EventBus=localstack.services.events.resource_providers.aws_events_eventbus_plugin:EventsEventBusProviderPlugin", "AWS::SNS::Topic=localstack.services.sns.resource_providers.aws_sns_topic_plugin:SNSTopicProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::EC2::VPCGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_vpcgatewayattachment_plugin:EC2VPCGatewayAttachmentProviderPlugin", "AWS::KMS::Key=localstack.services.kms.resource_providers.aws_kms_key_plugin:KMSKeyProviderPlugin", "AWS::OpenSearchService::Domain=localstack.services.opensearch.resource_providers.aws_opensearchservice_domain_plugin:OpenSearchServiceDomainProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::CloudWatch::CompositeAlarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_compositealarm_plugin:CloudWatchCompositeAlarmProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::SNS::TopicPolicy=localstack.services.sns.resource_providers.aws_sns_topicpolicy_plugin:SNSTopicPolicyProviderPlugin", "AWS::IAM::Role=localstack.services.iam.resource_providers.aws_iam_role_plugin:IAMRoleProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::Lambda::EventInvokeConfig=localstack.services.lambda_.resource_providers.aws_lambda_eventinvokeconfig_plugin:LambdaEventInvokeConfigProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::EC2::TransitGateway=localstack.services.ec2.resource_providers.aws_ec2_transitgateway_plugin:EC2TransitGatewayProviderPlugin", "AWS::ApiGateway::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::IAM::InstanceProfile=localstack.services.iam.resource_providers.aws_iam_instanceprofile_plugin:IAMInstanceProfileProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin", "AWS::EC2::VPC=localstack.services.ec2.resource_providers.aws_ec2_vpc_plugin:EC2VPCProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::Events::ApiDestination=localstack.services.events.resource_providers.aws_events_apidestination_plugin:EventsApiDestinationProviderPlugin", "AWS::DynamoDB::Table=localstack.services.dynamodb.resource_providers.aws_dynamodb_table_plugin:DynamoDBTableProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin"], "localstack.packages": ["elasticsearch/community=localstack.services.es.plugins:elasticsearch_package", "vosk/community=localstack.services.transcribe.plugins:vosk_package", "dynamodb-local/community=localstack.services.dynamodb.plugins:dynamodb_local_package", "ffmpeg/community=localstack.packages.plugins:ffmpeg_package", "java/community=localstack.packages.plugins:java_package", "terraform/community=localstack.packages.plugins:terraform_package", "lambda-java-libs/community=localstack.services.lambda_.plugins:lambda_java_libs", "lambda-runtime/community=localstack.services.lambda_.plugins:lambda_runtime_package", "opensearch/community=localstack.services.opensearch.plugins:opensearch_package", "kinesis-mock/community=localstack.services.kinesis.plugins:kinesismock_package", "jpype-jsonata/community=localstack.services.stepfunctions.plugins:jpype_jsonata_package"], "localstack.hooks.on_infra_start": ["setup_dns_configuration_on_host=localstack.dns.plugins:setup_dns_configuration_on_host", "start_dns_server=localstack.dns.plugins:start_dns_server", "delete_cached_certificate=localstack.plugins:delete_cached_certificate", "deprecation_warnings=localstack.plugins:deprecation_warnings", "_run_init_scripts_on_start=localstack.runtime.init:_run_init_scripts_on_start", "_publish_config_as_analytics_event=localstack.runtime.analytics:_publish_config_as_analytics_event", "_publish_container_info=localstack.runtime.analytics:_publish_container_info", "eager_load_services=localstack.services.plugins:eager_load_services", "apply_aws_runtime_patches=localstack.aws.patches:apply_aws_runtime_patches", "register_custom_endpoints=localstack.services.lambda_.plugins:register_custom_endpoints", "validate_configuration=localstack.services.lambda_.plugins:validate_configuration", "apply_runtime_patches=localstack.runtime.patches:apply_runtime_patches", "_patch_botocore_endpoint_in_memory=localstack.aws.client:_patch_botocore_endpoint_in_memory", "_patch_botocore_json_parser=localstack.aws.client:_patch_botocore_json_parser", "_patch_cbor2=localstack.aws.client:_patch_cbor2", "init_response_mutation_handler=localstack.aws.handlers.response:init_response_mutation_handler", "register_cloudformation_deploy_ui=localstack.services.cloudformation.plugins:register_cloudformation_deploy_ui", "register_swagger_endpoints=localstack.http.resources.swagger.plugins:register_swagger_endpoints", "conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger"], "localstack.hooks.on_infra_shutdown": ["stop_server=localstack.dns.plugins:stop_server", "_run_init_scripts_on_shutdown=localstack.runtime.init:_run_init_scripts_on_shutdown", "publish_metrics=localstack.utils.analytics.metrics.publisher:publish_metrics", "remove_custom_endpoints=localstack.services.lambda_.plugins:remove_custom_endpoints", "run_on_after_service_shutdown_handlers=localstack.runtime.shutdown:run_on_after_service_shutdown_handlers", "run_shutdown_handlers=localstack.runtime.shutdown:run_shutdown_handlers", "shutdown_services=localstack.runtime.shutdown:shutdown_services"], "localstack.openapi.spec": ["localstack=localstack.plugins:CoreOASPlugin"], "localstack.init.runner": ["py=localstack.runtime.init:PythonScriptRunner", "sh=localstack.runtime.init:ShellScriptRunner"], "localstack.hooks.on_infra_ready": ["_run_init_scripts_on_ready=localstack.runtime.init:_run_init_scripts_on_ready"], "localstack.aws.provider": ["acm:default=localstack.services.providers:acm", "apigateway:default=localstack.services.providers:apigateway", "apigateway:legacy=localstack.services.providers:apigateway_legacy", "apigateway:next_gen=localstack.services.providers:apigateway_next_gen", "config:default=localstack.services.providers:awsconfig", "cloudformation:default=localstack.services.providers:cloudformation", "cloudformation:engine-v2=localstack.services.providers:cloudformation_v2", "cloudwatch:default=localstack.services.providers:cloudwatch", "cloudwatch:v1=localstack.services.providers:cloudwatch_v1", "cloudwatch:v2=localstack.services.providers:cloudwatch_v2", "dynamodb:default=localstack.services.providers:dynamodb", "dynamodb:v2=localstack.services.providers:dynamodb_v2", "dynamodbstreams:default=localstack.services.providers:dynamodbstreams", "dynamodbstreams:v2=localstack.services.providers:dynamodbstreams_v2", "ec2:default=localstack.services.providers:ec2", "es:default=localstack.services.providers:es", "events:default=localstack.services.providers:events", "events:legacy=localstack.services.providers:events_legacy", "events:v1=localstack.services.providers:events_v1", "events:v2=localstack.services.providers:events_v2", "firehose:default=localstack.services.providers:firehose", "iam:default=localstack.services.providers:iam", "kinesis:default=localstack.services.providers:kinesis", "kms:default=localstack.services.providers:kms", "lambda:default=localstack.services.providers:lambda_", "lambda:asf=localstack.services.providers:lambda_asf", "lambda:v2=localstack.services.providers:lambda_v2", "logs:default=localstack.services.providers:logs", "opensearch:default=localstack.services.providers:opensearch", "redshift:default=localstack.services.providers:redshift", "resource-groups:default=localstack.services.providers:resource_groups", "resourcegroupstaggingapi:default=localstack.services.providers:resourcegroupstaggingapi", "route53:default=localstack.services.providers:route53", "route53resolver:default=localstack.services.providers:route53resolver", "s3:default=localstack.services.providers:s3", "s3control:default=localstack.services.providers:s3control", "scheduler:default=localstack.services.providers:scheduler", "secretsmanager:default=localstack.services.providers:secretsmanager", "ses:default=localstack.services.providers:ses", "sns:default=localstack.services.providers:sns", "sqs:default=localstack.services.providers:sqs", "ssm:default=localstack.services.providers:ssm", "stepfunctions:default=localstack.services.providers:stepfunctions", "stepfunctions:v2=localstack.services.providers:stepfunctions_v2", "sts:default=localstack.services.providers:sts", "support:default=localstack.services.providers:support", "swf:default=localstack.services.providers:swf", "transcribe:default=localstack.services.providers:transcribe"], "localstack.runtime.server": ["hypercorn=localstack.runtime.server.plugins:HypercornRuntimeServerPlugin", "twisted=localstack.runtime.server.plugins:TwistedRuntimeServerPlugin"], "localstack.lambda.runtime_executor": ["docker=localstack.services.lambda_.invocation.plugins:DockerRuntimeExecutorPlugin"], "localstack.runtime.components": ["aws=localstack.aws.components:AwsComponents"], "localstack.hooks.configure_localstack_container": ["_mount_machine_file=localstack.utils.analytics.metadata:_mount_machine_file"], "localstack.hooks.prepare_host": ["prepare_host_machine_id=localstack.utils.analytics.metadata:prepare_host_machine_id"]}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"localstack.cloudformation.resource_providers": ["AWS::EC2::VPCGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_vpcgatewayattachment_plugin:EC2VPCGatewayAttachmentProviderPlugin", "AWS::EC2::NetworkAcl=localstack.services.ec2.resource_providers.aws_ec2_networkacl_plugin:EC2NetworkAclProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::CloudWatch::CompositeAlarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_compositealarm_plugin:CloudWatchCompositeAlarmProviderPlugin", "AWS::Lambda::Permission=localstack.services.lambda_.resource_providers.aws_lambda_permission_plugin:LambdaPermissionProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::IAM::InstanceProfile=localstack.services.iam.resource_providers.aws_iam_instanceprofile_plugin:IAMInstanceProfileProviderPlugin", "AWS::ApiGateway::ApiKey=localstack.services.apigateway.resource_providers.aws_apigateway_apikey_plugin:ApiGatewayApiKeyProviderPlugin", "AWS::DynamoDB::GlobalTable=localstack.services.dynamodb.resource_providers.aws_dynamodb_globaltable_plugin:DynamoDBGlobalTableProviderPlugin", "AWS::IAM::Role=localstack.services.iam.resource_providers.aws_iam_role_plugin:IAMRoleProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::OpenSearchService::Domain=localstack.services.opensearch.resource_providers.aws_opensearchservice_domain_plugin:OpenSearchServiceDomainProviderPlugin", "AWS::ApiGateway::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "AWS::SNS::TopicPolicy=localstack.services.sns.resource_providers.aws_sns_topicpolicy_plugin:SNSTopicPolicyProviderPlugin", "AWS::ApiGateway::DomainName=localstack.services.apigateway.resource_providers.aws_apigateway_domainname_plugin:ApiGatewayDomainNameProviderPlugin", "AWS::ApiGateway::RestApi=localstack.services.apigateway.resource_providers.aws_apigateway_restapi_plugin:ApiGatewayRestApiProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::Lambda::LayerVersionPermission=localstack.services.lambda_.resource_providers.aws_lambda_layerversionpermission_plugin:LambdaLayerVersionPermissionProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin", "AWS::EC2::Route=localstack.services.ec2.resource_providers.aws_ec2_route_plugin:EC2RouteProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin", "AWS::IAM::ManagedPolicy=localstack.services.iam.resource_providers.aws_iam_managedpolicy_plugin:IAMManagedPolicyProviderPlugin", "AWS::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "AWS::SQS::QueuePolicy=localstack.services.sqs.resource_providers.aws_sqs_queuepolicy_plugin:SQSQueuePolicyProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::IAM::ServerCertificate=localstack.services.iam.resource_providers.aws_iam_servercertificate_plugin:IAMServerCertificateProviderPlugin", "AWS::Lambda::Function=localstack.services.lambda_.resource_providers.aws_lambda_function_plugin:LambdaFunctionProviderPlugin", "AWS::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "AWS::Events::ApiDestination=localstack.services.events.resource_providers.aws_events_apidestination_plugin:EventsApiDestinationProviderPlugin", "AWS::Route53::HealthCheck=localstack.services.route53.resource_providers.aws_route53_healthcheck_plugin:Route53HealthCheckProviderPlugin", "AWS::Route53::RecordSet=localstack.services.route53.resource_providers.aws_route53_recordset_plugin:Route53RecordSetProviderPlugin", "AWS::SecretsManager::SecretTargetAttachment=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment_plugin:SecretsManagerSecretTargetAttachmentProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::IAM::Policy=localstack.services.iam.resource_providers.aws_iam_policy_plugin:IAMPolicyProviderPlugin", "AWS::CertificateManager::Certificate=localstack.services.certificatemanager.resource_providers.aws_certificatemanager_certificate_plugin:CertificateManagerCertificateProviderPlugin", "AWS::ApiGateway::Deployment=localstack.services.apigateway.resource_providers.aws_apigateway_deployment_plugin:ApiGatewayDeploymentProviderPlugin", "AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "AWS::EC2::VPC=localstack.services.ec2.resource_providers.aws_ec2_vpc_plugin:EC2VPCProviderPlugin", "AWS::EC2::Subnet=localstack.services.ec2.resource_providers.aws_ec2_subnet_plugin:EC2SubnetProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::Lambda::EventInvokeConfig=localstack.services.lambda_.resource_providers.aws_lambda_eventinvokeconfig_plugin:LambdaEventInvokeConfigProviderPlugin", "AWS::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin", "AWS::Kinesis::StreamConsumer=localstack.services.kinesis.resource_providers.aws_kinesis_streamconsumer_plugin:KinesisStreamConsumerProviderPlugin", "AWS::EC2::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::DynamoDB::Table=localstack.services.dynamodb.resource_providers.aws_dynamodb_table_plugin:DynamoDBTableProviderPlugin", "AWS::KMS::Key=localstack.services.kms.resource_providers.aws_kms_key_plugin:KMSKeyProviderPlugin", "AWS::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::Events::EventBusPolicy=localstack.services.events.resource_providers.aws_events_eventbuspolicy_plugin:EventsEventBusPolicyProviderPlugin", "AWS::EC2::TransitGateway=localstack.services.ec2.resource_providers.aws_ec2_transitgateway_plugin:EC2TransitGatewayProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "AWS::EC2::PrefixList=localstack.services.ec2.resource_providers.aws_ec2_prefixlist_plugin:EC2PrefixListProviderPlugin", "AWS::SNS::Subscription=localstack.services.sns.resource_providers.aws_sns_subscription_plugin:SNSSubscriptionProviderPlugin", "AWS::KMS::Alias=localstack.services.kms.resource_providers.aws_kms_alias_plugin:KMSAliasProviderPlugin", "AWS::Lambda::Alias=localstack.services.lambda_.resource_providers.lambda_alias_plugin:LambdaAliasProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "AWS::EC2::RouteTable=localstack.services.ec2.resource_providers.aws_ec2_routetable_plugin:EC2RouteTableProviderPlugin", "AWS::Lambda::Version=localstack.services.lambda_.resource_providers.aws_lambda_version_plugin:LambdaVersionProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::ApiGateway::Method=localstack.services.apigateway.resource_providers.aws_apigateway_method_plugin:ApiGatewayMethodProviderPlugin", "AWS::Events::EventBus=localstack.services.events.resource_providers.aws_events_eventbus_plugin:EventsEventBusProviderPlugin", "AWS::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::Lambda::EventSourceMapping=localstack.services.lambda_.resource_providers.aws_lambda_eventsourcemapping_plugin:LambdaEventSourceMappingProviderPlugin", "AWS::SNS::Topic=localstack.services.sns.resource_providers.aws_sns_topic_plugin:SNSTopicProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::ApiGateway::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "AWS::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin"], "localstack.runtime.server": ["hypercorn=localstack.runtime.server.plugins:HypercornRuntimeServerPlugin", "twisted=localstack.runtime.server.plugins:TwistedRuntimeServerPlugin"], "localstack.lambda.runtime_executor": ["docker=localstack.services.lambda_.invocation.plugins:DockerRuntimeExecutorPlugin"], "localstack.hooks.on_infra_start": ["register_cloudformation_deploy_ui=localstack.services.cloudformation.plugins:register_cloudformation_deploy_ui", "eager_load_services=localstack.services.plugins:eager_load_services", "setup_dns_configuration_on_host=localstack.dns.plugins:setup_dns_configuration_on_host", "start_dns_server=localstack.dns.plugins:start_dns_server", "register_custom_endpoints=localstack.services.lambda_.plugins:register_custom_endpoints", "validate_configuration=localstack.services.lambda_.plugins:validate_configuration", "_run_init_scripts_on_start=localstack.runtime.init:_run_init_scripts_on_start", "apply_aws_runtime_patches=localstack.aws.patches:apply_aws_runtime_patches", "_publish_config_as_analytics_event=localstack.runtime.analytics:_publish_config_as_analytics_event", "_publish_container_info=localstack.runtime.analytics:_publish_container_info", "apply_runtime_patches=localstack.runtime.patches:apply_runtime_patches", "register_swagger_endpoints=localstack.http.resources.swagger.plugins:register_swagger_endpoints", "init_response_mutation_handler=localstack.aws.handlers.response:init_response_mutation_handler", "_patch_botocore_endpoint_in_memory=localstack.aws.client:_patch_botocore_endpoint_in_memory", "_patch_botocore_json_parser=localstack.aws.client:_patch_botocore_json_parser", "_patch_cbor2=localstack.aws.client:_patch_cbor2", "delete_cached_certificate=localstack.plugins:delete_cached_certificate", "deprecation_warnings=localstack.plugins:deprecation_warnings", "conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger"], "localstack.hooks.on_infra_shutdown": ["stop_server=localstack.dns.plugins:stop_server", "remove_custom_endpoints=localstack.services.lambda_.plugins:remove_custom_endpoints", "_run_init_scripts_on_shutdown=localstack.runtime.init:_run_init_scripts_on_shutdown", "publish_metrics=localstack.utils.analytics.metrics.publisher:publish_metrics", "run_on_after_service_shutdown_handlers=localstack.runtime.shutdown:run_on_after_service_shutdown_handlers", "run_shutdown_handlers=localstack.runtime.shutdown:run_shutdown_handlers", "shutdown_services=localstack.runtime.shutdown:shutdown_services"], "localstack.packages": ["lambda-java-libs/community=localstack.services.lambda_.plugins:lambda_java_libs", "lambda-runtime/community=localstack.services.lambda_.plugins:lambda_runtime_package", "ffmpeg/community=localstack.packages.plugins:ffmpeg_package", "java/community=localstack.packages.plugins:java_package", "terraform/community=localstack.packages.plugins:terraform_package", "jpype-jsonata/community=localstack.services.stepfunctions.plugins:jpype_jsonata_package", "opensearch/community=localstack.services.opensearch.plugins:opensearch_package", "kinesis-mock/community=localstack.services.kinesis.plugins:kinesismock_package", "vosk/community=localstack.services.transcribe.plugins:vosk_package", "dynamodb-local/community=localstack.services.dynamodb.plugins:dynamodb_local_package", "elasticsearch/community=localstack.services.es.plugins:elasticsearch_package"], "localstack.init.runner": ["py=localstack.runtime.init:PythonScriptRunner", "sh=localstack.runtime.init:ShellScriptRunner"], "localstack.hooks.on_infra_ready": ["_run_init_scripts_on_ready=localstack.runtime.init:_run_init_scripts_on_ready"], "localstack.hooks.configure_localstack_container": ["_mount_machine_file=localstack.utils.analytics.metadata:_mount_machine_file"], "localstack.hooks.prepare_host": ["prepare_host_machine_id=localstack.utils.analytics.metadata:prepare_host_machine_id"], "localstack.openapi.spec": ["localstack=localstack.plugins:CoreOASPlugin"], "localstack.runtime.components": ["aws=localstack.aws.components:AwsComponents"], "localstack.aws.provider": ["acm:default=localstack.services.providers:acm", "apigateway:default=localstack.services.providers:apigateway", "apigateway:legacy=localstack.services.providers:apigateway_legacy", "apigateway:next_gen=localstack.services.providers:apigateway_next_gen", "config:default=localstack.services.providers:awsconfig", "cloudformation:default=localstack.services.providers:cloudformation", "cloudformation:engine-v2=localstack.services.providers:cloudformation_v2", "cloudwatch:default=localstack.services.providers:cloudwatch", "cloudwatch:v1=localstack.services.providers:cloudwatch_v1", "cloudwatch:v2=localstack.services.providers:cloudwatch_v2", "dynamodb:default=localstack.services.providers:dynamodb", "dynamodb:v2=localstack.services.providers:dynamodb_v2", "dynamodbstreams:default=localstack.services.providers:dynamodbstreams", "dynamodbstreams:v2=localstack.services.providers:dynamodbstreams_v2", "ec2:default=localstack.services.providers:ec2", "es:default=localstack.services.providers:es", "events:default=localstack.services.providers:events", "events:legacy=localstack.services.providers:events_legacy", "events:v1=localstack.services.providers:events_v1", "events:v2=localstack.services.providers:events_v2", "firehose:default=localstack.services.providers:firehose", "iam:default=localstack.services.providers:iam", "kinesis:default=localstack.services.providers:kinesis", "kms:default=localstack.services.providers:kms", "lambda:default=localstack.services.providers:lambda_", "lambda:asf=localstack.services.providers:lambda_asf", "lambda:v2=localstack.services.providers:lambda_v2", "logs:default=localstack.services.providers:logs", "opensearch:default=localstack.services.providers:opensearch", "redshift:default=localstack.services.providers:redshift", "resource-groups:default=localstack.services.providers:resource_groups", "resourcegroupstaggingapi:default=localstack.services.providers:resourcegroupstaggingapi", "route53:default=localstack.services.providers:route53", "route53resolver:default=localstack.services.providers:route53resolver", "s3:default=localstack.services.providers:s3", "s3control:default=localstack.services.providers:s3control", "scheduler:default=localstack.services.providers:scheduler", "secretsmanager:default=localstack.services.providers:secretsmanager", "ses:default=localstack.services.providers:ses", "sns:default=localstack.services.providers:sns", "sqs:default=localstack.services.providers:sqs", "ssm:default=localstack.services.providers:ssm", "stepfunctions:default=localstack.services.providers:stepfunctions", "stepfunctions:v2=localstack.services.providers:stepfunctions_v2", "sts:default=localstack.services.providers:sts", "support:default=localstack.services.providers:support", "swf:default=localstack.services.providers:swf", "transcribe:default=localstack.services.providers:transcribe"]}
|
File without changes
|
{localstack_core-4.5.1.dev62.data → localstack_core-4.5.1.dev63.data}/scripts/localstack-supervisor
RENAMED
File without changes
|
{localstack_core-4.5.1.dev62.data → localstack_core-4.5.1.dev63.data}/scripts/localstack.bat
RENAMED
File without changes
|
File without changes
|
{localstack_core-4.5.1.dev62.dist-info → localstack_core-4.5.1.dev63.dist-info}/entry_points.txt
RENAMED
File without changes
|
{localstack_core-4.5.1.dev62.dist-info → localstack_core-4.5.1.dev63.dist-info}/licenses/LICENSE.txt
RENAMED
File without changes
|
{localstack_core-4.5.1.dev62.dist-info → localstack_core-4.5.1.dev63.dist-info}/top_level.txt
RENAMED
File without changes
|