localstack-core 4.8.2.dev11__py3-none-any.whl → 4.8.2.dev13__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.

Potentially problematic release.


This version of localstack-core might be problematic. Click here for more details.

Files changed (30) hide show
  1. localstack/aws/api/cloudwatch/__init__.py +1 -1
  2. localstack/aws/api/core.py +4 -0
  3. localstack/aws/client.py +7 -2
  4. localstack/aws/forwarder.py +52 -5
  5. localstack/aws/handlers/analytics.py +1 -1
  6. localstack/aws/handlers/service.py +10 -5
  7. localstack/aws/protocol/parser.py +10 -8
  8. localstack/aws/protocol/serializer.py +5 -4
  9. localstack/aws/protocol/service_router.py +120 -20
  10. localstack/aws/skeleton.py +4 -2
  11. localstack/aws/spec-patches.json +38 -0
  12. localstack/aws/spec.py +32 -12
  13. localstack/services/apigateway/legacy/provider.py +1 -0
  14. localstack/services/apigateway/next_gen/execute_api/integrations/aws.py +3 -0
  15. localstack/services/cloudwatch/provider_v2.py +1 -1
  16. localstack/services/moto.py +1 -0
  17. localstack/services/sqs/query_api.py +1 -1
  18. localstack/utils/time.py +10 -1
  19. localstack/version.py +2 -2
  20. {localstack_core-4.8.2.dev11.dist-info → localstack_core-4.8.2.dev13.dist-info}/METADATA +1 -1
  21. {localstack_core-4.8.2.dev11.dist-info → localstack_core-4.8.2.dev13.dist-info}/RECORD +29 -29
  22. localstack_core-4.8.2.dev13.dist-info/plux.json +1 -0
  23. localstack_core-4.8.2.dev11.dist-info/plux.json +0 -1
  24. {localstack_core-4.8.2.dev11.data → localstack_core-4.8.2.dev13.data}/scripts/localstack +0 -0
  25. {localstack_core-4.8.2.dev11.data → localstack_core-4.8.2.dev13.data}/scripts/localstack-supervisor +0 -0
  26. {localstack_core-4.8.2.dev11.data → localstack_core-4.8.2.dev13.data}/scripts/localstack.bat +0 -0
  27. {localstack_core-4.8.2.dev11.dist-info → localstack_core-4.8.2.dev13.dist-info}/WHEEL +0 -0
  28. {localstack_core-4.8.2.dev11.dist-info → localstack_core-4.8.2.dev13.dist-info}/entry_points.txt +0 -0
  29. {localstack_core-4.8.2.dev11.dist-info → localstack_core-4.8.2.dev13.dist-info}/licenses/LICENSE.txt +0 -0
  30. {localstack_core-4.8.2.dev11.dist-info → localstack_core-4.8.2.dev13.dist-info}/top_level.txt +0 -0
@@ -218,7 +218,7 @@ class ConcurrentModificationException(ServiceException):
218
218
  class ConflictException(ServiceException):
219
219
  code: str = "ConflictException"
220
220
  sender_fault: bool = False
221
- status_code: int = 400
221
+ status_code: int = 409
222
222
 
223
223
 
224
224
  class DashboardValidationMessage(TypedDict, total=False):
@@ -13,6 +13,7 @@ from botocore.model import OperationModel, ServiceModel
13
13
  from rolo.gateway import RequestContext as RoloRequestContext
14
14
 
15
15
  from localstack.aws.connect import InternalRequestParameters
16
+ from localstack.aws.spec import ProtocolName
16
17
  from localstack.http import Request, Response
17
18
  from localstack.utils.strings import long_uid
18
19
 
@@ -88,6 +89,8 @@ class RequestContext(RoloRequestContext):
88
89
  """The underlying incoming HTTP request."""
89
90
  service: ServiceModel | None
90
91
  """The botocore ServiceModel of the service the request is made to."""
92
+ protocol: ProtocolName | None
93
+ """The botocore Protocol for the service the request is made to."""
91
94
  operation: OperationModel | None
92
95
  """The botocore OperationModel of the AWS operation being invoked."""
93
96
  region: str
@@ -112,6 +115,7 @@ class RequestContext(RoloRequestContext):
112
115
  def __init__(self, request: Request):
113
116
  super().__init__(request)
114
117
  self.service = None
118
+ self.protocol = None
115
119
  self.operation = None
116
120
  self.region = None # type: ignore[assignment] # type=str, because we know it will always be set downstream
117
121
  self.partition = "aws" # Sensible default - will be overwritten by region-handler
localstack/aws/client.py CHANGED
@@ -21,6 +21,7 @@ from localstack.utils.strings import to_str
21
21
  from .api import CommonServiceException, RequestContext, ServiceException, ServiceResponse
22
22
  from .connect import get_service_endpoint
23
23
  from .gateway import Gateway
24
+ from .spec import ProtocolName
24
25
 
25
26
  LOG = logging.getLogger(__name__)
26
27
 
@@ -284,13 +285,17 @@ def _patch_botocore_endpoint_in_memory():
284
285
 
285
286
 
286
287
  def parse_response(
287
- operation: OperationModel, response: Response, include_response_metadata: bool = True
288
+ operation: OperationModel,
289
+ protocol: ProtocolName,
290
+ response: Response,
291
+ include_response_metadata: bool = True,
288
292
  ) -> ServiceResponse:
289
293
  """
290
294
  Parses an HTTP Response object into an AWS response object using botocore. It does this by adapting the
291
295
  procedure of ``botocore.endpoint.convert_to_response_dict`` to work with Werkzeug's server-side response object.
292
296
 
293
297
  :param operation: the operation of the original request
298
+ :param protocol: the protocol of the original request
294
299
  :param response: the HTTP response object containing the response of the operation
295
300
  :param include_response_metadata: True if the ResponseMetadata (typical for boto response dicts) should be included
296
301
  :return: a parsed dictionary as it is returned by botocore
@@ -322,7 +327,7 @@ def parse_response(
322
327
  timestamp_parser=_cbor_timestamp_parser, blob_parser=_cbor_blob_parser
323
328
  )
324
329
 
325
- parser = factory.create_parser(operation.service_model.protocol)
330
+ parser = factory.create_parser(protocol)
326
331
  parsed_response = parser.parse(response_dict, operation.output_shape)
327
332
 
328
333
  if response.status_code >= 301:
@@ -8,6 +8,8 @@ from typing import Any
8
8
 
9
9
  from botocore.awsrequest import AWSPreparedRequest, prepare_request_dict
10
10
  from botocore.config import Config as BotoConfig
11
+ from botocore.model import OperationModel
12
+ from botocore.serialize import create_serializer
11
13
  from werkzeug.datastructures import Headers
12
14
 
13
15
  from localstack.aws.api.core import (
@@ -19,7 +21,7 @@ from localstack.aws.api.core import (
19
21
  from localstack.aws.client import create_http_request, parse_response, raise_service_exception
20
22
  from localstack.aws.connect import connect_to
21
23
  from localstack.aws.skeleton import DispatchTable, create_dispatch_table
22
- from localstack.aws.spec import load_service
24
+ from localstack.aws.spec import ProtocolName, load_service
23
25
  from localstack.constants import AWS_REGION_US_EAST_1
24
26
  from localstack.http import Response
25
27
  from localstack.http.proxy import Proxy
@@ -79,7 +81,7 @@ class AwsRequestProxy:
79
81
  if not self.parse_response:
80
82
  return http_response
81
83
  parsed_response = parse_response(
82
- context.operation, http_response, self.include_response_metadata
84
+ context.operation, context.protocol, http_response, self.include_response_metadata
83
85
  )
84
86
  raise_service_exception(http_response, parsed_response)
85
87
  return parsed_response
@@ -90,6 +92,7 @@ class AwsRequestProxy:
90
92
  action=original.operation.name,
91
93
  parameters=service_request,
92
94
  region=original.region,
95
+ protocol=original.protocol,
93
96
  )
94
97
  # update the newly created context with non-payload specific request headers (the payload can differ from
95
98
  # the original request, f.e. it could be JSON encoded now while the initial request was CBOR encoded)
@@ -184,7 +187,9 @@ def dispatch_to_backend(
184
187
  :raises ServiceException: if the dispatcher returned an error response
185
188
  """
186
189
  http_response = http_request_dispatcher(context)
187
- parsed_response = parse_response(context.operation, http_response, include_response_metadata)
190
+ parsed_response = parse_response(
191
+ context.operation, context.protocol, http_response, include_response_metadata
192
+ )
188
193
  raise_service_exception(http_response, parsed_response)
189
194
  return parsed_response
190
195
 
@@ -196,6 +201,7 @@ _non_validating_boto_config = BotoConfig(parameter_validation=False)
196
201
  def create_aws_request_context(
197
202
  service_name: str,
198
203
  action: str,
204
+ protocol: ProtocolName = None,
199
205
  parameters: Mapping[str, Any] = None,
200
206
  region: str = None,
201
207
  endpoint_url: str | None = None,
@@ -210,6 +216,7 @@ def create_aws_request_context(
210
216
 
211
217
  :param service_name: the AWS service
212
218
  :param action: the action to invoke
219
+ :param protocol: the protocol to use
213
220
  :param parameters: the invocation parameters
214
221
  :param region: the region name (default is us-east-1)
215
222
  :param endpoint_url: the endpoint to call (defaults to localstack)
@@ -222,6 +229,8 @@ def create_aws_request_context(
222
229
 
223
230
  service = load_service(service_name)
224
231
  operation = service.operation_model(action)
232
+ # TODO: remove this once every usage upstream has been removed
233
+ protocol = protocol or service.resolved_protocol
225
234
 
226
235
  # we re-use botocore internals here to serialize the HTTP request,
227
236
  # but deactivate validation (validation errors should be handled by the backend)
@@ -243,8 +252,14 @@ def create_aws_request_context(
243
252
  endpoint_url = "http://localhost.localstack.cloud"
244
253
  # pre-process the request args (some params are modified using botocore event handlers)
245
254
  parameters = client._emit_api_params(parameters, operation, request_context)
246
- request_dict = client._convert_to_request_dict(
247
- parameters, operation, endpoint_url, context=request_context
255
+
256
+ request_dict = _convert_to_request_dict_with_protocol(
257
+ client=client,
258
+ protocol=protocol,
259
+ api_params=parameters,
260
+ operation_model=operation,
261
+ endpoint_url=endpoint_url,
262
+ context=request_context,
248
263
  )
249
264
 
250
265
  if auth_path := request_dict.get("auth_path"):
@@ -266,7 +281,39 @@ def create_aws_request_context(
266
281
  context = RequestContext(request=create_http_request(aws_request))
267
282
  context.service = service
268
283
  context.operation = operation
284
+ context.protocol = protocol
269
285
  context.region = region
270
286
  context.service_request = parameters
271
287
 
272
288
  return context
289
+
290
+
291
+ def _convert_to_request_dict_with_protocol(
292
+ client,
293
+ protocol: ProtocolName,
294
+ api_params: dict,
295
+ operation_model: OperationModel,
296
+ endpoint_url: str,
297
+ context: dict,
298
+ set_user_agent_header: bool = True,
299
+ ) -> dict:
300
+ """
301
+ This function is taken from botocore Client._convert_to_request_dict, but we are overriding the serializer
302
+ Botocore does not expose a way to create a client with a specific protocol, but we need this functionality
303
+ to support multi-protocols.
304
+ """
305
+ serializer = create_serializer(protocol, include_validation=False)
306
+ request_dict = serializer.serialize_to_request(api_params, operation_model)
307
+ if not client._client_config.inject_host_prefix:
308
+ request_dict.pop("host_prefix", None)
309
+ if set_user_agent_header:
310
+ user_agent = client._user_agent_creator.to_string()
311
+ else:
312
+ user_agent = None
313
+ prepare_request_dict(
314
+ request_dict,
315
+ endpoint_url=endpoint_url,
316
+ user_agent=user_agent,
317
+ context=context,
318
+ )
319
+ return request_dict
@@ -60,7 +60,7 @@ class ServiceRequestCounter:
60
60
  if context.service_exception:
61
61
  return context.service_exception.code
62
62
 
63
- response = parse_response(context.operation, response)
63
+ response = parse_response(context.operation, context.protocol, response)
64
64
  return response["Error"]["Code"]
65
65
  except Exception:
66
66
  if config.DEBUG_ANALYTICS:
@@ -17,7 +17,7 @@ from ..chain import CompositeResponseHandler, ExceptionHandler, Handler, Handler
17
17
  from ..client import parse_response, parse_service_exception
18
18
  from ..protocol.parser import RequestParser, create_parser
19
19
  from ..protocol.serializer import create_serializer
20
- from ..protocol.service_router import determine_aws_service_model
20
+ from ..protocol.service_router import determine_aws_protocol, determine_aws_service_model
21
21
  from ..skeleton import Skeleton, create_skeleton
22
22
 
23
23
  LOG = logging.getLogger(__name__)
@@ -33,6 +33,8 @@ class ServiceNameParser(Handler):
33
33
  # example). If it is already set, we can skip the parsing of the request. It is very important for S3, because
34
34
  # parsing the request will consume the data stream and prevent streaming.
35
35
  if context.service:
36
+ if not context.protocol:
37
+ context.protocol = determine_aws_protocol(context.request, context.service)
36
38
  return
37
39
 
38
40
  service_model = determine_aws_service_model(context.request)
@@ -41,6 +43,7 @@ class ServiceNameParser(Handler):
41
43
  return
42
44
 
43
45
  context.service = service_model
46
+ context.protocol = determine_aws_protocol(context.request, service_model)
44
47
 
45
48
 
46
49
  class ServiceRequestParser(Handler):
@@ -63,7 +66,7 @@ class ServiceRequestParser(Handler):
63
66
  return self.parse_and_enrich(context)
64
67
 
65
68
  def parse_and_enrich(self, context: RequestContext):
66
- parser = create_parser(context.service)
69
+ parser = create_parser(context.service, context.protocol)
67
70
  operation, instance = parser.parse(context.request)
68
71
 
69
72
  # enrich context
@@ -137,7 +140,7 @@ class ServiceRequestRouter(Handler):
137
140
  operation_name = operation.name
138
141
  message = f"no handler for operation '{operation_name}' on service '{service_name}'"
139
142
  error = CommonServiceException("InternalFailure", message, status_code=501)
140
- serializer = create_serializer(context.service)
143
+ serializer = create_serializer(context.service, context.protocol)
141
144
  return serializer.serialize_error_to_response(
142
145
  error, operation, context.request.headers, context.request_id
143
146
  )
@@ -209,7 +212,7 @@ class ServiceExceptionSerializer(ExceptionHandler):
209
212
  ).with_traceback(exception.__traceback__)
210
213
  context.service_exception = error
211
214
 
212
- serializer = create_serializer(context.service) # TODO: serializer cache
215
+ serializer = create_serializer(context.service, context.protocol)
213
216
  return serializer.serialize_error_to_response(
214
217
  error, operation, context.request.headers, context.request_id
215
218
  )
@@ -252,7 +255,9 @@ class ServiceResponseParser(Handler):
252
255
  return
253
256
 
254
257
  # in this case we need to parse the raw response
255
- parsed = parse_response(context.operation, response, include_response_metadata=False)
258
+ parsed = parse_response(
259
+ context.operation, context.protocol, response, include_response_metadata=False
260
+ )
256
261
  if service_exception := parse_service_exception(response, parsed):
257
262
  context.service_exception = service_exception
258
263
  else:
@@ -359,13 +359,11 @@ class RequestParser(abc.ABC):
359
359
 
360
360
  @staticmethod
361
361
  def _timestamp_unixtimestamp(timestamp_string: str) -> datetime.datetime:
362
- dt = datetime.datetime.fromtimestamp(int(timestamp_string), tz=datetime.UTC)
363
- return dt.replace(tzinfo=None)
362
+ return datetime.datetime.fromtimestamp(int(timestamp_string), tz=datetime.UTC)
364
363
 
365
364
  @staticmethod
366
365
  def _timestamp_unixtimestampmillis(timestamp_string: str) -> datetime.datetime:
367
- dt = datetime.datetime.fromtimestamp(float(timestamp_string) / 1000, tz=datetime.UTC)
368
- return dt.replace(tzinfo=None)
366
+ return datetime.datetime.fromtimestamp(float(timestamp_string) / 1000, tz=datetime.UTC)
369
367
 
370
368
  @staticmethod
371
369
  def _timestamp_rfc822(datetime_string: str) -> datetime.datetime:
@@ -1168,6 +1166,14 @@ class BaseCBORRequestParser(RequestParser, ABC):
1168
1166
  def _parse_blob(self, _, __, node: bytes, ___) -> bytes:
1169
1167
  return node
1170
1168
 
1169
+ @_text_content
1170
+ def _parse_timestamp(
1171
+ self, _, shape: Shape, node: datetime.datetime | str, ___
1172
+ ) -> datetime.datetime:
1173
+ if isinstance(node, datetime.datetime):
1174
+ return node
1175
+ return super()._parse_timestamp(_, shape, node, ___)
1176
+
1171
1177
  # This helper method is intended for use when parsing indefinite length items.
1172
1178
  # It does nothing if the next byte is not the break code. If the next byte is
1173
1179
  # the break code, it advances past that byte and returns True so the calling
@@ -1266,8 +1272,6 @@ class BaseRpcV2RequestParser(RequestParser):
1266
1272
  "RPC v2 does not accept 'X-Amz-Target' or 'X-Amzn-Target'. "
1267
1273
  "Such requests are rejected for security reasons."
1268
1274
  )
1269
- # TODO: add this special path handling to the ServiceNameParser to allow RPC v2 service to be properly extracted
1270
- # path = '/service/{service_name}/operation/{operation_name}'
1271
1275
  # The Smithy RPCv2 CBOR protocol will only use the last four segments of the URL when routing requests.
1272
1276
  rpc_v2_params = request.path.lstrip("/").split("/")
1273
1277
  if len(rpc_v2_params) < 4 or not (
@@ -1580,8 +1584,6 @@ def create_parser(service: ServiceModel, protocol: ProtocolName | None = None) -
1580
1584
  # this is not an "official" protocol defined from the spec, but is derived from ``json``
1581
1585
  }
1582
1586
 
1583
- # TODO: do we want to add a check if the user-defined protocol is part of the available ones in the ServiceModel?
1584
- # or should it be checked once
1585
1587
  service_protocol = protocol or service.protocol
1586
1588
 
1587
1589
  # Try to select a service- and protocol-specific parser implementation
@@ -1773,6 +1773,8 @@ class CBORResponseSerializer(BaseCBORResponseSerializer):
1773
1773
  mime_type: str,
1774
1774
  request_id: str,
1775
1775
  ) -> bytes | None:
1776
+ if shape is None:
1777
+ return b""
1776
1778
  body = bytearray()
1777
1779
  self._serialize_data_item(body, params, shape)
1778
1780
  return bytes(body)
@@ -1839,6 +1841,8 @@ class RpcV2CBORResponseSerializer(BaseRpcV2ResponseSerializer, BaseCBORResponseS
1839
1841
  mime_type: str,
1840
1842
  request_id: str,
1841
1843
  ) -> bytes | None:
1844
+ if shape is None:
1845
+ return b""
1842
1846
  body = bytearray()
1843
1847
  self._serialize_data_item(body, params, shape)
1844
1848
  return bytes(body)
@@ -2263,9 +2267,6 @@ def create_serializer(
2263
2267
  # CBOR handling from JSONResponseParser
2264
2268
  # this is not an "official" protocol defined from the spec, but is derived from ``json``
2265
2269
  }
2266
- # TODO: even though our Service Name Parser will only use a protocol that is available for the service, we might
2267
- # want to verify if the given protocol here is available for that service, in case we are manually calling
2268
- # this factory. Revisit once we implement multi-protocol support
2269
2270
  service_protocol = protocol or service.protocol
2270
2271
 
2271
2272
  # Try to select a service- and protocol-specific serializer implementation
@@ -2307,7 +2308,7 @@ def aws_response_serializer(
2307
2308
  def _decorate(fn):
2308
2309
  service_model = load_service(service_name, protocol=protocol)
2309
2310
  operation_model = service_model.operation_model(operation)
2310
- serializer = create_serializer(service_model)
2311
+ serializer = create_serializer(service_model, protocol=protocol)
2311
2312
 
2312
2313
  def _proxy(*args, **kwargs) -> WerkzeugResponse:
2313
2314
  # extract request from function invocation (decorator can be used for methods as well as for functions).
@@ -6,9 +6,11 @@ from werkzeug.exceptions import RequestEntityTooLarge
6
6
  from werkzeug.http import parse_dict_header
7
7
 
8
8
  from localstack.aws.spec import (
9
+ ProtocolName,
9
10
  ServiceCatalog,
10
11
  ServiceModelIdentifier,
11
12
  get_service_catalog,
13
+ is_protocol_in_service_model_identifier,
12
14
  )
13
15
  from localstack.http import Request
14
16
  from localstack.services.s3.utils import uses_host_addressing
@@ -17,6 +19,23 @@ from localstack.utils.strings import to_bytes
17
19
 
18
20
  LOG = logging.getLogger(__name__)
19
21
 
22
+ _PROTOCOL_DETECTION_PRIORITY: list[ProtocolName] = [
23
+ "smithy-rpc-v2-cbor",
24
+ "json",
25
+ "query",
26
+ "ec2",
27
+ "rest-json",
28
+ "rest-xml",
29
+ ]
30
+
31
+
32
+ class ProtocolError(Exception):
33
+ """
34
+ Error which is thrown if we cannot detect the protocol for the request.
35
+ """
36
+
37
+ pass
38
+
20
39
 
21
40
  class _ServiceIndicators(NamedTuple):
22
41
  """
@@ -43,6 +62,7 @@ def _extract_service_indicators(request: Request) -> _ServiceIndicators:
43
62
  """Extracts all different fields that might indicate which service a request is targeting."""
44
63
  x_amz_target = request.headers.get("x-amz-target")
45
64
  authorization = request.headers.get("authorization")
65
+ is_rpc_v2 = "rpc-v2-cbor" in request.headers.get("Smithy-Protocol", "")
46
66
 
47
67
  signing_name = None
48
68
  if authorization:
@@ -55,7 +75,15 @@ def _extract_service_indicators(request: Request) -> _ServiceIndicators:
55
75
  except (ValueError, KeyError):
56
76
  LOG.debug("auth header could not be parsed for service routing: %s", authorization)
57
77
  pass
58
- if x_amz_target:
78
+ if is_rpc_v2:
79
+ # https://smithy.io/2.0/additional-specs/protocols/smithy-rpc-v2.html#requests
80
+ rpc_v2_params = request.path.lstrip("/").split("/")
81
+ if len(rpc_v2_params) >= 4:
82
+ *_, service_shape_name, __, operation = rpc_v2_params
83
+ target_prefix = service_shape_name.split("#")[-1]
84
+ else:
85
+ target_prefix, operation = None, None
86
+ elif x_amz_target:
59
87
  if "." in x_amz_target:
60
88
  target_prefix, operation = x_amz_target.split(".", 1)
61
89
  else:
@@ -67,6 +95,48 @@ def _extract_service_indicators(request: Request) -> _ServiceIndicators:
67
95
  return _ServiceIndicators(signing_name, target_prefix, operation, request.host, request.path)
68
96
 
69
97
 
98
+ def _matches_protocol(request: Request, protocol: ProtocolName) -> bool:
99
+ headers = request.headers
100
+ mimetype = request.mimetype.lower()
101
+ match protocol:
102
+ case "smithy-rpc-v2-cbor":
103
+ # Every request for the rpcv2Cbor protocol MUST contain a `Smithy-Protocol` header with the value
104
+ # of `rpc-v2-cbor`.
105
+ # https://smithy.io/2.0/additional-specs/protocols/smithy-rpc-v2.html
106
+ return headers.get("Smithy-Protocol", "") == "rpc-v2-cbor"
107
+ case "json":
108
+ return mimetype.startswith("application/x-amz-json")
109
+ case "query" | "ec2":
110
+ # https://smithy.io/2.0/aws/protocols/aws-query-protocol.html#request-serialization
111
+ return (
112
+ mimetype.startswith("application/x-www-form-urlencoded") or "Action" in request.args
113
+ )
114
+ case "rest-xml" | "rest-json":
115
+ # `rest-json` and `rest-xml` can accept any kind of Content-Type, and it can be configured on the operation
116
+ # level.
117
+ # https://smithy.io/2.0/aws/protocols/aws-restjson1-protocol.html
118
+ return True
119
+ case _:
120
+ return False
121
+
122
+
123
+ def match_available_protocols(
124
+ request: Request, available_protocols: list[ProtocolName]
125
+ ) -> ProtocolName | None:
126
+ """
127
+ Tries to match the current request and determine the protocol used amongst the available protocols given.
128
+ We use a priority order to try to determine the protocol, as some protocols are more permissive that others.
129
+ :param request: the incoming request
130
+ :param available_protocols: the available protocols of the Service the request is directed to
131
+ :return: the protocol matched, if any
132
+ """
133
+ for protocol in _PROTOCOL_DETECTION_PRIORITY:
134
+ if protocol in available_protocols and _matches_protocol(request, protocol):
135
+ return protocol
136
+
137
+ return None
138
+
139
+
70
140
  signing_name_path_prefix_rules = {
71
141
  # custom rules based on URI path prefixes that are not easily generalizable
72
142
  "apigateway": {
@@ -248,10 +318,10 @@ def resolve_conflicts(
248
318
  # The `application/x-amz-json-1.0` header is mandatory for requests targeting SQS with the `json` protocol. We
249
319
  # can safely route them to the `sqs` JSON parser/serializer. If not present, route the request to the
250
320
  # sqs-query protocol.
251
- content_type = request.headers.get("Content-Type")
321
+ protocol = match_available_protocols(request, available_protocols=["json", "query"])
252
322
  return (
253
323
  ServiceModelIdentifier("sqs")
254
- if content_type == "application/x-amz-json-1.0"
324
+ if protocol == "json"
255
325
  else ServiceModelIdentifier("sqs", "query")
256
326
  )
257
327
 
@@ -266,7 +336,25 @@ def determine_aws_service_model_for_data_plane(
266
336
  custom_host_match = custom_host_addressing_rules(request.host)
267
337
  if custom_host_match:
268
338
  services = services or get_service_catalog()
269
- return services.get(*custom_host_match)
339
+ return services.get(custom_host_match.name, custom_host_match.protocol)
340
+
341
+
342
+ def determine_aws_protocol(request: Request, service_model: ServiceModel) -> ProtocolName:
343
+ if not (protocols := service_model.metadata.get("protocols")):
344
+ # if the service does not define multiple protocols, return the `protocol` defined for the service
345
+ return service_model.protocol
346
+
347
+ if len(protocols) == 1:
348
+ return protocols[0]
349
+
350
+ if protocol := match_available_protocols(request, available_protocols=protocols):
351
+ return protocol
352
+
353
+ raise ProtocolError(
354
+ f"Could not determine the protocol for the request: "
355
+ f"{request.method} {request.path} for the service '{service_model.service_name}' "
356
+ f"(available protocols: {protocols})"
357
+ )
270
358
 
271
359
 
272
360
  def determine_aws_service_model(
@@ -287,12 +375,13 @@ def determine_aws_service_model(
287
375
  signing_name_candidates = services.by_signing_name(signing_name)
288
376
  if len(signing_name_candidates) == 1:
289
377
  # a unique signing-name -> service name mapping is the case for ~75% of service operations
290
- return services.get(*signing_name_candidates[0])
378
+ candidate = signing_name_candidates[0]
379
+ return services.get(candidate.name, candidate.protocol)
291
380
 
292
381
  # try to find a match with the custom signing name rules
293
382
  custom_match = custom_signing_name_rules(signing_name, path)
294
383
  if custom_match:
295
- return services.get(*custom_match)
384
+ return services.get(custom_match.name, custom_match.protocol)
296
385
 
297
386
  # still ambiguous - add the services to the list of candidates
298
387
  candidates.update(signing_name_candidates)
@@ -302,33 +391,34 @@ def determine_aws_service_model(
302
391
  target_candidates = services.by_target_prefix(target_prefix)
303
392
  if len(target_candidates) == 1:
304
393
  # a unique target prefix
305
- return services.get(*target_candidates[0])
394
+ candidate = target_candidates[0]
395
+ return services.get(candidate.name, candidate.protocol)
306
396
 
307
397
  # still ambiguous - add the services to the list of candidates
308
398
  candidates.update(target_candidates)
309
399
 
310
400
  # exclude services where the operation is not contained in the service spec
311
401
  for service_identifier in list(candidates):
312
- service = services.get(*service_identifier)
402
+ service = services.get(service_identifier.name, service_identifier.protocol)
313
403
  if operation not in service.operation_names:
314
404
  candidates.remove(service_identifier)
315
405
  else:
316
406
  # exclude services which have a target prefix (the current request does not have one)
317
407
  for service_identifier in list(candidates):
318
- service = services.get(*service_identifier)
408
+ service = services.get(service_identifier.name, service_identifier.protocol)
319
409
  if service.metadata.get("targetPrefix") is not None:
320
410
  candidates.remove(service_identifier)
321
411
 
322
412
  if len(candidates) == 1:
323
413
  service_identifier = candidates.pop()
324
- return services.get(*service_identifier)
414
+ return services.get(service_identifier.name, service_identifier.protocol)
325
415
 
326
416
  # 3. check the path if it is set and not a trivial root path
327
417
  if path and path != "/":
328
418
  # try to find a match with the custom path rules
329
419
  custom_path_match = custom_path_addressing_rules(path)
330
420
  if custom_path_match:
331
- return services.get(*custom_path_match)
421
+ return services.get(custom_path_match.name, custom_path_match.protocol)
332
422
 
333
423
  # 4. check the host (custom host addressing rules)
334
424
  if host:
@@ -337,12 +427,14 @@ def determine_aws_service_model(
337
427
  # this prevents a virtual host addressed bucket to be wrongly recognized
338
428
  if host.startswith(f"{prefix}.") and ".s3." not in host:
339
429
  if len(services_per_prefix) == 1:
340
- return services.get(*services_per_prefix[0])
430
+ candidate = services_per_prefix[0]
431
+ return services.get(candidate.name, candidate.protocol)
341
432
  candidates.update(services_per_prefix)
342
433
 
343
434
  custom_host_match = custom_host_addressing_rules(host)
344
435
  if custom_host_match:
345
- return services.get(*custom_host_match)
436
+ candidate = custom_host_match[0]
437
+ return services.get(candidate.name, candidate.protocol)
346
438
 
347
439
  if request.shallow:
348
440
  # from here on we would need access to the request body, which doesn't exist for shallow requests like
@@ -357,21 +449,28 @@ def determine_aws_service_model(
357
449
  query_candidates = [
358
450
  service
359
451
  for service in services.by_operation(values["Action"])
360
- if service.protocol in ("ec2", "query")
452
+ if any(
453
+ is_protocol_in_service_model_identifier(protocol, service)
454
+ for protocol in ("ec2", "query")
455
+ )
361
456
  ]
362
457
 
363
458
  if len(query_candidates) == 1:
364
- return services.get(*query_candidates[0])
459
+ candidate = query_candidates[0]
460
+ return services.get(candidate.name, candidate.protocol)
365
461
 
366
462
  if "Version" in values:
367
463
  for service_identifier in list(query_candidates):
368
- service_model = services.get(*service_identifier)
464
+ service_model = services.get(
465
+ service_identifier.name, service_identifier.protocol
466
+ )
369
467
  if values["Version"] != service_model.api_version:
370
468
  # the combination of Version and Action is not unique, add matches to the candidates
371
469
  query_candidates.remove(service_identifier)
372
470
 
373
471
  if len(query_candidates) == 1:
374
- return services.get(*query_candidates[0])
472
+ candidate = query_candidates[0]
473
+ return services.get(candidate.name, candidate.protocol)
375
474
 
376
475
  candidates.update(query_candidates)
377
476
 
@@ -387,15 +486,16 @@ def determine_aws_service_model(
387
486
  # 6. resolve service spec conflicts
388
487
  resolved_conflict = resolve_conflicts(candidates, request)
389
488
  if resolved_conflict:
390
- return services.get(*resolved_conflict)
489
+ return services.get(resolved_conflict.name, resolved_conflict.protocol)
391
490
 
392
491
  # 7. check the legacy S3 rules in the end
393
492
  legacy_match = legacy_s3_rules(request)
394
493
  if legacy_match:
395
- return services.get(*legacy_match)
494
+ return services.get(legacy_match.name, legacy_match.protocol)
396
495
 
397
496
  if signing_name:
398
497
  return services.get(name=signing_name)
399
498
  if candidates:
400
- return services.get(*candidates.pop())
499
+ candidate = candidates.pop()
500
+ return services.get(candidate.name, candidate.protocol)
401
501
  return None
@@ -130,14 +130,16 @@ class Skeleton:
130
130
  self.dispatch_table = create_dispatch_table(implementation)
131
131
 
132
132
  def invoke(self, context: RequestContext) -> Response:
133
- serializer = create_serializer(context.service)
133
+ serializer = create_serializer(context.service, context.protocol)
134
134
 
135
135
  if context.operation and context.service_request:
136
136
  # if the parsed request is already set in the context, re-use them
137
137
  operation, instance = context.operation, context.service_request
138
138
  else:
139
139
  # otherwise, parse the incoming HTTPRequest
140
- operation, instance = create_parser(context.service).parse(context.request)
140
+ operation, instance = create_parser(context.service, context.protocol).parse(
141
+ context.request
142
+ )
141
143
  context.operation = operation
142
144
 
143
145
  try:
@@ -1352,5 +1352,43 @@
1352
1352
  "path": "/operations/CreateApiMapping/http/responseCode",
1353
1353
  "value": 200
1354
1354
  }
1355
+ ],
1356
+ "cloudwatch/2010-08-01/service-2": [
1357
+ {
1358
+ "op": "add",
1359
+ "path": "/metadata/awsQueryCompatible",
1360
+ "value": {}
1361
+ },
1362
+ {
1363
+ "op": "add",
1364
+ "path": "/metadata/jsonVersion",
1365
+ "value": "1.0"
1366
+ },
1367
+ {
1368
+ "op": "add",
1369
+ "path": "/metadata/targetPrefix",
1370
+ "value": "GraniteServiceVersion20100801"
1371
+ },
1372
+ {
1373
+ "op": "replace",
1374
+ "path": "/metadata/protocol",
1375
+ "value": "smithy-rpc-v2-cbor"
1376
+ },
1377
+ {
1378
+ "op": "replace",
1379
+ "path": "/metadata/protocols",
1380
+ "value": [
1381
+ "smithy-rpc-v2-cbor",
1382
+ "json",
1383
+ "query"
1384
+ ]
1385
+ },
1386
+ {
1387
+ "op": "add",
1388
+ "path": "/shapes/ConflictException/error",
1389
+ "value": {
1390
+ "httpStatusCode": 409
1391
+ }
1392
+ }
1355
1393
  ]
1356
1394
  }
localstack/aws/spec.py CHANGED
@@ -33,6 +33,7 @@ class ServiceModelIdentifier(NamedTuple):
33
33
 
34
34
  name: ServiceName
35
35
  protocol: ProtocolName | None = None
36
+ protocols: tuple[ProtocolName] | None = None
36
37
 
37
38
 
38
39
  spec_patches_json = os.path.join(os.path.dirname(__file__), "spec-patches.json")
@@ -114,9 +115,13 @@ def load_service(
114
115
  :raises: UnknownServiceProtocolError if the specific protocol of the service cannot be found
115
116
  """
116
117
  service_description = loader.load_service_model(service, "service-2", version)
118
+ service_metadata = service_description.get("metadata", {})
119
+ service_protocols = {service_metadata.get("protocol")}
120
+ if protocols := service_metadata.get("protocols"):
121
+ service_protocols.update(protocols)
117
122
 
118
123
  # check if the protocol is defined, and if so, if the loaded service defines this protocol
119
- if protocol is not None and protocol != service_description.get("metadata", {}).get("protocol"):
124
+ if protocol is not None and protocol not in service_protocols:
120
125
  # if the protocol is defined, but not the one of the currently loaded service,
121
126
  # check if we already loaded the custom spec based on the naming convention (<service>-<protocol>),
122
127
  # f.e. "sqs-query"
@@ -132,7 +137,7 @@ def load_service(
132
137
 
133
138
  # remove potential protocol names from the service name
134
139
  # FIXME add more protocols here if we have to internalize more than just sqs-query
135
- # TODO this should not contain specific internalized serivce names
140
+ # TODO this should not contain specific internalized service names
136
141
  service = {"sqs-query": "sqs"}.get(service, service)
137
142
  return ServiceModel(service_description, service)
138
143
 
@@ -149,6 +154,27 @@ def iterate_service_operations() -> Generator[tuple[ServiceModel, OperationModel
149
154
  yield service, service.operation_model(op_name)
150
155
 
151
156
 
157
+ def is_protocol_in_service_model_identifier(
158
+ protocol: ProtocolName, service_model_identifier: ServiceModelIdentifier
159
+ ) -> bool:
160
+ """
161
+ :param protocol: the protocol name to check
162
+ :param service_model_identifier:
163
+ :return: boolean to indicate if the protocol is available for that service
164
+ """
165
+ protocols = service_model_identifier.protocols or []
166
+ return protocol in protocols or protocol == service_model_identifier.protocol
167
+
168
+
169
+ def get_service_model_identifier(service_model: ServiceModel) -> ServiceModelIdentifier:
170
+ protocols = service_model.metadata.get("protocols")
171
+ return ServiceModelIdentifier(
172
+ name=service_model.service_name,
173
+ protocol=service_model.protocol,
174
+ protocols=tuple(protocols) if protocols else None,
175
+ )
176
+
177
+
152
178
  @dataclasses.dataclass
153
179
  class ServiceCatalogIndex:
154
180
  """
@@ -178,9 +204,7 @@ class LazyServiceCatalogIndex:
178
204
  for service_model in service_models:
179
205
  target_prefix = service_model.metadata.get("targetPrefix")
180
206
  if target_prefix:
181
- result[target_prefix].append(
182
- ServiceModelIdentifier(service_model.service_name, service_model.protocol)
183
- )
207
+ result[target_prefix].append(get_service_model_identifier(service_model))
184
208
  return dict(result)
185
209
 
186
210
  @cached_property
@@ -189,7 +213,7 @@ class LazyServiceCatalogIndex:
189
213
  for service_models in self._services.values():
190
214
  for service_model in service_models:
191
215
  result[service_model.signing_name].append(
192
- ServiceModelIdentifier(service_model.service_name, service_model.protocol)
216
+ get_service_model_identifier(service_model)
193
217
  )
194
218
  return dict(result)
195
219
 
@@ -201,11 +225,7 @@ class LazyServiceCatalogIndex:
201
225
  operations = service_model.operation_names
202
226
  if operations:
203
227
  for operation in operations:
204
- result[operation].append(
205
- ServiceModelIdentifier(
206
- service_model.service_name, service_model.protocol
207
- )
208
- )
228
+ result[operation].append(get_service_model_identifier(service_model))
209
229
  return dict(result)
210
230
 
211
231
  @cached_property
@@ -214,7 +234,7 @@ class LazyServiceCatalogIndex:
214
234
  for service_models in self._services.values():
215
235
  for service_model in service_models:
216
236
  result[service_model.endpoint_prefix].append(
217
- ServiceModelIdentifier(service_model.service_name, service_model.protocol)
237
+ get_service_model_identifier(service_model)
218
238
  )
219
239
  return dict(result)
220
240
 
@@ -2977,6 +2977,7 @@ def create_custom_context(
2977
2977
  ctx = create_aws_request_context(
2978
2978
  service_name=context.service.service_name,
2979
2979
  action=action,
2980
+ protocol=context.service.protocol,
2980
2981
  parameters=parameters,
2981
2982
  region=context.region,
2982
2983
  )
@@ -211,6 +211,9 @@ class RestApiAwsIntegration(RestApiIntegration):
211
211
  action = parsed_uri["path"]
212
212
 
213
213
  if target := self.get_action_service_target(service_name, action):
214
+ # TODO: properly implement the auto-`Content-Type` headers depending on the service protocol
215
+ # e.g. `x-amz-json-1.0` for DynamoDB
216
+ # this is needed to properly support multi-protocol
214
217
  headers["X-Amz-Target"] = target
215
218
 
216
219
  query_params["Action"] = action
@@ -280,7 +280,7 @@ class CloudwatchProvider(CloudwatchApi, ServiceLifecycleHook):
280
280
  timestamp_value_dicts = [
281
281
  {
282
282
  "Timestamp": timestamp,
283
- "Value": value,
283
+ "Value": float(value),
284
284
  }
285
285
  for timestamp, value in zip(timestamps, values, strict=False)
286
286
  ]
@@ -66,6 +66,7 @@ def call_moto_with_request(
66
66
  action=context.operation.name,
67
67
  parameters=service_request,
68
68
  region=context.region,
69
+ protocol=context.protocol,
69
70
  )
70
71
  # we keep the headers from the original request, but override them with the ones created from the `service_request`
71
72
  headers = copy.deepcopy(context.request.headers)
@@ -35,7 +35,7 @@ LOG = logging.getLogger(__name__)
35
35
 
36
36
  service = load_service("sqs-query")
37
37
  parser = create_parser(service)
38
- serializer = create_serializer(service)
38
+ serializer = create_serializer(service, "query")
39
39
 
40
40
 
41
41
  @route(
localstack/utils/time.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import time
2
2
  from datetime import date, datetime, timezone, tzinfo
3
3
  from typing import Optional
4
+ from zoneinfo import ZoneInfo
4
5
 
5
6
  TIMESTAMP_FORMAT = "%Y-%m-%dT%H:%M:%S"
6
7
  TIMESTAMP_FORMAT_TZ = "%Y-%m-%dT%H:%M:%SZ"
@@ -42,6 +43,11 @@ def epoch_timestamp() -> float:
42
43
 
43
44
 
44
45
  def parse_timestamp(ts_str: str) -> datetime:
46
+ """
47
+ Parse the incoming date string into a timezone aware datetime object
48
+ :param ts_str:
49
+ :return:
50
+ """
45
51
  for ts_format in [
46
52
  TIMESTAMP_FORMAT,
47
53
  TIMESTAMP_FORMAT_TZ,
@@ -49,7 +55,10 @@ def parse_timestamp(ts_str: str) -> datetime:
49
55
  TIMESTAMP_READABLE_FORMAT,
50
56
  ]:
51
57
  try:
52
- return datetime.strptime(ts_str, ts_format)
58
+ value = datetime.strptime(ts_str, ts_format)
59
+ if value.tzinfo is None:
60
+ value = value.replace(tzinfo=ZoneInfo("UTC"))
61
+ return value
53
62
  except ValueError:
54
63
  pass
55
64
  raise Exception(f"Unable to parse timestamp string with any known formats: {ts_str}")
localstack/version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '4.8.2.dev11'
32
- __version_tuple__ = version_tuple = (4, 8, 2, 'dev11')
31
+ __version__ = version = '4.8.2.dev13'
32
+ __version_tuple__ = version_tuple = (4, 8, 2, 'dev13')
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: localstack-core
3
- Version: 4.8.2.dev11
3
+ Version: 4.8.2.dev13
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,29 +4,29 @@ localstack/deprecations.py,sha256=78Sf99fgH3ckJ20a9SMqsu01r1cm5GgcomkuY4yDMDo,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=eR3jMftzNO9CacakejlPSYrdiIUxh0fjQ4qkwxv2paI,719
7
+ localstack/version.py,sha256=vRci3sCirjkA3naGEMCqQfQfjAjk94Kp_Cr1VRN8q9A,719
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
11
11
  localstack/aws/chain.py,sha256=upf7GDohphsH1tKBbwU_J5J5xK8rqcWb-dU3dJL0Coo,1221
12
- localstack/aws/client.py,sha256=yZRIrhRSEv3YT3wd55zoNKeWp9I3QQ0KNEaqRPbpri4,15957
12
+ localstack/aws/client.py,sha256=CqUugJjgl-ZQyv2sDrSt0ppoCjzDQI9Gv3rIB9bCbXk,16059
13
13
  localstack/aws/components.py,sha256=nzZtcasAaLoMRJ2V6EcX4xD9uPwxmS8ovRHVyrMzabA,607
14
14
  localstack/aws/connect.py,sha256=3KxuSq3G9jbb65-DWxWfPe8D33Ato_90j14c-B44oq4,29810
15
- localstack/aws/forwarder.py,sha256=xPI0GkiDqVRmbSnOe7QqGRoUAB8FE5FwjrUwYYo4oLM,11269
15
+ localstack/aws/forwarder.py,sha256=GGo3l0GCsaASLOC7THKoUsVaH678WVH-PJoMzEotk0Y,12868
16
16
  localstack/aws/gateway.py,sha256=d_Tm0N2-mAnuvE4puXfRjgzMHwR3EuuOQH5IIWX-vAQ,903
17
17
  localstack/aws/mocking.py,sha256=JZZ7ZyAmlCGzywTF8jH4IelPGIiLqyz_ltDtO046a3E,13683
18
18
  localstack/aws/patches.py,sha256=r5EDhDE_OL25fQzT6oEhV7LvpBzTisOqxdn-JD_ZfrI,1883
19
19
  localstack/aws/scaffold.py,sha256=9GLeSaWQdCWBpFJghj92tFuGZ2CaCNE9iqJ020vs8a0,20029
20
- localstack/aws/skeleton.py,sha256=zlbzAEiMV-tS5EQz5MxqflInalK613BrTOFviyT4X5Y,8175
21
- localstack/aws/spec-patches.json,sha256=9zIgusH52V72SmOaRHTlWcu4aX5GEb2SzX1U9EL7SpU,42563
22
- localstack/aws/spec.py,sha256=61aAB3bqJ5rVJKh35ApLJR6cSGUGIgElKSnN2n2i8w8,14255
20
+ localstack/aws/skeleton.py,sha256=N_siYCImRXn_ckr0f2oRFhdox6grAGXi5q02LOxgGDA,8241
21
+ localstack/aws/spec-patches.json,sha256=C05aUHXG41WaD4amPhmDAAL_BFl9GMMQWU-dUIVspTY,43317
22
+ localstack/aws/spec.py,sha256=EHioKRZyVuDMyP6iOf0O51Tyc2MTfD2eodhnJquhjno,14988
23
23
  localstack/aws/api/__init__.py,sha256=JspwCauxfTTdLNVAr7AkQaPu1lELdBQ1miB9B9sndOo,297
24
- localstack/aws/api/core.py,sha256=5BdwwThfkrZThxgGIbIabXdtMSPZfElzNdzRlw224m4,6733
24
+ localstack/aws/api/core.py,sha256=7qi_hFySJTnOSh1Kv-FCAp2JNpK5jP8sucoG-VTyH4k,6913
25
25
  localstack/aws/api/acm/__init__.py,sha256=67OHJbngmz4nKaXm9grkLW_Rl4RLRCeOBffhh3u1z0k,19079
26
26
  localstack/aws/api/apigateway/__init__.py,sha256=30pTFfEn2VzlJeTm78Rjrj4MYtkVdobS-1hoOnnTZ0I,79884
27
27
  localstack/aws/api/cloudcontrol/__init__.py,sha256=rVF7U2eYowakBDklAocYNjDzLtLNZqGgK1IBfnh_cG0,11595
28
28
  localstack/aws/api/cloudformation/__init__.py,sha256=9pywbIDO5DKjUqRu_X78vZIvUMnrJZ_0tbpqW7lsMxA,117360
29
- localstack/aws/api/cloudwatch/__init__.py,sha256=dppw7e1AHs-Dhf0WhCVheHkXxlGyCz9n-S9T96HzeoY,47224
29
+ localstack/aws/api/cloudwatch/__init__.py,sha256=EgYlhAU_w0D2E2VMd9jzjTnjwR5S9-AObvLl7RYLFLw,47224
30
30
  localstack/aws/api/config/__init__.py,sha256=6ATQPkUBu3_KSrG2siHjh7e-qZq5MgPBcT0SLBe2lLA,144985
31
31
  localstack/aws/api/dynamodb/__init__.py,sha256=DrFVVZOiEPM2oidelJvhFlq_KFRkyu8OFTGdMG6eM6M,94576
32
32
  localstack/aws/api/dynamodbstreams/__init__.py,sha256=WUSvC51HIBnpDqDLQjCi2zh1HD1GccwsnpLiqcoftik,7316
@@ -62,7 +62,7 @@ localstack/aws/api/transcribe/__init__.py,sha256=oIh5LgOejT1qCgYu4rH97m0XXKcLoRC
62
62
  localstack/aws/data/sqs-query/2012-11-05/README.md,sha256=kCa30EG7duD8naEHFmWNYt-mpPzl3Z5oU2YS5sz_4Mg,1117
63
63
  localstack/aws/data/sqs-query/2012-11-05/service-2.json,sha256=QFuVuRqTC82O-uVvrBf5r6Wk-lRm8oCxgLgWRGvRELo,34136
64
64
  localstack/aws/handlers/__init__.py,sha256=qeSfvzPAALcgwDZRQmPQL0ULorMd5CFPmLU09FsEmww,2025
65
- localstack/aws/handlers/analytics.py,sha256=gq9Mj48okCGERbkkwJUH6k4_tLE9Q1lveiaBRz1AKKM,2424
65
+ localstack/aws/handlers/analytics.py,sha256=RARHggnOGGPjIiuf2WwJ2j8uMSoN0AnY03Lo7wCEV_0,2442
66
66
  localstack/aws/handlers/auth.py,sha256=mCFMGQSnt1rTgZ8HAXWHZJPYNLtyVwR30Medn1BD5ao,1946
67
67
  localstack/aws/handlers/codec.py,sha256=PuHaUVXEEjkFKTjoqDrJocUTzVNov_nYPXfkbQf84kU,1337
68
68
  localstack/aws/handlers/cors.py,sha256=ZEmcftE_4bpA5avBCRksV-0A9EvLhihGb8j_atB7_7w,10733
@@ -77,16 +77,16 @@ localstack/aws/handlers/proxy.py,sha256=SnLQ70IWxPrrN_rhTaNGUy79kiysWaF0qrOMNavA
77
77
  localstack/aws/handlers/region.py,sha256=EV4QhpzJRYFrS6h5ntUAO9uwwsRv_RBbNpGOwR7XgCM,3550
78
78
  localstack/aws/handlers/response.py,sha256=gc0jooGNt1Jtqn7cx-9Jw6CHDYBk6DcpCun3O3qfiPc,934
79
79
  localstack/aws/handlers/routes.py,sha256=O4NfJy3_SACxdKGOt9hcQurGmlv7blOheKR9JBbOBDI,84
80
- localstack/aws/handlers/service.py,sha256=IDeULP_CTAUcHOPELHptY0uy1KG_yF7D7pC6x1uMW7o,11646
80
+ localstack/aws/handlers/service.py,sha256=qGI0sxUXSqYZwSh7K8lzNOfiAoA-16UKJ4VDN6JHnOg,11949
81
81
  localstack/aws/handlers/service_plugin.py,sha256=9dOZIkgeF7zKM-ThhetMgVEhbgdSrutStbNcaOAKlrE,3596
82
82
  localstack/aws/handlers/tracing.py,sha256=y_BUJKjNgaRGebm88NSqni4GFCQ_ZgB2JBRnEt5V9z4,1407
83
83
  localstack/aws/handlers/validation.py,sha256=4iyHdJx3ijd49rySwMQNx2UW0XNN5fnkFQxdUO7-AQM,4386
84
84
  localstack/aws/protocol/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
85
  localstack/aws/protocol/op_router.py,sha256=2nSpL6H9seK1h_AuIZlBG1yYa_ykARIgJJrKm4Hkc0s,12039
86
- localstack/aws/protocol/parser.py,sha256=yVM8SSa2ZoaJDAMV7n-wG77xiwKDWE90dmwgqm7VpPg,70911
86
+ localstack/aws/protocol/parser.py,sha256=KHCBSpBzVhFcg5Yd4HLmtUCJbl5LhhGtelRrZt3gUaM,70764
87
87
  localstack/aws/protocol/routing.py,sha256=x9AFpMQsVHD7JadtLHR7zjfBw3AJBayITNAYiUtnlwQ,3217
88
- localstack/aws/protocol/serializer.py,sha256=UXIOyB--iQcv2s8AazaSFrvk1eAPJOcqNqiv25wT3R8,103498
89
- localstack/aws/protocol/service_router.py,sha256=nJK1s9oCPax5rBWBDry5RgLqGojRJSkQscZuNzPut_M,16418
88
+ localstack/aws/protocol/serializer.py,sha256=JTu79bp4IWZ-OX0EEgF88az0_4B51gOEx7nnqzgosq4,103316
89
+ localstack/aws/protocol/service_router.py,sha256=M5iQ8XKUaPV65DyKewlVYHYNmu4k17Zn_p6_Jdj2Bw8,20705
90
90
  localstack/aws/protocol/validate.py,sha256=j3HJAQEKS6V_arrmvlPmP2jbge3LutxwEXDNabDlDdY,5285
91
91
  localstack/aws/serving/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
92
  localstack/aws/serving/asgi.py,sha256=_6x0o8nn6d5ZmorSS6p00LyW6KldUaZw_8fJYPOFi1c,76
@@ -175,7 +175,7 @@ localstack/runtime/server/twisted.py,sha256=bDYoRvF4HRGn2eYyPJ1AMCDeQ45ks1vVwzhx
175
175
  localstack/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
176
176
  localstack/services/edge.py,sha256=Z7ZOeUZE11Z31DeYiXOtzxbxtzWWVOzOYlVlR8ld7xY,6793
177
177
  localstack/services/internal.py,sha256=V5c_VnRjUmRptCyaRpLxs43zEzH3KxOAnuIvbLH1npk,11812
178
- localstack/services/moto.py,sha256=TqMuGh_7rXgauPhLA-DKIWB1cZL1q5zcxf0yqo4WRGI,9753
178
+ localstack/services/moto.py,sha256=fz5CDqN9Xf1udFU7ycWuiSnDM_-2A4vCmMITwptS8vc,9788
179
179
  localstack/services/plugins.py,sha256=yC8ImTk-SHtadctEXsvGMpOfQ2Hc7dQqrN41peCtry8,25053
180
180
  localstack/services/providers.py,sha256=cOolOC-hT8CHbOxC8j1VYpI5RE6hQOt-S7CsH2gK6K8,13209
181
181
  localstack/services/stores.py,sha256=11eON1arTKsLAcs4Z6aPKJL3jUxMpJrZBHEy-HcNfMw,11653
@@ -192,7 +192,7 @@ localstack/services/apigateway/legacy/context.py,sha256=Srs_q3YItn9ylzrR7W64JEGm
192
192
  localstack/services/apigateway/legacy/helpers.py,sha256=zEWCHvb7EnyT5uSFjnyIvrXTMfIq3m3BgNDnfEAORsw,27595
193
193
  localstack/services/apigateway/legacy/integration.py,sha256=5kmMuAumwkpYt6uGoJB08aesT-SjecZrWYO1hlrKiPo,48705
194
194
  localstack/services/apigateway/legacy/invocations.py,sha256=6zzau8rr-ww-6Yvh7SvT7nKvQVWuD0RumYWyhNGQfj8,15393
195
- localstack/services/apigateway/legacy/provider.py,sha256=QA6rWA_PPzrOCICM-ztyb_AkHToeVgwKAqMHPzs8-v8,133474
195
+ localstack/services/apigateway/legacy/provider.py,sha256=t98XZ-FH3XMzXmbDICF8vCvl4J-k50RxH4G_WMYtb54,133517
196
196
  localstack/services/apigateway/legacy/router_asf.py,sha256=Usj-inyFvTLeDJgspQFl6Ztxcb5gT4gZHVam1XjE-BU,6096
197
197
  localstack/services/apigateway/legacy/templates.py,sha256=56fo6AoFexgXxAJL8heWLFhBeDTj5LZfSmRA3g-_9IY,15015
198
198
  localstack/services/apigateway/next_gen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -223,7 +223,7 @@ localstack/services/apigateway/next_gen/execute_api/handlers/parse.py,sha256=KOp
223
223
  localstack/services/apigateway/next_gen/execute_api/handlers/resource_router.py,sha256=HY9VLQuFvYrpXhlURtGdbLHYQ20qjrYY_O-mxHeukBU,6503
224
224
  localstack/services/apigateway/next_gen/execute_api/handlers/response_enricher.py,sha256=XNCJQ0OpfxIw_hrPhJ_UKbJuTWbrHe5ZNwbIWDATiGw,1145
225
225
  localstack/services/apigateway/next_gen/execute_api/integrations/__init__.py,sha256=-eU2l2ktfSZoLAXNjsmbsFoDKjSV885Faqr1UHBmy00,562
226
- localstack/services/apigateway/next_gen/execute_api/integrations/aws.py,sha256=QDLX-jMmIZoSw7LafKjn6fzLwkHpMQhuXy58j_VfA80,24250
226
+ localstack/services/apigateway/next_gen/execute_api/integrations/aws.py,sha256=FpCxjUZStRRYHz5t6K0-deJUcZYiBPJwDZ88MB625AE,24482
227
227
  localstack/services/apigateway/next_gen/execute_api/integrations/core.py,sha256=Kl0gzTT2LdboY5zw1aJdSLGOjZNMEUXq4wns_TgDh-A,572
228
228
  localstack/services/apigateway/next_gen/execute_api/integrations/http.py,sha256=siakDGFWvmfidpuKonJCbTAdxlNBn6I7XkZAf0i0eE0,6381
229
229
  localstack/services/apigateway/next_gen/execute_api/integrations/mock.py,sha256=rf00sXwDpRA683Zn0Z1WPgV1PpPVipEORDu2RmZ7g3Q,4238
@@ -344,7 +344,7 @@ localstack/services/cloudwatch/alarm_scheduler.py,sha256=HPzQgZvDVXIXaEkjJ39L-jB
344
344
  localstack/services/cloudwatch/cloudwatch_database_helper.py,sha256=IK_MgxG3xTkpKbBe-Buv_6wUuHEc3MGQOqMAqHoEOzk,17270
345
345
  localstack/services/cloudwatch/models.py,sha256=y3JPWSZcDofSbkr2orW9pWD1cC4meP7mQ4YbYkVfGx8,3957
346
346
  localstack/services/cloudwatch/provider.py,sha256=naHmJCEwNr_dmU3s__H1ru1S6C-OGuNn1TUd59n5W5Y,19479
347
- localstack/services/cloudwatch/provider_v2.py,sha256=Nfz5CupS6aUbuo0Qdcwr7v38t48_K1UmLiQ4YSI8_4Y,45162
347
+ localstack/services/cloudwatch/provider_v2.py,sha256=S8a4RiYqfXagu4Mo35k5k5EEbFDXKX2JsruEfCW9Fu0,45169
348
348
  localstack/services/cloudwatch/resource_providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
349
349
  localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm.py,sha256=T0P5uTDjQO3lNw5w4wcdBgzFthGDjJXUkPtHo1BP13I,5172
350
350
  localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm.schema.json,sha256=8Nam5WqGfyW85m55UVCwJF17Re4tPOIJY_m6Wq37y8k,3829
@@ -763,7 +763,7 @@ localstack/services/sqs/constants.py,sha256=9MLAOW4-hcbZlP2qYMY3giUnubHD_mgoORT0
763
763
  localstack/services/sqs/exceptions.py,sha256=aMmTD1Mex37NKndt6_hpj_d0JAZeN3eX0g7r8BlNO7M,570
764
764
  localstack/services/sqs/models.py,sha256=sGaL5lZjw1_cUcvfGjXQAj2XjelOOJH0nuTS1KDoN4g,50536
765
765
  localstack/services/sqs/provider.py,sha256=ZpJEdgdytatIRGnnok1_-xtL3nede5qZ6if3w0bdQs0,77491
766
- localstack/services/sqs/query_api.py,sha256=Gr47Xm6SbxtLN12zgwV38Ufa3yMVVBBUmgMVO-gkNsg,8646
766
+ localstack/services/sqs/query_api.py,sha256=5elf1kDdWlUuH5FJzhs8vWdiB85fziYvFsbivuN5OQQ,8655
767
767
  localstack/services/sqs/queue.py,sha256=Y5lVjrv71WTDU75VevTOKHSkfVzF1k_j1X0AOZ0-Xz4,1730
768
768
  localstack/services/sqs/utils.py,sha256=_s_SC5pI6zZwOcf5PqyMoAPbSkCMi1kOoqF-F5-MgG4,6707
769
769
  localstack/services/sqs/resource_providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1246,7 +1246,7 @@ localstack/utils/sync.py,sha256=Lx0T33Qausn4utYn9HZg4C-o4PliE_7j1HZ8vtD1vyc,3664
1246
1246
  localstack/utils/tagging.py,sha256=ayRhBEIkLxqWNzdkLtVNLU2EmAOJYTR0Kujj2FsG8T8,1439
1247
1247
  localstack/utils/testutil.py,sha256=5mfG_I6mE4p31bI0nFINeDRqc4TxoaeDwhwK5dyfgcE,21555
1248
1248
  localstack/utils/threads.py,sha256=ib2BuB-dzLY2nnr7mPUcOxHQ8hvIobTXczGzDOamfbY,5050
1249
- localstack/utils/time.py,sha256=lF8XUtMdx8Yt7qhAh3eM0JTXF10NKrlwBropb49uJnU,2015
1249
+ localstack/utils/time.py,sha256=1OCRiBPRDVP8Y6LZ4ENj5VgHImTgWTZzkxfyD5y-gno,2291
1250
1250
  localstack/utils/urls.py,sha256=s66FfBL_KJcCKOvMn-vi1PksrWFud602Os0Vzg01_XA,717
1251
1251
  localstack/utils/venv.py,sha256=ORSmZn6fWhN9jml_lsv_WE8PvOn9cIGgEMbeY6paAQo,3210
1252
1252
  localstack/utils/xml.py,sha256=mxxtDYhRFXFakP6UL61pcFWcztGPo7ZbSUaZY9LiJ2w,1449
@@ -1294,13 +1294,13 @@ localstack/utils/server/tcp_proxy.py,sha256=rR6d5jR0ozDvIlpHiqW0cfyY9a2fRGdOzyA8
1294
1294
  localstack/utils/xray/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1295
1295
  localstack/utils/xray/trace_header.py,sha256=ahXk9eonq7LpeENwlqUEPj3jDOCiVRixhntQuxNor-Q,6209
1296
1296
  localstack/utils/xray/traceid.py,sha256=GKO-R2sMMjlrH2UaLPXlQlZ6flbE7ZKb6IZMtMu_M5U,1110
1297
- localstack_core-4.8.2.dev11.data/scripts/localstack,sha256=WyL11vp5CkuP79iIR-L8XT7Cj8nvmxX7XRAgxhbmXNE,529
1298
- localstack_core-4.8.2.dev11.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1299
- localstack_core-4.8.2.dev11.data/scripts/localstack.bat,sha256=tlzZTXtveHkMX_s_fa7VDfvdNdS8iVpEz2ER3uk9B_c,29
1300
- localstack_core-4.8.2.dev11.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1301
- localstack_core-4.8.2.dev11.dist-info/METADATA,sha256=cG4A0DWxLYpiOr2cS4YONX9fKE5uP-5Kk_vM_LX2bDk,5538
1302
- localstack_core-4.8.2.dev11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1303
- localstack_core-4.8.2.dev11.dist-info/entry_points.txt,sha256=5IoyjalZoY-PWY5Lk_AeEjEEQ-rKQJhijLe697GVlnM,20953
1304
- localstack_core-4.8.2.dev11.dist-info/plux.json,sha256=PtS9NhgIg-mLDM2KstcbSWWNrLKzKlh440QP6x6PHuQ,21181
1305
- localstack_core-4.8.2.dev11.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1306
- localstack_core-4.8.2.dev11.dist-info/RECORD,,
1297
+ localstack_core-4.8.2.dev13.data/scripts/localstack,sha256=WyL11vp5CkuP79iIR-L8XT7Cj8nvmxX7XRAgxhbmXNE,529
1298
+ localstack_core-4.8.2.dev13.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1299
+ localstack_core-4.8.2.dev13.data/scripts/localstack.bat,sha256=tlzZTXtveHkMX_s_fa7VDfvdNdS8iVpEz2ER3uk9B_c,29
1300
+ localstack_core-4.8.2.dev13.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1301
+ localstack_core-4.8.2.dev13.dist-info/METADATA,sha256=4ZWWnAfEMyZW42AdHcEczdKasaHby3mRqU5LAz15rh4,5538
1302
+ localstack_core-4.8.2.dev13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1303
+ localstack_core-4.8.2.dev13.dist-info/entry_points.txt,sha256=5IoyjalZoY-PWY5Lk_AeEjEEQ-rKQJhijLe697GVlnM,20953
1304
+ localstack_core-4.8.2.dev13.dist-info/plux.json,sha256=g99YRj7xfS74i3_iQCuS_nR4J4pJd3V9pnH-hzaO0Cc,21181
1305
+ localstack_core-4.8.2.dev13.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1306
+ localstack_core-4.8.2.dev13.dist-info/RECORD,,
@@ -0,0 +1 @@
1
+ {"localstack.cloudformation.resource_providers": ["AWS::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin", "AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "AWS::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::CertificateManager::Certificate=localstack.services.certificatemanager.resource_providers.aws_certificatemanager_certificate_plugin:CertificateManagerCertificateProviderPlugin", "AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::SNS::Topic=localstack.services.sns.resource_providers.aws_sns_topic_plugin:SNSTopicProviderPlugin", "AWS::ApiGateway::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "AWS::Lambda::EventInvokeConfig=localstack.services.lambda_.resource_providers.aws_lambda_eventinvokeconfig_plugin:LambdaEventInvokeConfigProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "AWS::Lambda::LayerVersionPermission=localstack.services.lambda_.resource_providers.aws_lambda_layerversionpermission_plugin:LambdaLayerVersionPermissionProviderPlugin", "AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::ApiGateway::ApiKey=localstack.services.apigateway.resource_providers.aws_apigateway_apikey_plugin:ApiGatewayApiKeyProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::Lambda::Version=localstack.services.lambda_.resource_providers.aws_lambda_version_plugin:LambdaVersionProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "AWS::Lambda::Function=localstack.services.lambda_.resource_providers.aws_lambda_function_plugin:LambdaFunctionProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "AWS::SNS::Subscription=localstack.services.sns.resource_providers.aws_sns_subscription_plugin:SNSSubscriptionProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "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::ApiGateway::Method=localstack.services.apigateway.resource_providers.aws_apigateway_method_plugin:ApiGatewayMethodProviderPlugin", "AWS::ApiGateway::Deployment=localstack.services.apigateway.resource_providers.aws_apigateway_deployment_plugin:ApiGatewayDeploymentProviderPlugin", "AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::Lambda::EventSourceMapping=localstack.services.lambda_.resource_providers.aws_lambda_eventsourcemapping_plugin:LambdaEventSourceMappingProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::EC2::Subnet=localstack.services.ec2.resource_providers.aws_ec2_subnet_plugin:EC2SubnetProviderPlugin", "AWS::Kinesis::StreamConsumer=localstack.services.kinesis.resource_providers.aws_kinesis_streamconsumer_plugin:KinesisStreamConsumerProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin", "AWS::IAM::Policy=localstack.services.iam.resource_providers.aws_iam_policy_plugin:IAMPolicyProviderPlugin", "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::EC2::RouteTable=localstack.services.ec2.resource_providers.aws_ec2_routetable_plugin:EC2RouteTableProviderPlugin", "AWS::EC2::PrefixList=localstack.services.ec2.resource_providers.aws_ec2_prefixlist_plugin:EC2PrefixListProviderPlugin", "AWS::DynamoDB::Table=localstack.services.dynamodb.resource_providers.aws_dynamodb_table_plugin:DynamoDBTableProviderPlugin", "AWS::IAM::ManagedPolicy=localstack.services.iam.resource_providers.aws_iam_managedpolicy_plugin:IAMManagedPolicyProviderPlugin", "AWS::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "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::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::Events::EventBus=localstack.services.events.resource_providers.aws_events_eventbus_plugin:EventsEventBusProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::ApiGateway::DomainName=localstack.services.apigateway.resource_providers.aws_apigateway_domainname_plugin:ApiGatewayDomainNameProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin", "AWS::EC2::NetworkAcl=localstack.services.ec2.resource_providers.aws_ec2_networkacl_plugin:EC2NetworkAclProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "AWS::SecretsManager::SecretTargetAttachment=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment_plugin:SecretsManagerSecretTargetAttachmentProviderPlugin", "AWS::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::Route53::RecordSet=localstack.services.route53.resource_providers.aws_route53_recordset_plugin:Route53RecordSetProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::SNS::TopicPolicy=localstack.services.sns.resource_providers.aws_sns_topicpolicy_plugin:SNSTopicPolicyProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::SQS::QueuePolicy=localstack.services.sqs.resource_providers.aws_sqs_queuepolicy_plugin:SQSQueuePolicyProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin", "AWS::Lambda::Permission=localstack.services.lambda_.resource_providers.aws_lambda_permission_plugin:LambdaPermissionProviderPlugin", "AWS::DynamoDB::GlobalTable=localstack.services.dynamodb.resource_providers.aws_dynamodb_globaltable_plugin:DynamoDBGlobalTableProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::EC2::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::EC2::Route=localstack.services.ec2.resource_providers.aws_ec2_route_plugin:EC2RouteProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::IAM::InstanceProfile=localstack.services.iam.resource_providers.aws_iam_instanceprofile_plugin:IAMInstanceProfileProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin", "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::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::ApiGateway::RestApi=localstack.services.apigateway.resource_providers.aws_apigateway_restapi_plugin:ApiGatewayRestApiProviderPlugin", "AWS::IAM::ServerCertificate=localstack.services.iam.resource_providers.aws_iam_servercertificate_plugin:IAMServerCertificateProviderPlugin", "AWS::ApiGateway::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::Events::ApiDestination=localstack.services.events.resource_providers.aws_events_apidestination_plugin:EventsApiDestinationProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::KMS::Key=localstack.services.kms.resource_providers.aws_kms_key_plugin:KMSKeyProviderPlugin", "AWS::KMS::Alias=localstack.services.kms.resource_providers.aws_kms_alias_plugin:KMSAliasProviderPlugin", "AWS::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::Route53::HealthCheck=localstack.services.route53.resource_providers.aws_route53_healthcheck_plugin:Route53HealthCheckProviderPlugin"], "localstack.hooks.on_infra_start": ["apply_aws_runtime_patches=localstack.aws.patches:apply_aws_runtime_patches", "eager_load_services=localstack.services.plugins:eager_load_services", "register_swagger_endpoints=localstack.http.resources.swagger.plugins:register_swagger_endpoints", "_publish_config_as_analytics_event=localstack.runtime.analytics:_publish_config_as_analytics_event", "_publish_container_info=localstack.runtime.analytics:_publish_container_info", "init_response_mutation_handler=localstack.aws.handlers.response:init_response_mutation_handler", "delete_cached_certificate=localstack.plugins:delete_cached_certificate", "deprecation_warnings=localstack.plugins:deprecation_warnings", "apply_runtime_patches=localstack.runtime.patches:apply_runtime_patches", "_run_init_scripts_on_start=localstack.runtime.init:_run_init_scripts_on_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", "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", "conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger"], "localstack.hooks.on_infra_shutdown": ["publish_metrics=localstack.utils.analytics.metrics.publisher:publish_metrics", "_run_init_scripts_on_shutdown=localstack.runtime.init:_run_init_scripts_on_shutdown", "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", "stop_server=localstack.dns.plugins:stop_server"], "localstack.packages": ["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", "opensearch/community=localstack.services.opensearch.plugins:opensearch_package", "kinesis-mock/community=localstack.services.kinesis.plugins:kinesismock_package", "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", "jpype-jsonata/community=localstack.services.stepfunctions.plugins:jpype_jsonata_package"], "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.hooks.on_infra_ready": ["publish_provider_assignment=localstack.utils.analytics.service_providers:publish_provider_assignment", "_run_init_scripts_on_ready=localstack.runtime.init:_run_init_scripts_on_ready"], "localstack.openapi.spec": ["localstack=localstack.plugins:CoreOASPlugin"], "localstack.utils.catalog": ["aws-catalog-remote-state=localstack.utils.catalog.catalog:AwsCatalogRemoteStatePlugin", "aws-catalog-runtime-only=localstack.utils.catalog.catalog:AwsCatalogRuntimePlugin"], "localstack.runtime.components": ["aws=localstack.aws.components:AwsComponents"], "localstack.aws.provider": ["acm:default=localstack.services.providers:acm", "apigateway:default=localstack.services.providers:apigateway", "apigateway:legacy=localstack.services.providers:apigateway_legacy", "apigateway:next_gen=localstack.services.providers:apigateway_next_gen", "config:default=localstack.services.providers:awsconfig", "cloudformation:engine-legacy=localstack.services.providers:cloudformation", "cloudformation:default=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", "sns:v2=localstack.services.providers:sns_v2", "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.init.runner": ["py=localstack.runtime.init:PythonScriptRunner", "sh=localstack.runtime.init:ShellScriptRunner"], "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"]}
@@ -1 +0,0 @@
1
- {"localstack.hooks.on_infra_start": ["conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger", "register_custom_endpoints=localstack.services.lambda_.plugins:register_custom_endpoints", "validate_configuration=localstack.services.lambda_.plugins:validate_configuration", "eager_load_services=localstack.services.plugins:eager_load_services", "init_response_mutation_handler=localstack.aws.handlers.response:init_response_mutation_handler", "apply_aws_runtime_patches=localstack.aws.patches:apply_aws_runtime_patches", "setup_dns_configuration_on_host=localstack.dns.plugins:setup_dns_configuration_on_host", "start_dns_server=localstack.dns.plugins:start_dns_server", "_publish_config_as_analytics_event=localstack.runtime.analytics:_publish_config_as_analytics_event", "_publish_container_info=localstack.runtime.analytics:_publish_container_info", "register_cloudformation_deploy_ui=localstack.services.cloudformation.plugins:register_cloudformation_deploy_ui", "apply_runtime_patches=localstack.runtime.patches:apply_runtime_patches", "_patch_botocore_endpoint_in_memory=localstack.aws.client:_patch_botocore_endpoint_in_memory", "_patch_botocore_json_parser=localstack.aws.client:_patch_botocore_json_parser", "_patch_cbor2=localstack.aws.client:_patch_cbor2", "register_swagger_endpoints=localstack.http.resources.swagger.plugins:register_swagger_endpoints", "_run_init_scripts_on_start=localstack.runtime.init:_run_init_scripts_on_start", "delete_cached_certificate=localstack.plugins:delete_cached_certificate", "deprecation_warnings=localstack.plugins:deprecation_warnings"], "localstack.packages": ["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", "opensearch/community=localstack.services.opensearch.plugins:opensearch_package", "ffmpeg/community=localstack.packages.plugins:ffmpeg_package", "java/community=localstack.packages.plugins:java_package", "kinesis-mock/community=localstack.services.kinesis.plugins:kinesismock_package", "vosk/community=localstack.services.transcribe.plugins:vosk_package", "dynamodb-local/community=localstack.services.dynamodb.plugins:dynamodb_local_package", "jpype-jsonata/community=localstack.services.stepfunctions.plugins:jpype_jsonata_package"], "localstack.hooks.on_infra_shutdown": ["remove_custom_endpoints=localstack.services.lambda_.plugins:remove_custom_endpoints", "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", "_run_init_scripts_on_shutdown=localstack.runtime.init:_run_init_scripts_on_shutdown"], "localstack.cloudformation.resource_providers": ["AWS::SNS::Topic=localstack.services.sns.resource_providers.aws_sns_topic_plugin:SNSTopicProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::EC2::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::EC2::TransitGateway=localstack.services.ec2.resource_providers.aws_ec2_transitgateway_plugin:EC2TransitGatewayProviderPlugin", "AWS::SNS::Subscription=localstack.services.sns.resource_providers.aws_sns_subscription_plugin:SNSSubscriptionProviderPlugin", "AWS::ApiGateway::RestApi=localstack.services.apigateway.resource_providers.aws_apigateway_restapi_plugin:ApiGatewayRestApiProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "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::Events::EventBus=localstack.services.events.resource_providers.aws_events_eventbus_plugin:EventsEventBusProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::Route53::RecordSet=localstack.services.route53.resource_providers.aws_route53_recordset_plugin:Route53RecordSetProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::Lambda::Version=localstack.services.lambda_.resource_providers.aws_lambda_version_plugin:LambdaVersionProviderPlugin", "AWS::ApiGateway::ApiKey=localstack.services.apigateway.resource_providers.aws_apigateway_apikey_plugin:ApiGatewayApiKeyProviderPlugin", "AWS::Lambda::EventSourceMapping=localstack.services.lambda_.resource_providers.aws_lambda_eventsourcemapping_plugin:LambdaEventSourceMappingProviderPlugin", "AWS::CertificateManager::Certificate=localstack.services.certificatemanager.resource_providers.aws_certificatemanager_certificate_plugin:CertificateManagerCertificateProviderPlugin", "AWS::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::Lambda::EventInvokeConfig=localstack.services.lambda_.resource_providers.aws_lambda_eventinvokeconfig_plugin:LambdaEventInvokeConfigProviderPlugin", "AWS::EC2::Subnet=localstack.services.ec2.resource_providers.aws_ec2_subnet_plugin:EC2SubnetProviderPlugin", "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::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "AWS::CloudWatch::CompositeAlarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_compositealarm_plugin:CloudWatchCompositeAlarmProviderPlugin", "AWS::ApiGateway::Method=localstack.services.apigateway.resource_providers.aws_apigateway_method_plugin:ApiGatewayMethodProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::ApiGateway::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "AWS::ApiGateway::Deployment=localstack.services.apigateway.resource_providers.aws_apigateway_deployment_plugin:ApiGatewayDeploymentProviderPlugin", "AWS::Lambda::LayerVersionPermission=localstack.services.lambda_.resource_providers.aws_lambda_layerversionpermission_plugin:LambdaLayerVersionPermissionProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin", "AWS::EC2::Route=localstack.services.ec2.resource_providers.aws_ec2_route_plugin:EC2RouteProviderPlugin", "AWS::SQS::QueuePolicy=localstack.services.sqs.resource_providers.aws_sqs_queuepolicy_plugin:SQSQueuePolicyProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::Events::EventBusPolicy=localstack.services.events.resource_providers.aws_events_eventbuspolicy_plugin:EventsEventBusPolicyProviderPlugin", "AWS::EC2::VPC=localstack.services.ec2.resource_providers.aws_ec2_vpc_plugin:EC2VPCProviderPlugin", "AWS::IAM::Role=localstack.services.iam.resource_providers.aws_iam_role_plugin:IAMRoleProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::DynamoDB::Table=localstack.services.dynamodb.resource_providers.aws_dynamodb_table_plugin:DynamoDBTableProviderPlugin", "AWS::IAM::Policy=localstack.services.iam.resource_providers.aws_iam_policy_plugin:IAMPolicyProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::KMS::Key=localstack.services.kms.resource_providers.aws_kms_key_plugin:KMSKeyProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::Lambda::Permission=localstack.services.lambda_.resource_providers.aws_lambda_permission_plugin:LambdaPermissionProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "AWS::KMS::Alias=localstack.services.kms.resource_providers.aws_kms_alias_plugin:KMSAliasProviderPlugin", "AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin", "AWS::Events::ApiDestination=localstack.services.events.resource_providers.aws_events_apidestination_plugin:EventsApiDestinationProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::OpenSearchService::Domain=localstack.services.opensearch.resource_providers.aws_opensearchservice_domain_plugin:OpenSearchServiceDomainProviderPlugin", "AWS::Kinesis::StreamConsumer=localstack.services.kinesis.resource_providers.aws_kinesis_streamconsumer_plugin:KinesisStreamConsumerProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::EC2::VPCGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_vpcgatewayattachment_plugin:EC2VPCGatewayAttachmentProviderPlugin", "AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::IAM::InstanceProfile=localstack.services.iam.resource_providers.aws_iam_instanceprofile_plugin:IAMInstanceProfileProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::SNS::TopicPolicy=localstack.services.sns.resource_providers.aws_sns_topicpolicy_plugin:SNSTopicPolicyProviderPlugin", "AWS::ApiGateway::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::IAM::ServerCertificate=localstack.services.iam.resource_providers.aws_iam_servercertificate_plugin:IAMServerCertificateProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin", "AWS::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin", "AWS::EC2::NetworkAcl=localstack.services.ec2.resource_providers.aws_ec2_networkacl_plugin:EC2NetworkAclProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::SecretsManager::SecretTargetAttachment=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment_plugin:SecretsManagerSecretTargetAttachmentProviderPlugin", "AWS::Lambda::Alias=localstack.services.lambda_.resource_providers.lambda_alias_plugin:LambdaAliasProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "AWS::Route53::HealthCheck=localstack.services.route53.resource_providers.aws_route53_healthcheck_plugin:Route53HealthCheckProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::ApiGateway::DomainName=localstack.services.apigateway.resource_providers.aws_apigateway_domainname_plugin:ApiGatewayDomainNameProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::DynamoDB::GlobalTable=localstack.services.dynamodb.resource_providers.aws_dynamodb_globaltable_plugin:DynamoDBGlobalTableProviderPlugin"], "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.utils.catalog": ["aws-catalog-remote-state=localstack.utils.catalog.catalog:AwsCatalogRemoteStatePlugin", "aws-catalog-runtime-only=localstack.utils.catalog.catalog:AwsCatalogRuntimePlugin"], "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:engine-legacy=localstack.services.providers:cloudformation", "cloudformation:default=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", "sns:v2=localstack.services.providers:sns_v2", "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"], "localstack.lambda.runtime_executor": ["docker=localstack.services.lambda_.invocation.plugins:DockerRuntimeExecutorPlugin"], "localstack.runtime.server": ["hypercorn=localstack.runtime.server.plugins:HypercornRuntimeServerPlugin", "twisted=localstack.runtime.server.plugins:TwistedRuntimeServerPlugin"], "localstack.hooks.on_infra_ready": ["publish_provider_assignment=localstack.utils.analytics.service_providers:publish_provider_assignment", "_run_init_scripts_on_ready=localstack.runtime.init:_run_init_scripts_on_ready"], "localstack.init.runner": ["py=localstack.runtime.init:PythonScriptRunner", "sh=localstack.runtime.init:ShellScriptRunner"], "localstack.openapi.spec": ["localstack=localstack.plugins:CoreOASPlugin"]}