localstack-core 4.8.2.dev39__py3-none-any.whl → 4.8.2.dev41__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 (20) hide show
  1. localstack/services/apigateway/next_gen/execute_api/integrations/http.py +3 -3
  2. localstack/services/apigateway/next_gen/execute_api/test_invoke.py +50 -6
  3. localstack/services/apigateway/next_gen/provider.py +5 -0
  4. localstack/services/lambda_/invocation/internal_sqs_queue.py +5 -9
  5. localstack/services/sqs/developer_api.py +205 -0
  6. localstack/services/sqs/models.py +40 -0
  7. localstack/services/sqs/provider.py +8 -318
  8. localstack/services/sqs/utils.py +121 -2
  9. localstack/version.py +2 -2
  10. {localstack_core-4.8.2.dev39.dist-info → localstack_core-4.8.2.dev41.dist-info}/METADATA +1 -1
  11. {localstack_core-4.8.2.dev39.dist-info → localstack_core-4.8.2.dev41.dist-info}/RECORD +19 -18
  12. localstack_core-4.8.2.dev41.dist-info/plux.json +1 -0
  13. localstack_core-4.8.2.dev39.dist-info/plux.json +0 -1
  14. {localstack_core-4.8.2.dev39.data → localstack_core-4.8.2.dev41.data}/scripts/localstack +0 -0
  15. {localstack_core-4.8.2.dev39.data → localstack_core-4.8.2.dev41.data}/scripts/localstack-supervisor +0 -0
  16. {localstack_core-4.8.2.dev39.data → localstack_core-4.8.2.dev41.data}/scripts/localstack.bat +0 -0
  17. {localstack_core-4.8.2.dev39.dist-info → localstack_core-4.8.2.dev41.dist-info}/WHEEL +0 -0
  18. {localstack_core-4.8.2.dev39.dist-info → localstack_core-4.8.2.dev41.dist-info}/entry_points.txt +0 -0
  19. {localstack_core-4.8.2.dev39.dist-info → localstack_core-4.8.2.dev41.dist-info}/licenses/LICENSE.txt +0 -0
  20. {localstack_core-4.8.2.dev39.dist-info → localstack_core-4.8.2.dev41.dist-info}/top_level.txt +0 -0
@@ -8,7 +8,7 @@ from werkzeug.datastructures import Headers
8
8
  from localstack.aws.api.apigateway import Integration
9
9
 
10
10
  from ..context import EndpointResponse, IntegrationRequest, RestApiInvocationContext
11
- from ..gateway_response import ApiConfigurationError, IntegrationFailureError
11
+ from ..gateway_response import ApiConfigurationError, IntegrationFailureError, InternalServerError
12
12
  from ..header_utils import build_multi_value_headers
13
13
  from .core import RestApiIntegration
14
14
 
@@ -72,7 +72,7 @@ class RestApiHttpIntegration(BaseRestApiHttpIntegration):
72
72
  except (requests.exceptions.InvalidURL, requests.exceptions.InvalidSchema) as e:
73
73
  LOG.warning("Execution failed due to configuration error: Invalid endpoint address")
74
74
  LOG.debug("The URI specified for the HTTP/HTTP_PROXY integration is invalid: %s", uri)
75
- raise ApiConfigurationError("Internal server error") from e
75
+ raise InternalServerError("Internal server error") from e
76
76
 
77
77
  except (requests.exceptions.Timeout, requests.exceptions.SSLError) as e:
78
78
  # TODO make the exception catching more fine grained
@@ -127,7 +127,7 @@ class RestApiHttpProxyIntegration(BaseRestApiHttpIntegration):
127
127
  except (requests.exceptions.InvalidURL, requests.exceptions.InvalidSchema) as e:
128
128
  LOG.warning("Execution failed due to configuration error: Invalid endpoint address")
129
129
  LOG.debug("The URI specified for the HTTP/HTTP_PROXY integration is invalid: %s", uri)
130
- raise ApiConfigurationError("Internal server error") from e
130
+ raise InternalServerError("Internal server error") from e
131
131
 
132
132
  except (requests.exceptions.Timeout, requests.exceptions.SSLError):
133
133
  # TODO make the exception catching more fine grained
@@ -62,6 +62,17 @@ TEST_INVOKE_TEMPLATE_MOCK = """Execution log for request {request_id}
62
62
  {formatted_date} : Method completed with status: {method_response_status}
63
63
  """
64
64
 
65
+ TEST_INVOKE_TEMPLATE_FAILED = """Execution log for request {request_id}
66
+ {formatted_date} : Starting execution for request: {request_id}
67
+ {formatted_date} : HTTP Method: {request_method}, Resource Path: {resource_path}
68
+ {formatted_date} : Method request path: {method_request_path_parameters}
69
+ {formatted_date} : Method request query string: {method_request_query_string}
70
+ {formatted_date} : Method request headers: {method_request_headers}
71
+ {formatted_date} : Method request body before transformations: {method_request_body}
72
+ {formatted_date} : Execution failed due to {error_type}: {error_message}
73
+ {formatted_date} : Method completed with status: {method_response_status}
74
+ """
75
+
65
76
 
66
77
  def _dump_headers(headers: Headers) -> str:
67
78
  if not headers:
@@ -80,9 +91,9 @@ def log_template(invocation_context: RestApiInvocationContext, response_headers:
80
91
  formatted_date = datetime.datetime.now(tz=datetime.UTC).strftime("%a %b %d %H:%M:%S %Z %Y")
81
92
  request = invocation_context.invocation_request
82
93
  context_var = invocation_context.context_variables
83
- integration_req = invocation_context.integration_request
84
- endpoint_resp = invocation_context.endpoint_response
85
- method_resp = invocation_context.invocation_response
94
+ integration_req = invocation_context.integration_request or {}
95
+ endpoint_resp = invocation_context.endpoint_response or {}
96
+ method_resp = invocation_context.invocation_response or {}
86
97
  # TODO: if endpoint_uri is an ARN, it means it's an AWS_PROXY integration
87
98
  # this should be transformed to the true URL of a lambda invoke call
88
99
  endpoint_uri = integration_req.get("uri", "")
@@ -116,7 +127,7 @@ def log_mock_template(
116
127
  formatted_date = datetime.datetime.now(tz=datetime.UTC).strftime("%a %b %d %H:%M:%S %Z %Y")
117
128
  request = invocation_context.invocation_request
118
129
  context_var = invocation_context.context_variables
119
- method_resp = invocation_context.invocation_response
130
+ method_resp = invocation_context.invocation_response or {}
120
131
 
121
132
  return TEST_INVOKE_TEMPLATE_MOCK.format(
122
133
  formatted_date=formatted_date,
@@ -133,6 +144,29 @@ def log_mock_template(
133
144
  )
134
145
 
135
146
 
147
+ def log_failed_template(
148
+ invocation_context: RestApiInvocationContext, response_status_code: int
149
+ ) -> str:
150
+ formatted_date = datetime.datetime.now(tz=datetime.UTC).strftime("%a %b %d %H:%M:%S %Z %Y")
151
+ request = invocation_context.invocation_request
152
+ context_var = invocation_context.context_variables
153
+
154
+ return TEST_INVOKE_TEMPLATE_FAILED.format(
155
+ formatted_date=formatted_date,
156
+ request_id=context_var["requestId"],
157
+ resource_path=request["path"],
158
+ request_method=request["http_method"],
159
+ method_request_path_parameters=dict_to_string(request["path_parameters"]),
160
+ method_request_query_string=dict_to_string(request["query_string_parameters"]),
161
+ method_request_headers=_dump_headers(request.get("headers")),
162
+ method_request_body=to_str(request.get("body", "")),
163
+ method_response_status=response_status_code,
164
+ # TODO: fix the error message
165
+ error_type="",
166
+ error_message="",
167
+ )
168
+
169
+
136
170
  def create_test_chain() -> HandlerChain[RestApiInvocationContext]:
137
171
  return HandlerChain(
138
172
  request_handlers=[
@@ -216,7 +250,9 @@ def create_test_invocation_context(
216
250
  responseOverride=ContextVarsResponseOverride(header={}, status=0),
217
251
  )
218
252
  invocation_context.trace_id = parse_handler.populate_trace_id({})
219
- resource_method = resource["resourceMethods"][http_method]
253
+ resource_method = (
254
+ resource["resourceMethods"].get(http_method) or resource["resourceMethods"]["ANY"]
255
+ )
220
256
  invocation_context.resource = resource
221
257
  invocation_context.resource_method = resource_method
222
258
  invocation_context.integration = resource_method["methodIntegration"]
@@ -256,7 +292,15 @@ def run_test_invocation(
256
292
  # AWS does not return the Content-Length for TestInvokeMethod
257
293
  response_headers.remove("Content-Length")
258
294
 
259
- if is_mock_integration:
295
+ if not invocation_context.invocation_response:
296
+ # TODO: this is an heuristic to guess if we encounter an exception in the call
297
+ # in the future, we should attach the exception to the context so we could act on it and properly
298
+ # log as we go through the invocation, so that if we have an error we stop logging at the right moment
299
+ for header in ("Content-Type", "X-Amzn-Trace-Id"):
300
+ response_headers.remove(header)
301
+ log = log_failed_template(invocation_context, test_response.status_code)
302
+
303
+ elif is_mock_integration:
260
304
  # TODO: revisit how we're building the logs
261
305
  log = log_mock_template(invocation_context, response_headers)
262
306
  else:
@@ -429,6 +429,11 @@ class ApigatewayNextGenProvider(ApigatewayProvider):
429
429
  if not resource:
430
430
  raise NotFoundException("Invalid Resource identifier specified")
431
431
 
432
+ resource_methods = resource.resource_methods
433
+
434
+ if request["httpMethod"] not in resource_methods and "ANY" not in resource_methods:
435
+ raise NotFoundException("Invalid Method identifier specified")
436
+
432
437
  # test httpMethod
433
438
 
434
439
  rest_api_container = get_rest_api_container(context, rest_api_id=rest_api_id)
@@ -19,13 +19,9 @@ from localstack.aws.api.sqs import (
19
19
  String,
20
20
  TagMap,
21
21
  )
22
- from localstack.services.sqs.models import SqsQueue, StandardQueue
23
- from localstack.services.sqs.provider import (
24
- QueueUpdateWorker,
25
- _create_message_attribute_hash,
26
- to_sqs_api_message,
27
- )
28
- from localstack.services.sqs.utils import generate_message_id
22
+ from localstack.services.sqs.models import SqsQueue, StandardQueue, to_sqs_api_message
23
+ from localstack.services.sqs.provider import QueueUpdateWorker
24
+ from localstack.services.sqs.utils import create_message_attribute_hash, generate_message_id
29
25
  from localstack.utils.objects import singleton_factory
30
26
  from localstack.utils.strings import md5
31
27
  from localstack.utils.time import now
@@ -189,7 +185,7 @@ class FakeSqsClient:
189
185
  MD5OfBody=md5(MessageBody),
190
186
  Body=MessageBody,
191
187
  Attributes=self._create_message_attributes(MessageSystemAttributes),
192
- MD5OfMessageAttributes=_create_message_attribute_hash(MessageAttributes),
188
+ MD5OfMessageAttributes=create_message_attribute_hash(MessageAttributes),
193
189
  MessageAttributes=MessageAttributes,
194
190
  )
195
191
  queue_item = queue.put(
@@ -204,7 +200,7 @@ class FakeSqsClient:
204
200
  "MD5OfMessageBody": message["MD5OfBody"],
205
201
  "MD5OfMessageAttributes": message.get("MD5OfMessageAttributes"),
206
202
  "SequenceNumber": queue_item.sequence_number,
207
- "MD5OfMessageSystemAttributes": _create_message_attribute_hash(MessageSystemAttributes),
203
+ "MD5OfMessageSystemAttributes": create_message_attribute_hash(MessageSystemAttributes),
208
204
  }
209
205
 
210
206
 
@@ -0,0 +1,205 @@
1
+ import logging
2
+ from typing import Literal
3
+
4
+ from werkzeug import Request as WerkzeugRequest
5
+
6
+ from localstack.aws.api import CommonServiceException, ServiceException
7
+ from localstack.aws.api.sqs import (
8
+ Message,
9
+ QueueAttributeName,
10
+ QueueDoesNotExist,
11
+ ReceiveMessageResult,
12
+ )
13
+ from localstack.aws.protocol.parser import create_parser
14
+ from localstack.aws.protocol.serializer import aws_response_serializer
15
+ from localstack.aws.spec import load_service
16
+ from localstack.http import Request, route
17
+ from localstack.services.sqs.models import (
18
+ FifoQueue,
19
+ SqsMessage,
20
+ SqsQueue,
21
+ StandardQueue,
22
+ sqs_stores,
23
+ to_sqs_api_message,
24
+ )
25
+ from localstack.services.sqs.utils import (
26
+ parse_queue_url,
27
+ )
28
+ from localstack.utils.aws.request_context import extract_region_from_headers
29
+
30
+ LOG = logging.getLogger(__name__)
31
+
32
+
33
+ class InvalidAddress(ServiceException):
34
+ code = "InvalidAddress"
35
+ message = "The address https://queue.amazonaws.com/ is not valid for this endpoint."
36
+ sender_fault = True
37
+ status_code = 404
38
+
39
+
40
+ def get_sqs_protocol(request: Request) -> Literal["query", "json"]:
41
+ content_type = request.headers.get("Content-Type")
42
+ return "json" if content_type == "application/x-amz-json-1.0" else "query"
43
+
44
+
45
+ def sqs_auto_protocol_aws_response_serializer(service_name: str, operation: str):
46
+ def _decorate(fn):
47
+ def _proxy(*args, **kwargs):
48
+ # extract request from function invocation (decorator can be used for methods as well as for functions).
49
+ if len(args) > 0 and isinstance(args[0], WerkzeugRequest):
50
+ # function
51
+ request = args[0]
52
+ elif len(args) > 1 and isinstance(args[1], WerkzeugRequest):
53
+ # method (arg[0] == self)
54
+ request = args[1]
55
+ elif "request" in kwargs:
56
+ request = kwargs["request"]
57
+ else:
58
+ raise ValueError(f"could not find Request in signature of function {fn}")
59
+
60
+ protocol = get_sqs_protocol(request)
61
+ return aws_response_serializer(service_name, operation, protocol)(fn)(*args, **kwargs)
62
+
63
+ return _proxy
64
+
65
+ return _decorate
66
+
67
+
68
+ class SqsDeveloperApi:
69
+ """
70
+ A set of SQS developer tool endpoints:
71
+
72
+ - ``/_aws/sqs/messages``: list SQS messages without side effects, compatible with ``ReceiveMessage``.
73
+ """
74
+
75
+ def __init__(self, stores=None):
76
+ self.stores = stores or sqs_stores
77
+
78
+ @route("/_aws/sqs/messages", methods=["GET", "POST"])
79
+ @sqs_auto_protocol_aws_response_serializer("sqs", "ReceiveMessage")
80
+ def list_messages(self, request: Request) -> ReceiveMessageResult:
81
+ """
82
+ This endpoint expects a ``QueueUrl`` request parameter (either as query arg or form parameter), similar to
83
+ the ``ReceiveMessage`` operation. It will parse the Queue URL generated by one of the SQS endpoint strategies.
84
+ """
85
+
86
+ if "x-amz-" in request.mimetype or "x-www-form-urlencoded" in request.mimetype:
87
+ # only parse the request using a parser if it comes from an AWS client
88
+ protocol = get_sqs_protocol(request)
89
+ operation, service_request = create_parser(
90
+ load_service("sqs", protocol=protocol)
91
+ ).parse(request)
92
+ if operation.name != "ReceiveMessage":
93
+ raise CommonServiceException(
94
+ "InvalidRequest", "This endpoint only accepts ReceiveMessage calls"
95
+ )
96
+ else:
97
+ service_request = dict(request.values)
98
+
99
+ if not service_request.get("QueueUrl"):
100
+ raise QueueDoesNotExist()
101
+
102
+ try:
103
+ account_id, region, queue_name = parse_queue_url(service_request.get("QueueUrl"))
104
+ except ValueError:
105
+ LOG.error(
106
+ "Error while parsing Queue URL from request values: %s",
107
+ service_request.get,
108
+ exc_info=LOG.isEnabledFor(logging.DEBUG),
109
+ )
110
+ raise InvalidAddress()
111
+
112
+ if not region:
113
+ region = extract_region_from_headers(request.headers)
114
+
115
+ return self._get_and_serialize_messages(request, region, account_id, queue_name)
116
+
117
+ @route("/_aws/sqs/messages/<region>/<account_id>/<queue_name>")
118
+ @sqs_auto_protocol_aws_response_serializer("sqs", "ReceiveMessage")
119
+ def list_messages_for_queue_url(
120
+ self, request: Request, region: str, account_id: str, queue_name: str
121
+ ) -> ReceiveMessageResult:
122
+ """
123
+ This endpoint extracts the region, account_id, and queue_name directly from the URL rather than requiring the
124
+ QueueUrl as parameter.
125
+ """
126
+ return self._get_and_serialize_messages(request, region, account_id, queue_name)
127
+
128
+ def _get_and_serialize_messages(
129
+ self,
130
+ request: Request,
131
+ region: str,
132
+ account_id: str,
133
+ queue_name: str,
134
+ ) -> ReceiveMessageResult:
135
+ show_invisible = request.values.get("ShowInvisible", "").lower() in ["true", "1"]
136
+ show_delayed = request.values.get("ShowDelayed", "").lower() in ["true", "1"]
137
+
138
+ try:
139
+ store = self.stores[account_id][region]
140
+ queue = store.queues[queue_name]
141
+ except KeyError:
142
+ LOG.info(
143
+ "no queue named %s in region %s and account %s", queue_name, region, account_id
144
+ )
145
+ raise QueueDoesNotExist()
146
+
147
+ messages = self._collect_messages(
148
+ queue, show_invisible=show_invisible, show_delayed=show_delayed
149
+ )
150
+
151
+ return ReceiveMessageResult(Messages=messages)
152
+
153
+ def _collect_messages(
154
+ self, queue: SqsQueue, show_invisible: bool = False, show_delayed: bool = False
155
+ ) -> list[Message]:
156
+ """
157
+ Retrieves from a given SqsQueue all visible messages without causing any side effects (not setting any
158
+ receive timestamps, receive counts, or visibility state).
159
+
160
+ :param queue: the queue
161
+ :param show_invisible: show invisible messages as well
162
+ :param show_delayed: show delayed messages as well
163
+ :return: a list of messages
164
+ """
165
+ receipt_handle = "SQS/BACKDOOR/ACCESS" # dummy receipt handle
166
+
167
+ sqs_messages: list[SqsMessage] = []
168
+
169
+ if show_invisible:
170
+ sqs_messages.extend(queue.inflight)
171
+
172
+ if isinstance(queue, StandardQueue):
173
+ sqs_messages.extend(queue.visible.queue)
174
+ elif isinstance(queue, FifoQueue):
175
+ if show_invisible:
176
+ for inflight_group in queue.inflight_groups:
177
+ # messages that have been received are held in ``queue.inflight``, even for FIFO queues. however,
178
+ # for fifo queues, messages that are in the same message group as messages that have been
179
+ # received, are also considered invisible, and are held here in ``inflight_group.messages``.
180
+ for sqs_message in inflight_group.messages:
181
+ sqs_messages.append(sqs_message)
182
+
183
+ for message_group in queue.message_group_queue.queue:
184
+ # these are all messages of message groups that are visible
185
+ for sqs_message in message_group.messages:
186
+ sqs_messages.append(sqs_message)
187
+ else:
188
+ raise ValueError(f"unknown queue type {type(queue)}")
189
+
190
+ if show_delayed:
191
+ sqs_messages.extend(queue.delayed)
192
+
193
+ messages = []
194
+
195
+ for sqs_message in sqs_messages:
196
+ message: Message = to_sqs_api_message(sqs_message, [QueueAttributeName.All], ["All"])
197
+ # these are all non-standard fields so we squelch the linter
198
+ if show_invisible:
199
+ message["Attributes"]["IsVisible"] = str(sqs_message.is_visible).lower() # noqa
200
+ if show_delayed:
201
+ message["Attributes"]["IsDelayed"] = str(sqs_message.is_delayed).lower() # noqa
202
+ messages.append(message)
203
+ message["ReceiptHandle"] = receipt_handle
204
+
205
+ return messages
@@ -1,3 +1,4 @@
1
+ import copy
1
2
  import hashlib
2
3
  import heapq
3
4
  import inspect
@@ -15,6 +16,7 @@ from localstack.aws.api.sqs import (
15
16
  AttributeNameList,
16
17
  InvalidAttributeName,
17
18
  Message,
19
+ MessageAttributeNameList,
18
20
  MessageSystemAttributeName,
19
21
  QueueAttributeMap,
20
22
  QueueAttributeName,
@@ -29,12 +31,15 @@ from localstack.services.sqs.exceptions import (
29
31
  )
30
32
  from localstack.services.sqs.queue import InterruptiblePriorityQueue, InterruptibleQueue
31
33
  from localstack.services.sqs.utils import (
34
+ create_message_attribute_hash,
32
35
  encode_move_task_handle,
33
36
  encode_receipt_handle,
34
37
  extract_receipt_handle_info,
35
38
  global_message_sequence,
36
39
  guess_endpoint_strategy_and_host,
37
40
  is_message_deduplication_id_required,
41
+ message_filter_attributes,
42
+ message_filter_message_attributes,
38
43
  )
39
44
  from localstack.services.stores import AccountRegionBundle, BaseStore, LocalAttribute
40
45
  from localstack.utils.aws.arns import get_partition
@@ -190,6 +195,41 @@ class SqsMessage:
190
195
  return f"SqsMessage(id={self.message_id},group={self.message_group_id})"
191
196
 
192
197
 
198
+ def to_sqs_api_message(
199
+ standard_message: SqsMessage,
200
+ attribute_names: AttributeNameList = None,
201
+ message_attribute_names: MessageAttributeNameList = None,
202
+ ) -> Message:
203
+ """
204
+ Utility function to convert an SQS message from LocalStack's internal representation to the AWS API
205
+ concept 'Message', which is the format returned by the ``ReceiveMessage`` operation.
206
+
207
+ :param standard_message: A LocalStack SQS message
208
+ :param attribute_names: the attribute name list to filter
209
+ :param message_attribute_names: the message attribute names to filter
210
+ :return: a copy of the original Message with updated message attributes and MD5 attribute hash sums
211
+ """
212
+ # prepare message for receiver
213
+ message = copy.deepcopy(standard_message.message)
214
+
215
+ # update system attributes of the message copy
216
+ message["Attributes"][MessageSystemAttributeName.ApproximateFirstReceiveTimestamp] = str(
217
+ int((standard_message.first_received or 0) * 1000)
218
+ )
219
+
220
+ # filter attributes for receiver
221
+ message_filter_attributes(message, attribute_names)
222
+ message_filter_message_attributes(message, message_attribute_names)
223
+ if message.get("MessageAttributes"):
224
+ message["MD5OfMessageAttributes"] = create_message_attribute_hash(
225
+ message["MessageAttributes"]
226
+ )
227
+ else:
228
+ # delete the value that was computed when creating the message
229
+ message.pop("MD5OfMessageAttributes", None)
230
+ return message
231
+
232
+
193
233
  class ReceiveMessageResult:
194
234
  """
195
235
  Object to communicate the result of a "receive messages" operation between the SqsProvider and
@@ -1,5 +1,3 @@
1
- import copy
2
- import hashlib
3
1
  import json
4
2
  import logging
5
3
  import re
@@ -8,15 +6,12 @@ import time
8
6
  from collections.abc import Iterable
9
7
  from concurrent.futures.thread import ThreadPoolExecutor
10
8
  from itertools import islice
11
- from typing import Literal
12
9
 
13
10
  from botocore.utils import InvalidArnException
14
- from moto.sqs.models import BINARY_TYPE_FIELD_INDEX, STRING_TYPE_FIELD_INDEX
15
- from moto.sqs.models import Message as MotoMessage
16
11
  from werkzeug import Request as WerkzeugRequest
17
12
 
18
13
  from localstack import config
19
- from localstack.aws.api import CommonServiceException, RequestContext, ServiceException
14
+ from localstack.aws.api import RequestContext, ServiceException
20
15
  from localstack.aws.api.sqs import (
21
16
  ActionNameList,
22
17
  AttributeNameList,
@@ -70,11 +65,8 @@ from localstack.aws.api.sqs import (
70
65
  Token,
71
66
  TooManyEntriesInBatchRequest,
72
67
  )
73
- from localstack.aws.protocol.parser import create_parser
74
- from localstack.aws.protocol.serializer import aws_response_serializer
75
68
  from localstack.aws.spec import load_service
76
69
  from localstack.config import SQS_DISABLE_MAX_NUMBER_OF_MESSAGE_LIMIT
77
- from localstack.http import Request, route
78
70
  from localstack.services.edge import ROUTER
79
71
  from localstack.services.plugins import ServiceLifecycleHook
80
72
  from localstack.services.sqs import constants as sqs_constants
@@ -84,6 +76,7 @@ from localstack.services.sqs.constants import (
84
76
  HEADER_LOCALSTACK_SQS_OVERRIDE_WAIT_TIME_SECONDS,
85
77
  MAX_RESULT_LIMIT,
86
78
  )
79
+ from localstack.services.sqs.developer_api import SqsDeveloperApi
87
80
  from localstack.services.sqs.exceptions import (
88
81
  InvalidParameterValueException,
89
82
  MissingRequiredParameterException,
@@ -97,8 +90,10 @@ from localstack.services.sqs.models import (
97
90
  SqsStore,
98
91
  StandardQueue,
99
92
  sqs_stores,
93
+ to_sqs_api_message,
100
94
  )
101
95
  from localstack.services.sqs.utils import (
96
+ create_message_attribute_hash,
102
97
  decode_move_task_handle,
103
98
  generate_message_id,
104
99
  is_fifo_queue,
@@ -107,7 +102,6 @@ from localstack.services.sqs.utils import (
107
102
  )
108
103
  from localstack.services.stores import AccountRegionBundle
109
104
  from localstack.utils.aws.arns import parse_arn
110
- from localstack.utils.aws.request_context import extract_region_from_headers
111
105
  from localstack.utils.bootstrap import is_api_enabled
112
106
  from localstack.utils.cloudwatch.cloudwatch_util import (
113
107
  SqsMetricBatchData,
@@ -127,13 +121,6 @@ MAX_NUMBER_OF_MESSAGES = 10
127
121
  _STORE_LOCK = threading.RLock()
128
122
 
129
123
 
130
- class InvalidAddress(ServiceException):
131
- code = "InvalidAddress"
132
- message = "The address https://queue.amazonaws.com/ is not valid for this endpoint."
133
- sender_fault = True
134
- status_code = 404
135
-
136
-
137
124
  def assert_queue_name(queue_name: str, fifo: bool = False):
138
125
  if queue_name.endswith(".fifo"):
139
126
  if not fifo:
@@ -640,174 +627,6 @@ def check_fifo_id(fifo_id: str | None, parameter: str):
640
627
  )
641
628
 
642
629
 
643
- def get_sqs_protocol(request: Request) -> Literal["query", "json"]:
644
- content_type = request.headers.get("Content-Type")
645
- return "json" if content_type == "application/x-amz-json-1.0" else "query"
646
-
647
-
648
- def sqs_auto_protocol_aws_response_serializer(service_name: str, operation: str):
649
- def _decorate(fn):
650
- def _proxy(*args, **kwargs):
651
- # extract request from function invocation (decorator can be used for methods as well as for functions).
652
- if len(args) > 0 and isinstance(args[0], WerkzeugRequest):
653
- # function
654
- request = args[0]
655
- elif len(args) > 1 and isinstance(args[1], WerkzeugRequest):
656
- # method (arg[0] == self)
657
- request = args[1]
658
- elif "request" in kwargs:
659
- request = kwargs["request"]
660
- else:
661
- raise ValueError(f"could not find Request in signature of function {fn}")
662
-
663
- protocol = get_sqs_protocol(request)
664
- return aws_response_serializer(service_name, operation, protocol)(fn)(*args, **kwargs)
665
-
666
- return _proxy
667
-
668
- return _decorate
669
-
670
-
671
- class SqsDeveloperEndpoints:
672
- """
673
- A set of SQS developer tool endpoints:
674
-
675
- - ``/_aws/sqs/messages``: list SQS messages without side effects, compatible with ``ReceiveMessage``.
676
- """
677
-
678
- def __init__(self, stores=None):
679
- self.stores = stores or sqs_stores
680
-
681
- @route("/_aws/sqs/messages", methods=["GET", "POST"])
682
- @sqs_auto_protocol_aws_response_serializer("sqs", "ReceiveMessage")
683
- def list_messages(self, request: Request) -> ReceiveMessageResult:
684
- """
685
- This endpoint expects a ``QueueUrl`` request parameter (either as query arg or form parameter), similar to
686
- the ``ReceiveMessage`` operation. It will parse the Queue URL generated by one of the SQS endpoint strategies.
687
- """
688
-
689
- if "x-amz-" in request.mimetype or "x-www-form-urlencoded" in request.mimetype:
690
- # only parse the request using a parser if it comes from an AWS client
691
- protocol = get_sqs_protocol(request)
692
- operation, service_request = create_parser(
693
- load_service("sqs", protocol=protocol)
694
- ).parse(request)
695
- if operation.name != "ReceiveMessage":
696
- raise CommonServiceException(
697
- "InvalidRequest", "This endpoint only accepts ReceiveMessage calls"
698
- )
699
- else:
700
- service_request = dict(request.values)
701
-
702
- if not service_request.get("QueueUrl"):
703
- raise QueueDoesNotExist()
704
-
705
- try:
706
- account_id, region, queue_name = parse_queue_url(service_request.get("QueueUrl"))
707
- except ValueError:
708
- LOG.error(
709
- "Error while parsing Queue URL from request values: %s",
710
- service_request.get,
711
- exc_info=LOG.isEnabledFor(logging.DEBUG),
712
- )
713
- raise InvalidAddress()
714
-
715
- if not region:
716
- region = extract_region_from_headers(request.headers)
717
-
718
- return self._get_and_serialize_messages(request, region, account_id, queue_name)
719
-
720
- @route("/_aws/sqs/messages/<region>/<account_id>/<queue_name>")
721
- @sqs_auto_protocol_aws_response_serializer("sqs", "ReceiveMessage")
722
- def list_messages_for_queue_url(
723
- self, request: Request, region: str, account_id: str, queue_name: str
724
- ) -> ReceiveMessageResult:
725
- """
726
- This endpoint extracts the region, account_id, and queue_name directly from the URL rather than requiring the
727
- QueueUrl as parameter.
728
- """
729
- return self._get_and_serialize_messages(request, region, account_id, queue_name)
730
-
731
- def _get_and_serialize_messages(
732
- self,
733
- request: Request,
734
- region: str,
735
- account_id: str,
736
- queue_name: str,
737
- ) -> ReceiveMessageResult:
738
- show_invisible = request.values.get("ShowInvisible", "").lower() in ["true", "1"]
739
- show_delayed = request.values.get("ShowDelayed", "").lower() in ["true", "1"]
740
-
741
- try:
742
- store = SqsProvider.get_store(account_id, region)
743
- queue = store.queues[queue_name]
744
- except KeyError:
745
- LOG.info(
746
- "no queue named %s in region %s and account %s", queue_name, region, account_id
747
- )
748
- raise QueueDoesNotExist()
749
-
750
- messages = self._collect_messages(
751
- queue, show_invisible=show_invisible, show_delayed=show_delayed
752
- )
753
-
754
- return ReceiveMessageResult(Messages=messages)
755
-
756
- def _collect_messages(
757
- self, queue: SqsQueue, show_invisible: bool = False, show_delayed: bool = False
758
- ) -> list[Message]:
759
- """
760
- Retrieves from a given SqsQueue all visible messages without causing any side effects (not setting any
761
- receive timestamps, receive counts, or visibility state).
762
-
763
- :param queue: the queue
764
- :param show_invisible: show invisible messages as well
765
- :param show_delayed: show delayed messages as well
766
- :return: a list of messages
767
- """
768
- receipt_handle = "SQS/BACKDOOR/ACCESS" # dummy receipt handle
769
-
770
- sqs_messages: list[SqsMessage] = []
771
-
772
- if show_invisible:
773
- sqs_messages.extend(queue.inflight)
774
-
775
- if isinstance(queue, StandardQueue):
776
- sqs_messages.extend(queue.visible.queue)
777
- elif isinstance(queue, FifoQueue):
778
- if show_invisible:
779
- for inflight_group in queue.inflight_groups:
780
- # messages that have been received are held in ``queue.inflight``, even for FIFO queues. however,
781
- # for fifo queues, messages that are in the same message group as messages that have been
782
- # received, are also considered invisible, and are held here in ``inflight_group.messages``.
783
- for sqs_message in inflight_group.messages:
784
- sqs_messages.append(sqs_message)
785
-
786
- for message_group in queue.message_group_queue.queue:
787
- # these are all messages of message groups that are visible
788
- for sqs_message in message_group.messages:
789
- sqs_messages.append(sqs_message)
790
- else:
791
- raise ValueError(f"unknown queue type {type(queue)}")
792
-
793
- if show_delayed:
794
- sqs_messages.extend(queue.delayed)
795
-
796
- messages = []
797
-
798
- for sqs_message in sqs_messages:
799
- message: Message = to_sqs_api_message(sqs_message, [QueueAttributeName.All], ["All"])
800
- # these are all non-standard fields so we squelch the linter
801
- if show_invisible:
802
- message["Attributes"]["IsVisible"] = str(sqs_message.is_visible).lower() # noqa
803
- if show_delayed:
804
- message["Attributes"]["IsDelayed"] = str(sqs_message.is_delayed).lower() # noqa
805
- messages.append(message)
806
- message["ReceiptHandle"] = receipt_handle
807
-
808
- return messages
809
-
810
-
811
630
  class SqsProvider(SqsApi, ServiceLifecycleHook):
812
631
  """
813
632
  LocalStack SQS Provider.
@@ -849,7 +668,6 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
849
668
  # default are limited to 500kb payload size by Werkzeug. we make sure we only *increase* the limit if it's
850
669
  # already set, and if it's already set to unlimited we leave it.
851
670
  from rolo import Request as RoloRequest
852
- from werkzeug import Request as WerkzeugRequest
853
671
 
854
672
  # needed for the webserver integration (webservers create Werkzeug request objects)
855
673
  if WerkzeugRequest.max_form_memory_size is not None:
@@ -864,7 +682,7 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
864
682
 
865
683
  def on_before_start(self):
866
684
  query_api.register(ROUTER)
867
- self._router_rules = ROUTER.add(SqsDeveloperEndpoints())
685
+ self._router_rules = ROUTER.add(SqsDeveloperApi())
868
686
  self._queue_update_worker.start()
869
687
  self._start_cloudwatch_metrics_reporting()
870
688
 
@@ -1159,7 +977,7 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
1159
977
  MD5OfMessageBody=message["MD5OfBody"],
1160
978
  MD5OfMessageAttributes=message.get("MD5OfMessageAttributes"),
1161
979
  SequenceNumber=queue_item.sequence_number,
1162
- MD5OfMessageSystemAttributes=_create_message_attribute_hash(message_system_attributes),
980
+ MD5OfMessageSystemAttributes=create_message_attribute_hash(message_system_attributes),
1163
981
  )
1164
982
 
1165
983
  def send_message_batch(
@@ -1205,7 +1023,7 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
1205
1023
  MessageId=message.get("MessageId"),
1206
1024
  MD5OfMessageBody=message.get("MD5OfBody"),
1207
1025
  MD5OfMessageAttributes=message.get("MD5OfMessageAttributes"),
1208
- MD5OfMessageSystemAttributes=_create_message_attribute_hash(
1026
+ MD5OfMessageSystemAttributes=create_message_attribute_hash(
1209
1027
  message.get("message_system_attributes")
1210
1028
  ),
1211
1029
  SequenceNumber=queue_item.sequence_number,
@@ -1259,7 +1077,7 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
1259
1077
  MD5OfBody=md5(message_body),
1260
1078
  Body=message_body,
1261
1079
  Attributes=self._create_message_attributes(context, message_system_attributes),
1262
- MD5OfMessageAttributes=_create_message_attribute_hash(message_attributes),
1080
+ MD5OfMessageAttributes=create_message_attribute_hash(message_attributes),
1263
1081
  MessageAttributes=message_attributes,
1264
1082
  )
1265
1083
  if self._cloudwatch_dispatcher:
@@ -1819,34 +1637,6 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
1819
1637
  self._cloudwatch_dispatcher.shutdown()
1820
1638
 
1821
1639
 
1822
- # Method from moto's attribute_md5 of moto/sqs/models.py, separated from the Message Object
1823
- def _create_message_attribute_hash(message_attributes) -> str | None:
1824
- # To avoid the need to check for dict conformity everytime we invoke this function
1825
- if not isinstance(message_attributes, dict):
1826
- return
1827
- hash = hashlib.md5()
1828
-
1829
- for attrName in sorted(message_attributes.keys()):
1830
- attr_value = message_attributes[attrName]
1831
- # Encode name
1832
- MotoMessage.update_binary_length_and_value(hash, MotoMessage.utf8(attrName))
1833
- # Encode data type
1834
- MotoMessage.update_binary_length_and_value(hash, MotoMessage.utf8(attr_value["DataType"]))
1835
- # Encode transport type and value
1836
- if attr_value.get("StringValue"):
1837
- hash.update(bytearray([STRING_TYPE_FIELD_INDEX]))
1838
- MotoMessage.update_binary_length_and_value(
1839
- hash, MotoMessage.utf8(attr_value.get("StringValue"))
1840
- )
1841
- elif attr_value.get("BinaryValue"):
1842
- hash.update(bytearray([BINARY_TYPE_FIELD_INDEX]))
1843
- decoded_binary_value = attr_value.get("BinaryValue")
1844
- MotoMessage.update_binary_length_and_value(hash, decoded_binary_value)
1845
- # string_list_value, binary_list_value type is not implemented, reserved for the future use.
1846
- # See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_MessageAttributeValue.html
1847
- return hash.hexdigest()
1848
-
1849
-
1850
1640
  def resolve_queue_location(
1851
1641
  context: RequestContext, queue_name: str | None = None, queue_url: str | None = None
1852
1642
  ) -> tuple[str, str | None, str]:
@@ -1871,106 +1661,6 @@ def resolve_queue_location(
1871
1661
  return context.account_id, context.region, queue_name
1872
1662
 
1873
1663
 
1874
- def to_sqs_api_message(
1875
- standard_message: SqsMessage,
1876
- attribute_names: AttributeNameList = None,
1877
- message_attribute_names: MessageAttributeNameList = None,
1878
- ) -> Message:
1879
- """
1880
- Utility function to convert an SQS message from LocalStack's internal representation to the AWS API
1881
- concept 'Message', which is the format returned by the ``ReceiveMessage`` operation.
1882
-
1883
- :param standard_message: A LocalStack SQS message
1884
- :param attribute_names: the attribute name list to filter
1885
- :param message_attribute_names: the message attribute names to filter
1886
- :return: a copy of the original Message with updated message attributes and MD5 attribute hash sums
1887
- """
1888
- # prepare message for receiver
1889
- message = copy.deepcopy(standard_message.message)
1890
-
1891
- # update system attributes of the message copy
1892
- message["Attributes"][MessageSystemAttributeName.ApproximateFirstReceiveTimestamp] = str(
1893
- int((standard_message.first_received or 0) * 1000)
1894
- )
1895
-
1896
- # filter attributes for receiver
1897
- message_filter_attributes(message, attribute_names)
1898
- message_filter_message_attributes(message, message_attribute_names)
1899
- if message.get("MessageAttributes"):
1900
- message["MD5OfMessageAttributes"] = _create_message_attribute_hash(
1901
- message["MessageAttributes"]
1902
- )
1903
- else:
1904
- # delete the value that was computed when creating the message
1905
- message.pop("MD5OfMessageAttributes", None)
1906
- return message
1907
-
1908
-
1909
- def message_filter_attributes(message: Message, names: AttributeNameList | None):
1910
- """
1911
- Utility function filter from the given message (in-place) the system attributes from the given list. It will
1912
- apply all rules according to:
1913
- https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sqs.html#SQS.Client.receive_message.
1914
-
1915
- :param message: The message to filter (it will be modified)
1916
- :param names: the attributes names/filters
1917
- """
1918
- if "Attributes" not in message:
1919
- return
1920
-
1921
- if not names:
1922
- del message["Attributes"]
1923
- return
1924
-
1925
- if QueueAttributeName.All in names:
1926
- return
1927
-
1928
- for k in list(message["Attributes"].keys()):
1929
- if k not in names:
1930
- del message["Attributes"][k]
1931
-
1932
-
1933
- def message_filter_message_attributes(message: Message, names: MessageAttributeNameList | None):
1934
- """
1935
- Utility function filter from the given message (in-place) the message attributes from the given list. It will
1936
- apply all rules according to:
1937
- https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sqs.html#SQS.Client.receive_message.
1938
-
1939
- :param message: The message to filter (it will be modified)
1940
- :param names: the attributes names/filters (can be 'All', '.*', '*' or prefix filters like 'Foo.*')
1941
- """
1942
- if not message.get("MessageAttributes"):
1943
- return
1944
-
1945
- if not names:
1946
- del message["MessageAttributes"]
1947
- return
1948
-
1949
- if "All" in names or ".*" in names or "*" in names:
1950
- return
1951
-
1952
- attributes = message["MessageAttributes"]
1953
- matched = []
1954
-
1955
- keys = [name for name in names if ".*" not in name]
1956
- prefixes = [name.split(".*")[0] for name in names if ".*" in name]
1957
-
1958
- # match prefix filters
1959
- for k in attributes:
1960
- if k in keys:
1961
- matched.append(k)
1962
- continue
1963
-
1964
- for prefix in prefixes:
1965
- if k.startswith(prefix):
1966
- matched.append(k)
1967
- break
1968
- if matched:
1969
- message["MessageAttributes"] = {k: attributes[k] for k in matched}
1970
- else:
1971
- message.pop("MessageAttributes")
1972
-
1973
-
1974
1664
  def extract_message_count_from_headers(context: RequestContext) -> int | None:
1975
1665
  if override := context.request.headers.get(
1976
1666
  HEADER_LOCALSTACK_SQS_OVERRIDE_MESSAGE_COUNT, default=None, type=int
@@ -1,12 +1,20 @@
1
1
  import base64
2
+ import hashlib
2
3
  import itertools
3
4
  import json
4
5
  import re
6
+ import struct
5
7
  import time
6
- from typing import Literal, NamedTuple
8
+ from typing import Any, Literal, NamedTuple
7
9
  from urllib.parse import urlparse
8
10
 
9
- from localstack.aws.api.sqs import QueueAttributeName, ReceiptHandleIsInvalid
11
+ from localstack.aws.api.sqs import (
12
+ AttributeNameList,
13
+ Message,
14
+ MessageAttributeNameList,
15
+ QueueAttributeName,
16
+ ReceiptHandleIsInvalid,
17
+ )
10
18
  from localstack.services.sqs.constants import (
11
19
  DOMAIN_STRATEGY_URL_REGEX,
12
20
  LEGACY_STRATEGY_URL_REGEX,
@@ -22,6 +30,11 @@ DOMAIN_ENDPOINT = re.compile(DOMAIN_STRATEGY_URL_REGEX)
22
30
  PATH_ENDPOINT = re.compile(PATH_STRATEGY_URL_REGEX)
23
31
  LEGACY_ENDPOINT = re.compile(LEGACY_STRATEGY_URL_REGEX)
24
32
 
33
+ STRING_TYPE_FIELD_INDEX = 1
34
+ BINARY_TYPE_FIELD_INDEX = 2
35
+ STRING_LIST_TYPE_FIELD_INDEX = 3
36
+ BINARY_LIST_TYPE_FIELD_INDEX = 4
37
+
25
38
 
26
39
  def is_sqs_queue_url(url: str) -> bool:
27
40
  return any(
@@ -184,3 +197,109 @@ def global_message_sequence():
184
197
 
185
198
  def generate_message_id():
186
199
  return long_uid()
200
+
201
+
202
+ def message_filter_attributes(message: Message, names: AttributeNameList | None):
203
+ """
204
+ Utility function filter from the given message (in-place) the system attributes from the given list. It will
205
+ apply all rules according to:
206
+ https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sqs.html#SQS.Client.receive_message.
207
+
208
+ :param message: The message to filter (it will be modified)
209
+ :param names: the attributes names/filters
210
+ """
211
+ if "Attributes" not in message:
212
+ return
213
+
214
+ if not names:
215
+ del message["Attributes"]
216
+ return
217
+
218
+ if QueueAttributeName.All in names:
219
+ return
220
+
221
+ for k in list(message["Attributes"].keys()):
222
+ if k not in names:
223
+ del message["Attributes"][k]
224
+
225
+
226
+ def message_filter_message_attributes(message: Message, names: MessageAttributeNameList | None):
227
+ """
228
+ Utility function filter from the given message (in-place) the message attributes from the given list. It will
229
+ apply all rules according to:
230
+ https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sqs.html#SQS.Client.receive_message.
231
+
232
+ :param message: The message to filter (it will be modified)
233
+ :param names: the attributes names/filters (can be 'All', '.*', '*' or prefix filters like 'Foo.*')
234
+ """
235
+ if not message.get("MessageAttributes"):
236
+ return
237
+
238
+ if not names:
239
+ del message["MessageAttributes"]
240
+ return
241
+
242
+ if "All" in names or ".*" in names or "*" in names:
243
+ return
244
+
245
+ attributes = message["MessageAttributes"]
246
+ matched = []
247
+
248
+ keys = [name for name in names if ".*" not in name]
249
+ prefixes = [name.split(".*")[0] for name in names if ".*" in name]
250
+
251
+ # match prefix filters
252
+ for k in attributes:
253
+ if k in keys:
254
+ matched.append(k)
255
+ continue
256
+
257
+ for prefix in prefixes:
258
+ if k.startswith(prefix):
259
+ matched.append(k)
260
+ break
261
+ if matched:
262
+ message["MessageAttributes"] = {k: attributes[k] for k in matched}
263
+ else:
264
+ message.pop("MessageAttributes")
265
+
266
+
267
+ def _utf8(value: Any) -> bytes: # type: ignore[misc]
268
+ if isinstance(value, str):
269
+ return value.encode("utf-8")
270
+ return value
271
+
272
+
273
+ def _update_binary_length_and_value(md5: Any, value: bytes) -> None: # type: ignore[misc]
274
+ length_bytes = struct.pack("!I".encode("ascii"), len(value))
275
+ md5.update(length_bytes)
276
+ md5.update(value)
277
+
278
+
279
+ def create_message_attribute_hash(message_attributes) -> str | None:
280
+ """
281
+ Method from moto's attribute_md5 of moto/sqs/models.py, separated from the Message Object.
282
+ """
283
+ # To avoid the need to check for dict conformity everytime we invoke this function
284
+ if not isinstance(message_attributes, dict):
285
+ return
286
+
287
+ hash = hashlib.md5()
288
+
289
+ for attrName in sorted(message_attributes.keys()):
290
+ attr_value = message_attributes[attrName]
291
+ # Encode name
292
+ _update_binary_length_and_value(hash, _utf8(attrName))
293
+ # Encode data type
294
+ _update_binary_length_and_value(hash, _utf8(attr_value["DataType"]))
295
+ # Encode transport type and value
296
+ if attr_value.get("StringValue"):
297
+ hash.update(bytearray([STRING_TYPE_FIELD_INDEX]))
298
+ _update_binary_length_and_value(hash, _utf8(attr_value.get("StringValue")))
299
+ elif attr_value.get("BinaryValue"):
300
+ hash.update(bytearray([BINARY_TYPE_FIELD_INDEX]))
301
+ decoded_binary_value = attr_value.get("BinaryValue")
302
+ _update_binary_length_and_value(hash, decoded_binary_value)
303
+ # string_list_value, binary_list_value type is not implemented, reserved for the future use.
304
+ # See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_MessageAttributeValue.html
305
+ return hash.hexdigest()
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.dev39'
32
- __version_tuple__ = version_tuple = (4, 8, 2, 'dev39')
31
+ __version__ = version = '4.8.2.dev41'
32
+ __version_tuple__ = version_tuple = (4, 8, 2, 'dev41')
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.dev39
3
+ Version: 4.8.2.dev41
4
4
  Summary: The core library and runtime of LocalStack
5
5
  Author-email: LocalStack Contributors <info@localstack.cloud>
6
6
  License-Expression: Apache-2.0
@@ -4,7 +4,7 @@ localstack/deprecations.py,sha256=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=u8VuN3V8nuLmGz2VhSMWdZV7KUVJW8d5UZkOaQw9fPA,719
7
+ localstack/version.py,sha256=_utQwPo_8Gc5n8rC9n5M5MXyPtOSOzpyG1p9bw7xUtw,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
@@ -196,7 +196,7 @@ localstack/services/apigateway/legacy/provider.py,sha256=t98XZ-FH3XMzXmbDICF8vCv
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
199
- localstack/services/apigateway/next_gen/provider.py,sha256=bTso2VEQ2qHwQee4o81H5YrU9isQ4y-1f_BtfftarJU,21500
199
+ localstack/services/apigateway/next_gen/provider.py,sha256=s7Tu4dHhn51HdMZbHsl9r4FTxDWoaYV-qC3RCUBqZSs,21722
200
200
  localstack/services/apigateway/next_gen/execute_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
201
201
  localstack/services/apigateway/next_gen/execute_api/api.py,sha256=E0eGYb-fHJG9rANDInAMotsyxziJ6T3G_HgyknUnc-Y,553
202
202
  localstack/services/apigateway/next_gen/execute_api/context.py,sha256=_HrlzG9dxmAD9vjNNhyS8QxJCA5qZ0OXGLYvsGjhKnM,5403
@@ -208,7 +208,7 @@ localstack/services/apigateway/next_gen/execute_api/moto_helpers.py,sha256=1_ww5
208
208
  localstack/services/apigateway/next_gen/execute_api/parameters_mapping.py,sha256=iDkI7WIp9xBnKQx--Xpao5bmTNpdDfu6Iz3HRfl6ykc,12173
209
209
  localstack/services/apigateway/next_gen/execute_api/router.py,sha256=HiQN4MWWAQipgS78ft2Piahle5qjoUC04Qbf107sYSc,10294
210
210
  localstack/services/apigateway/next_gen/execute_api/template_mapping.py,sha256=QDRoGpwKPxqrsgDrwVL2NfnKZUgVtYQ5ONQm45UgdkQ,10580
211
- localstack/services/apigateway/next_gen/execute_api/test_invoke.py,sha256=kwS7n6gKufeMUZUGF0pj5bSnNfl5sPQ33jQUK25eeu8,12382
211
+ localstack/services/apigateway/next_gen/execute_api/test_invoke.py,sha256=MBsoS8KEb25Pje8vDLEzjhF50NM72Bi0W3ggd7fWXQ4,14663
212
212
  localstack/services/apigateway/next_gen/execute_api/variables.py,sha256=UK4yTElx7f1caJ4uIp6uOz54u6ni8Wcu6hV-JUgGEvs,7707
213
213
  localstack/services/apigateway/next_gen/execute_api/handlers/__init__.py,sha256=6a7jt0l36AifxHho9WGBBiQZoEtHiiYsSYLBWUSBNJ4,1338
214
214
  localstack/services/apigateway/next_gen/execute_api/handlers/analytics.py,sha256=xhixUsSSCA-6OTXdX37QN66JrhZxiqzUWGZVSN8SQUw,1715
@@ -225,7 +225,7 @@ localstack/services/apigateway/next_gen/execute_api/handlers/response_enricher.p
225
225
  localstack/services/apigateway/next_gen/execute_api/integrations/__init__.py,sha256=-eU2l2ktfSZoLAXNjsmbsFoDKjSV885Faqr1UHBmy00,562
226
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
- localstack/services/apigateway/next_gen/execute_api/integrations/http.py,sha256=siakDGFWvmfidpuKonJCbTAdxlNBn6I7XkZAf0i0eE0,6381
228
+ localstack/services/apigateway/next_gen/execute_api/integrations/http.py,sha256=Qkx5_PaOX44DrqEsR3WZaO7qCRkVfH0YL7zj55Yrs6w,6398
229
229
  localstack/services/apigateway/next_gen/execute_api/integrations/mock.py,sha256=rf00sXwDpRA683Zn0Z1WPgV1PpPVipEORDu2RmZ7g3Q,4238
230
230
  localstack/services/apigateway/resource_providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
231
231
  localstack/services/apigateway/resource_providers/aws_apigateway_account.py,sha256=w8jaxdng7NFVf0tKOSX7RpKssBqcIFiX2DtaFDhHwvM,2880
@@ -583,7 +583,7 @@ localstack/services/lambda_/invocation/docker_runtime_executor.py,sha256=6C2SZPy
583
583
  localstack/services/lambda_/invocation/event_manager.py,sha256=B16z14LmEwgQUrKu9SyZe73k5AWRZyU5LsTV7wSwKNM,26973
584
584
  localstack/services/lambda_/invocation/execution_environment.py,sha256=v5drFAa1BS7zBg7RD5r5VCClrnIzUJzBduc-6bkWMyc,17183
585
585
  localstack/services/lambda_/invocation/executor_endpoint.py,sha256=v_tsvn4HqbjtO2vhYUq7TxVzb7zNgMF2snxntjgBqrk,11018
586
- localstack/services/lambda_/invocation/internal_sqs_queue.py,sha256=cci8K5GxvW_Sg0EhKMQvCglklqSs4MLnyWzELEQpU5k,7341
586
+ localstack/services/lambda_/invocation/internal_sqs_queue.py,sha256=RFjaDcZkFmdCvjHgtAnUQcPQrjOkWSJyqB3vzDo-rq0,7321
587
587
  localstack/services/lambda_/invocation/lambda_models.py,sha256=vUVA-YClmeE2sNkqkl3hjpYKiJWNWlQGF2JbsLh4gEc,19849
588
588
  localstack/services/lambda_/invocation/lambda_service.py,sha256=q274qpHs2OBIR4PlLEzgeaQ-rBhT-Tl0BYgNVyNVs8o,30705
589
589
  localstack/services/lambda_/invocation/logs.py,sha256=TD2oSyKAizn5_KHbnav1Rh_hITKxLV8RSrHR7lYgOUM,3798
@@ -761,12 +761,13 @@ localstack/services/sns/v2/models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
761
761
  localstack/services/sns/v2/provider.py,sha256=43n-H-VFCXZbtvi8fF58IdAbBL0OsbTCblZ5-E8362w,142
762
762
  localstack/services/sqs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
763
763
  localstack/services/sqs/constants.py,sha256=9MLAOW4-hcbZlP2qYMY3giUnubHD_mgoORT0nh5W04Q,2826
764
+ localstack/services/sqs/developer_api.py,sha256=fNQNMqCkDyvobRm8g4-ErXjSYQ4O-myYobXA_RneC9o,8004
764
765
  localstack/services/sqs/exceptions.py,sha256=aMmTD1Mex37NKndt6_hpj_d0JAZeN3eX0g7r8BlNO7M,570
765
- localstack/services/sqs/models.py,sha256=22I3oasGJaUBRXgUgF_9LQL6x3aB-Nl8iUamA7vx8tI,50535
766
- localstack/services/sqs/provider.py,sha256=MBcoiLODxjLVyDynL8lqDBEz4gxx4T7Hwf0O9XAB1zs,78124
766
+ localstack/services/sqs/models.py,sha256=LHtO8gS19iSHZEDVQTPhoHlqqO3oz1tAm6erLKj-0w0,52154
767
+ localstack/services/sqs/provider.py,sha256=aV4aEMPpAPRVjIdI4UvL9x9j9PAZo1t1TZ_kh07j3Ew,65504
767
768
  localstack/services/sqs/query_api.py,sha256=5elf1kDdWlUuH5FJzhs8vWdiB85fziYvFsbivuN5OQQ,8655
768
769
  localstack/services/sqs/queue.py,sha256=Y5lVjrv71WTDU75VevTOKHSkfVzF1k_j1X0AOZ0-Xz4,1730
769
- localstack/services/sqs/utils.py,sha256=_s_SC5pI6zZwOcf5PqyMoAPbSkCMi1kOoqF-F5-MgG4,6707
770
+ localstack/services/sqs/utils.py,sha256=L8i7g7FxAlP1RyvFOk_N_NNNO-M8HVYQku-QcqoOVKI,10773
770
771
  localstack/services/sqs/resource_providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
771
772
  localstack/services/sqs/resource_providers/aws_sqs_queue.py,sha256=FJbCsLWAHLnOn4vLdeiwbXiXnez_3AN5tAM7tk8ehpg,8458
772
773
  localstack/services/sqs/resource_providers/aws_sqs_queue.schema.json,sha256=TBo3EiksYhfuJogSZLvFXzVZZYw2Ulhb9GGvBdYd63o,6980
@@ -1295,13 +1296,13 @@ localstack/utils/server/tcp_proxy.py,sha256=rR6d5jR0ozDvIlpHiqW0cfyY9a2fRGdOzyA8
1295
1296
  localstack/utils/xray/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1296
1297
  localstack/utils/xray/trace_header.py,sha256=ahXk9eonq7LpeENwlqUEPj3jDOCiVRixhntQuxNor-Q,6209
1297
1298
  localstack/utils/xray/traceid.py,sha256=GKO-R2sMMjlrH2UaLPXlQlZ6flbE7ZKb6IZMtMu_M5U,1110
1298
- localstack_core-4.8.2.dev39.data/scripts/localstack,sha256=WyL11vp5CkuP79iIR-L8XT7Cj8nvmxX7XRAgxhbmXNE,529
1299
- localstack_core-4.8.2.dev39.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1300
- localstack_core-4.8.2.dev39.data/scripts/localstack.bat,sha256=tlzZTXtveHkMX_s_fa7VDfvdNdS8iVpEz2ER3uk9B_c,29
1301
- localstack_core-4.8.2.dev39.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1302
- localstack_core-4.8.2.dev39.dist-info/METADATA,sha256=TMAeAzyE0IvCdJUoXFsuA7FK20hv0S1erle9ssfTLmw,5538
1303
- localstack_core-4.8.2.dev39.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1304
- localstack_core-4.8.2.dev39.dist-info/entry_points.txt,sha256=5IoyjalZoY-PWY5Lk_AeEjEEQ-rKQJhijLe697GVlnM,20953
1305
- localstack_core-4.8.2.dev39.dist-info/plux.json,sha256=XDW484dDYm7lV7ht4OX30DCLS8RtnWklQYM2WdVZUec,21181
1306
- localstack_core-4.8.2.dev39.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1307
- localstack_core-4.8.2.dev39.dist-info/RECORD,,
1299
+ localstack_core-4.8.2.dev41.data/scripts/localstack,sha256=WyL11vp5CkuP79iIR-L8XT7Cj8nvmxX7XRAgxhbmXNE,529
1300
+ localstack_core-4.8.2.dev41.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1301
+ localstack_core-4.8.2.dev41.data/scripts/localstack.bat,sha256=tlzZTXtveHkMX_s_fa7VDfvdNdS8iVpEz2ER3uk9B_c,29
1302
+ localstack_core-4.8.2.dev41.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1303
+ localstack_core-4.8.2.dev41.dist-info/METADATA,sha256=iI4NWS51RM95u5_6DCI6-JbAgofNXv4AjISJqjBg9uY,5538
1304
+ localstack_core-4.8.2.dev41.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1305
+ localstack_core-4.8.2.dev41.dist-info/entry_points.txt,sha256=5IoyjalZoY-PWY5Lk_AeEjEEQ-rKQJhijLe697GVlnM,20953
1306
+ localstack_core-4.8.2.dev41.dist-info/plux.json,sha256=_EAwtg8JFJnS6nDze1NkSOtNMcxKvrfmJfY_q0d6MWo,21181
1307
+ localstack_core-4.8.2.dev41.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1308
+ localstack_core-4.8.2.dev41.dist-info/RECORD,,
@@ -0,0 +1 @@
1
+ {"localstack.cloudformation.resource_providers": ["AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::DynamoDB::GlobalTable=localstack.services.dynamodb.resource_providers.aws_dynamodb_globaltable_plugin:DynamoDBGlobalTableProviderPlugin", "AWS::Kinesis::StreamConsumer=localstack.services.kinesis.resource_providers.aws_kinesis_streamconsumer_plugin:KinesisStreamConsumerProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::EC2::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "AWS::CloudWatch::CompositeAlarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_compositealarm_plugin:CloudWatchCompositeAlarmProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::Events::EventBus=localstack.services.events.resource_providers.aws_events_eventbus_plugin:EventsEventBusProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::EC2::RouteTable=localstack.services.ec2.resource_providers.aws_ec2_routetable_plugin:EC2RouteTableProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "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::ApiGateway::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "AWS::IAM::Policy=localstack.services.iam.resource_providers.aws_iam_policy_plugin:IAMPolicyProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin", "AWS::EC2::TransitGateway=localstack.services.ec2.resource_providers.aws_ec2_transitgateway_plugin:EC2TransitGatewayProviderPlugin", "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::EC2::Route=localstack.services.ec2.resource_providers.aws_ec2_route_plugin:EC2RouteProviderPlugin", "AWS::SecretsManager::SecretTargetAttachment=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment_plugin:SecretsManagerSecretTargetAttachmentProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::SNS::TopicPolicy=localstack.services.sns.resource_providers.aws_sns_topicpolicy_plugin:SNSTopicPolicyProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "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::EC2::VPCGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_vpcgatewayattachment_plugin:EC2VPCGatewayAttachmentProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::ApiGateway::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "AWS::Lambda::EventSourceMapping=localstack.services.lambda_.resource_providers.aws_lambda_eventsourcemapping_plugin:LambdaEventSourceMappingProviderPlugin", "AWS::ApiGateway::RestApi=localstack.services.apigateway.resource_providers.aws_apigateway_restapi_plugin:ApiGatewayRestApiProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "AWS::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::SNS::Topic=localstack.services.sns.resource_providers.aws_sns_topic_plugin:SNSTopicProviderPlugin", "AWS::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::IAM::ServerCertificate=localstack.services.iam.resource_providers.aws_iam_servercertificate_plugin:IAMServerCertificateProviderPlugin", "AWS::Lambda::Permission=localstack.services.lambda_.resource_providers.aws_lambda_permission_plugin:LambdaPermissionProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::EC2::VPC=localstack.services.ec2.resource_providers.aws_ec2_vpc_plugin:EC2VPCProviderPlugin", "AWS::SNS::Subscription=localstack.services.sns.resource_providers.aws_sns_subscription_plugin:SNSSubscriptionProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "AWS::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::KMS::Key=localstack.services.kms.resource_providers.aws_kms_key_plugin:KMSKeyProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::SQS::QueuePolicy=localstack.services.sqs.resource_providers.aws_sqs_queuepolicy_plugin:SQSQueuePolicyProviderPlugin", "AWS::ApiGateway::DomainName=localstack.services.apigateway.resource_providers.aws_apigateway_domainname_plugin:ApiGatewayDomainNameProviderPlugin", "AWS::IAM::Role=localstack.services.iam.resource_providers.aws_iam_role_plugin:IAMRoleProviderPlugin", "AWS::Route53::RecordSet=localstack.services.route53.resource_providers.aws_route53_recordset_plugin:Route53RecordSetProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::Events::EventBusPolicy=localstack.services.events.resource_providers.aws_events_eventbuspolicy_plugin:EventsEventBusPolicyProviderPlugin", "AWS::CertificateManager::Certificate=localstack.services.certificatemanager.resource_providers.aws_certificatemanager_certificate_plugin:CertificateManagerCertificateProviderPlugin", "AWS::Lambda::Alias=localstack.services.lambda_.resource_providers.lambda_alias_plugin:LambdaAliasProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::KMS::Alias=localstack.services.kms.resource_providers.aws_kms_alias_plugin:KMSAliasProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "AWS::Lambda::Function=localstack.services.lambda_.resource_providers.aws_lambda_function_plugin:LambdaFunctionProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin", "AWS::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::EC2::NetworkAcl=localstack.services.ec2.resource_providers.aws_ec2_networkacl_plugin:EC2NetworkAclProviderPlugin", "AWS::ApiGateway::Method=localstack.services.apigateway.resource_providers.aws_apigateway_method_plugin:ApiGatewayMethodProviderPlugin", "AWS::OpenSearchService::Domain=localstack.services.opensearch.resource_providers.aws_opensearchservice_domain_plugin:OpenSearchServiceDomainProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin", "AWS::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin", "AWS::IAM::InstanceProfile=localstack.services.iam.resource_providers.aws_iam_instanceprofile_plugin:IAMInstanceProfileProviderPlugin", "AWS::EC2::PrefixList=localstack.services.ec2.resource_providers.aws_ec2_prefixlist_plugin:EC2PrefixListProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::IAM::ManagedPolicy=localstack.services.iam.resource_providers.aws_iam_managedpolicy_plugin:IAMManagedPolicyProviderPlugin", "AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "AWS::DynamoDB::Table=localstack.services.dynamodb.resource_providers.aws_dynamodb_table_plugin:DynamoDBTableProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::Route53::HealthCheck=localstack.services.route53.resource_providers.aws_route53_healthcheck_plugin:Route53HealthCheckProviderPlugin", "AWS::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::Events::ApiDestination=localstack.services.events.resource_providers.aws_events_apidestination_plugin:EventsApiDestinationProviderPlugin"], "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.hooks.configure_localstack_container": ["_mount_machine_file=localstack.utils.analytics.metadata:_mount_machine_file"], "localstack.hooks.prepare_host": ["prepare_host_machine_id=localstack.utils.analytics.metadata:prepare_host_machine_id"], "localstack.packages": ["ffmpeg/community=localstack.packages.plugins:ffmpeg_package", "java/community=localstack.packages.plugins:java_package", "elasticsearch/community=localstack.services.es.plugins:elasticsearch_package", "lambda-java-libs/community=localstack.services.lambda_.plugins:lambda_java_libs", "lambda-runtime/community=localstack.services.lambda_.plugins:lambda_runtime_package", "kinesis-mock/community=localstack.services.kinesis.plugins:kinesismock_package", "opensearch/community=localstack.services.opensearch.plugins:opensearch_package", "dynamodb-local/community=localstack.services.dynamodb.plugins:dynamodb_local_package", "jpype-jsonata/community=localstack.services.stepfunctions.plugins:jpype_jsonata_package", "vosk/community=localstack.services.transcribe.plugins:vosk_package"], "localstack.hooks.on_infra_start": ["register_cloudformation_deploy_ui=localstack.services.cloudformation.plugins:register_cloudformation_deploy_ui", "setup_dns_configuration_on_host=localstack.dns.plugins:setup_dns_configuration_on_host", "start_dns_server=localstack.dns.plugins:start_dns_server", "init_response_mutation_handler=localstack.aws.handlers.response:init_response_mutation_handler", "register_swagger_endpoints=localstack.http.resources.swagger.plugins:register_swagger_endpoints", "_run_init_scripts_on_start=localstack.runtime.init:_run_init_scripts_on_start", "register_custom_endpoints=localstack.services.lambda_.plugins:register_custom_endpoints", "validate_configuration=localstack.services.lambda_.plugins:validate_configuration", "delete_cached_certificate=localstack.plugins:delete_cached_certificate", "deprecation_warnings=localstack.plugins:deprecation_warnings", "_publish_config_as_analytics_event=localstack.runtime.analytics:_publish_config_as_analytics_event", "_publish_container_info=localstack.runtime.analytics:_publish_container_info", "apply_runtime_patches=localstack.runtime.patches:apply_runtime_patches", "apply_aws_runtime_patches=localstack.aws.patches:apply_aws_runtime_patches", "eager_load_services=localstack.services.plugins:eager_load_services", "conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger", "_patch_botocore_endpoint_in_memory=localstack.aws.client:_patch_botocore_endpoint_in_memory", "_patch_botocore_json_parser=localstack.aws.client:_patch_botocore_json_parser", "_patch_cbor2=localstack.aws.client:_patch_cbor2"], "localstack.hooks.on_infra_shutdown": ["stop_server=localstack.dns.plugins:stop_server", "publish_metrics=localstack.utils.analytics.metrics.publisher:publish_metrics", "_run_init_scripts_on_shutdown=localstack.runtime.init:_run_init_scripts_on_shutdown", "remove_custom_endpoints=localstack.services.lambda_.plugins:remove_custom_endpoints", "run_on_after_service_shutdown_handlers=localstack.runtime.shutdown:run_on_after_service_shutdown_handlers", "run_shutdown_handlers=localstack.runtime.shutdown:run_shutdown_handlers", "shutdown_services=localstack.runtime.shutdown:shutdown_services"], "localstack.runtime.components": ["aws=localstack.aws.components:AwsComponents"], "localstack.lambda.runtime_executor": ["docker=localstack.services.lambda_.invocation.plugins:DockerRuntimeExecutorPlugin"], "localstack.init.runner": ["py=localstack.runtime.init:PythonScriptRunner", "sh=localstack.runtime.init:ShellScriptRunner"], "localstack.hooks.on_infra_ready": ["_run_init_scripts_on_ready=localstack.runtime.init:_run_init_scripts_on_ready", "publish_provider_assignment=localstack.utils.analytics.service_providers:publish_provider_assignment"], "localstack.openapi.spec": ["localstack=localstack.plugins:CoreOASPlugin"], "localstack.runtime.server": ["hypercorn=localstack.runtime.server.plugins:HypercornRuntimeServerPlugin", "twisted=localstack.runtime.server.plugins:TwistedRuntimeServerPlugin"], "localstack.utils.catalog": ["aws-catalog-remote-state=localstack.utils.catalog.catalog:AwsCatalogRemoteStatePlugin", "aws-catalog-runtime-only=localstack.utils.catalog.catalog:AwsCatalogRuntimePlugin"]}
@@ -1 +0,0 @@
1
- {"localstack.cloudformation.resource_providers": ["AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::Events::EventBusPolicy=localstack.services.events.resource_providers.aws_events_eventbuspolicy_plugin:EventsEventBusPolicyProviderPlugin", "AWS::EC2::RouteTable=localstack.services.ec2.resource_providers.aws_ec2_routetable_plugin:EC2RouteTableProviderPlugin", "AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "AWS::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::Lambda::Version=localstack.services.lambda_.resource_providers.aws_lambda_version_plugin:LambdaVersionProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::Events::EventBus=localstack.services.events.resource_providers.aws_events_eventbus_plugin:EventsEventBusProviderPlugin", "AWS::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::IAM::InstanceProfile=localstack.services.iam.resource_providers.aws_iam_instanceprofile_plugin:IAMInstanceProfileProviderPlugin", "AWS::EC2::TransitGateway=localstack.services.ec2.resource_providers.aws_ec2_transitgateway_plugin:EC2TransitGatewayProviderPlugin", "AWS::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::ApiGateway::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "AWS::Lambda::EventSourceMapping=localstack.services.lambda_.resource_providers.aws_lambda_eventsourcemapping_plugin:LambdaEventSourceMappingProviderPlugin", "AWS::ApiGateway::Method=localstack.services.apigateway.resource_providers.aws_apigateway_method_plugin:ApiGatewayMethodProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::SNS::Topic=localstack.services.sns.resource_providers.aws_sns_topic_plugin:SNSTopicProviderPlugin", "AWS::EC2::VPCGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_vpcgatewayattachment_plugin:EC2VPCGatewayAttachmentProviderPlugin", "AWS::DynamoDB::GlobalTable=localstack.services.dynamodb.resource_providers.aws_dynamodb_globaltable_plugin:DynamoDBGlobalTableProviderPlugin", "AWS::ApiGateway::ApiKey=localstack.services.apigateway.resource_providers.aws_apigateway_apikey_plugin:ApiGatewayApiKeyProviderPlugin", "AWS::ApiGateway::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "AWS::IAM::ServerCertificate=localstack.services.iam.resource_providers.aws_iam_servercertificate_plugin:IAMServerCertificateProviderPlugin", "AWS::SNS::Subscription=localstack.services.sns.resource_providers.aws_sns_subscription_plugin:SNSSubscriptionProviderPlugin", "AWS::SNS::TopicPolicy=localstack.services.sns.resource_providers.aws_sns_topicpolicy_plugin:SNSTopicPolicyProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::Lambda::EventInvokeConfig=localstack.services.lambda_.resource_providers.aws_lambda_eventinvokeconfig_plugin:LambdaEventInvokeConfigProviderPlugin", "AWS::Lambda::Alias=localstack.services.lambda_.resource_providers.lambda_alias_plugin:LambdaAliasProviderPlugin", "AWS::ApiGateway::Deployment=localstack.services.apigateway.resource_providers.aws_apigateway_deployment_plugin:ApiGatewayDeploymentProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::Route53::RecordSet=localstack.services.route53.resource_providers.aws_route53_recordset_plugin:Route53RecordSetProviderPlugin", "AWS::EC2::PrefixList=localstack.services.ec2.resource_providers.aws_ec2_prefixlist_plugin:EC2PrefixListProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::Lambda::Permission=localstack.services.lambda_.resource_providers.aws_lambda_permission_plugin:LambdaPermissionProviderPlugin", "AWS::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::Lambda::LayerVersionPermission=localstack.services.lambda_.resource_providers.aws_lambda_layerversionpermission_plugin:LambdaLayerVersionPermissionProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::KMS::Key=localstack.services.kms.resource_providers.aws_kms_key_plugin:KMSKeyProviderPlugin", "AWS::DynamoDB::Table=localstack.services.dynamodb.resource_providers.aws_dynamodb_table_plugin:DynamoDBTableProviderPlugin", "AWS::EC2::Subnet=localstack.services.ec2.resource_providers.aws_ec2_subnet_plugin:EC2SubnetProviderPlugin", "AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "AWS::EC2::Route=localstack.services.ec2.resource_providers.aws_ec2_route_plugin:EC2RouteProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::EC2::NetworkAcl=localstack.services.ec2.resource_providers.aws_ec2_networkacl_plugin:EC2NetworkAclProviderPlugin", "AWS::CertificateManager::Certificate=localstack.services.certificatemanager.resource_providers.aws_certificatemanager_certificate_plugin:CertificateManagerCertificateProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "AWS::Route53::HealthCheck=localstack.services.route53.resource_providers.aws_route53_healthcheck_plugin:Route53HealthCheckProviderPlugin", "AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin", "AWS::EC2::VPC=localstack.services.ec2.resource_providers.aws_ec2_vpc_plugin:EC2VPCProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::SQS::QueuePolicy=localstack.services.sqs.resource_providers.aws_sqs_queuepolicy_plugin:SQSQueuePolicyProviderPlugin", "AWS::ApiGateway::DomainName=localstack.services.apigateway.resource_providers.aws_apigateway_domainname_plugin:ApiGatewayDomainNameProviderPlugin", "AWS::Lambda::Function=localstack.services.lambda_.resource_providers.aws_lambda_function_plugin:LambdaFunctionProviderPlugin", "AWS::IAM::ManagedPolicy=localstack.services.iam.resource_providers.aws_iam_managedpolicy_plugin:IAMManagedPolicyProviderPlugin", "AWS::OpenSearchService::Domain=localstack.services.opensearch.resource_providers.aws_opensearchservice_domain_plugin:OpenSearchServiceDomainProviderPlugin", "AWS::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "AWS::CloudWatch::CompositeAlarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_compositealarm_plugin:CloudWatchCompositeAlarmProviderPlugin", "AWS::KMS::Alias=localstack.services.kms.resource_providers.aws_kms_alias_plugin:KMSAliasProviderPlugin", "AWS::IAM::Role=localstack.services.iam.resource_providers.aws_iam_role_plugin:IAMRoleProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "AWS::IAM::Policy=localstack.services.iam.resource_providers.aws_iam_policy_plugin:IAMPolicyProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::Kinesis::StreamConsumer=localstack.services.kinesis.resource_providers.aws_kinesis_streamconsumer_plugin:KinesisStreamConsumerProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::ApiGateway::RestApi=localstack.services.apigateway.resource_providers.aws_apigateway_restapi_plugin:ApiGatewayRestApiProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::Events::ApiDestination=localstack.services.events.resource_providers.aws_events_apidestination_plugin:EventsApiDestinationProviderPlugin", "AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "AWS::EC2::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::SecretsManager::SecretTargetAttachment=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment_plugin:SecretsManagerSecretTargetAttachmentProviderPlugin"], "localstack.hooks.configure_localstack_container": ["_mount_machine_file=localstack.utils.analytics.metadata:_mount_machine_file"], "localstack.hooks.prepare_host": ["prepare_host_machine_id=localstack.utils.analytics.metadata:prepare_host_machine_id"], "localstack.packages": ["kinesis-mock/community=localstack.services.kinesis.plugins:kinesismock_package", "opensearch/community=localstack.services.opensearch.plugins:opensearch_package", "elasticsearch/community=localstack.services.es.plugins:elasticsearch_package", "vosk/community=localstack.services.transcribe.plugins:vosk_package", "jpype-jsonata/community=localstack.services.stepfunctions.plugins:jpype_jsonata_package", "ffmpeg/community=localstack.packages.plugins:ffmpeg_package", "java/community=localstack.packages.plugins:java_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"], "localstack.init.runner": ["py=localstack.runtime.init:PythonScriptRunner", "sh=localstack.runtime.init:ShellScriptRunner"], "localstack.hooks.on_infra_ready": ["_run_init_scripts_on_ready=localstack.runtime.init:_run_init_scripts_on_ready", "publish_provider_assignment=localstack.utils.analytics.service_providers:publish_provider_assignment"], "localstack.hooks.on_infra_shutdown": ["_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", "stop_server=localstack.dns.plugins:stop_server", "publish_metrics=localstack.utils.analytics.metrics.publisher:publish_metrics", "remove_custom_endpoints=localstack.services.lambda_.plugins:remove_custom_endpoints"], "localstack.hooks.on_infra_start": ["_run_init_scripts_on_start=localstack.runtime.init:_run_init_scripts_on_start", "setup_dns_configuration_on_host=localstack.dns.plugins:setup_dns_configuration_on_host", "start_dns_server=localstack.dns.plugins:start_dns_server", "apply_aws_runtime_patches=localstack.aws.patches:apply_aws_runtime_patches", "_publish_config_as_analytics_event=localstack.runtime.analytics:_publish_config_as_analytics_event", "_publish_container_info=localstack.runtime.analytics:_publish_container_info", "register_cloudformation_deploy_ui=localstack.services.cloudformation.plugins:register_cloudformation_deploy_ui", "conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger", "_patch_botocore_endpoint_in_memory=localstack.aws.client:_patch_botocore_endpoint_in_memory", "_patch_botocore_json_parser=localstack.aws.client:_patch_botocore_json_parser", "_patch_cbor2=localstack.aws.client:_patch_cbor2", "apply_runtime_patches=localstack.runtime.patches:apply_runtime_patches", "eager_load_services=localstack.services.plugins:eager_load_services", "register_swagger_endpoints=localstack.http.resources.swagger.plugins:register_swagger_endpoints", "init_response_mutation_handler=localstack.aws.handlers.response:init_response_mutation_handler", "register_custom_endpoints=localstack.services.lambda_.plugins:register_custom_endpoints", "validate_configuration=localstack.services.lambda_.plugins:validate_configuration", "delete_cached_certificate=localstack.plugins:delete_cached_certificate", "deprecation_warnings=localstack.plugins:deprecation_warnings"], "localstack.runtime.components": ["aws=localstack.aws.components:AwsComponents"], "localstack.runtime.server": ["hypercorn=localstack.runtime.server.plugins:HypercornRuntimeServerPlugin", "twisted=localstack.runtime.server.plugins:TwistedRuntimeServerPlugin"], "localstack.lambda.runtime_executor": ["docker=localstack.services.lambda_.invocation.plugins:DockerRuntimeExecutorPlugin"], "localstack.utils.catalog": ["aws-catalog-remote-state=localstack.utils.catalog.catalog:AwsCatalogRemoteStatePlugin", "aws-catalog-runtime-only=localstack.utils.catalog.catalog:AwsCatalogRuntimePlugin"], "localstack.openapi.spec": ["localstack=localstack.plugins:CoreOASPlugin"], "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"]}