localstack-core 4.2.1.dev61__py3-none-any.whl → 4.2.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.
Files changed (19) hide show
  1. localstack/services/cloudformation/engine/entities.py +15 -0
  2. localstack/services/cloudformation/engine/v2/change_set_model.py +116 -8
  3. localstack/services/cloudformation/engine/v2/change_set_model_describer.py +88 -10
  4. localstack/services/cloudformation/engine/v2/change_set_model_visitor.py +15 -0
  5. localstack/services/cloudformation/resource_provider.py +2 -4
  6. localstack/services/cloudformation/usage.py +6 -3
  7. localstack/services/cloudformation/v2/provider.py +278 -2
  8. localstack/version.py +2 -2
  9. {localstack_core-4.2.1.dev61.dist-info → localstack_core-4.2.1.dev63.dist-info}/METADATA +1 -1
  10. {localstack_core-4.2.1.dev61.dist-info → localstack_core-4.2.1.dev63.dist-info}/RECORD +18 -18
  11. localstack_core-4.2.1.dev63.dist-info/plux.json +1 -0
  12. localstack_core-4.2.1.dev61.dist-info/plux.json +0 -1
  13. {localstack_core-4.2.1.dev61.data → localstack_core-4.2.1.dev63.data}/scripts/localstack +0 -0
  14. {localstack_core-4.2.1.dev61.data → localstack_core-4.2.1.dev63.data}/scripts/localstack-supervisor +0 -0
  15. {localstack_core-4.2.1.dev61.data → localstack_core-4.2.1.dev63.data}/scripts/localstack.bat +0 -0
  16. {localstack_core-4.2.1.dev61.dist-info → localstack_core-4.2.1.dev63.dist-info}/LICENSE.txt +0 -0
  17. {localstack_core-4.2.1.dev61.dist-info → localstack_core-4.2.1.dev63.dist-info}/WHEEL +0 -0
  18. {localstack_core-4.2.1.dev61.dist-info → localstack_core-4.2.1.dev63.dist-info}/entry_points.txt +0 -0
  19. {localstack_core-4.2.1.dev61.dist-info → localstack_core-4.2.1.dev63.dist-info}/top_level.txt +0 -0
@@ -8,6 +8,10 @@ from localstack.services.cloudformation.engine.parameters import (
8
8
  mask_no_echo,
9
9
  strip_parameter_type,
10
10
  )
11
+ from localstack.services.cloudformation.engine.v2.change_set_model import (
12
+ ChangeSetModel,
13
+ NodeTemplate,
14
+ )
11
15
  from localstack.utils.aws import arns
12
16
  from localstack.utils.collections import select_attributes
13
17
  from localstack.utils.id_generator import ExistingIds, ResourceIdentifier, Tags, generate_short_uid
@@ -363,7 +367,10 @@ class Stack:
363
367
 
364
368
 
365
369
  # FIXME: remove inheritance
370
+ # TODO: what functionality of the Stack object do we rely on here?
366
371
  class StackChangeSet(Stack):
372
+ update_graph: NodeTemplate | None
373
+
367
374
  def __init__(self, account_id: str, region_name: str, stack: Stack, params=None, template=None):
368
375
  if template is None:
369
376
  template = {}
@@ -399,3 +406,11 @@ class StackChangeSet(Stack):
399
406
  def changes(self):
400
407
  result = self.metadata["Changes"] = self.metadata.get("Changes", [])
401
408
  return result
409
+
410
+ # V2 only
411
+ def populate_update_graph(self, before_template: dict | None, after_template: dict | None):
412
+ change_set_model = ChangeSetModel(
413
+ before_template=before_template,
414
+ after_template=after_template,
415
+ )
416
+ self.update_graph = change_set_model.get_update_model()
@@ -7,6 +7,8 @@ from typing import Any, Final, Generator, Optional, Union
7
7
 
8
8
  from typing_extensions import TypeVar
9
9
 
10
+ from localstack.utils.strings import camel_to_snake_case
11
+
10
12
  T = TypeVar("T")
11
13
 
12
14
 
@@ -129,6 +131,18 @@ class NodeProperty(ChangeSetNode):
129
131
  self.value = value
130
132
 
131
133
 
134
+ class NodeIntrinsicFunction(ChangeSetNode):
135
+ intrinsic_function: Final[str]
136
+ arguments: Final[ChangeSetEntity]
137
+
138
+ def __init__(
139
+ self, change_type: ChangeType, intrinsic_function: str, arguments: ChangeSetEntity
140
+ ):
141
+ super().__init__(change_type=change_type)
142
+ self.intrinsic_function = intrinsic_function
143
+ self.arguments = arguments
144
+
145
+
132
146
  class NodeObject(ChangeSetNode):
133
147
  bindings: Final[dict[str, ChangeSetEntity]]
134
148
 
@@ -178,6 +192,10 @@ class TerminalValueUnchanged(TerminalValue):
178
192
 
179
193
  ResourcesKey: Final[str] = "Resources"
180
194
  PropertiesKey: Final[str] = "Properties"
195
+ TypeKey: Final[str] = "Type"
196
+ # TODO: expand intrinsic functions set.
197
+ FnGetAttKey: Final[str] = "Fn::GetAtt"
198
+ INTRINSIC_FUNCTIONS: Final[set[str]] = {FnGetAttKey}
181
199
 
182
200
 
183
201
  class ChangeSetModel:
@@ -185,24 +203,29 @@ class ChangeSetModel:
185
203
 
186
204
  # TODO: can probably improve the typehints to use CFN's 'language' eg. dict -> Template|Properties, etc.
187
205
 
188
- # TODO: typechecks for key-value pairs?
206
+ # TODO: add support for 'replacement' computation, and ensure this state is propagated in tree traversals
207
+ # such as intrinsic functions.
189
208
 
190
209
  _before_template: Final[Maybe[dict]]
191
210
  _after_template: Final[Maybe[dict]]
211
+ # TODO: generalise this lookup for other goto visitable types such as parameters and conditions
212
+ _visited_resources: Final[dict[str, NodeResource]]
192
213
  _node_template: Final[NodeTemplate]
193
214
 
194
215
  def __init__(self, before_template: Optional[dict], after_template: Optional[dict]):
195
216
  self._before_template = before_template or Nothing
196
217
  self._after_template = after_template or Nothing
218
+ self._visited_resources = dict()
197
219
  self._node_template = self._model(
198
- before_template=before_template, after_template=after_template
220
+ before_template=self._before_template, after_template=self._after_template
199
221
  )
222
+ # TODO: need to do template preprocessing e.g. parameter resolution, conditions etc.
200
223
 
201
224
  def get_update_model(self) -> NodeTemplate:
202
225
  # TODO: rethink naming of this for outer utils
203
226
  return self._node_template
204
227
 
205
- def _visit_terminal_value( # noqa
228
+ def _visit_terminal_value(
206
229
  self, before_value: Maybe[Any], after_value: Maybe[Any]
207
230
  ) -> TerminalValue:
208
231
  if self._is_created(before=before_value, after=after_value):
@@ -213,6 +236,71 @@ class ChangeSetModel:
213
236
  return TerminalValueUnchanged(value=before_value)
214
237
  return TerminalValueModified(value=before_value, modified_value=after_value)
215
238
 
239
+ def _visit_intrinsic_function(
240
+ self, intrinsic_function: str, before_arguments: Maybe[Any], after_arguments: Maybe[Any]
241
+ ) -> NodeIntrinsicFunction:
242
+ arguments = self._visit_value(before_value=before_arguments, after_value=after_arguments)
243
+
244
+ if self._is_created(before=before_arguments, after=after_arguments):
245
+ change_type = ChangeType.CREATED
246
+ elif self._is_removed(before=before_arguments, after=after_arguments):
247
+ change_type = ChangeType.REMOVED
248
+ else:
249
+ function_name = intrinsic_function.replace("::", "_")
250
+ function_name = camel_to_snake_case(function_name)
251
+ visit_function_name = f"_resolve_intrinsic_function_{function_name}"
252
+ visit_function = getattr(self, visit_function_name)
253
+ change_type = visit_function(arguments)
254
+
255
+ return NodeIntrinsicFunction(
256
+ change_type=change_type, intrinsic_function=intrinsic_function, arguments=arguments
257
+ )
258
+
259
+ def _resolve_intrinsic_function_fn_get_att(self, arguments: ChangeSetEntity) -> ChangeType:
260
+ # TODO: add support for nested intrinsic functions.
261
+ # TODO: validate arguments structure and type.
262
+ # TODO: should this check for deletion of resources and/or properties, if so what error should be raised?
263
+
264
+ if not isinstance(arguments, NodeArray) or not arguments.array:
265
+ raise RuntimeError()
266
+ logical_name_of_resource_entity = arguments.array[0]
267
+ if not isinstance(logical_name_of_resource_entity, TerminalValue):
268
+ raise RuntimeError()
269
+ logical_name_of_resource: str = logical_name_of_resource_entity.value
270
+ if not isinstance(logical_name_of_resource, str):
271
+ raise RuntimeError()
272
+ node_resource: NodeResource = self._retrieve_or_visit_resource(
273
+ resource_name=logical_name_of_resource
274
+ )
275
+
276
+ node_property_attribute_name = arguments.array[1]
277
+ if not isinstance(node_property_attribute_name, TerminalValue):
278
+ raise RuntimeError()
279
+ if isinstance(node_property_attribute_name, TerminalValueModified):
280
+ attribute_name = node_property_attribute_name.modified_value
281
+ else:
282
+ attribute_name = node_property_attribute_name.value
283
+
284
+ # TODO: this is another use case for which properties should be referenced by name
285
+ for node_property in node_resource.properties.properties:
286
+ if node_property.name == attribute_name:
287
+ return node_property.change_type
288
+
289
+ return ChangeType.UNCHANGED
290
+
291
+ def _retrieve_or_visit_resource(self, resource_name: str) -> NodeResource:
292
+ before_resources, after_resources = self._sample_from(
293
+ ResourcesKey, self._before_template, self._after_template
294
+ )
295
+ before_resource, after_resource = self._sample_from(
296
+ resource_name, before_resources, after_resources
297
+ )
298
+ return self._visit_resource(
299
+ resource_name=resource_name,
300
+ before_resource=before_resource,
301
+ after_resource=after_resource,
302
+ )
303
+
216
304
  def _visit_array(self, before_array: Maybe[list], after_array: Maybe[list]) -> NodeArray:
217
305
  change_type = ChangeType.UNCHANGED
218
306
  array: list[ChangeSetEntity] = list()
@@ -228,9 +316,15 @@ class ChangeSetModel:
228
316
  binding_names = self._keys_of(before_object, after_object)
229
317
  bindings: dict[str, ChangeSetEntity] = dict()
230
318
  for binding_name in binding_names:
231
- # TODO: check the binding names for intrinsic functions and redirect.
232
319
  before_value, after_value = self._sample_from(binding_name, before_object, after_object)
233
- value = self._visit_value(before_value=before_value, after_value=after_value)
320
+ if self._is_intrinsic_function_name(function_name=binding_name):
321
+ value = self._visit_intrinsic_function(
322
+ intrinsic_function=binding_name,
323
+ before_arguments=before_value,
324
+ after_arguments=after_value,
325
+ )
326
+ else:
327
+ value = self._visit_value(before_value=before_value, after_value=after_value)
234
328
  bindings[binding_name] = value
235
329
  if value.change_type != ChangeType.UNCHANGED:
236
330
  change_type = ChangeType.MODIFIED
@@ -305,6 +399,10 @@ class ChangeSetModel:
305
399
  def _visit_resource(
306
400
  self, resource_name: str, before_resource: Maybe[dict], after_resource: Maybe[dict]
307
401
  ) -> NodeResource:
402
+ node_resource = self._visited_resources.get(resource_name)
403
+ if node_resource is not None:
404
+ return node_resource
405
+
308
406
  if self._is_created(before=before_resource, after=after_resource):
309
407
  change_type = ChangeType.CREATED
310
408
  elif self._is_removed(before=before_resource, after=after_resource):
@@ -312,6 +410,9 @@ class ChangeSetModel:
312
410
  else:
313
411
  change_type = ChangeType.UNCHANGED
314
412
 
413
+ # TODO: investigate behaviour with type changes, for now this is filler code.
414
+ type_str = self._sample_from(TypeKey, before_resource)
415
+
315
416
  before_properties, after_properties = self._sample_from(
316
417
  PropertiesKey, before_resource, after_resource
317
418
  )
@@ -322,13 +423,14 @@ class ChangeSetModel:
322
423
  if change_type == ChangeType.UNCHANGED and properties.change_type != ChangeType.UNCHANGED:
323
424
  change_type = ChangeType.MODIFIED
324
425
 
325
- return NodeResource(
426
+ node_resource = NodeResource(
326
427
  change_type=change_type,
327
428
  name=resource_name,
328
- # TODO: investigate behaviour with type changes, for now this is filler code.
329
- type_=TerminalValueUnchanged(value="<Type>"),
429
+ type_=TerminalValueUnchanged(value=type_str),
330
430
  properties=properties,
331
431
  )
432
+ self._visited_resources[resource_name] = node_resource
433
+ return node_resource
332
434
 
333
435
  def _visit_resources(
334
436
  self, before_resources: Maybe[dict], after_resources: Maybe[dict]
@@ -363,6 +465,12 @@ class ChangeSetModel:
363
465
  # TODO: what is a change type for templates?
364
466
  return NodeTemplate(change_type=resources.change_type, resources=resources)
365
467
 
468
+ @staticmethod
469
+ def _is_intrinsic_function_name(function_name: str) -> bool:
470
+ # TODO: expand vocabulary.
471
+ # TODO: are intrinsic functions soft keywords?
472
+ return function_name in INTRINSIC_FUNCTIONS
473
+
366
474
  @staticmethod
367
475
  def _sample_from(key: str, *objects: Maybe[dict]) -> Maybe[Any]:
368
476
  results = list()
@@ -1,17 +1,22 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import abc
4
- from typing import Any, Optional
4
+ from typing import Any, Final, Optional
5
5
 
6
6
  from localstack.aws.api.cloudformation import ChangeAction, ResourceChange
7
7
  from localstack.services.cloudformation.engine.v2.change_set_model import (
8
8
  ChangeSetEntity,
9
9
  ChangeType,
10
10
  NodeArray,
11
+ NodeIntrinsicFunction,
11
12
  NodeObject,
12
13
  NodeProperties,
14
+ NodeProperty,
13
15
  NodeResource,
14
16
  NodeResources,
17
+ NodeTemplate,
18
+ PropertiesKey,
19
+ TerminalValue,
15
20
  TerminalValueCreated,
16
21
  TerminalValueModified,
17
22
  TerminalValueRemoved,
@@ -21,6 +26,8 @@ from localstack.services.cloudformation.engine.v2.change_set_model_visitor impor
21
26
  ChangeSetModelVisitor,
22
27
  )
23
28
 
29
+ CHANGESET_KNOWN_AFTER_APPLY: Final[str] = "{{changeSet:KNOWN_AFTER_APPLY}}"
30
+
24
31
 
25
32
  class DescribeUnit(abc.ABC):
26
33
  before_context: Optional[Any] = None
@@ -32,10 +39,17 @@ class DescribeUnit(abc.ABC):
32
39
 
33
40
 
34
41
  class ChangeSetModelDescriber(ChangeSetModelVisitor):
35
- resource_changes: list[ResourceChange] = list()
42
+ _node_template: Final[NodeTemplate]
43
+ _resource_changes: Final[list[ResourceChange]]
44
+
45
+ def __init__(self, node_template: NodeTemplate):
46
+ self._node_template = node_template
47
+ self._resource_changes = list()
48
+ self.visit(self._node_template)
36
49
 
37
- def __init__(self):
38
- self.resource_changes = list()
50
+ def get_resource_changes(self) -> list[ResourceChange]:
51
+ # TODO return 'list[Change]' instead.
52
+ return [{"ResourceChange": change, "Type": "Resource"} for change in self._resource_changes]
39
53
 
40
54
  def visit(self, change_set_entity: ChangeSetEntity) -> DescribeUnit:
41
55
  # Overridden for the return type-hints.
@@ -62,9 +76,19 @@ class ChangeSetModelDescriber(ChangeSetModelVisitor):
62
76
  def visit_terminal_value_unchanged(
63
77
  self, terminal_value_unchanged: TerminalValueUnchanged
64
78
  ) -> DescribeUnit:
65
- return DescribeUnit(before_context=terminal_value_unchanged.value)
79
+ return DescribeUnit(
80
+ before_context=terminal_value_unchanged.value,
81
+ after_context=terminal_value_unchanged.value,
82
+ )
66
83
 
67
84
  def visit_node_object(self, node_object: NodeObject) -> DescribeUnit:
85
+ # TODO: improve check syntax
86
+ if len(node_object.bindings) == 1:
87
+ binding_values = list(node_object.bindings.values())
88
+ unique_value = binding_values[0]
89
+ if isinstance(unique_value, NodeIntrinsicFunction):
90
+ return self.visit(unique_value)
91
+
68
92
  before_context = dict()
69
93
  after_context = dict()
70
94
  for name, change_set_entity in node_object.bindings.items():
@@ -77,6 +101,58 @@ class ChangeSetModelDescriber(ChangeSetModelVisitor):
77
101
  after_context[name] = describe_unit.after_context
78
102
  case ChangeType.REMOVED:
79
103
  before_context[name] = describe_unit.before_context
104
+ case ChangeType.UNCHANGED:
105
+ before_context[name] = describe_unit.before_context
106
+ after_context[name] = describe_unit.before_context
107
+ return DescribeUnit(before_context=before_context, after_context=after_context)
108
+
109
+ @staticmethod
110
+ def _get_node_resource_for(resource_name: str, node_template: NodeTemplate) -> NodeResource:
111
+ # TODO: this could be improved with hashmap lookups if the Node contained bindings and not lists.
112
+ for node_resource in node_template.resources.resources:
113
+ if node_resource.name == resource_name:
114
+ return node_resource
115
+ # TODO
116
+ raise RuntimeError()
117
+
118
+ @staticmethod
119
+ def _get_node_property_for(property_name: str, node_resource: NodeResource) -> NodeProperty:
120
+ # TODO: this could be improved with hashmap lookups if the Node contained bindings and not lists.
121
+ for node_property in node_resource.properties.properties:
122
+ if node_property.name == property_name:
123
+ return node_property
124
+ # TODO
125
+ raise RuntimeError()
126
+
127
+ def visit_node_intrinsic_function_fn_get_att(
128
+ self, node_intrinsic_function: NodeIntrinsicFunction
129
+ ) -> DescribeUnit:
130
+ arguments_unit = self.visit(node_intrinsic_function.arguments)
131
+ # TODO: validate the return value according to the spec.
132
+ before_argument_list = arguments_unit.before_context
133
+ before_logical_name_of_resource = before_argument_list[0]
134
+ before_attribute_name = before_argument_list[1]
135
+ before_node_resource = self._get_node_resource_for(
136
+ resource_name=before_logical_name_of_resource, node_template=self._node_template
137
+ )
138
+ node_property: TerminalValue = self._get_node_property_for(
139
+ property_name=before_attribute_name, node_resource=before_node_resource
140
+ )
141
+
142
+ before_context = node_property.value.value
143
+ if node_property.change_type != ChangeType.UNCHANGED:
144
+ after_context = CHANGESET_KNOWN_AFTER_APPLY
145
+ else:
146
+ after_context = node_property.value.value
147
+
148
+ match node_intrinsic_function.change_type:
149
+ case ChangeType.MODIFIED:
150
+ return DescribeUnit(before_context=before_context, after_context=after_context)
151
+ case ChangeType.CREATED:
152
+ return DescribeUnit(after_context=after_context)
153
+ case ChangeType.REMOVED:
154
+ return DescribeUnit(before_context=before_context)
155
+ # Unchanged
80
156
  return DescribeUnit(before_context=before_context, after_context=after_context)
81
157
 
82
158
  def visit_node_array(self, node_array: NodeArray) -> DescribeUnit:
@@ -101,8 +177,6 @@ class ChangeSetModelDescriber(ChangeSetModelVisitor):
101
177
  before_context: dict[str, Any] = dict()
102
178
  after_context: dict[str, Any] = dict()
103
179
  for node_property in node_properties.properties:
104
- if node_property.change_type == ChangeType.UNCHANGED:
105
- continue
106
180
  describe_unit = self.visit(node_property.value)
107
181
  property_name = node_property.name
108
182
  match node_property.change_type:
@@ -113,9 +187,13 @@ class ChangeSetModelDescriber(ChangeSetModelVisitor):
113
187
  after_context[property_name] = describe_unit.after_context
114
188
  case ChangeType.REMOVED:
115
189
  before_context[property_name] = describe_unit.before_context
190
+ case ChangeType.UNCHANGED:
191
+ if node_properties.change_type != ChangeType.UNCHANGED:
192
+ before_context[property_name] = describe_unit.before_context
193
+ after_context[property_name] = describe_unit.before_context
116
194
  # TODO: this object can probably be well-typed instead of a free dict(?)
117
- before_context = {"Properties": before_context}
118
- after_context = {"Properties": after_context}
195
+ before_context = {PropertiesKey: before_context}
196
+ after_context = {PropertiesKey: after_context}
119
197
  return DescribeUnit(before_context=before_context, after_context=after_context)
120
198
 
121
199
  def visit_node_resource(self, node_resource: NodeResource) -> DescribeUnit:
@@ -141,7 +219,7 @@ class ChangeSetModelDescriber(ChangeSetModelVisitor):
141
219
  resource_change["Action"] = ChangeAction.Remove
142
220
  resource_change["BeforeContext"] = properties_describe_unit.before_context
143
221
 
144
- self.resource_changes.append(resource_change)
222
+ self._resource_changes.append(resource_change)
145
223
 
146
224
  # TODO
147
225
  return None
@@ -3,6 +3,7 @@ import abc
3
3
  from localstack.services.cloudformation.engine.v2.change_set_model import (
4
4
  ChangeSetEntity,
5
5
  NodeArray,
6
+ NodeIntrinsicFunction,
6
7
  NodeObject,
7
8
  NodeProperties,
8
9
  NodeProperty,
@@ -51,6 +52,20 @@ class ChangeSetModelVisitor(abc.ABC):
51
52
  def visit_node_property(self, node_property: NodeProperty):
52
53
  self.visit_children(node_property)
53
54
 
55
+ def visit_node_intrinsic_function(self, node_intrinsic_function: NodeIntrinsicFunction):
56
+ # TODO: speed up this lookup logic
57
+ function_name = node_intrinsic_function.intrinsic_function
58
+ function_name = function_name.replace("::", "_")
59
+ function_name = camel_to_snake_case(function_name)
60
+ visit_function_name = f"visit_node_intrinsic_function_{function_name}"
61
+ visit_function = getattr(self, visit_function_name)
62
+ return visit_function(node_intrinsic_function)
63
+
64
+ def visit_node_intrinsic_function_fn_get_att(
65
+ self, node_intrinsic_function: NodeIntrinsicFunction
66
+ ):
67
+ self.visit_children(node_intrinsic_function)
68
+
54
69
  def visit_node_object(self, node_object: NodeObject):
55
70
  self.visit_children(node_object)
56
71
 
@@ -513,9 +513,6 @@ class ResourceProviderExecutor:
513
513
 
514
514
  match change_type:
515
515
  case "Add":
516
- # replicate previous event emitting behaviour
517
- usage.resource_type.record(request.resource_type)
518
-
519
516
  return resource_provider.create(request)
520
517
  case "Dynamic" | "Modify":
521
518
  try:
@@ -586,6 +583,7 @@ class ResourceProviderExecutor:
586
583
  # 2. try to load community resource provider
587
584
  try:
588
585
  plugin = plugin_manager.load(resource_type)
586
+ usage.resources.labels(resource_type=resource_type, missing=False).increment()
589
587
  return plugin.factory()
590
588
  except ValueError:
591
589
  # could not find a plugin for that name
@@ -604,7 +602,7 @@ class ResourceProviderExecutor:
604
602
  f'No resource provider found for "{resource_type}"',
605
603
  )
606
604
 
607
- usage.missing_resource_types.record(resource_type)
605
+ usage.resources.labels(resource_type=resource_type, missing=True).increment()
608
606
 
609
607
  if config.CFN_IGNORE_UNSUPPORTED_RESOURCE_TYPES:
610
608
  # TODO: figure out a better way to handle non-implemented here?
@@ -1,4 +1,7 @@
1
- from localstack.utils.analytics.usage import UsageSetCounter
1
+ from localstack.utils.analytics.metrics import Counter
2
2
 
3
- resource_type = UsageSetCounter("cloudformation:resourcetype")
4
- missing_resource_types = UsageSetCounter("cloudformation:missingresourcetypes")
3
+ COUNTER_NAMESPACE = "cloudformation"
4
+
5
+ resources = Counter(
6
+ namespace=COUNTER_NAMESPACE, name="resources", labels=["resource_type", "missing"]
7
+ )
@@ -1,5 +1,281 @@
1
- from localstack.services.cloudformation.provider import CloudformationProvider
1
+ from copy import deepcopy
2
+
3
+ from localstack.aws.api import RequestContext, handler
4
+ from localstack.aws.api.cloudformation import (
5
+ ChangeSetNameOrId,
6
+ ChangeSetNotFoundException,
7
+ ChangeSetType,
8
+ CreateChangeSetInput,
9
+ CreateChangeSetOutput,
10
+ DescribeChangeSetOutput,
11
+ IncludePropertyValues,
12
+ NextToken,
13
+ Parameter,
14
+ StackNameOrId,
15
+ StackStatus,
16
+ )
17
+ from localstack.services.cloudformation import api_utils
18
+ from localstack.services.cloudformation.engine import parameters as param_resolver
19
+ from localstack.services.cloudformation.engine import template_deployer, template_preparer
20
+ from localstack.services.cloudformation.engine.entities import Stack, StackChangeSet
21
+ from localstack.services.cloudformation.engine.parameters import mask_no_echo, strip_parameter_type
22
+ from localstack.services.cloudformation.engine.resource_ordering import (
23
+ NoResourceInStack,
24
+ order_resources,
25
+ )
26
+ from localstack.services.cloudformation.engine.template_utils import resolve_stack_conditions
27
+ from localstack.services.cloudformation.engine.v2.change_set_model_describer import (
28
+ ChangeSetModelDescriber,
29
+ )
30
+ from localstack.services.cloudformation.engine.validations import ValidationError
31
+ from localstack.services.cloudformation.provider import (
32
+ ARN_CHANGESET_REGEX,
33
+ ARN_STACK_REGEX,
34
+ CloudformationProvider,
35
+ clone_stack_params,
36
+ )
37
+ from localstack.services.cloudformation.stores import (
38
+ find_change_set,
39
+ find_stack,
40
+ get_cloudformation_store,
41
+ )
42
+ from localstack.utils.collections import remove_attributes
2
43
 
3
44
 
4
45
  class CloudformationProviderV2(CloudformationProvider):
5
- pass
46
+ @handler("CreateChangeSet", expand=False)
47
+ def create_change_set(
48
+ self, context: RequestContext, request: CreateChangeSetInput
49
+ ) -> CreateChangeSetOutput:
50
+ state = get_cloudformation_store(context.account_id, context.region)
51
+
52
+ req_params = request
53
+ change_set_type = req_params.get("ChangeSetType", "UPDATE")
54
+ stack_name = req_params.get("StackName")
55
+ change_set_name = req_params.get("ChangeSetName")
56
+ template_body = req_params.get("TemplateBody")
57
+ # s3 or secretsmanager url
58
+ template_url = req_params.get("TemplateURL")
59
+
60
+ # validate and resolve template
61
+ if template_body and template_url:
62
+ raise ValidationError(
63
+ "Specify exactly one of 'TemplateBody' or 'TemplateUrl'"
64
+ ) # TODO: check proper message
65
+
66
+ if not template_body and not template_url:
67
+ raise ValidationError(
68
+ "Specify exactly one of 'TemplateBody' or 'TemplateUrl'"
69
+ ) # TODO: check proper message
70
+
71
+ api_utils.prepare_template_body(
72
+ req_params
73
+ ) # TODO: function has too many unclear responsibilities
74
+ if not template_body:
75
+ template_body = req_params[
76
+ "TemplateBody"
77
+ ] # should then have been set by prepare_template_body
78
+ template = template_preparer.parse_template(req_params["TemplateBody"])
79
+
80
+ del req_params["TemplateBody"] # TODO: stop mutating req_params
81
+ template["StackName"] = stack_name
82
+ # TODO: validate with AWS what this is actually doing?
83
+ template["ChangeSetName"] = change_set_name
84
+
85
+ # this is intentionally not in a util yet. Let's first see how the different operations deal with these before generalizing
86
+ # handle ARN stack_name here (not valid for initial CREATE, since stack doesn't exist yet)
87
+ if ARN_STACK_REGEX.match(stack_name):
88
+ if not (stack := state.stacks.get(stack_name)):
89
+ raise ValidationError(f"Stack '{stack_name}' does not exist.")
90
+ else:
91
+ # stack name specified, so fetch the stack by name
92
+ stack_candidates: list[Stack] = [
93
+ s for stack_arn, s in state.stacks.items() if s.stack_name == stack_name
94
+ ]
95
+ active_stack_candidates = [
96
+ s for s in stack_candidates if self._stack_status_is_active(s.status)
97
+ ]
98
+
99
+ # on a CREATE an empty Stack should be generated if we didn't find an active one
100
+ if not active_stack_candidates and change_set_type == ChangeSetType.CREATE:
101
+ empty_stack_template = dict(template)
102
+ empty_stack_template["Resources"] = {}
103
+ req_params_copy = clone_stack_params(req_params)
104
+ stack = Stack(
105
+ context.account_id,
106
+ context.region,
107
+ req_params_copy,
108
+ empty_stack_template,
109
+ template_body=template_body,
110
+ )
111
+ state.stacks[stack.stack_id] = stack
112
+ stack.set_stack_status("REVIEW_IN_PROGRESS")
113
+ else:
114
+ if not active_stack_candidates:
115
+ raise ValidationError(f"Stack '{stack_name}' does not exist.")
116
+ stack = active_stack_candidates[0]
117
+
118
+ # TODO: test if rollback status is allowed as well
119
+ if (
120
+ change_set_type == ChangeSetType.CREATE
121
+ and stack.status != StackStatus.REVIEW_IN_PROGRESS
122
+ ):
123
+ raise ValidationError(
124
+ f"Stack [{stack_name}] already exists and cannot be created again with the changeSet [{change_set_name}]."
125
+ )
126
+
127
+ old_parameters: dict[str, Parameter] = {}
128
+ match change_set_type:
129
+ case ChangeSetType.UPDATE:
130
+ # add changeset to existing stack
131
+ old_parameters = {
132
+ k: mask_no_echo(strip_parameter_type(v))
133
+ for k, v in stack.resolved_parameters.items()
134
+ }
135
+ case ChangeSetType.IMPORT:
136
+ raise NotImplementedError() # TODO: implement importing resources
137
+ case ChangeSetType.CREATE:
138
+ pass
139
+ case _:
140
+ msg = (
141
+ f"1 validation error detected: Value '{change_set_type}' at 'changeSetType' failed to satisfy "
142
+ f"constraint: Member must satisfy enum value set: [IMPORT, UPDATE, CREATE] "
143
+ )
144
+ raise ValidationError(msg)
145
+
146
+ # resolve parameters
147
+ new_parameters: dict[str, Parameter] = param_resolver.convert_stack_parameters_to_dict(
148
+ request.get("Parameters")
149
+ )
150
+ parameter_declarations = param_resolver.extract_stack_parameter_declarations(template)
151
+ resolved_parameters = param_resolver.resolve_parameters(
152
+ account_id=context.account_id,
153
+ region_name=context.region,
154
+ parameter_declarations=parameter_declarations,
155
+ new_parameters=new_parameters,
156
+ old_parameters=old_parameters,
157
+ )
158
+
159
+ # TODO: remove this when fixing Stack.resources and transformation order
160
+ # currently we need to create a stack with existing resources + parameters so that resolve refs recursively in here will work.
161
+ # The correct way to do it would be at a later stage anyway just like a normal intrinsic function
162
+ req_params_copy = clone_stack_params(req_params)
163
+ temp_stack = Stack(context.account_id, context.region, req_params_copy, template)
164
+ temp_stack.set_resolved_parameters(resolved_parameters)
165
+
166
+ # TODO: everything below should be async
167
+ # apply template transformations
168
+ transformed_template = template_preparer.transform_template(
169
+ context.account_id,
170
+ context.region,
171
+ template,
172
+ stack_name=temp_stack.stack_name,
173
+ resources=temp_stack.resources,
174
+ mappings=temp_stack.mappings,
175
+ conditions={}, # TODO: we don't have any resolved conditions yet at this point but we need the conditions because of the samtranslator...
176
+ resolved_parameters=resolved_parameters,
177
+ )
178
+
179
+ # create change set for the stack and apply changes
180
+ change_set = StackChangeSet(
181
+ context.account_id, context.region, stack, req_params, transformed_template
182
+ )
183
+ # only set parameters for the changeset, then switch to stack on execute_change_set
184
+ change_set.template_body = template_body
185
+ change_set.populate_update_graph(stack.template, transformed_template)
186
+
187
+ # TODO: evaluate conditions
188
+ raw_conditions = transformed_template.get("Conditions", {})
189
+ resolved_stack_conditions = resolve_stack_conditions(
190
+ account_id=context.account_id,
191
+ region_name=context.region,
192
+ conditions=raw_conditions,
193
+ parameters=resolved_parameters,
194
+ mappings=temp_stack.mappings,
195
+ stack_name=stack_name,
196
+ )
197
+ change_set.set_resolved_stack_conditions(resolved_stack_conditions)
198
+
199
+ # a bit gross but use the template ordering to validate missing resources
200
+ try:
201
+ order_resources(
202
+ transformed_template["Resources"],
203
+ resolved_parameters=resolved_parameters,
204
+ resolved_conditions=resolved_stack_conditions,
205
+ )
206
+ except NoResourceInStack as e:
207
+ raise ValidationError(str(e)) from e
208
+
209
+ deployer = template_deployer.TemplateDeployer(
210
+ context.account_id, context.region, change_set
211
+ )
212
+ changes = deployer.construct_changes(
213
+ stack,
214
+ change_set,
215
+ change_set_id=change_set.change_set_id,
216
+ append_to_changeset=True,
217
+ filter_unchanged_resources=True,
218
+ )
219
+ stack.change_sets.append(change_set)
220
+ if not changes:
221
+ change_set.metadata["Status"] = "FAILED"
222
+ change_set.metadata["ExecutionStatus"] = "UNAVAILABLE"
223
+ change_set.metadata["StatusReason"] = (
224
+ "The submitted information didn't contain changes. Submit different information to create a change set."
225
+ )
226
+ else:
227
+ change_set.metadata["Status"] = (
228
+ "CREATE_COMPLETE" # technically for some time this should first be CREATE_PENDING
229
+ )
230
+ change_set.metadata["ExecutionStatus"] = (
231
+ "AVAILABLE" # technically for some time this should first be UNAVAILABLE
232
+ )
233
+
234
+ return CreateChangeSetOutput(StackId=change_set.stack_id, Id=change_set.change_set_id)
235
+
236
+ @handler("DescribeChangeSet")
237
+ def describe_change_set(
238
+ self,
239
+ context: RequestContext,
240
+ change_set_name: ChangeSetNameOrId,
241
+ stack_name: StackNameOrId = None,
242
+ next_token: NextToken = None,
243
+ include_property_values: IncludePropertyValues = None,
244
+ **kwargs,
245
+ ) -> DescribeChangeSetOutput:
246
+ # TODO add support for include_property_values
247
+ # only relevant if change_set_name isn't an ARN
248
+ if not ARN_CHANGESET_REGEX.match(change_set_name):
249
+ if not stack_name:
250
+ raise ValidationError(
251
+ "StackName must be specified if ChangeSetName is not specified as an ARN."
252
+ )
253
+
254
+ stack = find_stack(context.account_id, context.region, stack_name)
255
+ if not stack:
256
+ raise ValidationError(f"Stack [{stack_name}] does not exist")
257
+
258
+ change_set = find_change_set(
259
+ context.account_id, context.region, change_set_name, stack_name=stack_name
260
+ )
261
+ if not change_set:
262
+ raise ChangeSetNotFoundException(f"ChangeSet [{change_set_name}] does not exist")
263
+
264
+ change_set_describer = ChangeSetModelDescriber(node_template=change_set.update_graph)
265
+ resource_changes = change_set_describer.get_resource_changes()
266
+
267
+ attrs = [
268
+ "ChangeSetType",
269
+ "StackStatus",
270
+ "LastUpdatedTime",
271
+ "DisableRollback",
272
+ "EnableTerminationProtection",
273
+ "Transform",
274
+ ]
275
+ result = remove_attributes(deepcopy(change_set.metadata), attrs)
276
+ # TODO: replace this patch with a better solution
277
+ result["Parameters"] = [
278
+ mask_no_echo(strip_parameter_type(p)) for p in result.get("Parameters", [])
279
+ ]
280
+ result["Changes"] = resource_changes
281
+ return result
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.2.1.dev61'
21
- __version_tuple__ = version_tuple = (4, 2, 1, 'dev61')
20
+ __version__ = version = '4.2.1.dev63'
21
+ __version_tuple__ = version_tuple = (4, 2, 1, 'dev63')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: localstack-core
3
- Version: 4.2.1.dev61
3
+ Version: 4.2.1.dev63
4
4
  Summary: The core library and runtime of LocalStack
5
5
  Author-email: LocalStack Contributors <info@localstack.cloud>
6
6
  Project-URL: Homepage, https://localstack.cloud
@@ -3,7 +3,7 @@ localstack/constants.py,sha256=bBh6djh4x37MrS8az8LizX_APMZ56XdtJHCnZdOnmeg,6867
3
3
  localstack/deprecations.py,sha256=t3zeaZaHhKYM8snP1wRZhpvAy6MbB12Vqv5hK78bwJ0,15162
4
4
  localstack/openapi.yaml,sha256=B803NmpwsxG8PHpHrdZYBrUYjnrRh7B_JX0XuNynuFs,30237
5
5
  localstack/plugins.py,sha256=BIJC9dlo0WbP7lLKkCiGtd_2q5oeqiHZohvoRTcejXM,2457
6
- localstack/version.py,sha256=XZVlEk5RW4Ts4KCY4_qThpnAfW2Butlc4QrO-cAm634,526
6
+ localstack/version.py,sha256=OvQU2jycL-2BGfbOutBAd4YSCtkWPPgfunCosv0v7gE,526
7
7
  localstack/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  localstack/aws/accounts.py,sha256=102zpGowOxo0S6UGMpfjw14QW7WCLVAGsnFK5xFMLoo,3043
9
9
  localstack/aws/app.py,sha256=n9bJCfJRuMz_gLGAH430c3bIQXgUXeWO5NPfcdL2MV8,5145
@@ -286,13 +286,13 @@ localstack/services/cloudformation/deployment_utils.py,sha256=86NQNVZ7fwFHPrtV_H
286
286
  localstack/services/cloudformation/plugins.py,sha256=8E1i9U65RnjZJoXz214ceV8OXcnpHNU44unK3raXkWs,336
287
287
  localstack/services/cloudformation/provider.py,sha256=uMLNL5fUvX9IMkcnku_oH4BSOoaMBu6_o3-jNqEiVvQ,52245
288
288
  localstack/services/cloudformation/provider_utils.py,sha256=37GrPaTuLEqOT57J1AVETQl6pav0bC7ItiRzyyZgstc,8994
289
- localstack/services/cloudformation/resource_provider.py,sha256=WKx90_MAazmTNgm-vjKDgLskHajd2yBoSr4YziObvGc,23659
289
+ localstack/services/cloudformation/resource_provider.py,sha256=VusFTdZZj3wH2f5hqn_p15yCJZCeZFuB1DBk33F_Scs,23648
290
290
  localstack/services/cloudformation/service_models.py,sha256=uo2sr2PIazsdE0-PfdoaaG9BEbKpjPP8ChCIJfX0pm8,5186
291
291
  localstack/services/cloudformation/stores.py,sha256=sGcmn_iwWtVDtVxvN2ICx8pRPsUrUoRQ1nfNUTDL8Xw,4674
292
- localstack/services/cloudformation/usage.py,sha256=GVfCg0raMF5_0iNqqBOI_jG343DN4OPz6aA2_2YBmMU,205
292
+ localstack/services/cloudformation/usage.py,sha256=bkCnwHnyR0H92RZRulZEWlUV-WV0yfBhCn4m5DsApdM,204
293
293
  localstack/services/cloudformation/engine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
294
294
  localstack/services/cloudformation/engine/changes.py,sha256=xeRkoHuf9hdqgWzIwfpjExAyjh622hmjX8ehNh3rfDs,363
295
- localstack/services/cloudformation/engine/entities.py,sha256=utFgaTp_8E3H8BA14jgrpoqAx6rqQpKgdee-Kgb4Ka4,14573
295
+ localstack/services/cloudformation/engine/entities.py,sha256=ntub70mNMQLgNSU9dwHj8yKf2PIz2jK8n4zVI8oMjyI,15111
296
296
  localstack/services/cloudformation/engine/errors.py,sha256=vgFpq9SUVwJ3BLTSMOUVOy5Tq3hULllliZPDEnkop6k,105
297
297
  localstack/services/cloudformation/engine/parameters.py,sha256=AYsF-UCUUFCOveJvvqlq6EiEyl5uNpmsWgcJOTQBbN4,9308
298
298
  localstack/services/cloudformation/engine/policy_loader.py,sha256=MjnNEzPTVl9HeBNRRwMnpNQa7b9G-EabyppnkHItzk8,438
@@ -307,9 +307,9 @@ localstack/services/cloudformation/engine/types.py,sha256=YIhmTrO__obIviYvzzCovK
307
307
  localstack/services/cloudformation/engine/validations.py,sha256=brq7s8O8exA5kvnfzR9ulOtQ7i4konrWQs07-0h_ByE,2847
308
308
  localstack/services/cloudformation/engine/yaml_parser.py,sha256=LQpAVq9Syze9jXUGen9Mz8SjosBuodpV5XvsCSn9bDg,2164
309
309
  localstack/services/cloudformation/engine/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
310
- localstack/services/cloudformation/engine/v2/change_set_model.py,sha256=N_s6OUwWDa9CxEDqTNa1jFjSTMbw9HgkBFDiQqTIp3c,14893
311
- localstack/services/cloudformation/engine/v2/change_set_model_describer.py,sha256=dMDDjXdsOrVFcpWx3VM5Rk0Uj0HcT7IpQiZB7oIODyQ,6801
312
- localstack/services/cloudformation/engine/v2/change_set_model_visitor.py,sha256=Ajw6wtiNCkx9PJmuOWcRzxnsEEQgVWqbclWqI7QBGvk,2491
310
+ localstack/services/cloudformation/engine/v2/change_set_model.py,sha256=O42ZsOxR5vRgDevJIWXLmXXdyw8yoYFprgPeBDWC1TY,19768
311
+ localstack/services/cloudformation/engine/v2/change_set_model_describer.py,sha256=TyHvJI1UfbqK9ZN7Ls8KxL9SXOomuccSMbMhKyckm0o,10474
312
+ localstack/services/cloudformation/engine/v2/change_set_model_visitor.py,sha256=VWZsQC4X0NlU9PHwHLk9dsLfPiwLFjjUuzVdc9iIMXk,3204
313
313
  localstack/services/cloudformation/models/__init__.py,sha256=da1PTClDMl-IBkrSvq6JC1lnS-K_BASzCvxVhNxN5Ls,13
314
314
  localstack/services/cloudformation/resource_providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
315
315
  localstack/services/cloudformation/resource_providers/aws_cloudformation_macro.py,sha256=Grn3dP1jANRlVO9HyKQV5GHv0x1eNRBeaIYhgn-FKv4,2812
@@ -327,7 +327,7 @@ localstack/services/cloudformation/resource_providers/aws_cloudformation_waitcon
327
327
  localstack/services/cloudformation/scaffolding/__main__.py,sha256=zjedOdqvnfN99WzQ43gxtGZxLDitSnbFGA-zpWbyMQ0,30960
328
328
  localstack/services/cloudformation/scaffolding/propgen.py,sha256=9YsSCkDegcU_Yp8Sfw8eNV26N5ibOlLC6Hg6lxPeBBM,7949
329
329
  localstack/services/cloudformation/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
330
- localstack/services/cloudformation/v2/provider.py,sha256=BBRh7qSpVJwxYt_tEkH0gq5jjoc0TBH658qFmpjohQI,146
330
+ localstack/services/cloudformation/v2/provider.py,sha256=6btFiaGzzBnx-GjmGa6toS-vFr0NVRfdy0AdB40zme4,12214
331
331
  localstack/services/cloudwatch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
332
332
  localstack/services/cloudwatch/alarm_scheduler.py,sha256=XFllg0gI_WNV7cNxOcgXifzmbNA07OPpuEUuf37keP4,15663
333
333
  localstack/services/cloudwatch/cloudwatch_database_helper.py,sha256=MDQix6E53s-EfjOiwbKfMFtFqSinOsvsz7wbeLUjpyU,17327
@@ -1266,13 +1266,13 @@ localstack/utils/server/tcp_proxy.py,sha256=rR6d5jR0ozDvIlpHiqW0cfyY9a2fRGdOzyA8
1266
1266
  localstack/utils/xray/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1267
1267
  localstack/utils/xray/trace_header.py,sha256=ahXk9eonq7LpeENwlqUEPj3jDOCiVRixhntQuxNor-Q,6209
1268
1268
  localstack/utils/xray/traceid.py,sha256=SQSsMV2rhbTNK6ceIoozZYuGU7Fg687EXcgqxoDl1Fw,1106
1269
- localstack_core-4.2.1.dev61.data/scripts/localstack,sha256=WyL11vp5CkuP79iIR-L8XT7Cj8nvmxX7XRAgxhbmXNE,529
1270
- localstack_core-4.2.1.dev61.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1271
- localstack_core-4.2.1.dev61.data/scripts/localstack.bat,sha256=tlzZTXtveHkMX_s_fa7VDfvdNdS8iVpEz2ER3uk9B_c,29
1272
- localstack_core-4.2.1.dev61.dist-info/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1273
- localstack_core-4.2.1.dev61.dist-info/METADATA,sha256=JM5ZC2JSMfeRLdRPvvWoq2BW5EgB4YIVX028KFIhk2c,5481
1274
- localstack_core-4.2.1.dev61.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
1275
- localstack_core-4.2.1.dev61.dist-info/entry_points.txt,sha256=UqGFR0MPKa2sfresdqiCpqBZuWyRxCb3UG77oPVMzVA,20564
1276
- localstack_core-4.2.1.dev61.dist-info/plux.json,sha256=sx6dNRQS1f6qmAPVMW-UDpUidsbzyxSU-hl8PCD2Z6c,20786
1277
- localstack_core-4.2.1.dev61.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1278
- localstack_core-4.2.1.dev61.dist-info/RECORD,,
1269
+ localstack_core-4.2.1.dev63.data/scripts/localstack,sha256=WyL11vp5CkuP79iIR-L8XT7Cj8nvmxX7XRAgxhbmXNE,529
1270
+ localstack_core-4.2.1.dev63.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1271
+ localstack_core-4.2.1.dev63.data/scripts/localstack.bat,sha256=tlzZTXtveHkMX_s_fa7VDfvdNdS8iVpEz2ER3uk9B_c,29
1272
+ localstack_core-4.2.1.dev63.dist-info/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1273
+ localstack_core-4.2.1.dev63.dist-info/METADATA,sha256=O7r95TeQpq1uTfSBmJhED26HrL8CjwPEguJIPK4LChE,5481
1274
+ localstack_core-4.2.1.dev63.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
1275
+ localstack_core-4.2.1.dev63.dist-info/entry_points.txt,sha256=UqGFR0MPKa2sfresdqiCpqBZuWyRxCb3UG77oPVMzVA,20564
1276
+ localstack_core-4.2.1.dev63.dist-info/plux.json,sha256=X460Knpugc2g9rzOMOaey-UHOCd_I0sv-FLdzd6ZB24,20786
1277
+ localstack_core-4.2.1.dev63.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1278
+ localstack_core-4.2.1.dev63.dist-info/RECORD,,
@@ -0,0 +1 @@
1
+ {"localstack.cloudformation.resource_providers": ["AWS::Lambda::Function=localstack.services.lambda_.resource_providers.aws_lambda_function_plugin:LambdaFunctionProviderPlugin", "AWS::CloudWatch::CompositeAlarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_compositealarm_plugin:CloudWatchCompositeAlarmProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "AWS::IAM::ManagedPolicy=localstack.services.iam.resource_providers.aws_iam_managedpolicy_plugin:IAMManagedPolicyProviderPlugin", "AWS::KMS::Alias=localstack.services.kms.resource_providers.aws_kms_alias_plugin:KMSAliasProviderPlugin", "AWS::EC2::VPCGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_vpcgatewayattachment_plugin:EC2VPCGatewayAttachmentProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::ApiGateway::Method=localstack.services.apigateway.resource_providers.aws_apigateway_method_plugin:ApiGatewayMethodProviderPlugin", "AWS::EC2::RouteTable=localstack.services.ec2.resource_providers.aws_ec2_routetable_plugin:EC2RouteTableProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::EC2::TransitGateway=localstack.services.ec2.resource_providers.aws_ec2_transitgateway_plugin:EC2TransitGatewayProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::IAM::Policy=localstack.services.iam.resource_providers.aws_iam_policy_plugin:IAMPolicyProviderPlugin", "AWS::EC2::NetworkAcl=localstack.services.ec2.resource_providers.aws_ec2_networkacl_plugin:EC2NetworkAclProviderPlugin", "AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::Route53::RecordSet=localstack.services.route53.resource_providers.aws_route53_recordset_plugin:Route53RecordSetProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "AWS::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "AWS::EC2::Route=localstack.services.ec2.resource_providers.aws_ec2_route_plugin:EC2RouteProviderPlugin", "AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::Route53::HealthCheck=localstack.services.route53.resource_providers.aws_route53_healthcheck_plugin:Route53HealthCheckProviderPlugin", "AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "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::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin", "AWS::Events::EventBusPolicy=localstack.services.events.resource_providers.aws_events_eventbuspolicy_plugin:EventsEventBusPolicyProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::Events::ApiDestination=localstack.services.events.resource_providers.aws_events_apidestination_plugin:EventsApiDestinationProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin", "AWS::ApiGateway::DomainName=localstack.services.apigateway.resource_providers.aws_apigateway_domainname_plugin:ApiGatewayDomainNameProviderPlugin", "AWS::SQS::QueuePolicy=localstack.services.sqs.resource_providers.aws_sqs_queuepolicy_plugin:SQSQueuePolicyProviderPlugin", "AWS::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "AWS::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::Kinesis::StreamConsumer=localstack.services.kinesis.resource_providers.aws_kinesis_streamconsumer_plugin:KinesisStreamConsumerProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::IAM::Role=localstack.services.iam.resource_providers.aws_iam_role_plugin:IAMRoleProviderPlugin", "AWS::Lambda::Version=localstack.services.lambda_.resource_providers.aws_lambda_version_plugin:LambdaVersionProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::EC2::VPC=localstack.services.ec2.resource_providers.aws_ec2_vpc_plugin:EC2VPCProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin", "AWS::EC2::PrefixList=localstack.services.ec2.resource_providers.aws_ec2_prefixlist_plugin:EC2PrefixListProviderPlugin", "AWS::IAM::InstanceProfile=localstack.services.iam.resource_providers.aws_iam_instanceprofile_plugin:IAMInstanceProfileProviderPlugin", "AWS::DynamoDB::GlobalTable=localstack.services.dynamodb.resource_providers.aws_dynamodb_globaltable_plugin:DynamoDBGlobalTableProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::DynamoDB::Table=localstack.services.dynamodb.resource_providers.aws_dynamodb_table_plugin:DynamoDBTableProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::Lambda::Alias=localstack.services.lambda_.resource_providers.lambda_alias_plugin:LambdaAliasProviderPlugin", "AWS::SNS::TopicPolicy=localstack.services.sns.resource_providers.aws_sns_topicpolicy_plugin:SNSTopicPolicyProviderPlugin", "AWS::Lambda::EventInvokeConfig=localstack.services.lambda_.resource_providers.aws_lambda_eventinvokeconfig_plugin:LambdaEventInvokeConfigProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::Lambda::LayerVersionPermission=localstack.services.lambda_.resource_providers.aws_lambda_layerversionpermission_plugin:LambdaLayerVersionPermissionProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "AWS::EC2::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::ApiGateway::ApiKey=localstack.services.apigateway.resource_providers.aws_apigateway_apikey_plugin:ApiGatewayApiKeyProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::SNS::Topic=localstack.services.sns.resource_providers.aws_sns_topic_plugin:SNSTopicProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "AWS::KMS::Key=localstack.services.kms.resource_providers.aws_kms_key_plugin:KMSKeyProviderPlugin", "AWS::ApiGateway::Deployment=localstack.services.apigateway.resource_providers.aws_apigateway_deployment_plugin:ApiGatewayDeploymentProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "AWS::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::ApiGateway::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "AWS::Lambda::EventSourceMapping=localstack.services.lambda_.resource_providers.aws_lambda_eventsourcemapping_plugin:LambdaEventSourceMappingProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::ApiGateway::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "AWS::EC2::Subnet=localstack.services.ec2.resource_providers.aws_ec2_subnet_plugin:EC2SubnetProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::Lambda::Permission=localstack.services.lambda_.resource_providers.aws_lambda_permission_plugin:LambdaPermissionProviderPlugin", "AWS::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::Events::EventBus=localstack.services.events.resource_providers.aws_events_eventbus_plugin:EventsEventBusProviderPlugin", "AWS::CertificateManager::Certificate=localstack.services.certificatemanager.resource_providers.aws_certificatemanager_certificate_plugin:CertificateManagerCertificateProviderPlugin", "AWS::SNS::Subscription=localstack.services.sns.resource_providers.aws_sns_subscription_plugin:SNSSubscriptionProviderPlugin", "AWS::SecretsManager::SecretTargetAttachment=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment_plugin:SecretsManagerSecretTargetAttachmentProviderPlugin", "AWS::OpenSearchService::Domain=localstack.services.opensearch.resource_providers.aws_opensearchservice_domain_plugin:OpenSearchServiceDomainProviderPlugin"], "localstack.runtime.components": ["aws=localstack.aws.components:AwsComponents"], "localstack.packages": ["dynamodb-local/community=localstack.services.dynamodb.plugins:dynamodb_local_package", "lambda-java-libs/community=localstack.services.lambda_.plugins:lambda_java_libs", "lambda-runtime/community=localstack.services.lambda_.plugins:lambda_runtime_package", "elasticsearch/community=localstack.services.es.plugins:elasticsearch_package", "jpype-jsonata/community=localstack.services.stepfunctions.plugins:jpype_jsonata_package", "kinesis-mock/community=localstack.services.kinesis.plugins:kinesismock_package", "vosk/community=localstack.services.transcribe.plugins:vosk_package", "ffmpeg/community=localstack.packages.plugins:ffmpeg_package", "java/community=localstack.packages.plugins:java_package", "terraform/community=localstack.packages.plugins:terraform_package", "opensearch/community=localstack.services.opensearch.plugins:opensearch_package"], "localstack.runtime.server": ["hypercorn=localstack.runtime.server.plugins:HypercornRuntimeServerPlugin", "twisted=localstack.runtime.server.plugins:TwistedRuntimeServerPlugin"], "localstack.hooks.on_infra_shutdown": ["aggregate_and_send=localstack.utils.analytics.usage:aggregate_and_send", "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", "_run_init_scripts_on_shutdown=localstack.runtime.init:_run_init_scripts_on_shutdown", "publish_metrics=localstack.utils.analytics.metrics:publish_metrics", "stop_server=localstack.dns.plugins:stop_server"], "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.hooks.on_infra_start": ["_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_custom_endpoints=localstack.services.lambda_.plugins:register_custom_endpoints", "validate_configuration=localstack.services.lambda_.plugins:validate_configuration", "_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", "register_cloudformation_deploy_ui=localstack.services.cloudformation.plugins:register_cloudformation_deploy_ui", "_run_init_scripts_on_start=localstack.runtime.init:_run_init_scripts_on_start", "apply_aws_runtime_patches=localstack.aws.patches:apply_aws_runtime_patches", "register_swagger_endpoints=localstack.http.resources.swagger.plugins:register_swagger_endpoints", "setup_dns_configuration_on_host=localstack.dns.plugins:setup_dns_configuration_on_host", "start_dns_server=localstack.dns.plugins:start_dns_server", "conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger"], "localstack.lambda.runtime_executor": ["docker=localstack.services.lambda_.invocation.plugins:DockerRuntimeExecutorPlugin"], "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.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.packages": ["kinesis-mock/community=localstack.services.kinesis.plugins:kinesismock_package", "opensearch/community=localstack.services.opensearch.plugins:opensearch_package", "lambda-java-libs/community=localstack.services.lambda_.plugins:lambda_java_libs", "lambda-runtime/community=localstack.services.lambda_.plugins:lambda_runtime_package", "jpype-jsonata/community=localstack.services.stepfunctions.plugins:jpype_jsonata_package", "dynamodb-local/community=localstack.services.dynamodb.plugins:dynamodb_local_package", "vosk/community=localstack.services.transcribe.plugins:vosk_package", "elasticsearch/community=localstack.services.es.plugins:elasticsearch_package", "ffmpeg/community=localstack.packages.plugins:ffmpeg_package", "java/community=localstack.packages.plugins:java_package", "terraform/community=localstack.packages.plugins:terraform_package"], "localstack.cloudformation.resource_providers": ["AWS::Route53::RecordSet=localstack.services.route53.resource_providers.aws_route53_recordset_plugin:Route53RecordSetProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::OpenSearchService::Domain=localstack.services.opensearch.resource_providers.aws_opensearchservice_domain_plugin:OpenSearchServiceDomainProviderPlugin", "AWS::IAM::ServerCertificate=localstack.services.iam.resource_providers.aws_iam_servercertificate_plugin:IAMServerCertificateProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::EC2::Subnet=localstack.services.ec2.resource_providers.aws_ec2_subnet_plugin:EC2SubnetProviderPlugin", "AWS::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin", "AWS::EC2::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::CertificateManager::Certificate=localstack.services.certificatemanager.resource_providers.aws_certificatemanager_certificate_plugin:CertificateManagerCertificateProviderPlugin", "AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "AWS::IAM::Policy=localstack.services.iam.resource_providers.aws_iam_policy_plugin:IAMPolicyProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "AWS::EC2::PrefixList=localstack.services.ec2.resource_providers.aws_ec2_prefixlist_plugin:EC2PrefixListProviderPlugin", "AWS::CloudWatch::CompositeAlarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_compositealarm_plugin:CloudWatchCompositeAlarmProviderPlugin", "AWS::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::ApiGateway::DomainName=localstack.services.apigateway.resource_providers.aws_apigateway_domainname_plugin:ApiGatewayDomainNameProviderPlugin", "AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "AWS::ApiGateway::RestApi=localstack.services.apigateway.resource_providers.aws_apigateway_restapi_plugin:ApiGatewayRestApiProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::SQS::QueuePolicy=localstack.services.sqs.resource_providers.aws_sqs_queuepolicy_plugin:SQSQueuePolicyProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::EC2::RouteTable=localstack.services.ec2.resource_providers.aws_ec2_routetable_plugin:EC2RouteTableProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::IAM::InstanceProfile=localstack.services.iam.resource_providers.aws_iam_instanceprofile_plugin:IAMInstanceProfileProviderPlugin", "AWS::IAM::ManagedPolicy=localstack.services.iam.resource_providers.aws_iam_managedpolicy_plugin:IAMManagedPolicyProviderPlugin", "AWS::ApiGateway::Method=localstack.services.apigateway.resource_providers.aws_apigateway_method_plugin:ApiGatewayMethodProviderPlugin", "AWS::DynamoDB::GlobalTable=localstack.services.dynamodb.resource_providers.aws_dynamodb_globaltable_plugin:DynamoDBGlobalTableProviderPlugin", "AWS::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::Events::EventBus=localstack.services.events.resource_providers.aws_events_eventbus_plugin:EventsEventBusProviderPlugin", "AWS::ApiGateway::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "AWS::EC2::VPCGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_vpcgatewayattachment_plugin:EC2VPCGatewayAttachmentProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::Lambda::Version=localstack.services.lambda_.resource_providers.aws_lambda_version_plugin:LambdaVersionProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::Lambda::LayerVersionPermission=localstack.services.lambda_.resource_providers.aws_lambda_layerversionpermission_plugin:LambdaLayerVersionPermissionProviderPlugin", "AWS::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::EC2::NetworkAcl=localstack.services.ec2.resource_providers.aws_ec2_networkacl_plugin:EC2NetworkAclProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "AWS::ApiGateway::Deployment=localstack.services.apigateway.resource_providers.aws_apigateway_deployment_plugin:ApiGatewayDeploymentProviderPlugin", "AWS::SNS::Subscription=localstack.services.sns.resource_providers.aws_sns_subscription_plugin:SNSSubscriptionProviderPlugin", "AWS::Events::ApiDestination=localstack.services.events.resource_providers.aws_events_apidestination_plugin:EventsApiDestinationProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::ApiGateway::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "AWS::EC2::VPC=localstack.services.ec2.resource_providers.aws_ec2_vpc_plugin:EC2VPCProviderPlugin", "AWS::Events::EventBusPolicy=localstack.services.events.resource_providers.aws_events_eventbuspolicy_plugin:EventsEventBusPolicyProviderPlugin", "AWS::Lambda::EventInvokeConfig=localstack.services.lambda_.resource_providers.aws_lambda_eventinvokeconfig_plugin:LambdaEventInvokeConfigProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "AWS::Lambda::Alias=localstack.services.lambda_.resource_providers.lambda_alias_plugin:LambdaAliasProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::ApiGateway::ApiKey=localstack.services.apigateway.resource_providers.aws_apigateway_apikey_plugin:ApiGatewayApiKeyProviderPlugin", "AWS::DynamoDB::Table=localstack.services.dynamodb.resource_providers.aws_dynamodb_table_plugin:DynamoDBTableProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::Lambda::Function=localstack.services.lambda_.resource_providers.aws_lambda_function_plugin:LambdaFunctionProviderPlugin", "AWS::KMS::Alias=localstack.services.kms.resource_providers.aws_kms_alias_plugin:KMSAliasProviderPlugin", "AWS::KMS::Key=localstack.services.kms.resource_providers.aws_kms_key_plugin:KMSKeyProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::SNS::TopicPolicy=localstack.services.sns.resource_providers.aws_sns_topicpolicy_plugin:SNSTopicPolicyProviderPlugin", "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::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin", "AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::SecretsManager::SecretTargetAttachment=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment_plugin:SecretsManagerSecretTargetAttachmentProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::Route53::HealthCheck=localstack.services.route53.resource_providers.aws_route53_healthcheck_plugin:Route53HealthCheckProviderPlugin", "AWS::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::SNS::Topic=localstack.services.sns.resource_providers.aws_sns_topic_plugin:SNSTopicProviderPlugin", "AWS::Lambda::Permission=localstack.services.lambda_.resource_providers.aws_lambda_permission_plugin:LambdaPermissionProviderPlugin", "AWS::IAM::Role=localstack.services.iam.resource_providers.aws_iam_role_plugin:IAMRoleProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::Kinesis::StreamConsumer=localstack.services.kinesis.resource_providers.aws_kinesis_streamconsumer_plugin:KinesisStreamConsumerProviderPlugin", "AWS::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin", "AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::EC2::TransitGateway=localstack.services.ec2.resource_providers.aws_ec2_transitgateway_plugin:EC2TransitGatewayProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin"], "localstack.hooks.on_infra_start": ["register_cloudformation_deploy_ui=localstack.services.cloudformation.plugins:register_cloudformation_deploy_ui", "register_custom_endpoints=localstack.services.lambda_.plugins:register_custom_endpoints", "validate_configuration=localstack.services.lambda_.plugins:validate_configuration", "_publish_config_as_analytics_event=localstack.runtime.analytics:_publish_config_as_analytics_event", "_publish_container_info=localstack.runtime.analytics:_publish_container_info", "register_swagger_endpoints=localstack.http.resources.swagger.plugins:register_swagger_endpoints", "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", "setup_dns_configuration_on_host=localstack.dns.plugins:setup_dns_configuration_on_host", "start_dns_server=localstack.dns.plugins:start_dns_server", "_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", "apply_aws_runtime_patches=localstack.aws.patches:apply_aws_runtime_patches", "apply_runtime_patches=localstack.runtime.patches:apply_runtime_patches", "conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger"], "localstack.hooks.on_infra_shutdown": ["aggregate_and_send=localstack.utils.analytics.usage:aggregate_and_send", "remove_custom_endpoints=localstack.services.lambda_.plugins:remove_custom_endpoints", "_run_init_scripts_on_shutdown=localstack.runtime.init:_run_init_scripts_on_shutdown", "stop_server=localstack.dns.plugins:stop_server", "publish_metrics=localstack.utils.analytics.metrics: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.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.server": ["hypercorn=localstack.runtime.server.plugins:HypercornRuntimeServerPlugin", "twisted=localstack.runtime.server.plugins:TwistedRuntimeServerPlugin"], "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.lambda.runtime_executor": ["docker=localstack.services.lambda_.invocation.plugins:DockerRuntimeExecutorPlugin"], "localstack.runtime.components": ["aws=localstack.aws.components:AwsComponents"]}