localstack-core 4.7.1.dev16__py3-none-any.whl → 4.7.1.dev18__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/v2/change_set_model.py +32 -0
  2. localstack/services/cloudformation/engine/v2/change_set_model_describer.py +21 -8
  3. localstack/services/cloudformation/engine/v2/change_set_model_executor.py +140 -74
  4. localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +5 -0
  5. localstack/services/cloudformation/resource_provider.py +11 -8
  6. localstack/services/kms/utils.py +1 -1
  7. localstack/testing/pytest/cloudformation/fixtures.py +42 -12
  8. localstack/version.py +3 -16
  9. {localstack_core-4.7.1.dev16.dist-info → localstack_core-4.7.1.dev18.dist-info}/METADATA +1 -1
  10. {localstack_core-4.7.1.dev16.dist-info → localstack_core-4.7.1.dev18.dist-info}/RECORD +18 -18
  11. localstack_core-4.7.1.dev18.dist-info/plux.json +1 -0
  12. localstack_core-4.7.1.dev16.dist-info/plux.json +0 -1
  13. {localstack_core-4.7.1.dev16.data → localstack_core-4.7.1.dev18.data}/scripts/localstack +0 -0
  14. {localstack_core-4.7.1.dev16.data → localstack_core-4.7.1.dev18.data}/scripts/localstack-supervisor +0 -0
  15. {localstack_core-4.7.1.dev16.data → localstack_core-4.7.1.dev18.data}/scripts/localstack.bat +0 -0
  16. {localstack_core-4.7.1.dev16.dist-info → localstack_core-4.7.1.dev18.dist-info}/WHEEL +0 -0
  17. {localstack_core-4.7.1.dev16.dist-info → localstack_core-4.7.1.dev18.dist-info}/entry_points.txt +0 -0
  18. {localstack_core-4.7.1.dev16.dist-info → localstack_core-4.7.1.dev18.dist-info}/licenses/LICENSE.txt +0 -0
  19. {localstack_core-4.7.1.dev16.dist-info → localstack_core-4.7.1.dev18.dist-info}/top_level.txt +0 -0
@@ -8,6 +8,7 @@ from typing import Any, Final, Generator, Optional, TypedDict, Union, cast
8
8
  from typing_extensions import TypeVar
9
9
 
10
10
  from localstack.aws.api.cloudformation import ChangeAction
11
+ from localstack.services.cloudformation.resource_provider import ResourceProviderExecutor
11
12
  from localstack.utils.strings import camel_to_snake_case
12
13
 
13
14
  T = TypeVar("T")
@@ -350,6 +351,7 @@ class NodeResource(ChangeSetNode):
350
351
  properties: Final[NodeProperties]
351
352
  condition_reference: Final[Maybe[TerminalValue]]
352
353
  depends_on: Final[Maybe[NodeDependsOn]]
354
+ requires_replacement: Final[bool]
353
355
 
354
356
  def __init__(
355
357
  self,
@@ -360,6 +362,7 @@ class NodeResource(ChangeSetNode):
360
362
  properties: NodeProperties,
361
363
  condition_reference: Maybe[TerminalValue],
362
364
  depends_on: Maybe[NodeDependsOn],
365
+ requires_replacement: bool,
363
366
  ):
364
367
  super().__init__(scope=scope, change_type=change_type)
365
368
  self.name = name
@@ -367,6 +370,7 @@ class NodeResource(ChangeSetNode):
367
370
  self.properties = properties
368
371
  self.condition_reference = condition_reference
369
372
  self.depends_on = depends_on
373
+ self.requires_replacement = requires_replacement
370
374
 
371
375
 
372
376
  class NodeProperties(ChangeSetNode):
@@ -722,6 +726,30 @@ class ChangeSetModel:
722
726
  change_type = parent_change_type_of([node_condition, *arguments[1:]])
723
727
  return change_type
724
728
 
729
+ def _resolve_requires_replacement(
730
+ self, node_properties: NodeProperties, resource_type: TerminalValue
731
+ ) -> bool:
732
+ # a bit hacky but we have to load the resource provider executor _and_ resource provider to get the schema
733
+ # Note: we don't log the attempt to load the resource provider, we need to make sure this is only done once and we already do this in the executor
734
+ resource_provider = ResourceProviderExecutor.try_load_resource_provider(resource_type.value)
735
+ if not resource_provider:
736
+ # if we don't support a resource, assume an in-place update for simplicity
737
+ return False
738
+
739
+ create_only_properties: list[str] = resource_provider.SCHEMA.get("createOnlyProperties", [])
740
+ # TODO: also hacky: strip the leading `/properties/` string from the definition
741
+ # ideally we should use a jsonpath or similar
742
+ create_only_properties = [
743
+ property.replace("/properties/", "", 1) for property in create_only_properties
744
+ ]
745
+ for node_property in node_properties.properties:
746
+ if (
747
+ node_property.change_type == ChangeType.MODIFIED
748
+ and node_property.name in create_only_properties
749
+ ):
750
+ return True
751
+ return False
752
+
725
753
  def _visit_array(
726
754
  self, scope: Scope, before_array: Maybe[list], after_array: Maybe[list]
727
755
  ) -> NodeArray:
@@ -917,6 +945,9 @@ class ChangeSetModel:
917
945
  change_type = change_type_of(
918
946
  before_resource, after_resource, [properties, condition_reference, depends_on]
919
947
  )
948
+ requires_replacement = self._resolve_requires_replacement(
949
+ node_properties=properties, resource_type=terminal_value_type
950
+ )
920
951
  node_resource = NodeResource(
921
952
  scope=scope,
922
953
  change_type=change_type,
@@ -925,6 +956,7 @@ class ChangeSetModel:
925
956
  properties=properties,
926
957
  condition_reference=condition_reference,
927
958
  depends_on=depends_on,
959
+ requires_replacement=requires_replacement,
928
960
  )
929
961
  self._visited_scopes[scope] = node_resource
930
962
  return node_resource
@@ -4,6 +4,7 @@ import json
4
4
  from typing import Final, Optional
5
5
 
6
6
  import localstack.aws.api.cloudformation as cfn_api
7
+ from localstack.aws.api.cloudformation import Replacement
7
8
  from localstack.services.cloudformation.engine.v2.change_set_model import (
8
9
  NodeIntrinsicFunction,
9
10
  NodeProperty,
@@ -118,6 +119,8 @@ class ChangeSetModelDescriber(ChangeSetModelPreproc):
118
119
  physical_id: Optional[str],
119
120
  before_properties: Optional[PreprocProperties],
120
121
  after_properties: Optional[PreprocProperties],
122
+ # TODO: remove default
123
+ requires_replacement: bool = False,
121
124
  ) -> None:
122
125
  action = cfn_api.ChangeAction.Modify
123
126
  if before_properties is None:
@@ -131,14 +134,23 @@ class ChangeSetModelDescriber(ChangeSetModelPreproc):
131
134
  resource_change["ResourceType"] = type_
132
135
  if physical_id:
133
136
  resource_change["PhysicalResourceId"] = physical_id
134
- if self._include_property_values and before_properties is not None:
135
- before_context_properties = {PropertiesKey: before_properties.properties}
136
- before_context_properties_json_str = json.dumps(before_context_properties)
137
- resource_change["BeforeContext"] = before_context_properties_json_str
138
- if self._include_property_values and after_properties is not None:
139
- after_context_properties = {PropertiesKey: after_properties.properties}
140
- after_context_properties_json_str = json.dumps(after_context_properties)
141
- resource_change["AfterContext"] = after_context_properties_json_str
137
+ if self._include_property_values:
138
+ if before_properties is not None:
139
+ before_context_properties = {PropertiesKey: before_properties.properties}
140
+ before_context_properties_json_str = json.dumps(before_context_properties)
141
+ resource_change["BeforeContext"] = before_context_properties_json_str
142
+
143
+ if after_properties is not None:
144
+ after_context_properties = {PropertiesKey: after_properties.properties}
145
+ after_context_properties_json_str = json.dumps(after_context_properties)
146
+ resource_change["AfterContext"] = after_context_properties_json_str
147
+
148
+ if action == cfn_api.ChangeAction.Modify:
149
+ # TODO: handle "Conditional" case
150
+ resource_change["Replacement"] = (
151
+ Replacement.True_ if requires_replacement else Replacement.False_
152
+ )
153
+
142
154
  self._changes.append(
143
155
  cfn_api.Change(Type=cfn_api.ChangeType.Resource, ResourceChange=resource_change)
144
156
  )
@@ -159,6 +171,7 @@ class ChangeSetModelDescriber(ChangeSetModelPreproc):
159
171
  type_=before.resource_type,
160
172
  before_properties=before.properties,
161
173
  after_properties=after.properties,
174
+ requires_replacement=after.requires_replacement,
162
175
  )
163
176
  # Case: type migration.
164
177
  # TODO: Add test to assert that on type change the resources are replaced.
@@ -3,7 +3,7 @@ import logging
3
3
  import uuid
4
4
  from dataclasses import dataclass
5
5
  from datetime import datetime, timezone
6
- from typing import Final, Optional
6
+ from typing import Final, Optional, Protocol
7
7
 
8
8
  from localstack import config
9
9
  from localstack.aws.api.cloudformation import (
@@ -57,12 +57,17 @@ class ChangeSetModelExecutorResult:
57
57
  exports: dict
58
58
 
59
59
 
60
+ class DeferredAction(Protocol):
61
+ def __call__(self) -> None: ...
62
+
63
+
60
64
  class ChangeSetModelExecutor(ChangeSetModelPreproc):
61
65
  # TODO: add typing for resolved resources and parameters.
62
66
  resources: Final[dict[str, ResolvedResource]]
63
67
  outputs: Final[dict]
64
68
  resolved_parameters: Final[dict]
65
69
  exports: Final[dict]
70
+ _deferred_actions: list[DeferredAction]
66
71
 
67
72
  def __init__(self, change_set: ChangeSet):
68
73
  super().__init__(change_set=change_set)
@@ -70,10 +75,25 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
70
75
  self.outputs = dict()
71
76
  self.resolved_parameters = dict()
72
77
  self.exports = dict()
78
+ self._deferred_actions = list()
79
+ self.resource_provider_executor = ResourceProviderExecutor(
80
+ stack_name=change_set.stack.stack_name,
81
+ stack_id=change_set.stack.stack_id,
82
+ )
73
83
 
74
- # TODO: use a structured type for the return value
75
84
  def execute(self) -> ChangeSetModelExecutorResult:
85
+ # constructive process
76
86
  self.process()
87
+
88
+ if self._deferred_actions:
89
+ self._change_set.stack.set_stack_status(StackStatus.UPDATE_COMPLETE_CLEANUP_IN_PROGRESS)
90
+
91
+ # perform all deferred actions such as deletions. These must happen in reverse from their
92
+ # defined order so that resource dependencies are honoured
93
+ # TODO: errors will stop all rollbacks; get parity on this behaviour
94
+ for action in self._deferred_actions[::-1]:
95
+ action()
96
+
77
97
  return ChangeSetModelExecutorResult(
78
98
  resources=self.resources,
79
99
  parameters=self.resolved_parameters,
@@ -81,6 +101,9 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
81
101
  exports=self.exports,
82
102
  )
83
103
 
104
+ def _defer_action(self, action: DeferredAction):
105
+ self._deferred_actions.append(action)
106
+
84
107
  def visit_node_parameter(self, node_parameter: NodeParameter) -> PreprocEntityDelta:
85
108
  delta = super().visit_node_parameter(node_parameter)
86
109
 
@@ -253,20 +276,55 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
253
276
  before_properties = self._merge_before_properties(name, before)
254
277
 
255
278
  self._process_event(ChangeAction.Modify, name, OperationStatus.IN_PROGRESS)
256
- event = self._execute_resource_action(
257
- action=ChangeAction.Modify,
258
- logical_resource_id=name,
259
- resource_type=before.resource_type,
260
- before_properties=before_properties,
261
- after_properties=after.properties,
262
- )
263
- self._process_event(
264
- ChangeAction.Modify,
265
- name,
266
- event.status,
267
- reason=event.message,
268
- resource_type=before.resource_type,
269
- )
279
+ if after.requires_replacement:
280
+ event = self._execute_resource_action(
281
+ action=ChangeAction.Add,
282
+ logical_resource_id=name,
283
+ resource_type=before.resource_type,
284
+ before_properties=None,
285
+ after_properties=after.properties,
286
+ )
287
+ self._process_event(
288
+ ChangeAction.Modify,
289
+ name,
290
+ event.status,
291
+ reason=event.message,
292
+ resource_type=before.resource_type,
293
+ )
294
+
295
+ def cleanup():
296
+ self._process_event(ChangeAction.Remove, name, OperationStatus.IN_PROGRESS)
297
+ event = self._execute_resource_action(
298
+ action=ChangeAction.Remove,
299
+ logical_resource_id=name,
300
+ resource_type=before.resource_type,
301
+ before_properties=before_properties,
302
+ after_properties=None,
303
+ )
304
+ self._process_event(
305
+ ChangeAction.Remove,
306
+ name,
307
+ event.status,
308
+ reason=event.message,
309
+ resource_type=before.resource_type,
310
+ )
311
+
312
+ self._defer_action(cleanup)
313
+ else:
314
+ event = self._execute_resource_action(
315
+ action=ChangeAction.Modify,
316
+ logical_resource_id=name,
317
+ resource_type=before.resource_type,
318
+ before_properties=before_properties,
319
+ after_properties=after.properties,
320
+ )
321
+ self._process_event(
322
+ ChangeAction.Modify,
323
+ name,
324
+ event.status,
325
+ reason=event.message,
326
+ resource_type=before.resource_type,
327
+ )
270
328
  # Case: type migration.
271
329
  # TODO: Add test to assert that on type change the resources are replaced.
272
330
  else:
@@ -274,21 +332,24 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
274
332
  before_properties = self._merge_before_properties(name, before)
275
333
  # Register a Removed for the previous type.
276
334
 
277
- event = self._execute_resource_action(
278
- action=ChangeAction.Remove,
279
- logical_resource_id=name,
280
- resource_type=before.resource_type,
281
- before_properties=before_properties,
282
- after_properties=None,
283
- )
284
- # Register a Create for the next type.
285
- self._process_event(
286
- ChangeAction.Modify,
287
- name,
288
- event.status,
289
- reason=event.message,
290
- resource_type=before.resource_type,
291
- )
335
+ def perform_deletion():
336
+ event = self._execute_resource_action(
337
+ action=ChangeAction.Remove,
338
+ logical_resource_id=name,
339
+ resource_type=before.resource_type,
340
+ before_properties=before_properties,
341
+ after_properties=None,
342
+ )
343
+ self._process_event(
344
+ ChangeAction.Modify,
345
+ name,
346
+ event.status,
347
+ reason=event.message,
348
+ resource_type=before.resource_type,
349
+ )
350
+
351
+ self._defer_action(perform_deletion)
352
+
292
353
  event = self._execute_resource_action(
293
354
  action=ChangeAction.Add,
294
355
  logical_resource_id=name,
@@ -308,26 +369,30 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
308
369
  # XXX hacky, stick the previous resources' properties into the payload
309
370
  # XXX hacky, stick the previous resources' properties into the payload
310
371
  before_properties = self._merge_before_properties(name, before)
311
- self._process_event(
312
- ChangeAction.Remove,
313
- name,
314
- OperationStatus.IN_PROGRESS,
315
- resource_type=before.resource_type,
316
- )
317
- event = self._execute_resource_action(
318
- action=ChangeAction.Remove,
319
- logical_resource_id=name,
320
- resource_type=before.resource_type,
321
- before_properties=before_properties,
322
- after_properties=None,
323
- )
324
- self._process_event(
325
- ChangeAction.Remove,
326
- name,
327
- event.status,
328
- reason=event.message,
329
- resource_type=before.resource_type,
330
- )
372
+
373
+ def perform_deletion():
374
+ self._process_event(
375
+ ChangeAction.Remove,
376
+ name,
377
+ OperationStatus.IN_PROGRESS,
378
+ resource_type=before.resource_type,
379
+ )
380
+ event = self._execute_resource_action(
381
+ action=ChangeAction.Remove,
382
+ logical_resource_id=name,
383
+ resource_type=before.resource_type,
384
+ before_properties=before_properties,
385
+ after_properties=None,
386
+ )
387
+ self._process_event(
388
+ ChangeAction.Remove,
389
+ name,
390
+ event.status,
391
+ reason=event.message,
392
+ resource_type=before.resource_type,
393
+ )
394
+
395
+ self._defer_action(perform_deletion)
331
396
  elif not is_nothing(after):
332
397
  # Case: addition
333
398
  self._process_event(
@@ -371,9 +436,6 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
371
436
  after_properties: Optional[PreprocProperties],
372
437
  ) -> ProgressEvent:
373
438
  LOG.debug("Executing resource action: %s for resource '%s'", action, logical_resource_id)
374
- resource_provider_executor = ResourceProviderExecutor(
375
- stack_name=self._change_set.stack.stack_name, stack_id=self._change_set.stack.stack_id
376
- )
377
439
  payload = self.create_resource_provider_payload(
378
440
  action=action,
379
441
  logical_resource_id=logical_resource_id,
@@ -381,13 +443,15 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
381
443
  before_properties=before_properties,
382
444
  after_properties=after_properties,
383
445
  )
384
- resource_provider = resource_provider_executor.try_load_resource_provider(resource_type)
446
+ resource_provider = self.resource_provider_executor.try_load_resource_provider(
447
+ resource_type
448
+ )
385
449
  track_resource_operation(action, resource_type, missing=resource_provider is not None)
386
450
 
387
451
  extra_resource_properties = {}
388
452
  if resource_provider is not None:
389
453
  try:
390
- event = resource_provider_executor.deploy_loop(
454
+ event = self.resource_provider_executor.deploy_loop(
391
455
  resource_provider, extra_resource_properties, payload
392
456
  )
393
457
  except Exception as e:
@@ -438,24 +502,26 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
438
502
  # TODO: avoid the use of setdefault (debuggability/readability)
439
503
  # TODO: review the use of merge
440
504
 
441
- status_from_action = EventOperationFromAction[action.value]
442
- physical_resource_id = (
443
- extra_resource_properties["PhysicalResourceId"]
444
- if resource_provider
445
- else MOCKED_REFERENCE
446
- )
447
- resolved_resource = ResolvedResource(
448
- Properties=event.resource_model,
449
- LogicalResourceId=logical_resource_id,
450
- Type=resource_type,
451
- LastUpdatedTimestamp=datetime.now(timezone.utc),
452
- ResourceStatus=ResourceStatus(f"{status_from_action}_COMPLETE"),
453
- PhysicalResourceId=physical_resource_id,
454
- )
455
- # TODO: do we actually need this line?
456
- resolved_resource.update(extra_resource_properties)
457
-
458
- self.resources[logical_resource_id] = resolved_resource
505
+ # Don't update the resolved resources if we have deleted that resource
506
+ if action != ChangeAction.Remove:
507
+ status_from_action = EventOperationFromAction[action.value]
508
+ physical_resource_id = (
509
+ extra_resource_properties["PhysicalResourceId"]
510
+ if resource_provider
511
+ else MOCKED_REFERENCE
512
+ )
513
+ resolved_resource = ResolvedResource(
514
+ Properties=event.resource_model,
515
+ LogicalResourceId=logical_resource_id,
516
+ Type=resource_type,
517
+ LastUpdatedTimestamp=datetime.now(timezone.utc),
518
+ ResourceStatus=ResourceStatus(f"{status_from_action}_COMPLETE"),
519
+ PhysicalResourceId=physical_resource_id,
520
+ )
521
+ # TODO: do we actually need this line?
522
+ resolved_resource.update(extra_resource_properties)
523
+
524
+ self.resources[logical_resource_id] = resolved_resource
459
525
 
460
526
  case OperationStatus.FAILED:
461
527
  reason = event.message
@@ -104,6 +104,7 @@ class PreprocResource:
104
104
  resource_type: str
105
105
  properties: PreprocProperties
106
106
  depends_on: Optional[list[str]]
107
+ requires_replacement: bool
107
108
 
108
109
  def __init__(
109
110
  self,
@@ -113,6 +114,7 @@ class PreprocResource:
113
114
  resource_type: str,
114
115
  properties: PreprocProperties,
115
116
  depends_on: Optional[list[str]],
117
+ requires_replacement: bool,
116
118
  ):
117
119
  self.logical_id = logical_id
118
120
  self.physical_resource_id = physical_resource_id
@@ -120,6 +122,7 @@ class PreprocResource:
120
122
  self.resource_type = resource_type
121
123
  self.properties = properties
122
124
  self.depends_on = depends_on
125
+ self.requires_replacement = requires_replacement
123
126
 
124
127
  @staticmethod
125
128
  def _compare_conditions(c1: bool, c2: bool):
@@ -1065,6 +1068,7 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
1065
1068
  resource_type=type_delta.before,
1066
1069
  properties=properties_delta.before,
1067
1070
  depends_on=depends_on_before,
1071
+ requires_replacement=False,
1068
1072
  )
1069
1073
  if change_type != ChangeType.REMOVED and is_nothing(condition_after) or condition_after:
1070
1074
  logical_resource_id = node_resource.name
@@ -1081,6 +1085,7 @@ class ChangeSetModelPreproc(ChangeSetModelVisitor):
1081
1085
  resource_type=type_delta.after,
1082
1086
  properties=properties_delta.after,
1083
1087
  depends_on=depends_on_after,
1088
+ requires_replacement=node_resource.requires_replacement,
1084
1089
  )
1085
1090
  return PreprocEntityDelta(before=before, after=after)
1086
1091
 
@@ -465,15 +465,18 @@ class ResourceProviderExecutor:
465
465
  "A ResourceProvider should always have a SCHEMA property defined."
466
466
  )
467
467
  resource_type_schema = resource_provider.SCHEMA
468
- physical_resource_id = self.extract_physical_resource_id_from_model_with_schema(
469
- event.resource_model,
470
- raw_payload["resourceType"],
471
- resource_type_schema,
472
- )
468
+ if raw_payload["action"] != "Remove":
469
+ physical_resource_id = (
470
+ self.extract_physical_resource_id_from_model_with_schema(
471
+ event.resource_model,
472
+ raw_payload["resourceType"],
473
+ resource_type_schema,
474
+ )
475
+ )
473
476
 
474
- resource["PhysicalResourceId"] = physical_resource_id
475
- resource["Properties"] = event.resource_model
476
- resource["_last_deployed_state"] = copy.deepcopy(event.resource_model)
477
+ resource["PhysicalResourceId"] = physical_resource_id
478
+ resource["Properties"] = event.resource_model
479
+ resource["_last_deployed_state"] = copy.deepcopy(event.resource_model)
477
480
  return event
478
481
  case OperationStatus.IN_PROGRESS:
479
482
  # update the shared state
@@ -8,7 +8,7 @@ from localstack.utils.aws.arns import ARN_PARTITION_REGEX
8
8
  T = TypeVar("T")
9
9
 
10
10
  KMS_KEY_ARN_PATTERN = re.compile(
11
- rf"{ARN_PARTITION_REGEX}:kms:(?P<region_name>[^:]+):(?P<account_id>\d{{12}}):key\/(?P<key_id>[^:]+)$"
11
+ rf"{ARN_PARTITION_REGEX}:kms:(?P<region_name>[^:]+):(?P<account_id>\d{{12}}):((?=key/)key/|(?=alias/))(?P<key_id>[^:]+)$"
12
12
  )
13
13
 
14
14
 
@@ -1,8 +1,9 @@
1
1
  import json
2
2
  from collections import defaultdict
3
- from typing import Callable, Optional, TypedDict
3
+ from typing import Callable, Generator, Optional, TypedDict
4
4
 
5
5
  import pytest
6
+ from botocore.exceptions import WaiterError
6
7
 
7
8
  from localstack.aws.api.cloudformation import DescribeChangeSetOutput, StackEvent
8
9
  from localstack.aws.connect import ServiceLevelClientFactory
@@ -32,23 +33,41 @@ def normalize_event(event: StackEvent) -> NormalizedEvent:
32
33
 
33
34
 
34
35
  @pytest.fixture
35
- def capture_per_resource_events(
36
- aws_client: ServiceLevelClientFactory,
37
- ) -> Callable[[str], PerResourceStackEvents]:
38
- def capture(stack_name: str) -> dict:
36
+ def capture_resource_state_changes(aws_client: ServiceLevelClientFactory):
37
+ def capture(stack_name: str) -> Generator[StackEvent, None, None]:
38
+ resource_states: dict[str, str] = {}
39
39
  events = aws_client.cloudformation.describe_stack_events(StackName=stack_name)[
40
40
  "StackEvents"
41
41
  ]
42
- per_resource_events = defaultdict(list)
43
42
  for event in events:
44
43
  # TODO: not supported events
45
44
  if event.get("ResourceStatus") in {
46
45
  "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS",
47
- "DELETE_IN_PROGRESS",
48
- "DELETE_COMPLETE",
49
46
  }:
50
47
  continue
51
48
 
49
+ resource = event["LogicalResourceId"]
50
+ status = event["ResourceStatus"]
51
+ if resource not in resource_states:
52
+ yield event
53
+ resource_states[resource] = status
54
+ continue
55
+
56
+ if status != resource_states[resource]:
57
+ yield event
58
+ resource_states[resource] = status
59
+
60
+ return capture
61
+
62
+
63
+ @pytest.fixture
64
+ def capture_per_resource_events(
65
+ capture_resource_state_changes,
66
+ ) -> Callable[[str], PerResourceStackEvents]:
67
+ def capture(stack_name: str) -> dict:
68
+ per_resource_events = defaultdict(list)
69
+ events = capture_resource_state_changes(stack_name)
70
+ for event in events:
52
71
  if logical_resource_id := event.get("LogicalResourceId"):
53
72
  resource_name = (
54
73
  logical_resource_id
@@ -108,7 +127,10 @@ def capture_update_process(aws_client_no_retry, cleanups, capture_per_resource_e
108
127
 
109
128
  def inner(
110
129
  snapshot, t1: dict | str, t2: dict | str, p1: dict | None = None, p2: dict | None = None
111
- ):
130
+ ) -> str:
131
+ """
132
+ :return: stack id
133
+ """
112
134
  snapshot.add_transformer(snapshot.transform.cloudformation_api())
113
135
 
114
136
  if isinstance(t1, dict):
@@ -203,9 +225,15 @@ def capture_update_process(aws_client_no_retry, cleanups, capture_per_resource_e
203
225
  snapshot.match("create-change-set-2", change_set_details)
204
226
  stack_id = change_set_details["StackId"]
205
227
  change_set_id = change_set_details["Id"]
206
- aws_client_no_retry.cloudformation.get_waiter("change_set_create_complete").wait(
207
- ChangeSetName=change_set_id
208
- )
228
+ try:
229
+ aws_client_no_retry.cloudformation.get_waiter("change_set_create_complete").wait(
230
+ ChangeSetName=change_set_id
231
+ )
232
+ except WaiterError as e:
233
+ desc = aws_client_no_retry.cloudformation.describe_change_set(
234
+ ChangeSetName=change_set_id
235
+ )
236
+ raise RuntimeError(f"Change set deployment failed: {desc}") from e
209
237
 
210
238
  describe_change_set_with_prop_values = (
211
239
  aws_client_no_retry.cloudformation.describe_change_set(
@@ -249,4 +277,6 @@ def capture_update_process(aws_client_no_retry, cleanups, capture_per_resource_e
249
277
  events = capture_per_resource_events(stack_id)
250
278
  snapshot.match("per-resource-events", events)
251
279
 
280
+ return stack_id
281
+
252
282
  yield inner
localstack/version.py CHANGED
@@ -1,14 +1,7 @@
1
1
  # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
3
 
4
- __all__ = [
5
- "__version__",
6
- "__version_tuple__",
7
- "version",
8
- "version_tuple",
9
- "__commit_id__",
10
- "commit_id",
11
- ]
4
+ __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
12
5
 
13
6
  TYPE_CHECKING = False
14
7
  if TYPE_CHECKING:
@@ -16,19 +9,13 @@ if TYPE_CHECKING:
16
9
  from typing import Union
17
10
 
18
11
  VERSION_TUPLE = Tuple[Union[int, str], ...]
19
- COMMIT_ID = Union[str, None]
20
12
  else:
21
13
  VERSION_TUPLE = object
22
- COMMIT_ID = object
23
14
 
24
15
  version: str
25
16
  __version__: str
26
17
  __version_tuple__: VERSION_TUPLE
27
18
  version_tuple: VERSION_TUPLE
28
- commit_id: COMMIT_ID
29
- __commit_id__: COMMIT_ID
30
19
 
31
- __version__ = version = '4.7.1.dev16'
32
- __version_tuple__ = version_tuple = (4, 7, 1, 'dev16')
33
-
34
- __commit_id__ = commit_id = None
20
+ __version__ = version = '4.7.1.dev18'
21
+ __version_tuple__ = version_tuple = (4, 7, 1, 'dev18')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: localstack-core
3
- Version: 4.7.1.dev16
3
+ Version: 4.7.1.dev18
4
4
  Summary: The core library and runtime of LocalStack
5
5
  Author-email: LocalStack Contributors <info@localstack.cloud>
6
6
  License-Expression: Apache-2.0
@@ -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=-T9vKhZPpzZppx3QqZERWgUZww6tNRbz8DbJQB4G6Mc,719
7
+ localstack/version.py,sha256=UdMTxE98dcCVbBsqbsHQwBA6id2qebPFK0iOT3gDu9Q,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
@@ -291,7 +291,7 @@ localstack/services/cloudformation/deployment_utils.py,sha256=86NQNVZ7fwFHPrtV_H
291
291
  localstack/services/cloudformation/plugins.py,sha256=8E1i9U65RnjZJoXz214ceV8OXcnpHNU44unK3raXkWs,336
292
292
  localstack/services/cloudformation/provider.py,sha256=U79fqNKc8X6po8Gv4fuzuhSoMq-xIhXa3Q516PBooNo,52921
293
293
  localstack/services/cloudformation/provider_utils.py,sha256=37GrPaTuLEqOT57J1AVETQl6pav0bC7ItiRzyyZgstc,8994
294
- localstack/services/cloudformation/resource_provider.py,sha256=Sv5_-odlKjKooMwgDSWyeG8_eeDR1nV3rByeW0Klo5o,22919
294
+ localstack/services/cloudformation/resource_provider.py,sha256=O4KyPd7TkTMcPFKppr2ffQqXvWzo61ZC_8M7eH_vWOQ,23081
295
295
  localstack/services/cloudformation/service_models.py,sha256=uo2sr2PIazsdE0-PfdoaaG9BEbKpjPP8ChCIJfX0pm8,5186
296
296
  localstack/services/cloudformation/stores.py,sha256=rBY3yDLW-DZB8dAjHuncZbNE1Jsj_OpOxQX7xRHgLhc,5529
297
297
  localstack/services/cloudformation/engine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -311,10 +311,10 @@ 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=SDeY8xS3VI7fZEZv35AeN4yGmji_JSM1O_hWFgJvb-Y,55635
315
- localstack/services/cloudformation/engine/v2/change_set_model_describer.py,sha256=wIk3tphi60zB6o4e1_TflftRGWmqQiTOea1o3NDwVe8,9979
316
- localstack/services/cloudformation/engine/v2/change_set_model_executor.py,sha256=woHg9R2npV4Yg_7SBPazJlIxZ1eoBB5R0WPSF_Gh2Z4,23509
317
- localstack/services/cloudformation/engine/v2/change_set_model_preproc.py,sha256=poNC0gVfyD_dS7G-giaHJ-e-GKFG5u-PJvBS9X2UFkg,49679
314
+ localstack/services/cloudformation/engine/v2/change_set_model.py,sha256=P2-nmVzLUs2NIn-R6-z7ClWHWKbxw7zq7G82P5RFAlM,57364
315
+ localstack/services/cloudformation/engine/v2/change_set_model_describer.py,sha256=ZGJIj5Q9wrwZJSAPCBKQuQA2r5EEDrDlu-tmyHHqYa0,10429
316
+ localstack/services/cloudformation/engine/v2/change_set_model_executor.py,sha256=xbqG3sa5SlFm1d36hNlv1R6OeYRyvhyInvtrIHRjVZw,26357
317
+ localstack/services/cloudformation/engine/v2/change_set_model_preproc.py,sha256=EmtBhGuXzqBey2Dlnb9bottOjY0Ga8MoYKOlvqkdG90,49920
318
318
  localstack/services/cloudformation/engine/v2/change_set_model_transform.py,sha256=qZz3TcfLnuBkp5HvpkmWxqIYJKNvlEqsQZ5WYVekBZ8,13417
319
319
  localstack/services/cloudformation/engine/v2/change_set_model_validator.py,sha256=NfS6TxbmMSXLbqba4be6wyWMgCGiQhsbqJ-9r49D_-E,2044
320
320
  localstack/services/cloudformation/engine/v2/change_set_model_visitor.py,sha256=ygUVPgM3b8SAXLLhLeGSD2k_Oo81ukFkug6bcmvRSJg,7843
@@ -531,7 +531,7 @@ localstack/services/kms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
531
531
  localstack/services/kms/exceptions.py,sha256=BgmFaOgGcBheRPQyZFFjn7_W8i6ChJXvJoSh_yV-Ti0,535
532
532
  localstack/services/kms/models.py,sha256=fGdPdrTIGl_OpsF7m_KksBQV0n7dJq_stZHZ4RpsF7M,37611
533
533
  localstack/services/kms/provider.py,sha256=v9DHCofR-9W_UHFzP6_OwCX2J20GzQbj33zVA2HIowE,68966
534
- localstack/services/kms/utils.py,sha256=olyIvRh3OL2t06vO9OG7EL4FJJdmrgrTCAIugAtVl5w,3201
534
+ localstack/services/kms/utils.py,sha256=F1hctD4HIheSJ4iLWo15GptL0Ly3B8aqtp4s9MJohbc,3221
535
535
  localstack/services/kms/resource_providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
536
536
  localstack/services/kms/resource_providers/aws_kms_alias.py,sha256=wn6BaAj-mccWTPLFDtxbf1qGzGta-xRQAE8GVRNNvOg,2630
537
537
  localstack/services/kms/resource_providers/aws_kms_alias.schema.json,sha256=i3PJRVJ7jnE1PzxitVBFz40dyk8M7O8sRzBSPL-kHsM,1795
@@ -1182,7 +1182,7 @@ localstack/testing/pytest/path_filter.py,sha256=U1V5qy23H7yZ6Tznr-MdveeH7TvCM_u4
1182
1182
  localstack/testing/pytest/util.py,sha256=TQAAb_Cj5gTSX0VkenAbSabvyCkl7THxEj70PrT_H7Y,941
1183
1183
  localstack/testing/pytest/validation_tracking.py,sha256=zGYn2r2n1xEe2Xq2JLPhS5dQJ9s29pIQEFpiF7ifehM,5630
1184
1184
  localstack/testing/pytest/cloudformation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1185
- localstack/testing/pytest/cloudformation/fixtures.py,sha256=JWfNeT-GedkJ3tAfZivMwOwoNlmATRpORb8AHl666cg,9294
1185
+ localstack/testing/pytest/cloudformation/fixtures.py,sha256=1aVRYXPfP0-hLrxo5N3Il6jx0eTcXVtvzNywDhOjgis,10318
1186
1186
  localstack/testing/pytest/stepfunctions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1187
1187
  localstack/testing/pytest/stepfunctions/fixtures.py,sha256=m9gdU7opK1LoDKuUDTJKcuUfWi4LWHw0idL0_GNlkfo,32817
1188
1188
  localstack/testing/pytest/stepfunctions/utils.py,sha256=L_Zc6-iDC76E5JsGAXltBIi_ZB3-vrCBTGcOcmfEO3g,32819
@@ -1284,13 +1284,13 @@ localstack/utils/server/tcp_proxy.py,sha256=rR6d5jR0ozDvIlpHiqW0cfyY9a2fRGdOzyA8
1284
1284
  localstack/utils/xray/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1285
1285
  localstack/utils/xray/trace_header.py,sha256=ahXk9eonq7LpeENwlqUEPj3jDOCiVRixhntQuxNor-Q,6209
1286
1286
  localstack/utils/xray/traceid.py,sha256=SQSsMV2rhbTNK6ceIoozZYuGU7Fg687EXcgqxoDl1Fw,1106
1287
- localstack_core-4.7.1.dev16.data/scripts/localstack,sha256=WyL11vp5CkuP79iIR-L8XT7Cj8nvmxX7XRAgxhbmXNE,529
1288
- localstack_core-4.7.1.dev16.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1289
- localstack_core-4.7.1.dev16.data/scripts/localstack.bat,sha256=tlzZTXtveHkMX_s_fa7VDfvdNdS8iVpEz2ER3uk9B_c,29
1290
- localstack_core-4.7.1.dev16.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1291
- localstack_core-4.7.1.dev16.dist-info/METADATA,sha256=1OWfiw-sLizAIPci7AkoD7ld9HJqeSKOjy3OgS6gUEQ,5570
1292
- localstack_core-4.7.1.dev16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1293
- localstack_core-4.7.1.dev16.dist-info/entry_points.txt,sha256=-GFtw80qM_1GQIDUcyqXojJvnqvP_8lK1Vc-M9ShaJE,20668
1294
- localstack_core-4.7.1.dev16.dist-info/plux.json,sha256=YorvdROf8_O1rd2wJgkizyuUk78c9MCGHiRRZK-QAM0,20891
1295
- localstack_core-4.7.1.dev16.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1296
- localstack_core-4.7.1.dev16.dist-info/RECORD,,
1287
+ localstack_core-4.7.1.dev18.data/scripts/localstack,sha256=WyL11vp5CkuP79iIR-L8XT7Cj8nvmxX7XRAgxhbmXNE,529
1288
+ localstack_core-4.7.1.dev18.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1289
+ localstack_core-4.7.1.dev18.data/scripts/localstack.bat,sha256=tlzZTXtveHkMX_s_fa7VDfvdNdS8iVpEz2ER3uk9B_c,29
1290
+ localstack_core-4.7.1.dev18.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1291
+ localstack_core-4.7.1.dev18.dist-info/METADATA,sha256=AaIp1c1iQ7Y-G0P265QCLHg_wF0dFoFSAcKnlnQsVvE,5570
1292
+ localstack_core-4.7.1.dev18.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1293
+ localstack_core-4.7.1.dev18.dist-info/entry_points.txt,sha256=-GFtw80qM_1GQIDUcyqXojJvnqvP_8lK1Vc-M9ShaJE,20668
1294
+ localstack_core-4.7.1.dev18.dist-info/plux.json,sha256=g3t3PsLTqvPu6YwoB680t7UFggmf5aggxAfhwexcVMw,20891
1295
+ localstack_core-4.7.1.dev18.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1296
+ localstack_core-4.7.1.dev18.dist-info/RECORD,,
@@ -0,0 +1 @@
1
+ {"localstack.cloudformation.resource_providers": ["AWS::ApiGateway::DomainName=localstack.services.apigateway.resource_providers.aws_apigateway_domainname_plugin:ApiGatewayDomainNameProviderPlugin", "AWS::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::EC2::VPC=localstack.services.ec2.resource_providers.aws_ec2_vpc_plugin:EC2VPCProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin", "AWS::Lambda::EventSourceMapping=localstack.services.lambda_.resource_providers.aws_lambda_eventsourcemapping_plugin:LambdaEventSourceMappingProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::EC2::VPCGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_vpcgatewayattachment_plugin:EC2VPCGatewayAttachmentProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::Lambda::Version=localstack.services.lambda_.resource_providers.aws_lambda_version_plugin:LambdaVersionProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::SNS::Topic=localstack.services.sns.resource_providers.aws_sns_topic_plugin:SNSTopicProviderPlugin", "AWS::OpenSearchService::Domain=localstack.services.opensearch.resource_providers.aws_opensearchservice_domain_plugin:OpenSearchServiceDomainProviderPlugin", "AWS::Lambda::Alias=localstack.services.lambda_.resource_providers.lambda_alias_plugin:LambdaAliasProviderPlugin", "AWS::KMS::Key=localstack.services.kms.resource_providers.aws_kms_key_plugin:KMSKeyProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::IAM::Role=localstack.services.iam.resource_providers.aws_iam_role_plugin:IAMRoleProviderPlugin", "AWS::Events::EventBus=localstack.services.events.resource_providers.aws_events_eventbus_plugin:EventsEventBusProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::SNS::TopicPolicy=localstack.services.sns.resource_providers.aws_sns_topicpolicy_plugin:SNSTopicPolicyProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "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::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "AWS::SecretsManager::SecretTargetAttachment=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment_plugin:SecretsManagerSecretTargetAttachmentProviderPlugin", "AWS::EC2::Subnet=localstack.services.ec2.resource_providers.aws_ec2_subnet_plugin:EC2SubnetProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::Lambda::EventInvokeConfig=localstack.services.lambda_.resource_providers.aws_lambda_eventinvokeconfig_plugin:LambdaEventInvokeConfigProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::ApiGateway::ApiKey=localstack.services.apigateway.resource_providers.aws_apigateway_apikey_plugin:ApiGatewayApiKeyProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "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::IAM::ManagedPolicy=localstack.services.iam.resource_providers.aws_iam_managedpolicy_plugin:IAMManagedPolicyProviderPlugin", "AWS::EC2::PrefixList=localstack.services.ec2.resource_providers.aws_ec2_prefixlist_plugin:EC2PrefixListProviderPlugin", "AWS::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "AWS::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::DynamoDB::GlobalTable=localstack.services.dynamodb.resource_providers.aws_dynamodb_globaltable_plugin:DynamoDBGlobalTableProviderPlugin", "AWS::Lambda::Function=localstack.services.lambda_.resource_providers.aws_lambda_function_plugin:LambdaFunctionProviderPlugin", "AWS::EC2::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "AWS::Lambda::LayerVersionPermission=localstack.services.lambda_.resource_providers.aws_lambda_layerversionpermission_plugin:LambdaLayerVersionPermissionProviderPlugin", "AWS::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::Events::EventBusPolicy=localstack.services.events.resource_providers.aws_events_eventbuspolicy_plugin:EventsEventBusPolicyProviderPlugin", "AWS::SNS::Subscription=localstack.services.sns.resource_providers.aws_sns_subscription_plugin:SNSSubscriptionProviderPlugin", "AWS::ApiGateway::Method=localstack.services.apigateway.resource_providers.aws_apigateway_method_plugin:ApiGatewayMethodProviderPlugin", "AWS::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::ApiGateway::Deployment=localstack.services.apigateway.resource_providers.aws_apigateway_deployment_plugin:ApiGatewayDeploymentProviderPlugin", "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::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::EC2::Route=localstack.services.ec2.resource_providers.aws_ec2_route_plugin:EC2RouteProviderPlugin", "AWS::KMS::Alias=localstack.services.kms.resource_providers.aws_kms_alias_plugin:KMSAliasProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "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::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "AWS::SQS::QueuePolicy=localstack.services.sqs.resource_providers.aws_sqs_queuepolicy_plugin:SQSQueuePolicyProviderPlugin", "AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::Lambda::Permission=localstack.services.lambda_.resource_providers.aws_lambda_permission_plugin:LambdaPermissionProviderPlugin", "AWS::Kinesis::StreamConsumer=localstack.services.kinesis.resource_providers.aws_kinesis_streamconsumer_plugin:KinesisStreamConsumerProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::EC2::NetworkAcl=localstack.services.ec2.resource_providers.aws_ec2_networkacl_plugin:EC2NetworkAclProviderPlugin", "AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::EC2::RouteTable=localstack.services.ec2.resource_providers.aws_ec2_routetable_plugin:EC2RouteTableProviderPlugin", "AWS::CloudWatch::CompositeAlarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_compositealarm_plugin:CloudWatchCompositeAlarmProviderPlugin", "AWS::EC2::TransitGateway=localstack.services.ec2.resource_providers.aws_ec2_transitgateway_plugin:EC2TransitGatewayProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::IAM::InstanceProfile=localstack.services.iam.resource_providers.aws_iam_instanceprofile_plugin:IAMInstanceProfileProviderPlugin", "AWS::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin"], "localstack.hooks.on_infra_start": ["_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", "conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger", "setup_dns_configuration_on_host=localstack.dns.plugins:setup_dns_configuration_on_host", "start_dns_server=localstack.dns.plugins:start_dns_server", "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", "eager_load_services=localstack.services.plugins:eager_load_services", "delete_cached_certificate=localstack.plugins:delete_cached_certificate", "deprecation_warnings=localstack.plugins:deprecation_warnings", "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", "_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"], "localstack.lambda.runtime_executor": ["docker=localstack.services.lambda_.invocation.plugins:DockerRuntimeExecutorPlugin"], "localstack.packages": ["jpype-jsonata/community=localstack.services.stepfunctions.plugins:jpype_jsonata_package", "vosk/community=localstack.services.transcribe.plugins:vosk_package", "opensearch/community=localstack.services.opensearch.plugins:opensearch_package", "elasticsearch/community=localstack.services.es.plugins:elasticsearch_package", "kinesis-mock/community=localstack.services.kinesis.plugins:kinesismock_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", "dynamodb-local/community=localstack.services.dynamodb.plugins:dynamodb_local_package"], "localstack.hooks.on_infra_shutdown": ["stop_server=localstack.dns.plugins:stop_server", "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", "remove_custom_endpoints=localstack.services.lambda_.plugins:remove_custom_endpoints", "publish_metrics=localstack.utils.analytics.metrics.publisher:publish_metrics", "_run_init_scripts_on_shutdown=localstack.runtime.init:_run_init_scripts_on_shutdown"], "localstack.runtime.server": ["hypercorn=localstack.runtime.server.plugins:HypercornRuntimeServerPlugin", "twisted=localstack.runtime.server.plugins:TwistedRuntimeServerPlugin"], "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.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.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.runtime.components": ["aws=localstack.aws.components:AwsComponents"]}
@@ -1 +0,0 @@
1
- {"localstack.cloudformation.resource_providers": ["AWS::EC2::PrefixList=localstack.services.ec2.resource_providers.aws_ec2_prefixlist_plugin:EC2PrefixListProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::Lambda::Function=localstack.services.lambda_.resource_providers.aws_lambda_function_plugin:LambdaFunctionProviderPlugin", "AWS::EC2::RouteTable=localstack.services.ec2.resource_providers.aws_ec2_routetable_plugin:EC2RouteTableProviderPlugin", "AWS::IAM::Policy=localstack.services.iam.resource_providers.aws_iam_policy_plugin:IAMPolicyProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::Lambda::LayerVersionPermission=localstack.services.lambda_.resource_providers.aws_lambda_layerversionpermission_plugin:LambdaLayerVersionPermissionProviderPlugin", "AWS::ApiGateway::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::KMS::Alias=localstack.services.kms.resource_providers.aws_kms_alias_plugin:KMSAliasProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::Lambda::EventSourceMapping=localstack.services.lambda_.resource_providers.aws_lambda_eventsourcemapping_plugin:LambdaEventSourceMappingProviderPlugin", "AWS::ApiGateway::Method=localstack.services.apigateway.resource_providers.aws_apigateway_method_plugin:ApiGatewayMethodProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::ApiGateway::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "AWS::CloudWatch::CompositeAlarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_compositealarm_plugin:CloudWatchCompositeAlarmProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::ApiGateway::RestApi=localstack.services.apigateway.resource_providers.aws_apigateway_restapi_plugin:ApiGatewayRestApiProviderPlugin", "AWS::EC2::TransitGateway=localstack.services.ec2.resource_providers.aws_ec2_transitgateway_plugin:EC2TransitGatewayProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::Kinesis::StreamConsumer=localstack.services.kinesis.resource_providers.aws_kinesis_streamconsumer_plugin:KinesisStreamConsumerProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::SQS::QueuePolicy=localstack.services.sqs.resource_providers.aws_sqs_queuepolicy_plugin:SQSQueuePolicyProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "AWS::ApiGateway::DomainName=localstack.services.apigateway.resource_providers.aws_apigateway_domainname_plugin:ApiGatewayDomainNameProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::Lambda::Alias=localstack.services.lambda_.resource_providers.lambda_alias_plugin:LambdaAliasProviderPlugin", "AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin", "AWS::KMS::Key=localstack.services.kms.resource_providers.aws_kms_key_plugin:KMSKeyProviderPlugin", "AWS::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::ApiGateway::ApiKey=localstack.services.apigateway.resource_providers.aws_apigateway_apikey_plugin:ApiGatewayApiKeyProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::Route53::RecordSet=localstack.services.route53.resource_providers.aws_route53_recordset_plugin:Route53RecordSetProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::EC2::VPC=localstack.services.ec2.resource_providers.aws_ec2_vpc_plugin:EC2VPCProviderPlugin", "AWS::EC2::VPCGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_vpcgatewayattachment_plugin:EC2VPCGatewayAttachmentProviderPlugin", "AWS::IAM::Role=localstack.services.iam.resource_providers.aws_iam_role_plugin:IAMRoleProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "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::Route53::HealthCheck=localstack.services.route53.resource_providers.aws_route53_healthcheck_plugin:Route53HealthCheckProviderPlugin", "AWS::Events::EventBusPolicy=localstack.services.events.resource_providers.aws_events_eventbuspolicy_plugin:EventsEventBusPolicyProviderPlugin", "AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::DynamoDB::GlobalTable=localstack.services.dynamodb.resource_providers.aws_dynamodb_globaltable_plugin:DynamoDBGlobalTableProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin", "AWS::IAM::ServerCertificate=localstack.services.iam.resource_providers.aws_iam_servercertificate_plugin:IAMServerCertificateProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin", "AWS::Lambda::Permission=localstack.services.lambda_.resource_providers.aws_lambda_permission_plugin:LambdaPermissionProviderPlugin", "AWS::CertificateManager::Certificate=localstack.services.certificatemanager.resource_providers.aws_certificatemanager_certificate_plugin:CertificateManagerCertificateProviderPlugin", "AWS::Events::EventBus=localstack.services.events.resource_providers.aws_events_eventbus_plugin:EventsEventBusProviderPlugin", "AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::OpenSearchService::Domain=localstack.services.opensearch.resource_providers.aws_opensearchservice_domain_plugin:OpenSearchServiceDomainProviderPlugin", "AWS::EC2::Route=localstack.services.ec2.resource_providers.aws_ec2_route_plugin:EC2RouteProviderPlugin", "AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "AWS::Lambda::Version=localstack.services.lambda_.resource_providers.aws_lambda_version_plugin:LambdaVersionProviderPlugin", "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::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::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::DynamoDB::Table=localstack.services.dynamodb.resource_providers.aws_dynamodb_table_plugin:DynamoDBTableProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::EC2::Subnet=localstack.services.ec2.resource_providers.aws_ec2_subnet_plugin:EC2SubnetProviderPlugin", "AWS::SNS::Topic=localstack.services.sns.resource_providers.aws_sns_topic_plugin:SNSTopicProviderPlugin", "AWS::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::EC2::NetworkAcl=localstack.services.ec2.resource_providers.aws_ec2_networkacl_plugin:EC2NetworkAclProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::ApiGateway::Deployment=localstack.services.apigateway.resource_providers.aws_apigateway_deployment_plugin:ApiGatewayDeploymentProviderPlugin", "AWS::EC2::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "AWS::SecretsManager::SecretTargetAttachment=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment_plugin:SecretsManagerSecretTargetAttachmentProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin"], "localstack.openapi.spec": ["localstack=localstack.plugins:CoreOASPlugin"], "localstack.hooks.on_infra_start": ["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", "register_custom_endpoints=localstack.services.lambda_.plugins:register_custom_endpoints", "validate_configuration=localstack.services.lambda_.plugins:validate_configuration", "init_response_mutation_handler=localstack.aws.handlers.response:init_response_mutation_handler", "register_cloudformation_deploy_ui=localstack.services.cloudformation.plugins:register_cloudformation_deploy_ui", "_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", "eager_load_services=localstack.services.plugins:eager_load_services", "apply_aws_runtime_patches=localstack.aws.patches:apply_aws_runtime_patches", "register_swagger_endpoints=localstack.http.resources.swagger.plugins:register_swagger_endpoints", "conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger", "_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"], "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.on_infra_shutdown": ["_run_init_scripts_on_shutdown=localstack.runtime.init:_run_init_scripts_on_shutdown", "publish_metrics=localstack.utils.analytics.metrics.publisher:publish_metrics", "stop_server=localstack.dns.plugins:stop_server", "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", "remove_custom_endpoints=localstack.services.lambda_.plugins:remove_custom_endpoints"], "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.packages": ["dynamodb-local/community=localstack.services.dynamodb.plugins:dynamodb_local_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", "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", "lambda-java-libs/community=localstack.services.lambda_.plugins:lambda_java_libs", "lambda-runtime/community=localstack.services.lambda_.plugins:lambda_runtime_package", "vosk/community=localstack.services.transcribe.plugins:vosk_package"], "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.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.components": ["aws=localstack.aws.components:AwsComponents"]}