localstack-core 4.9.3.dev40__py3-none-any.whl → 4.9.3.dev42__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- localstack/services/sns/constants.py +2 -1
- localstack/services/sns/v2/models.py +126 -2
- localstack/services/sns/v2/provider.py +407 -16
- localstack/services/sns/v2/utils.py +122 -0
- localstack/version.py +2 -2
- {localstack_core-4.9.3.dev40.dist-info → localstack_core-4.9.3.dev42.dist-info}/METADATA +1 -1
- {localstack_core-4.9.3.dev40.dist-info → localstack_core-4.9.3.dev42.dist-info}/RECORD +15 -14
- localstack_core-4.9.3.dev42.dist-info/plux.json +1 -0
- localstack_core-4.9.3.dev40.dist-info/plux.json +0 -1
- {localstack_core-4.9.3.dev40.data → localstack_core-4.9.3.dev42.data}/scripts/localstack +0 -0
- {localstack_core-4.9.3.dev40.data → localstack_core-4.9.3.dev42.data}/scripts/localstack-supervisor +0 -0
- {localstack_core-4.9.3.dev40.data → localstack_core-4.9.3.dev42.data}/scripts/localstack.bat +0 -0
- {localstack_core-4.9.3.dev40.dist-info → localstack_core-4.9.3.dev42.dist-info}/WHEEL +0 -0
- {localstack_core-4.9.3.dev40.dist-info → localstack_core-4.9.3.dev42.dist-info}/entry_points.txt +0 -0
- {localstack_core-4.9.3.dev40.dist-info → localstack_core-4.9.3.dev42.dist-info}/licenses/LICENSE.txt +0 -0
- {localstack_core-4.9.3.dev40.dist-info → localstack_core-4.9.3.dev42.dist-info}/top_level.txt +0 -0
@@ -13,7 +13,7 @@ SNS_PROTOCOLS = [
|
|
13
13
|
"firehose",
|
14
14
|
]
|
15
15
|
|
16
|
-
VALID_SUBSCRIPTION_ATTR_NAME = [
|
16
|
+
VALID_SUBSCRIPTION_ATTR_NAME: list[str] = [
|
17
17
|
"DeliveryPolicy",
|
18
18
|
"FilterPolicy",
|
19
19
|
"FilterPolicyScope",
|
@@ -39,3 +39,4 @@ SUBSCRIPTION_TOKENS_ENDPOINT = "/_aws/sns/subscription-tokens"
|
|
39
39
|
SNS_CERT_ENDPOINT = "/_aws/sns/SimpleNotificationService-6c6f63616c737461636b69736e696365.pem"
|
40
40
|
|
41
41
|
DUMMY_SUBSCRIPTION_PRINCIPAL = "arn:{partition}:iam::{account_id}:user/DummySNSPrincipal"
|
42
|
+
E164_REGEX = re.compile(r"^\+?[1-9]\d{1,14}$")
|
@@ -1,12 +1,24 @@
|
|
1
|
-
|
1
|
+
import itertools
|
2
|
+
import time
|
3
|
+
from dataclasses import dataclass, field
|
4
|
+
from enum import StrEnum
|
5
|
+
from typing import Literal, TypedDict
|
2
6
|
|
3
|
-
from localstack.aws.api.sns import
|
7
|
+
from localstack.aws.api.sns import (
|
8
|
+
MessageAttributeMap,
|
9
|
+
PublishBatchRequestEntry,
|
10
|
+
TopicAttributesMap,
|
11
|
+
subscriptionARN,
|
12
|
+
topicARN,
|
13
|
+
)
|
4
14
|
from localstack.services.stores import (
|
5
15
|
AccountRegionBundle,
|
6
16
|
BaseStore,
|
7
17
|
CrossRegionAttribute,
|
8
18
|
LocalAttribute,
|
9
19
|
)
|
20
|
+
from localstack.utils.objects import singleton_factory
|
21
|
+
from localstack.utils.strings import long_uid
|
10
22
|
from localstack.utils.tagging import TaggingService
|
11
23
|
|
12
24
|
|
@@ -14,11 +26,123 @@ class Topic(TypedDict, total=True):
|
|
14
26
|
arn: str
|
15
27
|
name: str
|
16
28
|
attributes: TopicAttributesMap
|
29
|
+
subscriptions: list[str]
|
30
|
+
|
31
|
+
|
32
|
+
SnsProtocols = Literal[
|
33
|
+
"http", "https", "email", "email-json", "sms", "sqs", "application", "lambda", "firehose"
|
34
|
+
]
|
35
|
+
|
36
|
+
SnsApplicationPlatforms = Literal[
|
37
|
+
"APNS", "APNS_SANDBOX", "ADM", "FCM", "Baidu", "GCM", "MPNS", "WNS"
|
38
|
+
]
|
39
|
+
SnsMessageProtocols = Literal[SnsProtocols, SnsApplicationPlatforms]
|
40
|
+
|
41
|
+
|
42
|
+
class SnsSubscription(TypedDict, total=False):
|
43
|
+
"""
|
44
|
+
In SNS, Subscription can be represented with only TopicArn, Endpoint, Protocol, SubscriptionArn and Owner, for
|
45
|
+
example in ListSubscriptions. However, when getting a subscription with GetSubscriptionAttributes, it will return
|
46
|
+
the Subscription object merged with its own attributes.
|
47
|
+
This represents this merged object, for internal use and in GetSubscriptionAttributes
|
48
|
+
https://docs.aws.amazon.com/cli/latest/reference/sns/get-subscription-attributes.html
|
49
|
+
"""
|
50
|
+
|
51
|
+
TopicArn: topicARN
|
52
|
+
Endpoint: str
|
53
|
+
Protocol: SnsProtocols
|
54
|
+
SubscriptionArn: subscriptionARN
|
55
|
+
PendingConfirmation: Literal["true", "false"]
|
56
|
+
Owner: str | None
|
57
|
+
SubscriptionPrincipal: str | None
|
58
|
+
FilterPolicy: str | None
|
59
|
+
FilterPolicyScope: Literal["MessageAttributes", "MessageBody"]
|
60
|
+
RawMessageDelivery: Literal["true", "false"]
|
61
|
+
ConfirmationWasAuthenticated: Literal["true", "false"]
|
62
|
+
SubscriptionRoleArn: str | None
|
63
|
+
DeliveryPolicy: str | None
|
64
|
+
|
65
|
+
|
66
|
+
@singleton_factory
|
67
|
+
def global_sns_message_sequence():
|
68
|
+
# creates a 20-digit number used as the start for the global sequence, adds 100 for it to be different from SQS's
|
69
|
+
# mostly for testing purpose, both global sequence would be initialized at the same and be identical
|
70
|
+
start = int(time.time() + 100) << 33
|
71
|
+
# itertools.count is thread safe over the GIL since its getAndIncrement operation is a single python bytecode op
|
72
|
+
return itertools.count(start)
|
73
|
+
|
74
|
+
|
75
|
+
def get_next_sequence_number():
|
76
|
+
return next(global_sns_message_sequence())
|
77
|
+
|
78
|
+
|
79
|
+
class SnsMessageType(StrEnum):
|
80
|
+
Notification = "Notification"
|
81
|
+
SubscriptionConfirmation = "SubscriptionConfirmation"
|
82
|
+
UnsubscribeConfirmation = "UnsubscribeConfirmation"
|
83
|
+
|
84
|
+
|
85
|
+
@dataclass
|
86
|
+
class SnsMessage:
|
87
|
+
type: SnsMessageType
|
88
|
+
message: (
|
89
|
+
str | dict
|
90
|
+
) # can be Dict if after being JSON decoded for validation if structure is `json`
|
91
|
+
message_attributes: MessageAttributeMap | None = None
|
92
|
+
message_structure: str | None = None
|
93
|
+
subject: str | None = None
|
94
|
+
message_deduplication_id: str | None = None
|
95
|
+
message_group_id: str | None = None
|
96
|
+
token: str | None = None
|
97
|
+
message_id: str = field(default_factory=long_uid)
|
98
|
+
is_fifo: bool | None = False
|
99
|
+
sequencer_number: str | None = None
|
100
|
+
|
101
|
+
def __post_init__(self):
|
102
|
+
if self.message_attributes is None:
|
103
|
+
self.message_attributes = {}
|
104
|
+
if self.is_fifo:
|
105
|
+
self.sequencer_number = str(get_next_sequence_number())
|
106
|
+
|
107
|
+
def message_content(self, protocol: SnsMessageProtocols) -> str:
|
108
|
+
"""
|
109
|
+
Helper function to retrieve the message content for the right protocol if the StructureMessage is `json`
|
110
|
+
See https://docs.aws.amazon.com/sns/latest/dg/sns-send-custom-platform-specific-payloads-mobile-devices.html
|
111
|
+
https://docs.aws.amazon.com/sns/latest/dg/example_sns_Publish_section.html
|
112
|
+
:param protocol:
|
113
|
+
:return: message content as string
|
114
|
+
"""
|
115
|
+
if self.message_structure == "json":
|
116
|
+
return self.message.get(protocol, self.message.get("default"))
|
117
|
+
|
118
|
+
return self.message
|
119
|
+
|
120
|
+
@classmethod
|
121
|
+
def from_batch_entry(cls, entry: PublishBatchRequestEntry, is_fifo=False) -> "SnsMessage":
|
122
|
+
return cls(
|
123
|
+
type=SnsMessageType.Notification,
|
124
|
+
message=entry["Message"],
|
125
|
+
subject=entry.get("Subject"),
|
126
|
+
message_structure=entry.get("MessageStructure"),
|
127
|
+
message_attributes=entry.get("MessageAttributes"),
|
128
|
+
message_deduplication_id=entry.get("MessageDeduplicationId"),
|
129
|
+
message_group_id=entry.get("MessageGroupId"),
|
130
|
+
is_fifo=is_fifo,
|
131
|
+
)
|
17
132
|
|
18
133
|
|
19
134
|
class SnsStore(BaseStore):
|
20
135
|
topics: dict[str, Topic] = LocalAttribute(default=dict)
|
21
136
|
|
137
|
+
# maps subscription ARN to SnsSubscription
|
138
|
+
subscriptions: dict[str, SnsSubscription] = LocalAttribute(default=dict)
|
139
|
+
|
140
|
+
# filter policy are stored as JSON string in subscriptions, store the decoded result Dict
|
141
|
+
subscription_filter_policy: dict[subscriptionARN, dict] = LocalAttribute(default=dict)
|
142
|
+
|
143
|
+
# maps confirmation token to subscription ARN
|
144
|
+
subscription_tokens: dict[str, str] = LocalAttribute(default=dict)
|
145
|
+
|
22
146
|
TAGS: TaggingService = CrossRegionAttribute(default=TaggingService)
|
23
147
|
|
24
148
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
import contextlib
|
2
|
+
import copy
|
1
3
|
import json
|
2
4
|
import logging
|
3
5
|
import re
|
@@ -6,23 +8,56 @@ from botocore.utils import InvalidArnException
|
|
6
8
|
|
7
9
|
from localstack.aws.api import RequestContext
|
8
10
|
from localstack.aws.api.sns import (
|
11
|
+
ConfirmSubscriptionResponse,
|
9
12
|
CreateTopicResponse,
|
13
|
+
GetSubscriptionAttributesResponse,
|
10
14
|
GetTopicAttributesResponse,
|
11
15
|
InvalidParameterException,
|
16
|
+
ListSubscriptionsByTopicResponse,
|
17
|
+
ListSubscriptionsResponse,
|
12
18
|
ListTopicsResponse,
|
13
19
|
NotFoundException,
|
14
20
|
SnsApi,
|
21
|
+
String,
|
22
|
+
SubscribeResponse,
|
23
|
+
Subscription,
|
24
|
+
SubscriptionAttributesMap,
|
15
25
|
TagList,
|
16
26
|
TopicAttributesMap,
|
17
27
|
attributeName,
|
18
28
|
attributeValue,
|
29
|
+
authenticateOnUnsubscribe,
|
30
|
+
endpoint,
|
19
31
|
nextToken,
|
32
|
+
protocol,
|
33
|
+
subscriptionARN,
|
20
34
|
topicARN,
|
21
35
|
topicName,
|
22
36
|
)
|
23
|
-
from localstack.services.sns
|
24
|
-
from localstack.
|
25
|
-
from localstack.
|
37
|
+
from localstack.services.sns import constants as sns_constants
|
38
|
+
from localstack.services.sns.certificate import SNS_SERVER_CERT
|
39
|
+
from localstack.services.sns.constants import DUMMY_SUBSCRIPTION_PRINCIPAL
|
40
|
+
from localstack.services.sns.filter import FilterPolicyValidator
|
41
|
+
from localstack.services.sns.publisher import PublishDispatcher, SnsPublishContext
|
42
|
+
from localstack.services.sns.v2.models import (
|
43
|
+
SnsMessage,
|
44
|
+
SnsMessageType,
|
45
|
+
SnsStore,
|
46
|
+
SnsSubscription,
|
47
|
+
Topic,
|
48
|
+
sns_stores,
|
49
|
+
)
|
50
|
+
from localstack.services.sns.v2.utils import (
|
51
|
+
create_subscription_arn,
|
52
|
+
encode_subscription_token_with_region,
|
53
|
+
get_next_page_token_from_arn,
|
54
|
+
get_region_from_subscription_token,
|
55
|
+
is_valid_e164_number,
|
56
|
+
parse_and_validate_topic_arn,
|
57
|
+
validate_subscription_attribute,
|
58
|
+
)
|
59
|
+
from localstack.utils.aws.arns import get_partition, parse_arn, sns_topic_arn
|
60
|
+
from localstack.utils.collections import PaginatedList, select_from_typed_dict
|
26
61
|
|
27
62
|
# set up logger
|
28
63
|
LOG = logging.getLogger(__name__)
|
@@ -32,6 +67,13 @@ SNS_TOPIC_NAME_PATTERN = r"^[a-zA-Z0-9_-]{1,256}$"
|
|
32
67
|
|
33
68
|
|
34
69
|
class SnsProvider(SnsApi):
|
70
|
+
def __init__(self) -> None:
|
71
|
+
super().__init__()
|
72
|
+
self._publisher = PublishDispatcher()
|
73
|
+
self._signature_cert_pem: str = SNS_SERVER_CERT
|
74
|
+
|
75
|
+
## Topic Operations
|
76
|
+
|
35
77
|
def create_topic(
|
36
78
|
self,
|
37
79
|
context: RequestContext,
|
@@ -65,15 +107,17 @@ class SnsProvider(SnsApi):
|
|
65
107
|
)
|
66
108
|
else:
|
67
109
|
# AWS does not seem to save explicit settings of fifo = false
|
110
|
+
|
68
111
|
attributes.pop("FifoTopic", None)
|
69
112
|
name_match = re.match(SNS_TOPIC_NAME_PATTERN, name)
|
70
113
|
if not name_match:
|
71
114
|
raise InvalidParameterException("Invalid parameter: Topic Name")
|
72
115
|
|
73
116
|
topic = _create_topic(name=name, attributes=attributes, context=context)
|
74
|
-
store.topics[topic_arn] = topic
|
75
117
|
# todo: tags
|
76
118
|
|
119
|
+
store.topics[topic_arn] = topic
|
120
|
+
|
77
121
|
return CreateTopicResponse(TopicArn=topic_arn)
|
78
122
|
|
79
123
|
def get_topic_attributes(
|
@@ -98,7 +142,9 @@ class SnsProvider(SnsApi):
|
|
98
142
|
topics = [{"TopicArn": t["arn"]} for t in list(store.topics.values())]
|
99
143
|
topics = PaginatedList(topics)
|
100
144
|
page, nxt = topics.get_page(
|
101
|
-
lambda
|
145
|
+
token_generator=lambda x: get_next_page_token_from_arn(x["TopicArn"]),
|
146
|
+
next_token=next_token,
|
147
|
+
page_size=100,
|
102
148
|
)
|
103
149
|
topics = {"Topics": page, "NextToken": nxt}
|
104
150
|
return ListTopicsResponse(**topics)
|
@@ -116,6 +162,361 @@ class SnsProvider(SnsApi):
|
|
116
162
|
raise InvalidParameterException("Invalid parameter: AttributeName")
|
117
163
|
topic["attributes"][attribute_name] = attribute_value
|
118
164
|
|
165
|
+
## Subscribe operations
|
166
|
+
|
167
|
+
def subscribe(
|
168
|
+
self,
|
169
|
+
context: RequestContext,
|
170
|
+
topic_arn: topicARN,
|
171
|
+
protocol: protocol,
|
172
|
+
endpoint: endpoint | None = None,
|
173
|
+
attributes: SubscriptionAttributesMap | None = None,
|
174
|
+
return_subscription_arn: bool | None = None,
|
175
|
+
**kwargs,
|
176
|
+
) -> SubscribeResponse:
|
177
|
+
parsed_topic_arn = parse_and_validate_topic_arn(topic_arn)
|
178
|
+
if context.region != parsed_topic_arn["region"]:
|
179
|
+
raise InvalidParameterException("Invalid parameter: TopicArn")
|
180
|
+
|
181
|
+
store = self.get_store(account_id=parsed_topic_arn["account"], region=context.region)
|
182
|
+
|
183
|
+
if topic_arn not in store.topics:
|
184
|
+
raise NotFoundException("Topic does not exist")
|
185
|
+
|
186
|
+
topic_subscriptions = store.topics[topic_arn]["subscriptions"]
|
187
|
+
if not endpoint:
|
188
|
+
# TODO: check AWS behaviour (because endpoint is optional)
|
189
|
+
raise NotFoundException("Endpoint not specified in subscription")
|
190
|
+
if protocol not in sns_constants.SNS_PROTOCOLS:
|
191
|
+
raise InvalidParameterException(
|
192
|
+
f"Invalid parameter: Amazon SNS does not support this protocol string: {protocol}"
|
193
|
+
)
|
194
|
+
elif protocol in ["http", "https"] and not endpoint.startswith(f"{protocol}://"):
|
195
|
+
raise InvalidParameterException(
|
196
|
+
"Invalid parameter: Endpoint must match the specified protocol"
|
197
|
+
)
|
198
|
+
elif protocol == "sms" and not is_valid_e164_number(endpoint):
|
199
|
+
raise InvalidParameterException(f"Invalid SMS endpoint: {endpoint}")
|
200
|
+
|
201
|
+
elif protocol == "sqs":
|
202
|
+
try:
|
203
|
+
parse_arn(endpoint)
|
204
|
+
except InvalidArnException:
|
205
|
+
raise InvalidParameterException("Invalid parameter: SQS endpoint ARN")
|
206
|
+
|
207
|
+
elif protocol == "application":
|
208
|
+
# TODO: This needs to be implemented once applications are ported from moto to the new provider
|
209
|
+
raise NotImplementedError(
|
210
|
+
"This functionality needs yet to be ported to the new SNS provider"
|
211
|
+
)
|
212
|
+
|
213
|
+
if ".fifo" in endpoint and ".fifo" not in topic_arn:
|
214
|
+
# TODO: move to sqs protocol block if possible
|
215
|
+
raise InvalidParameterException(
|
216
|
+
"Invalid parameter: Invalid parameter: Endpoint Reason: FIFO SQS Queues can not be subscribed to standard SNS topics"
|
217
|
+
)
|
218
|
+
|
219
|
+
sub_attributes = copy.deepcopy(attributes) if attributes else None
|
220
|
+
if sub_attributes:
|
221
|
+
for attr_name, attr_value in sub_attributes.items():
|
222
|
+
validate_subscription_attribute(
|
223
|
+
attribute_name=attr_name,
|
224
|
+
attribute_value=attr_value,
|
225
|
+
topic_arn=topic_arn,
|
226
|
+
endpoint=endpoint,
|
227
|
+
is_subscribe_call=True,
|
228
|
+
)
|
229
|
+
if raw_msg_delivery := sub_attributes.get("RawMessageDelivery"):
|
230
|
+
sub_attributes["RawMessageDelivery"] = raw_msg_delivery.lower()
|
231
|
+
|
232
|
+
# An endpoint may only be subscribed to a topic once. Subsequent
|
233
|
+
# subscribe calls do nothing (subscribe is idempotent), except if its attributes are different.
|
234
|
+
for existing_topic_subscription in topic_subscriptions:
|
235
|
+
sub = store.subscriptions.get(existing_topic_subscription, {})
|
236
|
+
if sub.get("Endpoint") == endpoint:
|
237
|
+
if sub_attributes:
|
238
|
+
# validate the subscription attributes aren't different
|
239
|
+
for attr in sns_constants.VALID_SUBSCRIPTION_ATTR_NAME:
|
240
|
+
# if a new attribute is present and different from an existent one, raise
|
241
|
+
if (new_attr := sub_attributes.get(attr)) and sub.get(attr) != new_attr:
|
242
|
+
raise InvalidParameterException(
|
243
|
+
"Invalid parameter: Attributes Reason: Subscription already exists with different attributes"
|
244
|
+
)
|
245
|
+
|
246
|
+
return SubscribeResponse(SubscriptionArn=sub["SubscriptionArn"])
|
247
|
+
principal = DUMMY_SUBSCRIPTION_PRINCIPAL.format(
|
248
|
+
partition=get_partition(context.region), account_id=context.account_id
|
249
|
+
)
|
250
|
+
subscription_arn = create_subscription_arn(topic_arn)
|
251
|
+
subscription = SnsSubscription(
|
252
|
+
# http://docs.aws.amazon.com/cli/latest/reference/sns/get-subscription-attributes.html
|
253
|
+
TopicArn=topic_arn,
|
254
|
+
Endpoint=endpoint,
|
255
|
+
Protocol=protocol,
|
256
|
+
SubscriptionArn=subscription_arn,
|
257
|
+
PendingConfirmation="true",
|
258
|
+
Owner=context.account_id,
|
259
|
+
RawMessageDelivery="false", # default value, will be overridden if set
|
260
|
+
FilterPolicyScope="MessageAttributes", # default value, will be overridden if set
|
261
|
+
SubscriptionPrincipal=principal, # dummy value, could be fetched with a call to STS?
|
262
|
+
)
|
263
|
+
if sub_attributes:
|
264
|
+
subscription.update(sub_attributes)
|
265
|
+
if "FilterPolicy" in sub_attributes:
|
266
|
+
filter_policy = (
|
267
|
+
json.loads(sub_attributes["FilterPolicy"])
|
268
|
+
if sub_attributes["FilterPolicy"]
|
269
|
+
else None
|
270
|
+
)
|
271
|
+
if filter_policy:
|
272
|
+
validator = FilterPolicyValidator(
|
273
|
+
scope=subscription.get("FilterPolicyScope", "MessageAttributes"),
|
274
|
+
is_subscribe_call=True,
|
275
|
+
)
|
276
|
+
validator.validate_filter_policy(filter_policy)
|
277
|
+
|
278
|
+
store.subscription_filter_policy[subscription_arn] = filter_policy
|
279
|
+
|
280
|
+
store.subscriptions[subscription_arn] = subscription
|
281
|
+
|
282
|
+
topic_subscriptions.append(subscription_arn)
|
283
|
+
|
284
|
+
# store the token and subscription arn
|
285
|
+
# TODO: the token is a 288 hex char string
|
286
|
+
subscription_token = encode_subscription_token_with_region(region=context.region)
|
287
|
+
store.subscription_tokens[subscription_token] = subscription_arn
|
288
|
+
|
289
|
+
response_subscription_arn = subscription_arn
|
290
|
+
# Send out confirmation message for HTTP(S), fix for https://github.com/localstack/localstack/issues/881
|
291
|
+
if protocol in ["http", "https"]:
|
292
|
+
message_ctx = SnsMessage(
|
293
|
+
type=SnsMessageType.SubscriptionConfirmation,
|
294
|
+
token=subscription_token,
|
295
|
+
message=f"You have chosen to subscribe to the topic {topic_arn}.\nTo confirm the subscription, visit the SubscribeURL included in this message.",
|
296
|
+
)
|
297
|
+
publish_ctx = SnsPublishContext(
|
298
|
+
message=message_ctx,
|
299
|
+
store=store,
|
300
|
+
request_headers=context.request.headers,
|
301
|
+
# TODO: add topic attributes once they are ported from moto to LocalStack
|
302
|
+
# topic_attributes=vars(self._get_topic(topic_arn, context)),
|
303
|
+
)
|
304
|
+
self._publisher.publish_to_topic_subscriber(
|
305
|
+
ctx=publish_ctx,
|
306
|
+
topic_arn=topic_arn,
|
307
|
+
subscription_arn=subscription_arn,
|
308
|
+
)
|
309
|
+
if not return_subscription_arn:
|
310
|
+
response_subscription_arn = "pending confirmation"
|
311
|
+
|
312
|
+
elif protocol not in ["email", "email-json"]:
|
313
|
+
# Only HTTP(S) and email subscriptions are not auto validated
|
314
|
+
# Except if the endpoint and the topic are not in the same AWS account, then you'd need to manually confirm
|
315
|
+
# the subscription with the token
|
316
|
+
# TODO: revisit for multi-account
|
317
|
+
# TODO: test with AWS for email & email-json confirmation message
|
318
|
+
# we need to add the following check:
|
319
|
+
# if parsed_topic_arn["account"] == endpoint account (depending on the type, SQS, lambda, parse the arn)
|
320
|
+
subscription["PendingConfirmation"] = "false"
|
321
|
+
subscription["ConfirmationWasAuthenticated"] = "true"
|
322
|
+
|
323
|
+
return SubscribeResponse(SubscriptionArn=response_subscription_arn)
|
324
|
+
|
325
|
+
def unsubscribe(
|
326
|
+
self, context: RequestContext, subscription_arn: subscriptionARN, **kwargs
|
327
|
+
) -> None:
|
328
|
+
if subscription_arn is None:
|
329
|
+
raise InvalidParameterException(
|
330
|
+
"Invalid parameter: SubscriptionArn Reason: no value for required parameter",
|
331
|
+
)
|
332
|
+
count = len(subscription_arn.split(":"))
|
333
|
+
try:
|
334
|
+
parsed_arn = parse_arn(subscription_arn)
|
335
|
+
except InvalidArnException:
|
336
|
+
# TODO: check for invalid SubscriptionGUID
|
337
|
+
raise InvalidParameterException(
|
338
|
+
f"Invalid parameter: SubscriptionArn Reason: An ARN must have at least 6 elements, not {count}"
|
339
|
+
)
|
340
|
+
|
341
|
+
account_id = parsed_arn["account"]
|
342
|
+
region_name = parsed_arn["region"]
|
343
|
+
|
344
|
+
store = self.get_store(account_id=account_id, region=region_name)
|
345
|
+
if count == 6 and subscription_arn not in store.subscriptions:
|
346
|
+
raise InvalidParameterException("Invalid parameter: SubscriptionId")
|
347
|
+
|
348
|
+
# TODO: here was a moto_backend.unsubscribe call, check correct functionality and remove this comment
|
349
|
+
# before switching to v2 for production
|
350
|
+
|
351
|
+
# pop the subscription at the end, to avoid race condition by iterating over the topic subscriptions
|
352
|
+
subscription = store.subscriptions.get(subscription_arn)
|
353
|
+
|
354
|
+
if not subscription:
|
355
|
+
# unsubscribe is idempotent, so unsubscribing from a non-existing topic does nothing
|
356
|
+
return
|
357
|
+
|
358
|
+
if subscription["Protocol"] in ["http", "https"]:
|
359
|
+
# TODO: actually validate this (re)subscribe behaviour somehow (localhost.run?)
|
360
|
+
# we might need to save the sub token in the store
|
361
|
+
# TODO: AWS only sends the UnsubscribeConfirmation if the call is unauthenticated or the requester is not
|
362
|
+
# the owner
|
363
|
+
subscription_token = encode_subscription_token_with_region(region=context.region)
|
364
|
+
message_ctx = SnsMessage(
|
365
|
+
type=SnsMessageType.UnsubscribeConfirmation,
|
366
|
+
token=subscription_token,
|
367
|
+
message=f"You have chosen to deactivate subscription {subscription_arn}.\nTo cancel this operation and restore the subscription, visit the SubscribeURL included in this message.",
|
368
|
+
)
|
369
|
+
publish_ctx = SnsPublishContext(
|
370
|
+
message=message_ctx,
|
371
|
+
store=store,
|
372
|
+
request_headers=context.request.headers,
|
373
|
+
# TODO: add the topic attributes once we ported them from moto to LocalStack
|
374
|
+
# topic_attributes=vars(moto_topic),
|
375
|
+
)
|
376
|
+
self._publisher.publish_to_topic_subscriber(
|
377
|
+
publish_ctx,
|
378
|
+
topic_arn=subscription["TopicArn"],
|
379
|
+
subscription_arn=subscription_arn,
|
380
|
+
)
|
381
|
+
|
382
|
+
with contextlib.suppress(KeyError):
|
383
|
+
store.topics[subscription["TopicArn"]]["subscriptions"].remove(subscription_arn)
|
384
|
+
store.subscription_filter_policy.pop(subscription_arn, None)
|
385
|
+
store.subscriptions.pop(subscription_arn, None)
|
386
|
+
|
387
|
+
def get_subscription_attributes(
|
388
|
+
self, context: RequestContext, subscription_arn: subscriptionARN, **kwargs
|
389
|
+
) -> GetSubscriptionAttributesResponse:
|
390
|
+
store = self.get_store(account_id=context.account_id, region=context.region)
|
391
|
+
sub = store.subscriptions.get(subscription_arn)
|
392
|
+
if not sub:
|
393
|
+
raise NotFoundException("Subscription does not exist")
|
394
|
+
removed_attrs = ["sqs_queue_url"]
|
395
|
+
if "FilterPolicyScope" in sub and not sub.get("FilterPolicy"):
|
396
|
+
removed_attrs.append("FilterPolicyScope")
|
397
|
+
removed_attrs.append("FilterPolicy")
|
398
|
+
elif "FilterPolicy" in sub and "FilterPolicyScope" not in sub:
|
399
|
+
sub["FilterPolicyScope"] = "MessageAttributes"
|
400
|
+
|
401
|
+
attributes = {k: v for k, v in sub.items() if k not in removed_attrs}
|
402
|
+
return GetSubscriptionAttributesResponse(Attributes=attributes)
|
403
|
+
|
404
|
+
def set_subscription_attributes(
|
405
|
+
self,
|
406
|
+
context: RequestContext,
|
407
|
+
subscription_arn: subscriptionARN,
|
408
|
+
attribute_name: attributeName,
|
409
|
+
attribute_value: attributeValue = None,
|
410
|
+
**kwargs,
|
411
|
+
) -> None:
|
412
|
+
store = self.get_store(account_id=context.account_id, region=context.region)
|
413
|
+
sub = store.subscriptions.get(subscription_arn)
|
414
|
+
if not sub:
|
415
|
+
raise NotFoundException("Subscription does not exist")
|
416
|
+
|
417
|
+
validate_subscription_attribute(
|
418
|
+
attribute_name=attribute_name,
|
419
|
+
attribute_value=attribute_value,
|
420
|
+
topic_arn=sub["TopicArn"],
|
421
|
+
endpoint=sub["Endpoint"],
|
422
|
+
)
|
423
|
+
if attribute_name == "RawMessageDelivery":
|
424
|
+
attribute_value = attribute_value.lower()
|
425
|
+
|
426
|
+
elif attribute_name == "FilterPolicy":
|
427
|
+
filter_policy = json.loads(attribute_value) if attribute_value else None
|
428
|
+
if filter_policy:
|
429
|
+
validator = FilterPolicyValidator(
|
430
|
+
scope=sub.get("FilterPolicyScope", "MessageAttributes"),
|
431
|
+
is_subscribe_call=False,
|
432
|
+
)
|
433
|
+
validator.validate_filter_policy(filter_policy)
|
434
|
+
|
435
|
+
store.subscription_filter_policy[subscription_arn] = filter_policy
|
436
|
+
|
437
|
+
sub[attribute_name] = attribute_value
|
438
|
+
|
439
|
+
def confirm_subscription(
|
440
|
+
self,
|
441
|
+
context: RequestContext,
|
442
|
+
topic_arn: topicARN,
|
443
|
+
token: String,
|
444
|
+
authenticate_on_unsubscribe: authenticateOnUnsubscribe = None,
|
445
|
+
**kwargs,
|
446
|
+
) -> ConfirmSubscriptionResponse:
|
447
|
+
# TODO: validate format on the token (seems to be 288 hex chars)
|
448
|
+
# this request can come from any http client, it might not be signed (we would need to implement
|
449
|
+
# `authenticate_on_unsubscribe` to force a signing client to do this request.
|
450
|
+
# so, the region and account_id might not be in the request. Use the ones from the topic_arn
|
451
|
+
try:
|
452
|
+
parsed_arn = parse_arn(topic_arn)
|
453
|
+
except InvalidArnException:
|
454
|
+
raise InvalidParameterException("Invalid parameter: Topic")
|
455
|
+
|
456
|
+
store = self.get_store(account_id=parsed_arn["account"], region=parsed_arn["region"])
|
457
|
+
|
458
|
+
# it seems SNS is able to know what the region of the topic should be, even though a wrong topic is accepted
|
459
|
+
if parsed_arn["region"] != get_region_from_subscription_token(token):
|
460
|
+
raise InvalidParameterException("Invalid parameter: Topic")
|
461
|
+
|
462
|
+
subscription_arn = store.subscription_tokens.get(token)
|
463
|
+
if not subscription_arn:
|
464
|
+
raise InvalidParameterException("Invalid parameter: Token")
|
465
|
+
|
466
|
+
subscription = store.subscriptions.get(subscription_arn)
|
467
|
+
if not subscription:
|
468
|
+
# subscription could have been deleted in the meantime
|
469
|
+
raise InvalidParameterException("Invalid parameter: Token")
|
470
|
+
|
471
|
+
# ConfirmSubscription is idempotent
|
472
|
+
if subscription.get("PendingConfirmation") == "false":
|
473
|
+
return ConfirmSubscriptionResponse(SubscriptionArn=subscription_arn)
|
474
|
+
|
475
|
+
subscription["PendingConfirmation"] = "false"
|
476
|
+
subscription["ConfirmationWasAuthenticated"] = "true"
|
477
|
+
|
478
|
+
return ConfirmSubscriptionResponse(SubscriptionArn=subscription_arn)
|
479
|
+
|
480
|
+
def list_subscriptions(
|
481
|
+
self, context: RequestContext, next_token: nextToken = None, **kwargs
|
482
|
+
) -> ListSubscriptionsResponse:
|
483
|
+
store = self.get_store(context.account_id, context.region)
|
484
|
+
subscriptions = [
|
485
|
+
select_from_typed_dict(Subscription, sub) for sub in list(store.subscriptions.values())
|
486
|
+
]
|
487
|
+
paginated_subscriptions = PaginatedList(subscriptions)
|
488
|
+
page, next_token = paginated_subscriptions.get_page(
|
489
|
+
token_generator=lambda x: get_next_page_token_from_arn(x["SubscriptionArn"]),
|
490
|
+
page_size=100,
|
491
|
+
next_token=next_token,
|
492
|
+
)
|
493
|
+
|
494
|
+
response = ListSubscriptionsResponse(Subscriptions=page)
|
495
|
+
if next_token:
|
496
|
+
response["NextToken"] = next_token
|
497
|
+
return response
|
498
|
+
|
499
|
+
def list_subscriptions_by_topic(
|
500
|
+
self, context: RequestContext, topic_arn: topicARN, next_token: nextToken = None, **kwargs
|
501
|
+
) -> ListSubscriptionsByTopicResponse:
|
502
|
+
topic: Topic = self._get_topic(topic_arn, context)
|
503
|
+
parsed_topic_arn = parse_and_validate_topic_arn(topic_arn)
|
504
|
+
store = self.get_store(parsed_topic_arn["account"], parsed_topic_arn["region"])
|
505
|
+
sub_arns: list[str] = topic.get("subscriptions", [])
|
506
|
+
subscriptions = [store.subscriptions[k] for k in sub_arns if k in store.subscriptions]
|
507
|
+
|
508
|
+
paginated_subscriptions = PaginatedList(subscriptions)
|
509
|
+
page, next_token = paginated_subscriptions.get_page(
|
510
|
+
token_generator=lambda x: get_next_page_token_from_arn(x["SubscriptionArn"]),
|
511
|
+
page_size=100,
|
512
|
+
next_token=next_token,
|
513
|
+
)
|
514
|
+
|
515
|
+
response = ListSubscriptionsResponse(Subscriptions=page)
|
516
|
+
if next_token:
|
517
|
+
response["NextToken"] = next_token
|
518
|
+
return response
|
519
|
+
|
119
520
|
@staticmethod
|
120
521
|
def get_store(account_id: str, region: str) -> SnsStore:
|
121
522
|
return sns_stores[account_id][region]
|
@@ -138,17 +539,6 @@ class SnsProvider(SnsApi):
|
|
138
539
|
raise NotFoundException("Topic does not exist")
|
139
540
|
|
140
541
|
|
141
|
-
def parse_and_validate_topic_arn(topic_arn: str | None) -> ArnData:
|
142
|
-
topic_arn = topic_arn or ""
|
143
|
-
try:
|
144
|
-
return parse_arn(topic_arn)
|
145
|
-
except InvalidArnException:
|
146
|
-
count = len(topic_arn.split(":"))
|
147
|
-
raise InvalidParameterException(
|
148
|
-
f"Invalid parameter: TopicArn Reason: An ARN must have at least 6 elements, not {count}"
|
149
|
-
)
|
150
|
-
|
151
|
-
|
152
542
|
def _create_topic(name: str, attributes: dict, context: RequestContext) -> Topic:
|
153
543
|
topic_arn = sns_topic_arn(
|
154
544
|
topic_name=name, region_name=context.region, account_id=context.account_id
|
@@ -157,6 +547,7 @@ def _create_topic(name: str, attributes: dict, context: RequestContext) -> Topic
|
|
157
547
|
"name": name,
|
158
548
|
"arn": topic_arn,
|
159
549
|
"attributes": {},
|
550
|
+
"subscriptions": [],
|
160
551
|
}
|
161
552
|
attrs = _default_attributes(topic, context)
|
162
553
|
attrs.update(attributes or {})
|
@@ -0,0 +1,122 @@
|
|
1
|
+
import base64
|
2
|
+
import json
|
3
|
+
from uuid import uuid4
|
4
|
+
|
5
|
+
from botocore.utils import InvalidArnException
|
6
|
+
|
7
|
+
from localstack.aws.api.sns import InvalidParameterException
|
8
|
+
from localstack.services.sns.constants import E164_REGEX, VALID_SUBSCRIPTION_ATTR_NAME
|
9
|
+
from localstack.utils.aws.arns import ArnData, parse_arn
|
10
|
+
from localstack.utils.strings import short_uid, to_bytes, to_str
|
11
|
+
|
12
|
+
|
13
|
+
def parse_and_validate_topic_arn(topic_arn: str | None) -> ArnData:
|
14
|
+
topic_arn = topic_arn or ""
|
15
|
+
try:
|
16
|
+
return parse_arn(topic_arn)
|
17
|
+
except InvalidArnException:
|
18
|
+
count = len(topic_arn.split(":"))
|
19
|
+
raise InvalidParameterException(
|
20
|
+
f"Invalid parameter: TopicArn Reason: An ARN must have at least 6 elements, not {count}"
|
21
|
+
)
|
22
|
+
|
23
|
+
|
24
|
+
def is_valid_e164_number(number: str) -> bool:
|
25
|
+
return E164_REGEX.match(number) is not None
|
26
|
+
|
27
|
+
|
28
|
+
def validate_subscription_attribute(
|
29
|
+
attribute_name: str,
|
30
|
+
attribute_value: str,
|
31
|
+
topic_arn: str,
|
32
|
+
endpoint: str,
|
33
|
+
is_subscribe_call: bool = False,
|
34
|
+
) -> None:
|
35
|
+
"""
|
36
|
+
Validate the subscription attribute to be set. See:
|
37
|
+
https://docs.aws.amazon.com/sns/latest/api/API_SetSubscriptionAttributes.html
|
38
|
+
:param attribute_name: the subscription attribute name, must be in VALID_SUBSCRIPTION_ATTR_NAME
|
39
|
+
:param attribute_value: the subscription attribute value
|
40
|
+
:param topic_arn: the topic_arn of the subscription, needed to know if it is FIFO
|
41
|
+
:param endpoint: the subscription endpoint (like an SQS queue ARN)
|
42
|
+
:param is_subscribe_call: the error message is different if called from Subscribe or SetSubscriptionAttributes
|
43
|
+
:raises InvalidParameterException
|
44
|
+
:return:
|
45
|
+
"""
|
46
|
+
error_prefix = (
|
47
|
+
"Invalid parameter: Attributes Reason: " if is_subscribe_call else "Invalid parameter: "
|
48
|
+
)
|
49
|
+
if attribute_name not in VALID_SUBSCRIPTION_ATTR_NAME:
|
50
|
+
raise InvalidParameterException(f"{error_prefix}AttributeName")
|
51
|
+
|
52
|
+
if attribute_name == "FilterPolicy":
|
53
|
+
try:
|
54
|
+
json.loads(attribute_value or "{}")
|
55
|
+
except json.JSONDecodeError:
|
56
|
+
raise InvalidParameterException(f"{error_prefix}FilterPolicy: failed to parse JSON.")
|
57
|
+
elif attribute_name == "FilterPolicyScope":
|
58
|
+
if attribute_value not in ("MessageAttributes", "MessageBody"):
|
59
|
+
raise InvalidParameterException(
|
60
|
+
f"{error_prefix}FilterPolicyScope: Invalid value [{attribute_value}]. "
|
61
|
+
f"Please use either MessageBody or MessageAttributes"
|
62
|
+
)
|
63
|
+
elif attribute_name == "RawMessageDelivery":
|
64
|
+
# TODO: only for SQS and https(s) subs, + firehose
|
65
|
+
if attribute_value.lower() not in ("true", "false"):
|
66
|
+
raise InvalidParameterException(
|
67
|
+
f"{error_prefix}RawMessageDelivery: Invalid value [{attribute_value}]. "
|
68
|
+
f"Must be true or false."
|
69
|
+
)
|
70
|
+
|
71
|
+
elif attribute_name == "RedrivePolicy":
|
72
|
+
try:
|
73
|
+
dlq_target_arn = json.loads(attribute_value).get("deadLetterTargetArn", "")
|
74
|
+
except json.JSONDecodeError:
|
75
|
+
raise InvalidParameterException(f"{error_prefix}RedrivePolicy: failed to parse JSON.")
|
76
|
+
try:
|
77
|
+
parsed_arn = parse_arn(dlq_target_arn)
|
78
|
+
except InvalidArnException:
|
79
|
+
raise InvalidParameterException(
|
80
|
+
f"{error_prefix}RedrivePolicy: deadLetterTargetArn is an invalid arn"
|
81
|
+
)
|
82
|
+
|
83
|
+
if topic_arn.endswith(".fifo"):
|
84
|
+
if endpoint.endswith(".fifo") and (
|
85
|
+
not parsed_arn["resource"].endswith(".fifo") or "sqs" not in parsed_arn["service"]
|
86
|
+
):
|
87
|
+
raise InvalidParameterException(
|
88
|
+
f"{error_prefix}RedrivePolicy: must use a FIFO queue as DLQ for a FIFO Subscription to a FIFO Topic."
|
89
|
+
)
|
90
|
+
|
91
|
+
|
92
|
+
def create_subscription_arn(topic_arn: str) -> str:
|
93
|
+
# This is the format of a Subscription ARN
|
94
|
+
# arn:aws:sns:us-west-2:123456789012:my-topic:8a21d249-4329-4871-acc6-7be709c6ea7f
|
95
|
+
return f"{topic_arn}:{uuid4()}"
|
96
|
+
|
97
|
+
|
98
|
+
def encode_subscription_token_with_region(region: str) -> str:
|
99
|
+
"""
|
100
|
+
Create a 64 characters Subscription Token with the region encoded
|
101
|
+
:param region:
|
102
|
+
:return: a subscription token with the region encoded
|
103
|
+
"""
|
104
|
+
return ((region.encode() + b"/").hex() + short_uid() * 8)[:64]
|
105
|
+
|
106
|
+
|
107
|
+
def get_next_page_token_from_arn(resource_arn: str) -> str:
|
108
|
+
return to_str(base64.b64encode(to_bytes(resource_arn)))
|
109
|
+
|
110
|
+
|
111
|
+
def get_region_from_subscription_token(token: str) -> str:
|
112
|
+
"""
|
113
|
+
Try to decode and return the region from a subscription token
|
114
|
+
:param token:
|
115
|
+
:return: the region if able to decode it
|
116
|
+
:raises: InvalidParameterException if the token is invalid
|
117
|
+
"""
|
118
|
+
try:
|
119
|
+
region = token.split("2f", maxsplit=1)[0]
|
120
|
+
return bytes.fromhex(region).decode("utf-8")
|
121
|
+
except (IndexError, ValueError, TypeError, UnicodeDecodeError):
|
122
|
+
raise InvalidParameterException("Invalid parameter: Token")
|
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.9.3.
|
32
|
-
__version_tuple__ = version_tuple = (4, 9, 3, '
|
31
|
+
__version__ = version = '4.9.3.dev42'
|
32
|
+
__version_tuple__ = version_tuple = (4, 9, 3, 'dev42')
|
33
33
|
|
34
34
|
__commit_id__ = commit_id = None
|
@@ -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=
|
7
|
+
localstack/version.py,sha256=R6WReT_EbNwc6MIm73a-7ZbGAxDGRV6il63PE67jHgk,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
|
@@ -741,7 +741,7 @@ localstack/services/ses/resource_providers/aws_ses_emailidentity_plugin.py,sha25
|
|
741
741
|
localstack/services/sns/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
742
742
|
localstack/services/sns/analytics.py,sha256=ecVRQ1l722ppZiKPny3m3rbNM0SKxO90rdyYWE5SI78,379
|
743
743
|
localstack/services/sns/certificate.py,sha256=g30Pi4CMu9u4hFTGUPua6JG5f-kOFmRIJdDu0RpIj7I,1882
|
744
|
-
localstack/services/sns/constants.py,sha256=
|
744
|
+
localstack/services/sns/constants.py,sha256=8CeBPRg8pvFtd441tOWJm3ifPSzSCmQdW3S8oWD-hhk,1274
|
745
745
|
localstack/services/sns/executor.py,sha256=VRaoalDYwo-K_1iDAMkeNZ6uXHo_WtGv4qPgNMxmAAk,4134
|
746
746
|
localstack/services/sns/filter.py,sha256=aHkd3oF2RTvuHiFZvVv1dD2qVpLUQkAeU2hJBQnW4xU,22990
|
747
747
|
localstack/services/sns/models.py,sha256=X0CMwm04vwIIK2Kj9ooP_2van1cA5fMvualDiq6guf4,6888
|
@@ -757,8 +757,9 @@ localstack/services/sns/resource_providers/aws_sns_topic_plugin.py,sha256=6I9qK7
|
|
757
757
|
localstack/services/sns/resource_providers/aws_sns_topicpolicy.py,sha256=su9pOM3M0sh24yGSdrm-QjM5G7B0n7zh4b3__KcR5Co,3471
|
758
758
|
localstack/services/sns/resource_providers/aws_sns_topicpolicy.schema.json,sha256=Q5XQbEaVKxIfvm_6GlYzl3BtezcE6hET8MuJmlGwohY,1677
|
759
759
|
localstack/services/sns/resource_providers/aws_sns_topicpolicy_plugin.py,sha256=7VfQhlKCLiYpI9_6qo2pKm4Al-ihxtoOGlpC7sWcTmc,527
|
760
|
-
localstack/services/sns/v2/models.py,sha256=
|
761
|
-
localstack/services/sns/v2/provider.py,sha256=
|
760
|
+
localstack/services/sns/v2/models.py,sha256=8deGSW3EDFKyX5q3Er0qKMSQHH6wawBGoMJpXnQDDKw,5341
|
761
|
+
localstack/services/sns/v2/provider.py,sha256=_C-9aeIydFgWmFWGv3Xa0IHoaX-_b4Gy_s5LhK2EwJs,25810
|
762
|
+
localstack/services/sns/v2/utils.py,sha256=_bb1bYRXWqDLbpG9Yuq6x_apiAAjYf5AMHp85KiK_qs,4919
|
762
763
|
localstack/services/sqs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
763
764
|
localstack/services/sqs/constants.py,sha256=9MLAOW4-hcbZlP2qYMY3giUnubHD_mgoORT0nh5W04Q,2826
|
764
765
|
localstack/services/sqs/developer_api.py,sha256=fNQNMqCkDyvobRm8g4-ErXjSYQ4O-myYobXA_RneC9o,8004
|
@@ -1296,13 +1297,13 @@ localstack/utils/server/tcp_proxy.py,sha256=y2NJAmvftTiAYsLU_8qe4W5LGqwUw21i90Pu
|
|
1296
1297
|
localstack/utils/xray/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1297
1298
|
localstack/utils/xray/trace_header.py,sha256=ahXk9eonq7LpeENwlqUEPj3jDOCiVRixhntQuxNor-Q,6209
|
1298
1299
|
localstack/utils/xray/traceid.py,sha256=GKO-R2sMMjlrH2UaLPXlQlZ6flbE7ZKb6IZMtMu_M5U,1110
|
1299
|
-
localstack_core-4.9.3.
|
1300
|
-
localstack_core-4.9.3.
|
1301
|
-
localstack_core-4.9.3.
|
1302
|
-
localstack_core-4.9.3.
|
1303
|
-
localstack_core-4.9.3.
|
1304
|
-
localstack_core-4.9.3.
|
1305
|
-
localstack_core-4.9.3.
|
1306
|
-
localstack_core-4.9.3.
|
1307
|
-
localstack_core-4.9.3.
|
1308
|
-
localstack_core-4.9.3.
|
1300
|
+
localstack_core-4.9.3.dev42.data/scripts/localstack,sha256=WyL11vp5CkuP79iIR-L8XT7Cj8nvmxX7XRAgxhbmXNE,529
|
1301
|
+
localstack_core-4.9.3.dev42.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
|
1302
|
+
localstack_core-4.9.3.dev42.data/scripts/localstack.bat,sha256=tlzZTXtveHkMX_s_fa7VDfvdNdS8iVpEz2ER3uk9B_c,29
|
1303
|
+
localstack_core-4.9.3.dev42.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
|
1304
|
+
localstack_core-4.9.3.dev42.dist-info/METADATA,sha256=1OSdv08N6sN0zjZfCyJTjh7EqWXPdMDC58hvKCiML00,5539
|
1305
|
+
localstack_core-4.9.3.dev42.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
1306
|
+
localstack_core-4.9.3.dev42.dist-info/entry_points.txt,sha256=5IoyjalZoY-PWY5Lk_AeEjEEQ-rKQJhijLe697GVlnM,20953
|
1307
|
+
localstack_core-4.9.3.dev42.dist-info/plux.json,sha256=tfoczGrwo9cwbGIR5rnVO9M0SnaUkFzBKKPygm1w5IU,21181
|
1308
|
+
localstack_core-4.9.3.dev42.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
|
1309
|
+
localstack_core-4.9.3.dev42.dist-info/RECORD,,
|
@@ -0,0 +1 @@
|
|
1
|
+
{"localstack.hooks.on_infra_start": ["_publish_config_as_analytics_event=localstack.runtime.analytics:_publish_config_as_analytics_event", "_publish_container_info=localstack.runtime.analytics:_publish_container_info", "apply_runtime_patches=localstack.runtime.patches:apply_runtime_patches", "_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", "_run_init_scripts_on_start=localstack.runtime.init:_run_init_scripts_on_start", "delete_cached_certificate=localstack.plugins:delete_cached_certificate", "deprecation_warnings=localstack.plugins:deprecation_warnings", "conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger", "init_response_mutation_handler=localstack.aws.handlers.response:init_response_mutation_handler", "eager_load_services=localstack.services.plugins:eager_load_services", "register_cloudformation_deploy_ui=localstack.services.cloudformation.plugins:register_cloudformation_deploy_ui", "register_custom_endpoints=localstack.services.lambda_.plugins:register_custom_endpoints", "validate_configuration=localstack.services.lambda_.plugins:validate_configuration", "register_swagger_endpoints=localstack.http.resources.swagger.plugins:register_swagger_endpoints", "apply_aws_runtime_patches=localstack.aws.patches:apply_aws_runtime_patches", "setup_dns_configuration_on_host=localstack.dns.plugins:setup_dns_configuration_on_host", "start_dns_server=localstack.dns.plugins:start_dns_server"], "localstack.cloudformation.resource_providers": ["AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "AWS::ApiGateway::RestApi=localstack.services.apigateway.resource_providers.aws_apigateway_restapi_plugin:ApiGatewayRestApiProviderPlugin", "AWS::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::CertificateManager::Certificate=localstack.services.certificatemanager.resource_providers.aws_certificatemanager_certificate_plugin:CertificateManagerCertificateProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::EC2::NetworkAcl=localstack.services.ec2.resource_providers.aws_ec2_networkacl_plugin:EC2NetworkAclProviderPlugin", "AWS::Lambda::Permission=localstack.services.lambda_.resource_providers.aws_lambda_permission_plugin:LambdaPermissionProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::EC2::RouteTable=localstack.services.ec2.resource_providers.aws_ec2_routetable_plugin:EC2RouteTableProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::KMS::Key=localstack.services.kms.resource_providers.aws_kms_key_plugin:KMSKeyProviderPlugin", "AWS::SNS::Subscription=localstack.services.sns.resource_providers.aws_sns_subscription_plugin:SNSSubscriptionProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "AWS::IAM::ManagedPolicy=localstack.services.iam.resource_providers.aws_iam_managedpolicy_plugin:IAMManagedPolicyProviderPlugin", "AWS::DynamoDB::Table=localstack.services.dynamodb.resource_providers.aws_dynamodb_table_plugin:DynamoDBTableProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::Events::ApiDestination=localstack.services.events.resource_providers.aws_events_apidestination_plugin:EventsApiDestinationProviderPlugin", "AWS::EC2::Route=localstack.services.ec2.resource_providers.aws_ec2_route_plugin:EC2RouteProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "AWS::DynamoDB::GlobalTable=localstack.services.dynamodb.resource_providers.aws_dynamodb_globaltable_plugin:DynamoDBGlobalTableProviderPlugin", "AWS::Events::EventBus=localstack.services.events.resource_providers.aws_events_eventbus_plugin:EventsEventBusProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "AWS::IAM::Policy=localstack.services.iam.resource_providers.aws_iam_policy_plugin:IAMPolicyProviderPlugin", "AWS::Lambda::Function=localstack.services.lambda_.resource_providers.aws_lambda_function_plugin:LambdaFunctionProviderPlugin", "AWS::Lambda::EventInvokeConfig=localstack.services.lambda_.resource_providers.aws_lambda_eventinvokeconfig_plugin:LambdaEventInvokeConfigProviderPlugin", "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::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::Route53::RecordSet=localstack.services.route53.resource_providers.aws_route53_recordset_plugin:Route53RecordSetProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "AWS::EC2::PrefixList=localstack.services.ec2.resource_providers.aws_ec2_prefixlist_plugin:EC2PrefixListProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::ApiGateway::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "AWS::Kinesis::StreamConsumer=localstack.services.kinesis.resource_providers.aws_kinesis_streamconsumer_plugin:KinesisStreamConsumerProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::SQS::QueuePolicy=localstack.services.sqs.resource_providers.aws_sqs_queuepolicy_plugin:SQSQueuePolicyProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::EC2::VPC=localstack.services.ec2.resource_providers.aws_ec2_vpc_plugin:EC2VPCProviderPlugin", "AWS::Route53::HealthCheck=localstack.services.route53.resource_providers.aws_route53_healthcheck_plugin:Route53HealthCheckProviderPlugin", "AWS::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::EC2::TransitGateway=localstack.services.ec2.resource_providers.aws_ec2_transitgateway_plugin:EC2TransitGatewayProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::Lambda::LayerVersionPermission=localstack.services.lambda_.resource_providers.aws_lambda_layerversionpermission_plugin:LambdaLayerVersionPermissionProviderPlugin", "AWS::EC2::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin", "AWS::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::ApiGateway::ApiKey=localstack.services.apigateway.resource_providers.aws_apigateway_apikey_plugin:ApiGatewayApiKeyProviderPlugin", "AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin", "AWS::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::SNS::TopicPolicy=localstack.services.sns.resource_providers.aws_sns_topicpolicy_plugin:SNSTopicPolicyProviderPlugin", "AWS::CloudWatch::CompositeAlarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_compositealarm_plugin:CloudWatchCompositeAlarmProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::ApiGateway::Deployment=localstack.services.apigateway.resource_providers.aws_apigateway_deployment_plugin:ApiGatewayDeploymentProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "AWS::Lambda::Alias=localstack.services.lambda_.resource_providers.lambda_alias_plugin:LambdaAliasProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "AWS::Lambda::Version=localstack.services.lambda_.resource_providers.aws_lambda_version_plugin:LambdaVersionProviderPlugin", "AWS::OpenSearchService::Domain=localstack.services.opensearch.resource_providers.aws_opensearchservice_domain_plugin:OpenSearchServiceDomainProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::ApiGateway::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::IAM::ServerCertificate=localstack.services.iam.resource_providers.aws_iam_servercertificate_plugin:IAMServerCertificateProviderPlugin", "AWS::Events::EventBusPolicy=localstack.services.events.resource_providers.aws_events_eventbuspolicy_plugin:EventsEventBusPolicyProviderPlugin", "AWS::ApiGateway::DomainName=localstack.services.apigateway.resource_providers.aws_apigateway_domainname_plugin:ApiGatewayDomainNameProviderPlugin", "AWS::EC2::Subnet=localstack.services.ec2.resource_providers.aws_ec2_subnet_plugin:EC2SubnetProviderPlugin", "AWS::SecretsManager::SecretTargetAttachment=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment_plugin:SecretsManagerSecretTargetAttachmentProviderPlugin", "AWS::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin", "AWS::IAM::InstanceProfile=localstack.services.iam.resource_providers.aws_iam_instanceprofile_plugin:IAMInstanceProfileProviderPlugin", "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::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"], "localstack.hooks.on_infra_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", "_run_init_scripts_on_shutdown=localstack.runtime.init:_run_init_scripts_on_shutdown", "publish_metrics=localstack.utils.analytics.metrics.publisher:publish_metrics", "remove_custom_endpoints=localstack.services.lambda_.plugins:remove_custom_endpoints", "stop_server=localstack.dns.plugins:stop_server"], "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": ["elasticsearch/community=localstack.services.es.plugins:elasticsearch_package", "opensearch/community=localstack.services.opensearch.plugins:opensearch_package", "kinesis-mock/community=localstack.services.kinesis.plugins:kinesismock_package", "jpype-jsonata/community=localstack.services.stepfunctions.plugins:jpype_jsonata_package", "lambda-java-libs/community=localstack.services.lambda_.plugins:lambda_java_libs", "lambda-runtime/community=localstack.services.lambda_.plugins:lambda_runtime_package", "vosk/community=localstack.services.transcribe.plugins:vosk_package", "ffmpeg/community=localstack.packages.plugins:ffmpeg_package", "java/community=localstack.packages.plugins:java_package", "dynamodb-local/community=localstack.services.dynamodb.plugins:dynamodb_local_package"], "localstack.hooks.on_infra_ready": ["publish_provider_assignment=localstack.utils.analytics.service_providers:publish_provider_assignment", "_run_init_scripts_on_ready=localstack.runtime.init:_run_init_scripts_on_ready"], "localstack.init.runner": ["py=localstack.runtime.init:PythonScriptRunner", "sh=localstack.runtime.init:ShellScriptRunner"], "localstack.openapi.spec": ["localstack=localstack.plugins:CoreOASPlugin"], "localstack.runtime.server": ["hypercorn=localstack.runtime.server.plugins:HypercornRuntimeServerPlugin", "twisted=localstack.runtime.server.plugins:TwistedRuntimeServerPlugin"], "localstack.runtime.components": ["aws=localstack.aws.components:AwsComponents"], "localstack.aws.provider": ["acm:default=localstack.services.providers:acm", "apigateway:default=localstack.services.providers:apigateway", "apigateway:legacy=localstack.services.providers:apigateway_legacy", "apigateway:next_gen=localstack.services.providers:apigateway_next_gen", "config:default=localstack.services.providers:awsconfig", "cloudformation:engine-legacy=localstack.services.providers:cloudformation", "cloudformation:default=localstack.services.providers:cloudformation_v2", "cloudwatch:default=localstack.services.providers:cloudwatch", "cloudwatch:v1=localstack.services.providers:cloudwatch_v1", "cloudwatch:v2=localstack.services.providers:cloudwatch_v2", "dynamodb:default=localstack.services.providers:dynamodb", "dynamodb:v2=localstack.services.providers:dynamodb_v2", "dynamodbstreams:default=localstack.services.providers:dynamodbstreams", "dynamodbstreams:v2=localstack.services.providers:dynamodbstreams_v2", "ec2:default=localstack.services.providers:ec2", "es:default=localstack.services.providers:es", "events:default=localstack.services.providers:events", "events:legacy=localstack.services.providers:events_legacy", "events:v1=localstack.services.providers:events_v1", "events:v2=localstack.services.providers:events_v2", "firehose:default=localstack.services.providers:firehose", "iam:default=localstack.services.providers:iam", "kinesis:default=localstack.services.providers:kinesis", "kms:default=localstack.services.providers:kms", "lambda:default=localstack.services.providers:lambda_", "lambda:asf=localstack.services.providers:lambda_asf", "lambda:v2=localstack.services.providers:lambda_v2", "logs:default=localstack.services.providers:logs", "opensearch:default=localstack.services.providers:opensearch", "redshift:default=localstack.services.providers:redshift", "resource-groups:default=localstack.services.providers:resource_groups", "resourcegroupstaggingapi:default=localstack.services.providers:resourcegroupstaggingapi", "route53:default=localstack.services.providers:route53", "route53resolver:default=localstack.services.providers:route53resolver", "s3:default=localstack.services.providers:s3", "s3control:default=localstack.services.providers:s3control", "scheduler:default=localstack.services.providers:scheduler", "secretsmanager:default=localstack.services.providers:secretsmanager", "ses:default=localstack.services.providers:ses", "sns:default=localstack.services.providers:sns", "sns:v2=localstack.services.providers:sns_v2", "sqs:default=localstack.services.providers:sqs", "ssm:default=localstack.services.providers:ssm", "stepfunctions:default=localstack.services.providers:stepfunctions", "stepfunctions:v2=localstack.services.providers:stepfunctions_v2", "sts:default=localstack.services.providers:sts", "support:default=localstack.services.providers:support", "swf:default=localstack.services.providers:swf", "transcribe:default=localstack.services.providers:transcribe"], "localstack.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"]}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"localstack.cloudformation.resource_providers": ["AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::EC2::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "AWS::Lambda::Version=localstack.services.lambda_.resource_providers.aws_lambda_version_plugin:LambdaVersionProviderPlugin", "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::KMS::Key=localstack.services.kms.resource_providers.aws_kms_key_plugin:KMSKeyProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "AWS::Events::EventBusPolicy=localstack.services.events.resource_providers.aws_events_eventbuspolicy_plugin:EventsEventBusPolicyProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::DynamoDB::Table=localstack.services.dynamodb.resource_providers.aws_dynamodb_table_plugin:DynamoDBTableProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::EC2::Subnet=localstack.services.ec2.resource_providers.aws_ec2_subnet_plugin:EC2SubnetProviderPlugin", "AWS::ApiGateway::Deployment=localstack.services.apigateway.resource_providers.aws_apigateway_deployment_plugin:ApiGatewayDeploymentProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::SNS::Topic=localstack.services.sns.resource_providers.aws_sns_topic_plugin:SNSTopicProviderPlugin", "AWS::SNS::TopicPolicy=localstack.services.sns.resource_providers.aws_sns_topicpolicy_plugin:SNSTopicPolicyProviderPlugin", "AWS::IAM::Policy=localstack.services.iam.resource_providers.aws_iam_policy_plugin:IAMPolicyProviderPlugin", "AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::KMS::Alias=localstack.services.kms.resource_providers.aws_kms_alias_plugin:KMSAliasProviderPlugin", "AWS::EC2::RouteTable=localstack.services.ec2.resource_providers.aws_ec2_routetable_plugin:EC2RouteTableProviderPlugin", "AWS::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::EC2::TransitGateway=localstack.services.ec2.resource_providers.aws_ec2_transitgateway_plugin:EC2TransitGatewayProviderPlugin", "AWS::Route53::RecordSet=localstack.services.route53.resource_providers.aws_route53_recordset_plugin:Route53RecordSetProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::EC2::PrefixList=localstack.services.ec2.resource_providers.aws_ec2_prefixlist_plugin:EC2PrefixListProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::Lambda::LayerVersionPermission=localstack.services.lambda_.resource_providers.aws_lambda_layerversionpermission_plugin:LambdaLayerVersionPermissionProviderPlugin", "AWS::CloudWatch::CompositeAlarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_compositealarm_plugin:CloudWatchCompositeAlarmProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::IAM::ServerCertificate=localstack.services.iam.resource_providers.aws_iam_servercertificate_plugin:IAMServerCertificateProviderPlugin", "AWS::Route53::HealthCheck=localstack.services.route53.resource_providers.aws_route53_healthcheck_plugin:Route53HealthCheckProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::IAM::ManagedPolicy=localstack.services.iam.resource_providers.aws_iam_managedpolicy_plugin:IAMManagedPolicyProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "AWS::EC2::VPC=localstack.services.ec2.resource_providers.aws_ec2_vpc_plugin:EC2VPCProviderPlugin", "AWS::Lambda::Permission=localstack.services.lambda_.resource_providers.aws_lambda_permission_plugin:LambdaPermissionProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin", "AWS::Lambda::Function=localstack.services.lambda_.resource_providers.aws_lambda_function_plugin:LambdaFunctionProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::OpenSearchService::Domain=localstack.services.opensearch.resource_providers.aws_opensearchservice_domain_plugin:OpenSearchServiceDomainProviderPlugin", "AWS::ApiGateway::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "AWS::CertificateManager::Certificate=localstack.services.certificatemanager.resource_providers.aws_certificatemanager_certificate_plugin:CertificateManagerCertificateProviderPlugin", "AWS::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "AWS::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::IAM::Role=localstack.services.iam.resource_providers.aws_iam_role_plugin:IAMRoleProviderPlugin", "AWS::EC2::VPCGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_vpcgatewayattachment_plugin:EC2VPCGatewayAttachmentProviderPlugin", "AWS::Lambda::Alias=localstack.services.lambda_.resource_providers.lambda_alias_plugin:LambdaAliasProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::Lambda::EventSourceMapping=localstack.services.lambda_.resource_providers.aws_lambda_eventsourcemapping_plugin:LambdaEventSourceMappingProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "AWS::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::Events::ApiDestination=localstack.services.events.resource_providers.aws_events_apidestination_plugin:EventsApiDestinationProviderPlugin", "AWS::IAM::InstanceProfile=localstack.services.iam.resource_providers.aws_iam_instanceprofile_plugin:IAMInstanceProfileProviderPlugin", "AWS::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::EC2::Route=localstack.services.ec2.resource_providers.aws_ec2_route_plugin:EC2RouteProviderPlugin", "AWS::SNS::Subscription=localstack.services.sns.resource_providers.aws_sns_subscription_plugin:SNSSubscriptionProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "AWS::Lambda::EventInvokeConfig=localstack.services.lambda_.resource_providers.aws_lambda_eventinvokeconfig_plugin:LambdaEventInvokeConfigProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::ApiGateway::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "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::Events::EventBus=localstack.services.events.resource_providers.aws_events_eventbus_plugin:EventsEventBusProviderPlugin", "AWS::ApiGateway::ApiKey=localstack.services.apigateway.resource_providers.aws_apigateway_apikey_plugin:ApiGatewayApiKeyProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::SecretsManager::SecretTargetAttachment=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment_plugin:SecretsManagerSecretTargetAttachmentProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::ApiGateway::RestApi=localstack.services.apigateway.resource_providers.aws_apigateway_restapi_plugin:ApiGatewayRestApiProviderPlugin", "AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "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"], "localstack.utils.catalog": ["aws-catalog-remote-state=localstack.utils.catalog.catalog:AwsCatalogRemoteStatePlugin", "aws-catalog-runtime-only=localstack.utils.catalog.catalog:AwsCatalogRuntimePlugin"], "localstack.hooks.on_infra_start": ["eager_load_services=localstack.services.plugins:eager_load_services", "setup_dns_configuration_on_host=localstack.dns.plugins:setup_dns_configuration_on_host", "start_dns_server=localstack.dns.plugins:start_dns_server", "register_swagger_endpoints=localstack.http.resources.swagger.plugins:register_swagger_endpoints", "_publish_config_as_analytics_event=localstack.runtime.analytics:_publish_config_as_analytics_event", "_publish_container_info=localstack.runtime.analytics:_publish_container_info", "register_custom_endpoints=localstack.services.lambda_.plugins:register_custom_endpoints", "validate_configuration=localstack.services.lambda_.plugins:validate_configuration", "register_cloudformation_deploy_ui=localstack.services.cloudformation.plugins:register_cloudformation_deploy_ui", "_run_init_scripts_on_start=localstack.runtime.init:_run_init_scripts_on_start", "delete_cached_certificate=localstack.plugins:delete_cached_certificate", "deprecation_warnings=localstack.plugins:deprecation_warnings", "apply_aws_runtime_patches=localstack.aws.patches:apply_aws_runtime_patches", "_patch_botocore_endpoint_in_memory=localstack.aws.client:_patch_botocore_endpoint_in_memory", "_patch_botocore_json_parser=localstack.aws.client:_patch_botocore_json_parser", "_patch_cbor2=localstack.aws.client:_patch_cbor2", "apply_runtime_patches=localstack.runtime.patches:apply_runtime_patches", "conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger", "init_response_mutation_handler=localstack.aws.handlers.response:init_response_mutation_handler"], "localstack.hooks.on_infra_shutdown": ["stop_server=localstack.dns.plugins:stop_server", "remove_custom_endpoints=localstack.services.lambda_.plugins:remove_custom_endpoints", "run_on_after_service_shutdown_handlers=localstack.runtime.shutdown:run_on_after_service_shutdown_handlers", "run_shutdown_handlers=localstack.runtime.shutdown:run_shutdown_handlers", "shutdown_services=localstack.runtime.shutdown:shutdown_services", "_run_init_scripts_on_shutdown=localstack.runtime.init:_run_init_scripts_on_shutdown", "publish_metrics=localstack.utils.analytics.metrics.publisher:publish_metrics"], "localstack.packages": ["vosk/community=localstack.services.transcribe.plugins:vosk_package", "ffmpeg/community=localstack.packages.plugins:ffmpeg_package", "java/community=localstack.packages.plugins:java_package", "opensearch/community=localstack.services.opensearch.plugins:opensearch_package", "lambda-java-libs/community=localstack.services.lambda_.plugins:lambda_java_libs", "lambda-runtime/community=localstack.services.lambda_.plugins:lambda_runtime_package", "kinesis-mock/community=localstack.services.kinesis.plugins:kinesismock_package", "elasticsearch/community=localstack.services.es.plugins:elasticsearch_package", "jpype-jsonata/community=localstack.services.stepfunctions.plugins:jpype_jsonata_package", "dynamodb-local/community=localstack.services.dynamodb.plugins:dynamodb_local_package"], "localstack.lambda.runtime_executor": ["docker=localstack.services.lambda_.invocation.plugins:DockerRuntimeExecutorPlugin"], "localstack.runtime.server": ["hypercorn=localstack.runtime.server.plugins:HypercornRuntimeServerPlugin", "twisted=localstack.runtime.server.plugins:TwistedRuntimeServerPlugin"], "localstack.hooks.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.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.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.openapi.spec": ["localstack=localstack.plugins:CoreOASPlugin"], "localstack.runtime.components": ["aws=localstack.aws.components:AwsComponents"]}
|
File without changes
|
{localstack_core-4.9.3.dev40.data → localstack_core-4.9.3.dev42.data}/scripts/localstack-supervisor
RENAMED
File without changes
|
{localstack_core-4.9.3.dev40.data → localstack_core-4.9.3.dev42.data}/scripts/localstack.bat
RENAMED
File without changes
|
File without changes
|
{localstack_core-4.9.3.dev40.dist-info → localstack_core-4.9.3.dev42.dist-info}/entry_points.txt
RENAMED
File without changes
|
{localstack_core-4.9.3.dev40.dist-info → localstack_core-4.9.3.dev42.dist-info}/licenses/LICENSE.txt
RENAMED
File without changes
|
{localstack_core-4.9.3.dev40.dist-info → localstack_core-4.9.3.dev42.dist-info}/top_level.txt
RENAMED
File without changes
|