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

@@ -19,22 +19,24 @@ The class hierarchy looks as follows:
19
19
  │RequestParser│
20
20
  └─────────────┘
21
21
  ▲ ▲ ▲
22
- ┌─────────────────┘ │ └────────────────────┐
23
- ┌────────┴─────────┐ ┌─────────┴───────────┐ ┌──────────┴──────────┐
24
- │QueryRequestParser│ │BaseRestRequestParser│ │BaseJSONRequestParser│
25
- └──────────────────┘ └─────────────────────┘ └─────────────────────┘
26
- ▲ ▲ ▲ ▲ ▲
27
- ┌───────┴────────┐ ┌─────────┴──────────┐ │ │
28
- │EC2RequestParser│ │RestXMLRequestParser│ │ │
29
- └────────────────┘ └────────────────────┘ │ │
30
- ┌────────────────┴───┴┐ ┌────────┴────────┐
31
- │RestJSONRequestParser│ │JSONRequestParser│
32
- └─────────────────────┘ └─────────────────┘
22
+ ┌─────────────────┘ │ └────────────────────┬───────────────────────┐
23
+ ┌────────┴─────────┐ ┌─────────┴───────────┐ ┌──────────┴──────────┐ ┌──────────┴──────────┐
24
+ │QueryRequestParser│ │BaseRestRequestParser│ │BaseJSONRequestParser│ │BaseCBORRequestParser│
25
+ └──────────────────┘ └─────────────────────┘ └─────────────────────┘ └─────────────────────┘
26
+ ▲ ▲ ▲ ▲ ▲
27
+ ┌───────┴────────┐ ┌─────────┴──────────┐ │ │ ┌────────┴────────┐
28
+ │EC2RequestParser│ │RestXMLRequestParser│ │ │ JSONRequestParser│ │
29
+ └────────────────┘ └────────────────────┘ │ │ └─────────────────┘
30
+ ┌────────────────┴───┴┐ ▲ │
31
+ │RestJSONRequestParser│ ┌───┴──────┴──────┐
32
+ └─────────────────────┘ │CBORRequestParser│
33
+ └─────────────────┘
34
+
33
35
  ::
34
36
 
35
37
  The ``RequestParser`` contains the logic that is used among all the
36
38
  different protocols (``query``, ``json``, ``rest-json``, ``rest-xml``,
37
- and ``ec2``).
39
+ ``cbor`` and ``ec2``).
38
40
  The relation between the different protocols is described in the
39
41
  ``serializer``.
40
42
 
@@ -46,11 +48,16 @@ The classes are structured as follows:
46
48
  protocol specifics (i.e. specific HTTP metadata parsing).
47
49
  * The ``BaseJSONRequestParser`` contains the logic for the JSON body
48
50
  parsing.
51
+ * The ``BaseCBORRequestParser`` contains the logic for the CBOR body
52
+ parsing.
49
53
  * The ``RestJSONRequestParser`` inherits the ReST specific logic from
50
54
  the ``BaseRestRequestParser`` and the JSON body parsing from the
51
55
  ``BaseJSONRequestParser``.
52
- * The ``QueryRequestParser``, ``RestXMLRequestParser``, and the
53
- ``JSONRequestParser`` have a conventional inheritance structure.
56
+ * The ``CBORRequestParser`` inherits the ``json``-protocol specific
57
+ logic from the ``JSONRequestParser`` and the CBOR body parsing
58
+ from the ``BaseCBORRequestParser``.
59
+ * The ``QueryRequestParser``, ``RestXMLRequestParser`` and
60
+ ``JSONRequestParser`` have a conventional inheritance structure.
54
61
 
55
62
  The services and their protocols are defined by using AWS's Smithy
56
63
  (a language to define services in a - somewhat - protocol-agnostic
@@ -66,7 +73,10 @@ import abc
66
73
  import base64
67
74
  import datetime
68
75
  import functools
76
+ import io
77
+ import os
69
78
  import re
79
+ import struct
70
80
  from abc import ABC
71
81
  from collections.abc import Mapping
72
82
  from email.utils import parsedate_to_datetime
@@ -332,7 +342,7 @@ class RequestParser(abc.ABC):
332
342
  _parse_double = _parse_float
333
343
  _parse_long = _parse_integer
334
344
 
335
- def _convert_str_to_timestamp(self, value: str, timestamp_format=None):
345
+ def _convert_str_to_timestamp(self, value: str, timestamp_format=None) -> datetime.datetime:
336
346
  if timestamp_format is None:
337
347
  timestamp_format = self.TIMESTAMP_FORMAT
338
348
  timestamp_format = timestamp_format.lower()
@@ -346,11 +356,13 @@ class RequestParser(abc.ABC):
346
356
 
347
357
  @staticmethod
348
358
  def _timestamp_unixtimestamp(timestamp_string: str) -> datetime.datetime:
349
- return datetime.datetime.utcfromtimestamp(int(timestamp_string))
359
+ dt = datetime.datetime.fromtimestamp(int(timestamp_string), tz=datetime.UTC)
360
+ return dt.replace(tzinfo=None)
350
361
 
351
362
  @staticmethod
352
363
  def _timestamp_unixtimestampmillis(timestamp_string: str) -> datetime.datetime:
353
- return datetime.datetime.utcfromtimestamp(float(timestamp_string) / 1000)
364
+ dt = datetime.datetime.fromtimestamp(float(timestamp_string) / 1000, tz=datetime.UTC)
365
+ return dt.replace(tzinfo=None)
354
366
 
355
367
  @staticmethod
356
368
  def _timestamp_rfc822(datetime_string: str) -> datetime.datetime:
@@ -976,6 +988,262 @@ class RestJSONRequestParser(BaseRestRequestParser, BaseJSONRequestParser):
976
988
  raise NotImplementedError
977
989
 
978
990
 
991
+ class BaseCBORRequestParser(RequestParser, ABC):
992
+ """
993
+ The ``BaseCBORRequestParser`` is the base class for all CBOR-based AWS service protocols.
994
+ This base-class handles parsing the payload / body as CBOR.
995
+ """
996
+
997
+ INDEFINITE_ITEM_ADDITIONAL_INFO = 31
998
+ BREAK_CODE = 0xFF
999
+ # timestamp format for requests with CBOR content type
1000
+ TIMESTAMP_FORMAT = "unixtimestamp"
1001
+
1002
+ @functools.cached_property
1003
+ def major_type_to_parsing_method_map(self):
1004
+ return {
1005
+ 0: self._parse_type_unsigned_integer,
1006
+ 1: self._parse_type_negative_integer,
1007
+ 2: self._parse_type_byte_string,
1008
+ 3: self._parse_type_text_string,
1009
+ 4: self._parse_type_array,
1010
+ 5: self._parse_type_map,
1011
+ 6: self._parse_type_tag,
1012
+ 7: self._parse_type_simple_and_float,
1013
+ }
1014
+
1015
+ @staticmethod
1016
+ def get_peekable_stream_from_bytes(_bytes: bytes) -> io.BufferedReader:
1017
+ return io.BufferedReader(io.BytesIO(_bytes))
1018
+
1019
+ def parse_data_item(self, stream: io.BufferedReader) -> Any:
1020
+ # CBOR data is divided into "data items", and each data item starts
1021
+ # with an initial byte that describes how the following bytes should be parsed
1022
+ initial_byte = self._read_bytes_as_int(stream, 1)
1023
+ # The highest order three bits of the initial byte describe the CBOR major type
1024
+ major_type = initial_byte >> 5
1025
+ # The lowest order 5 bits of the initial byte tells us more information about
1026
+ # how the bytes should be parsed that will be used
1027
+ additional_info: int = initial_byte & 0b00011111
1028
+
1029
+ if major_type in self.major_type_to_parsing_method_map:
1030
+ method = self.major_type_to_parsing_method_map[major_type]
1031
+ return method(stream, additional_info)
1032
+ else:
1033
+ raise ProtocolParserError(
1034
+ f"Unsupported inital byte found for data item- "
1035
+ f"Major type:{major_type}, Additional info: "
1036
+ f"{additional_info}"
1037
+ )
1038
+
1039
+ # Major type 0 - unsigned integers
1040
+ def _parse_type_unsigned_integer(self, stream: io.BufferedReader, additional_info: int) -> int:
1041
+ additional_info_to_num_bytes = {
1042
+ 24: 1,
1043
+ 25: 2,
1044
+ 26: 4,
1045
+ 27: 8,
1046
+ }
1047
+ # Values under 24 don't need a full byte to be stored; their values are
1048
+ # instead stored as the "additional info" in the initial byte
1049
+ if additional_info < 24:
1050
+ return additional_info
1051
+ elif additional_info in additional_info_to_num_bytes:
1052
+ num_bytes = additional_info_to_num_bytes[additional_info]
1053
+ return self._read_bytes_as_int(stream, num_bytes)
1054
+ else:
1055
+ raise ProtocolParserError(
1056
+ "Invalid CBOR integer returned from the service; unparsable "
1057
+ f"additional info found for major type 0 or 1: {additional_info}"
1058
+ )
1059
+
1060
+ # Major type 1 - negative integers
1061
+ def _parse_type_negative_integer(self, stream: io.BufferedReader, additional_info: int) -> int:
1062
+ return -1 - self._parse_type_unsigned_integer(stream, additional_info)
1063
+
1064
+ # Major type 2 - byte string
1065
+ def _parse_type_byte_string(self, stream: io.BufferedReader, additional_info: int) -> bytes:
1066
+ if additional_info != self.INDEFINITE_ITEM_ADDITIONAL_INFO:
1067
+ length = self._parse_type_unsigned_integer(stream, additional_info)
1068
+ return self._read_from_stream(stream, length)
1069
+ else:
1070
+ chunks = []
1071
+ while True:
1072
+ if self._handle_break_code(stream):
1073
+ break
1074
+ initial_byte = self._read_bytes_as_int(stream, 1)
1075
+ additional_info = initial_byte & 0b00011111
1076
+ length = self._parse_type_unsigned_integer(stream, additional_info)
1077
+ chunks.append(self._read_from_stream(stream, length))
1078
+ return b"".join(chunks)
1079
+
1080
+ # Major type 3 - text string
1081
+ def _parse_type_text_string(self, stream: io.BufferedReader, additional_info: int) -> str:
1082
+ return self._parse_type_byte_string(stream, additional_info).decode("utf-8")
1083
+
1084
+ # Major type 4 - lists
1085
+ def _parse_type_array(self, stream: io.BufferedReader, additional_info: int) -> list:
1086
+ if additional_info != self.INDEFINITE_ITEM_ADDITIONAL_INFO:
1087
+ length = self._parse_type_unsigned_integer(stream, additional_info)
1088
+ return [self.parse_data_item(stream) for _ in range(length)]
1089
+ else:
1090
+ items = []
1091
+ while not self._handle_break_code(stream):
1092
+ items.append(self.parse_data_item(stream))
1093
+ return items
1094
+
1095
+ # Major type 5 - maps
1096
+ def _parse_type_map(self, stream: io.BufferedReader, additional_info: int) -> dict:
1097
+ items = {}
1098
+ if additional_info != self.INDEFINITE_ITEM_ADDITIONAL_INFO:
1099
+ length = self._parse_type_unsigned_integer(stream, additional_info)
1100
+ for _ in range(length):
1101
+ self._parse_type_key_value_pair(stream, items)
1102
+ return items
1103
+
1104
+ else:
1105
+ while not self._handle_break_code(stream):
1106
+ self._parse_type_key_value_pair(stream, items)
1107
+ return items
1108
+
1109
+ def _parse_type_key_value_pair(self, stream: io.BufferedReader, items: dict) -> None:
1110
+ key = self.parse_data_item(stream)
1111
+ value = self.parse_data_item(stream)
1112
+ if value is not None:
1113
+ items[key] = value
1114
+
1115
+ # Major type 6 is tags. The only tag we currently support is tag 1 for unix
1116
+ # timestamps
1117
+ def _parse_type_tag(self, stream: io.BufferedReader, additional_info: int):
1118
+ tag = self._parse_type_unsigned_integer(stream, additional_info)
1119
+ value = self.parse_data_item(stream)
1120
+ if tag == 1: # Epoch-based date/time in milliseconds
1121
+ return self._parse_type_datetime(value)
1122
+ else:
1123
+ raise ProtocolParserError(f"Found CBOR tag not supported by botocore: {tag}")
1124
+
1125
+ def _parse_type_datetime(self, value: int | float) -> datetime.datetime:
1126
+ if isinstance(value, (int, float)):
1127
+ return self._convert_str_to_timestamp(str(value))
1128
+ else:
1129
+ raise ProtocolParserError(f"Unable to parse datetime value: {value}")
1130
+
1131
+ # Major type 7 includes floats and "simple" types. Supported simple types are
1132
+ # currently boolean values, CBOR's null, and CBOR's undefined type. All other
1133
+ # values are either floats or invalid.
1134
+ def _parse_type_simple_and_float(
1135
+ self, stream: io.BufferedReader, additional_info: int
1136
+ ) -> bool | float | None:
1137
+ # For major type 7, values 20-23 correspond to CBOR "simple" values
1138
+ additional_info_simple_values = {
1139
+ 20: False, # CBOR false
1140
+ 21: True, # CBOR true
1141
+ 22: None, # CBOR null
1142
+ 23: None, # CBOR undefined
1143
+ }
1144
+ # First we check if the additional info corresponds to a supported simple value
1145
+ if additional_info in additional_info_simple_values:
1146
+ return additional_info_simple_values[additional_info]
1147
+
1148
+ # If it's not a simple value, we need to parse it into the correct format and
1149
+ # number fo bytes
1150
+ float_formats = {
1151
+ 25: (">e", 2),
1152
+ 26: (">f", 4),
1153
+ 27: (">d", 8),
1154
+ }
1155
+
1156
+ if additional_info in float_formats:
1157
+ float_format, num_bytes = float_formats[additional_info]
1158
+ return struct.unpack(float_format, self._read_from_stream(stream, num_bytes))[0]
1159
+ raise ProtocolParserError(
1160
+ f"Invalid additional info found for major type 7: {additional_info}. "
1161
+ f"This indicates an unsupported simple type or an indefinite float value"
1162
+ )
1163
+
1164
+ @_text_content
1165
+ def _parse_blob(self, _, __, node: bytes, ___) -> bytes:
1166
+ return node
1167
+
1168
+ # This helper method is intended for use when parsing indefinite length items.
1169
+ # It does nothing if the next byte is not the break code. If the next byte is
1170
+ # the break code, it advances past that byte and returns True so the calling
1171
+ # method knows to stop parsing that data item.
1172
+ def _handle_break_code(self, stream: io.BufferedReader) -> bool | None:
1173
+ if int.from_bytes(stream.peek(1)[:1], "big") == self.BREAK_CODE:
1174
+ stream.seek(1, os.SEEK_CUR)
1175
+ return True
1176
+
1177
+ def _read_bytes_as_int(self, stream: IO[bytes], num_bytes: int) -> int:
1178
+ byte = self._read_from_stream(stream, num_bytes)
1179
+ return int.from_bytes(byte, "big")
1180
+
1181
+ @staticmethod
1182
+ def _read_from_stream(stream: IO[bytes], num_bytes: int) -> bytes:
1183
+ value = stream.read(num_bytes)
1184
+ if len(value) != num_bytes:
1185
+ raise ProtocolParserError(
1186
+ "End of stream reached; this indicates a "
1187
+ "malformed CBOR response from the server or an "
1188
+ "issue in botocore"
1189
+ )
1190
+ return value
1191
+
1192
+
1193
+ class CBORRequestParser(BaseCBORRequestParser, JSONRequestParser):
1194
+ """
1195
+ The ``CBORRequestParser`` is responsible for parsing incoming requests for services which use the ``cbor``
1196
+ protocol.
1197
+ The requests for these services encode the majority of their parameters as CBOR in the request body.
1198
+ The operation is defined in an HTTP header field.
1199
+ This protocol is not properly defined in the specs, but it is derived from the ``json`` protocol. Only Kinesis uses
1200
+ it for now.
1201
+ """
1202
+
1203
+ # timestamp format is different from traditional CBOR
1204
+ TIMESTAMP_FORMAT = "unixtimestampmillis"
1205
+
1206
+ def _do_parse(
1207
+ self, request: Request, shape: Shape, uri_params: Mapping[str, Any] = None
1208
+ ) -> dict:
1209
+ parsed = {}
1210
+ if shape is not None:
1211
+ event_name = shape.event_stream_name
1212
+ if event_name:
1213
+ parsed = self._handle_event_stream(request, shape, event_name)
1214
+ else:
1215
+ self._parse_payload(request, shape, parsed, uri_params)
1216
+ return parsed
1217
+
1218
+ def _handle_event_stream(self, request: Request, shape: Shape, event_name: str):
1219
+ # TODO handle event streams
1220
+ raise NotImplementedError
1221
+
1222
+ def _parse_payload(
1223
+ self,
1224
+ request: Request,
1225
+ shape: Shape,
1226
+ final_parsed: dict,
1227
+ uri_params: Mapping[str, Any] = None,
1228
+ ) -> None:
1229
+ original_parsed = self._initial_body_parse(request)
1230
+ body_parsed = self._parse_shape(request, shape, original_parsed, uri_params)
1231
+ final_parsed.update(body_parsed)
1232
+
1233
+ def _initial_body_parse(self, request: Request) -> Any:
1234
+ body_contents = request.data
1235
+ if body_contents == b"":
1236
+ return body_contents
1237
+ body_contents_stream = self.get_peekable_stream_from_bytes(body_contents)
1238
+ return self.parse_data_item(body_contents_stream)
1239
+
1240
+ def _parse_timestamp(
1241
+ self, request: Request, shape: Shape, node: str, uri_params: Mapping[str, Any] = None
1242
+ ) -> datetime.datetime:
1243
+ # TODO: remove once CBOR support has been removed from `JSONRequestParser`
1244
+ return super()._parse_timestamp(request, shape, node, uri_params)
1245
+
1246
+
979
1247
  class EC2RequestParser(QueryRequestParser):
980
1248
  """
981
1249
  The ``EC2RequestParser`` is responsible for parsing incoming requests for services which use the ``ec2``
@@ -1176,6 +1444,9 @@ def create_parser(service: ServiceModel) -> RequestParser:
1176
1444
  "rest-json": RestJSONRequestParser,
1177
1445
  "rest-xml": RestXMLRequestParser,
1178
1446
  "ec2": EC2RequestParser,
1447
+ # TODO: implement multi-protocol support for Kinesis, so that it can uses the `cbor` protocol and remove
1448
+ # CBOR handling from JSONRequestParser
1449
+ # this is not an "official" protocol defined from the spec, but is derived from ``json``
1179
1450
  }
1180
1451
 
1181
1452
  # Try to select a service- and protocol-specific parser implementation
@@ -14,18 +14,19 @@ The different protocols have many similarities. The class hierarchy is
14
14
  designed such that the serializers share as much logic as possible.
15
15
  The class hierarchy looks as follows:
16
16
  ::
17
- ┌───────────────────┐
18
- │ResponseSerializer │
19
- └───────────────────┘
20
-
21
- ┌──────────────────────┘ └──────────────────┐
22
- ┌────────────┴────────────┐ ┌────────────┴─────────────┐ ┌─────────┴────────────┐
23
- │BaseXMLResponseSerializer│ │BaseRestResponseSerializer│ │JSONResponseSerializer│
24
- └─────────────────────────┘ └──────────────────────────┘ └──────────────────────┘
25
- ▲ ▲ ▲ ▲
26
- ┌──────────────────────┴─┐ ┌┴─────────────┴──────────┐ ┌┴──────────────┴──────────┐
27
- │QueryResponseSerializer │RestXMLResponseSerializer│ │RestJSONResponseSerializer│
28
- └────────────────────────┘ └─────────────────────────┘ └──────────────────────────┘
17
+ ┌────────────────────┐
18
+ ResponseSerializer │
19
+ └────────────────────┘
20
+
21
+ │ │ └─────────────────────────────────────────────┐
22
+ ┌───────────────────────┘ │ └─────────────────────┐ │
23
+ ┌────────────┴────────────┐ ┌────────────┴─────────────┐ ┌─────────┴────────────┐ ┌────────────┴─────────────┐
24
+ │BaseXMLResponseSerializer│ │BaseRestResponseSerializer│ │JSONResponseSerializer│ │BaseCBORResponseSerializer│
25
+ └─────────────────────────┘ └──────────────────────────┘ └──────────────────────┘ └──────────────────────────┘
26
+ ▲ ▲ ▲ ▲ ▲ ▲
27
+ ┌──────────────────────┴─┐ ┌┴─────────────┴──────────┐ ┌┴──────────────┴──────────┐ ┌───────────┴────────────┐
28
+ │QueryResponseSerializer │ │RestXMLResponseSerializer│ │RestJSONResponseSerializer│ │ CBORResponseSerializer │
29
+ └────────────────────────┘ └─────────────────────────┘ └──────────────────────────┘ └────────────────────────┘
29
30
 
30
31
  ┌──────────┴──────────┐
31
32
  │EC2ResponseSerializer│
@@ -33,8 +34,8 @@ The class hierarchy looks as follows:
33
34
  ::
34
35
 
35
36
  The ``ResponseSerializer`` contains the logic that is used among all the
36
- different protocols (``query``, ``json``, ``rest-json``, ``rest-xml``, and
37
- ``ec2``).
37
+ different protocols (``query``, ``json``, ``rest-json``, ``rest-xml``, ``cbor``
38
+ and ``ec2``).
38
39
  The protocols relate to each other in the following ways:
39
40
 
40
41
  * The ``query`` and the ``rest-xml`` protocols both have XML bodies in their
@@ -42,8 +43,10 @@ The protocols relate to each other in the following ways:
42
43
  type).
43
44
  * The ``json`` and the ``rest-json`` protocols both have JSON bodies in their
44
45
  responses which are serialized the same way.
46
+ * The ``cbor`` protocol is not properly defined in the spec, but mirrors the
47
+ ``json`` protocol.
45
48
  * The ``rest-json`` and ``rest-xml`` protocols serialize some metadata in
46
- the HTTP response's header fields
49
+ the HTTP response's header fields.
47
50
  * The ``ec2`` protocol is basically similar to the ``query`` protocol with a
48
51
  specific error response formatting.
49
52
 
@@ -54,13 +57,17 @@ The classes are structured as follows:
54
57
 
55
58
  * The ``ResponseSerializer`` contains all the basic logic for the
56
59
  serialization which is shared among all different protocols.
57
- * The ``BaseXMLResponseSerializer`` and the ``JSONResponseSerializer``
58
- contain the logic for the XML and the JSON serialization respectively.
60
+ * The ``BaseXMLResponseSerializer``, ``JSONResponseSerializer`` and
61
+ ``BaseCBORResponseSerializer`` contain the logic for the XML, JSON
62
+ and the CBOR serialization respectively.
59
63
  * The ``BaseRestResponseSerializer`` contains the logic for the REST
60
64
  protocol specifics (i.e. specific HTTP header serializations).
61
65
  * The ``RestXMLResponseSerializer`` and the ``RestJSONResponseSerializer``
62
66
  inherit the ReST specific logic from the ``BaseRestResponseSerializer``
63
67
  and the XML / JSON body serialization from their second super class.
68
+ * The ``CBORResponseSerializer`` contains the logic specific to the
69
+ non-official ``cbor`` protocol, mirroring the ``json`` protocol but
70
+ with CBOR encoded body
64
71
 
65
72
  The services and their protocols are defined by using AWS's Smithy
66
73
  (a language to define services in a - somewhat - protocol-agnostic
@@ -73,21 +80,32 @@ be sent back to the calling client.
73
80
 
74
81
  import abc
75
82
  import base64
83
+ import copy
76
84
  import functools
77
85
  import json
78
86
  import logging
87
+ import math
79
88
  import string
89
+ import struct
80
90
  from abc import ABC
81
91
  from binascii import crc32
82
92
  from collections.abc import Iterable, Iterator
83
93
  from datetime import datetime
84
94
  from email.utils import formatdate
85
95
  from struct import pack
86
- from typing import Any
96
+ from typing import IO, Any
87
97
  from xml.etree import ElementTree as ETree
88
98
 
89
99
  import xmltodict
90
- from botocore.model import ListShape, MapShape, OperationModel, ServiceModel, Shape, StructureShape
100
+ from botocore.model import (
101
+ ListShape,
102
+ MapShape,
103
+ OperationModel,
104
+ ServiceModel,
105
+ Shape,
106
+ StringShape,
107
+ StructureShape,
108
+ )
91
109
  from botocore.serialize import ISO8601, ISO8601_MICRO
92
110
  from botocore.utils import calculate_md5, is_json_value_header, parse_to_aware_datetime
93
111
 
@@ -1407,6 +1425,318 @@ class RestJSONResponseSerializer(BaseRestResponseSerializer, JSONResponseSeriali
1407
1425
  serialized.headers["Content-Type"] = mime_type
1408
1426
 
1409
1427
 
1428
+ class BaseCBORResponseSerializer(ResponseSerializer):
1429
+ UNSIGNED_INT_MAJOR_TYPE = 0
1430
+ NEGATIVE_INT_MAJOR_TYPE = 1
1431
+ BLOB_MAJOR_TYPE = 2
1432
+ STRING_MAJOR_TYPE = 3
1433
+ LIST_MAJOR_TYPE = 4
1434
+ MAP_MAJOR_TYPE = 5
1435
+ TAG_MAJOR_TYPE = 6
1436
+ FLOAT_AND_SIMPLE_MAJOR_TYPE = 7
1437
+
1438
+ def _serialize_data_item(
1439
+ self, serialized: bytearray, value: Any, shape: Shape | None, name: str | None = None
1440
+ ) -> None:
1441
+ method = getattr(self, f"_serialize_type_{shape.type_name}")
1442
+ if method is None:
1443
+ raise ValueError(
1444
+ f"Unrecognized C2J type: {shape.type_name}, unable to serialize request"
1445
+ )
1446
+ method(serialized, value, shape, name)
1447
+
1448
+ def _serialize_type_integer(
1449
+ self, serialized: bytearray, value: int, shape: Shape | None, name: str | None = None
1450
+ ) -> None:
1451
+ if value >= 0:
1452
+ major_type = self.UNSIGNED_INT_MAJOR_TYPE
1453
+ else:
1454
+ major_type = self.NEGATIVE_INT_MAJOR_TYPE
1455
+ # The only differences in serializing negative and positive integers is
1456
+ # that for negative, we set the major type to 1 and set the value to -1
1457
+ # minus the value
1458
+ value = -1 - value
1459
+ additional_info, num_bytes = self._get_additional_info_and_num_bytes(value)
1460
+ initial_byte = self._get_initial_byte(major_type, additional_info)
1461
+ if num_bytes == 0:
1462
+ serialized.extend(initial_byte)
1463
+ else:
1464
+ serialized.extend(initial_byte + value.to_bytes(num_bytes, "big"))
1465
+
1466
+ def _serialize_type_long(
1467
+ self, serialized: bytearray, value: int, shape: Shape, name: str | None = None
1468
+ ) -> None:
1469
+ self._serialize_type_integer(serialized, value, shape, name)
1470
+
1471
+ def _serialize_type_blob(
1472
+ self,
1473
+ serialized: bytearray,
1474
+ value: str | bytes | IO[bytes],
1475
+ shape: Shape | None,
1476
+ name: str | None = None,
1477
+ ) -> None:
1478
+ if isinstance(value, str):
1479
+ value = value.encode("utf-8")
1480
+ elif not isinstance(value, (bytes, bytearray)):
1481
+ # We support file-like objects for blobs; these already have been
1482
+ # validated to ensure they have a read method
1483
+ value = value.read()
1484
+ length = len(value)
1485
+ additional_info, num_bytes = self._get_additional_info_and_num_bytes(length)
1486
+ initial_byte = self._get_initial_byte(self.BLOB_MAJOR_TYPE, additional_info)
1487
+ if num_bytes == 0:
1488
+ serialized.extend(initial_byte)
1489
+ else:
1490
+ serialized.extend(initial_byte + length.to_bytes(num_bytes, "big"))
1491
+ serialized.extend(value)
1492
+
1493
+ def _serialize_type_string(
1494
+ self, serialized: bytearray, value: str, shape: Shape | None, name: str | None = None
1495
+ ) -> None:
1496
+ encoded = value.encode("utf-8")
1497
+ length = len(encoded)
1498
+ additional_info, num_bytes = self._get_additional_info_and_num_bytes(length)
1499
+ initial_byte = self._get_initial_byte(self.STRING_MAJOR_TYPE, additional_info)
1500
+ if num_bytes == 0:
1501
+ serialized.extend(initial_byte + encoded)
1502
+ else:
1503
+ serialized.extend(initial_byte + length.to_bytes(num_bytes, "big") + encoded)
1504
+
1505
+ def _serialize_type_list(
1506
+ self, serialized: bytearray, value: str, shape: Shape | None, name: str | None = None
1507
+ ) -> None:
1508
+ length = len(value)
1509
+ additional_info, num_bytes = self._get_additional_info_and_num_bytes(length)
1510
+ initial_byte = self._get_initial_byte(self.LIST_MAJOR_TYPE, additional_info)
1511
+ if num_bytes == 0:
1512
+ serialized.extend(initial_byte)
1513
+ else:
1514
+ serialized.extend(initial_byte + length.to_bytes(num_bytes, "big"))
1515
+ for item in value:
1516
+ self._serialize_data_item(serialized, item, shape.member)
1517
+
1518
+ def _serialize_type_map(
1519
+ self, serialized: bytearray, value: dict, shape: Shape | None, name: str | None = None
1520
+ ) -> None:
1521
+ length = len(value)
1522
+ additional_info, num_bytes = self._get_additional_info_and_num_bytes(length)
1523
+ initial_byte = self._get_initial_byte(self.MAP_MAJOR_TYPE, additional_info)
1524
+ if num_bytes == 0:
1525
+ serialized.extend(initial_byte)
1526
+ else:
1527
+ serialized.extend(initial_byte + length.to_bytes(num_bytes, "big"))
1528
+ for key_item, item in value.items():
1529
+ self._serialize_data_item(serialized, key_item, shape.key)
1530
+ self._serialize_data_item(serialized, item, shape.value)
1531
+
1532
+ def _serialize_type_structure(
1533
+ self, serialized: bytearray, value: dict, shape: Shape | None, name: str | None = None
1534
+ ) -> None:
1535
+ if name is not None:
1536
+ # For nested structures, we need to serialize the key first
1537
+ self._serialize_data_item(serialized, name, shape.key_shape)
1538
+
1539
+ # Remove `None` values from the dictionary
1540
+ value = {k: v for k, v in value.items() if v is not None}
1541
+
1542
+ map_length = len(value)
1543
+ additional_info, num_bytes = self._get_additional_info_and_num_bytes(map_length)
1544
+ initial_byte = self._get_initial_byte(self.MAP_MAJOR_TYPE, additional_info)
1545
+ if num_bytes == 0:
1546
+ serialized.extend(initial_byte)
1547
+ else:
1548
+ serialized.extend(initial_byte + map_length.to_bytes(num_bytes, "big"))
1549
+
1550
+ members = shape.members
1551
+ for member_key, member_value in value.items():
1552
+ member_shape = members[member_key]
1553
+ if "name" in member_shape.serialization:
1554
+ member_key = member_shape.serialization["name"]
1555
+ if member_value is not None:
1556
+ self._serialize_type_string(serialized, member_key, None, None)
1557
+ self._serialize_data_item(serialized, member_value, member_shape)
1558
+
1559
+ def _serialize_type_timestamp(
1560
+ self,
1561
+ serialized: bytearray,
1562
+ value: int | str | datetime,
1563
+ shape: Shape | None,
1564
+ name: str | None = None,
1565
+ ) -> None:
1566
+ timestamp = int(self._convert_timestamp_to_str(value))
1567
+ tag = 1 # Use tag 1 for unix timestamp
1568
+ initial_byte = self._get_initial_byte(self.TAG_MAJOR_TYPE, tag)
1569
+ serialized.extend(initial_byte) # Tagging the timestamp
1570
+ additional_info, num_bytes = self._get_additional_info_and_num_bytes(timestamp)
1571
+
1572
+ if num_bytes == 0:
1573
+ initial_byte = self._get_initial_byte(self.UNSIGNED_INT_MAJOR_TYPE, timestamp)
1574
+ serialized.extend(initial_byte)
1575
+ else:
1576
+ initial_byte = self._get_initial_byte(self.UNSIGNED_INT_MAJOR_TYPE, additional_info)
1577
+ serialized.extend(initial_byte + timestamp.to_bytes(num_bytes, "big"))
1578
+
1579
+ def _serialize_type_float(
1580
+ self, serialized: bytearray, value: float, shape: Shape | None, name: str | None = None
1581
+ ) -> None:
1582
+ if self._is_special_number(value):
1583
+ serialized.extend(
1584
+ self._get_bytes_for_special_numbers(value)
1585
+ ) # Handle special values like NaN or Infinity
1586
+ else:
1587
+ initial_byte = self._get_initial_byte(self.FLOAT_AND_SIMPLE_MAJOR_TYPE, 26)
1588
+ serialized.extend(initial_byte + struct.pack(">f", value))
1589
+
1590
+ def _serialize_type_double(
1591
+ self, serialized: bytearray, value: float, shape: Shape | None, name: str | None = None
1592
+ ) -> None:
1593
+ if self._is_special_number(value):
1594
+ serialized.extend(
1595
+ self._get_bytes_for_special_numbers(value)
1596
+ ) # Handle special values like NaN or Infinity
1597
+ else:
1598
+ initial_byte = self._get_initial_byte(self.FLOAT_AND_SIMPLE_MAJOR_TYPE, 27)
1599
+ serialized.extend(initial_byte + struct.pack(">d", value))
1600
+
1601
+ def _serialize_type_boolean(
1602
+ self, serialized: bytearray, value: bool, shape: Shape | None, name: str | None = None
1603
+ ) -> None:
1604
+ additional_info = 21 if value else 20
1605
+ serialized.extend(self._get_initial_byte(self.FLOAT_AND_SIMPLE_MAJOR_TYPE, additional_info))
1606
+
1607
+ @staticmethod
1608
+ def _get_additional_info_and_num_bytes(value: int) -> tuple[int, int]:
1609
+ # Values under 24 can be stored in the initial byte and don't need further
1610
+ # encoding
1611
+ if value < 24:
1612
+ return value, 0
1613
+ # Values between 24 and 255 (inclusive) can be stored in 1 byte and
1614
+ # correspond to additional info 24
1615
+ elif value < 256:
1616
+ return 24, 1
1617
+ # Values up to 65535 can be stored in two bytes and correspond to additional
1618
+ # info 25
1619
+ elif value < 65536:
1620
+ return 25, 2
1621
+ # Values up to 4294967296 can be stored in four bytes and correspond to
1622
+ # additional info 26
1623
+ elif value < 4294967296:
1624
+ return 26, 4
1625
+ # The maximum number of bytes in a definite length data items is 8 which
1626
+ # to additional info 27
1627
+ else:
1628
+ return 27, 8
1629
+
1630
+ def _get_initial_byte(self, major_type: int, additional_info: int) -> bytes:
1631
+ # The highest order three bits are the major type, so we need to bitshift the
1632
+ # major type by 5
1633
+ major_type_bytes = major_type << 5
1634
+ return (major_type_bytes | additional_info).to_bytes(1, "big")
1635
+
1636
+ @staticmethod
1637
+ def _is_special_number(value: int | float) -> bool:
1638
+ return any(
1639
+ [
1640
+ value == float("inf"),
1641
+ value == float("-inf"),
1642
+ math.isnan(value),
1643
+ ]
1644
+ )
1645
+
1646
+ def _get_bytes_for_special_numbers(self, value: int | float) -> bytes:
1647
+ additional_info = 25
1648
+ initial_byte = self._get_initial_byte(self.FLOAT_AND_SIMPLE_MAJOR_TYPE, additional_info)
1649
+ if value == float("inf"):
1650
+ return initial_byte + struct.pack(">H", 0x7C00)
1651
+ elif value == float("-inf"):
1652
+ return initial_byte + struct.pack(">H", 0xFC00)
1653
+ elif math.isnan(value):
1654
+ return initial_byte + struct.pack(">H", 0x7E00)
1655
+
1656
+
1657
+ class CBORResponseSerializer(BaseCBORResponseSerializer):
1658
+ """
1659
+ The ``CBORResponseSerializer`` is responsible for the serialization of responses from services with the ``cbor``
1660
+ protocol. It implements the CBOR response body serialization, which is only currently used by Kinesis and is derived
1661
+ conceptually from the ``JSONResponseSerializer``
1662
+ """
1663
+
1664
+ SUPPORTED_MIME_TYPES = [APPLICATION_CBOR, APPLICATION_AMZ_CBOR_1_1]
1665
+
1666
+ TIMESTAMP_FORMAT = "unixtimestamp"
1667
+
1668
+ def _serialize_error(
1669
+ self,
1670
+ error: ServiceException,
1671
+ response: Response,
1672
+ shape: StructureShape,
1673
+ operation_model: OperationModel,
1674
+ mime_type: str,
1675
+ request_id: str,
1676
+ ) -> None:
1677
+ body = bytearray()
1678
+ response.content_type = mime_type
1679
+ response.headers["X-Amzn-Errortype"] = error.code
1680
+
1681
+ if shape:
1682
+ # FIXME: we need to manually add the `__type` field to the shape as it is not part of the specs
1683
+ # think about a better way, this is very hacky
1684
+ shape_copy = copy.deepcopy(shape)
1685
+ shape_copy.members["__type"] = StringShape(
1686
+ shape_name="__type", shape_model={"type": "string"}
1687
+ )
1688
+ remaining_params = {"__type": error.code}
1689
+
1690
+ for member_name in shape_copy.members:
1691
+ if hasattr(error, member_name):
1692
+ remaining_params[member_name] = getattr(error, member_name)
1693
+ # Default error message fields can sometimes have different casing in the specs
1694
+ elif member_name.lower() in ["code", "message"] and hasattr(
1695
+ error, member_name.lower()
1696
+ ):
1697
+ remaining_params[member_name] = getattr(error, member_name.lower())
1698
+
1699
+ self._serialize_data_item(body, remaining_params, shape_copy, None)
1700
+
1701
+ response.set_response(bytes(body))
1702
+
1703
+ def _serialize_response(
1704
+ self,
1705
+ parameters: dict,
1706
+ response: Response,
1707
+ shape: Shape | None,
1708
+ shape_members: dict,
1709
+ operation_model: OperationModel,
1710
+ mime_type: str,
1711
+ request_id: str,
1712
+ ) -> None:
1713
+ response.content_type = mime_type
1714
+ response.set_response(
1715
+ self._serialize_body_params(parameters, shape, operation_model, mime_type, request_id)
1716
+ )
1717
+
1718
+ def _serialize_body_params(
1719
+ self,
1720
+ params: dict,
1721
+ shape: Shape,
1722
+ operation_model: OperationModel,
1723
+ mime_type: str,
1724
+ request_id: str,
1725
+ ) -> bytes | None:
1726
+ body = bytearray()
1727
+ self._serialize_data_item(body, params, shape)
1728
+ return bytes(body)
1729
+
1730
+ def _prepare_additional_traits_in_response(
1731
+ self, response: Response, operation_model: OperationModel, request_id: str
1732
+ ) -> Response:
1733
+ response.headers["x-amzn-requestid"] = request_id
1734
+ response = super()._prepare_additional_traits_in_response(
1735
+ response, operation_model, request_id
1736
+ )
1737
+ return response
1738
+
1739
+
1410
1740
  class S3ResponseSerializer(RestXMLResponseSerializer):
1411
1741
  """
1412
1742
  The ``S3ResponseSerializer`` adds some minor logic to handle S3 specific peculiarities with the error response
@@ -1768,6 +2098,9 @@ def create_serializer(service: ServiceModel) -> ResponseSerializer:
1768
2098
  "rest-json": RestJSONResponseSerializer,
1769
2099
  "rest-xml": RestXMLResponseSerializer,
1770
2100
  "ec2": EC2ResponseSerializer,
2101
+ # TODO: implement multi-protocol support for Kinesis, so that it can uses the `cbor` protocol and remove
2102
+ # CBOR handling from JSONResponseParser
2103
+ # this is not an "official" protocol defined from the spec, but is derived from ``json``
1771
2104
  }
1772
2105
 
1773
2106
  # Try to select a service- and protocol-specific serializer implementation
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.dev2'
32
- __version_tuple__ = version_tuple = (4, 8, 2, 'dev2')
31
+ __version__ = version = '4.8.2.dev3'
32
+ __version_tuple__ = version_tuple = (4, 8, 2, 'dev3')
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.dev2
3
+ Version: 4.8.2.dev3
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=7nia_jiUAKerqeb5QbrZBp8zTQiSWlOhjXRUIK3bInE,717
7
+ localstack/version.py,sha256=kaeG6D7EsDHfixIw0CEh3TtxAkDCOIA0bXuITH_66fg,717
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
@@ -83,9 +83,9 @@ localstack/aws/handlers/tracing.py,sha256=y_BUJKjNgaRGebm88NSqni4GFCQ_ZgB2JBRnEt
83
83
  localstack/aws/handlers/validation.py,sha256=4iyHdJx3ijd49rySwMQNx2UW0XNN5fnkFQxdUO7-AQM,4386
84
84
  localstack/aws/protocol/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
85
  localstack/aws/protocol/op_router.py,sha256=2nSpL6H9seK1h_AuIZlBG1yYa_ykARIgJJrKm4Hkc0s,12039
86
- localstack/aws/protocol/parser.py,sha256=IQeYwrT_V8MtVhgajm3-OYF4lNdDNbmZvWDwaTJC0u4,52207
86
+ localstack/aws/protocol/parser.py,sha256=0GbN2Jp4mf7zvaf0Mz3bOX9miDnIJzsk-s_Y2Kgw4vo,64489
87
87
  localstack/aws/protocol/routing.py,sha256=x9AFpMQsVHD7JadtLHR7zjfBw3AJBayITNAYiUtnlwQ,3217
88
- localstack/aws/protocol/serializer.py,sha256=c5-ep5XvHYS0wEPhVG7ckSaq9PidCRVQJjHiN6JXC8Q,81699
88
+ localstack/aws/protocol/serializer.py,sha256=ODwltli1RAh8AcaiMxwDtEV9Ax6Vx5sVQB0v61l9bBI,95906
89
89
  localstack/aws/protocol/service_router.py,sha256=nJK1s9oCPax5rBWBDry5RgLqGojRJSkQscZuNzPut_M,16418
90
90
  localstack/aws/protocol/validate.py,sha256=j3HJAQEKS6V_arrmvlPmP2jbge3LutxwEXDNabDlDdY,5285
91
91
  localstack/aws/serving/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1291,13 +1291,13 @@ localstack/utils/server/tcp_proxy.py,sha256=rR6d5jR0ozDvIlpHiqW0cfyY9a2fRGdOzyA8
1291
1291
  localstack/utils/xray/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1292
1292
  localstack/utils/xray/trace_header.py,sha256=ahXk9eonq7LpeENwlqUEPj3jDOCiVRixhntQuxNor-Q,6209
1293
1293
  localstack/utils/xray/traceid.py,sha256=GKO-R2sMMjlrH2UaLPXlQlZ6flbE7ZKb6IZMtMu_M5U,1110
1294
- localstack_core-4.8.2.dev2.data/scripts/localstack,sha256=WyL11vp5CkuP79iIR-L8XT7Cj8nvmxX7XRAgxhbmXNE,529
1295
- localstack_core-4.8.2.dev2.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1296
- localstack_core-4.8.2.dev2.data/scripts/localstack.bat,sha256=tlzZTXtveHkMX_s_fa7VDfvdNdS8iVpEz2ER3uk9B_c,29
1297
- localstack_core-4.8.2.dev2.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1298
- localstack_core-4.8.2.dev2.dist-info/METADATA,sha256=aDO59DU5z0-Xkm-rn-lqPb5yA_jhvWnDl3r9lUYIXkA,5536
1299
- localstack_core-4.8.2.dev2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1300
- localstack_core-4.8.2.dev2.dist-info/entry_points.txt,sha256=_ZJMdzN2FZoPbjxM2Q2yVTF6eucmoJsNpwav9_UyfTA,20821
1301
- localstack_core-4.8.2.dev2.dist-info/plux.json,sha256=-C4wi68ybjp1p95BvfeBxAVIy4AJYsxVWsc2X-p4B6Y,21046
1302
- localstack_core-4.8.2.dev2.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1303
- localstack_core-4.8.2.dev2.dist-info/RECORD,,
1294
+ localstack_core-4.8.2.dev3.data/scripts/localstack,sha256=WyL11vp5CkuP79iIR-L8XT7Cj8nvmxX7XRAgxhbmXNE,529
1295
+ localstack_core-4.8.2.dev3.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1296
+ localstack_core-4.8.2.dev3.data/scripts/localstack.bat,sha256=tlzZTXtveHkMX_s_fa7VDfvdNdS8iVpEz2ER3uk9B_c,29
1297
+ localstack_core-4.8.2.dev3.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1298
+ localstack_core-4.8.2.dev3.dist-info/METADATA,sha256=9-5hy1pbLVQNU8csnUd-1Tt0HBybAlnzAxi-rsxX05Q,5536
1299
+ localstack_core-4.8.2.dev3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1300
+ localstack_core-4.8.2.dev3.dist-info/entry_points.txt,sha256=_ZJMdzN2FZoPbjxM2Q2yVTF6eucmoJsNpwav9_UyfTA,20821
1301
+ localstack_core-4.8.2.dev3.dist-info/plux.json,sha256=QV16zZYfrphFqS5jqJfWyE89B2FMh_eKyLgOkS5mCpI,21046
1302
+ localstack_core-4.8.2.dev3.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1303
+ localstack_core-4.8.2.dev3.dist-info/RECORD,,
@@ -0,0 +1 @@
1
+ {"localstack.cloudformation.resource_providers": ["AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "AWS::EC2::RouteTable=localstack.services.ec2.resource_providers.aws_ec2_routetable_plugin:EC2RouteTableProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::CloudWatch::CompositeAlarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_compositealarm_plugin:CloudWatchCompositeAlarmProviderPlugin", "AWS::CertificateManager::Certificate=localstack.services.certificatemanager.resource_providers.aws_certificatemanager_certificate_plugin:CertificateManagerCertificateProviderPlugin", "AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::EC2::VPCGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_vpcgatewayattachment_plugin:EC2VPCGatewayAttachmentProviderPlugin", "AWS::Lambda::Version=localstack.services.lambda_.resource_providers.aws_lambda_version_plugin:LambdaVersionProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::ApiGateway::DomainName=localstack.services.apigateway.resource_providers.aws_apigateway_domainname_plugin:ApiGatewayDomainNameProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::Kinesis::StreamConsumer=localstack.services.kinesis.resource_providers.aws_kinesis_streamconsumer_plugin:KinesisStreamConsumerProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::Lambda::Alias=localstack.services.lambda_.resource_providers.lambda_alias_plugin:LambdaAliasProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::ApiGateway::RestApi=localstack.services.apigateway.resource_providers.aws_apigateway_restapi_plugin:ApiGatewayRestApiProviderPlugin", "AWS::SQS::QueuePolicy=localstack.services.sqs.resource_providers.aws_sqs_queuepolicy_plugin:SQSQueuePolicyProviderPlugin", "AWS::SNS::Subscription=localstack.services.sns.resource_providers.aws_sns_subscription_plugin:SNSSubscriptionProviderPlugin", "AWS::ApiGateway::ApiKey=localstack.services.apigateway.resource_providers.aws_apigateway_apikey_plugin:ApiGatewayApiKeyProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::DynamoDB::Table=localstack.services.dynamodb.resource_providers.aws_dynamodb_table_plugin:DynamoDBTableProviderPlugin", "AWS::Lambda::LayerVersionPermission=localstack.services.lambda_.resource_providers.aws_lambda_layerversionpermission_plugin:LambdaLayerVersionPermissionProviderPlugin", "AWS::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::SNS::TopicPolicy=localstack.services.sns.resource_providers.aws_sns_topicpolicy_plugin:SNSTopicPolicyProviderPlugin", "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::Events::EventBus=localstack.services.events.resource_providers.aws_events_eventbus_plugin:EventsEventBusProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::Lambda::EventInvokeConfig=localstack.services.lambda_.resource_providers.aws_lambda_eventinvokeconfig_plugin:LambdaEventInvokeConfigProviderPlugin", "AWS::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::IAM::ServerCertificate=localstack.services.iam.resource_providers.aws_iam_servercertificate_plugin:IAMServerCertificateProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::Lambda::Function=localstack.services.lambda_.resource_providers.aws_lambda_function_plugin:LambdaFunctionProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "AWS::SNS::Topic=localstack.services.sns.resource_providers.aws_sns_topic_plugin:SNSTopicProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::OpenSearchService::Domain=localstack.services.opensearch.resource_providers.aws_opensearchservice_domain_plugin:OpenSearchServiceDomainProviderPlugin", "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::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::EC2::PrefixList=localstack.services.ec2.resource_providers.aws_ec2_prefixlist_plugin:EC2PrefixListProviderPlugin", "AWS::DynamoDB::GlobalTable=localstack.services.dynamodb.resource_providers.aws_dynamodb_globaltable_plugin:DynamoDBGlobalTableProviderPlugin", "AWS::IAM::Policy=localstack.services.iam.resource_providers.aws_iam_policy_plugin:IAMPolicyProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin", "AWS::Route53::HealthCheck=localstack.services.route53.resource_providers.aws_route53_healthcheck_plugin:Route53HealthCheckProviderPlugin", "AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin", "AWS::Events::ApiDestination=localstack.services.events.resource_providers.aws_events_apidestination_plugin:EventsApiDestinationProviderPlugin", "AWS::EC2::TransitGateway=localstack.services.ec2.resource_providers.aws_ec2_transitgateway_plugin:EC2TransitGatewayProviderPlugin", "AWS::IAM::InstanceProfile=localstack.services.iam.resource_providers.aws_iam_instanceprofile_plugin:IAMInstanceProfileProviderPlugin", "AWS::Route53::RecordSet=localstack.services.route53.resource_providers.aws_route53_recordset_plugin:Route53RecordSetProviderPlugin", "AWS::ApiGateway::Deployment=localstack.services.apigateway.resource_providers.aws_apigateway_deployment_plugin:ApiGatewayDeploymentProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::ApiGateway::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "AWS::EC2::Subnet=localstack.services.ec2.resource_providers.aws_ec2_subnet_plugin:EC2SubnetProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::Events::EventBusPolicy=localstack.services.events.resource_providers.aws_events_eventbuspolicy_plugin:EventsEventBusPolicyProviderPlugin", "AWS::KMS::Alias=localstack.services.kms.resource_providers.aws_kms_alias_plugin:KMSAliasProviderPlugin", "AWS::EC2::NetworkAcl=localstack.services.ec2.resource_providers.aws_ec2_networkacl_plugin:EC2NetworkAclProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "AWS::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin", "AWS::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "AWS::IAM::ManagedPolicy=localstack.services.iam.resource_providers.aws_iam_managedpolicy_plugin:IAMManagedPolicyProviderPlugin", "AWS::IAM::Role=localstack.services.iam.resource_providers.aws_iam_role_plugin:IAMRoleProviderPlugin", "AWS::ApiGateway::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "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::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::Lambda::EventSourceMapping=localstack.services.lambda_.resource_providers.aws_lambda_eventsourcemapping_plugin:LambdaEventSourceMappingProviderPlugin"], "localstack.packages": ["elasticsearch/community=localstack.services.es.plugins:elasticsearch_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", "lambda-java-libs/community=localstack.services.lambda_.plugins:lambda_java_libs", "lambda-runtime/community=localstack.services.lambda_.plugins:lambda_runtime_package", "ffmpeg/community=localstack.packages.plugins:ffmpeg_package", "java/community=localstack.packages.plugins:java_package", "terraform/community=localstack.packages.plugins:terraform_package", "vosk/community=localstack.services.transcribe.plugins:vosk_package", "jpype-jsonata/community=localstack.services.stepfunctions.plugins:jpype_jsonata_package"], "localstack.hooks.on_infra_start": ["register_swagger_endpoints=localstack.http.resources.swagger.plugins:register_swagger_endpoints", "_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", "init_response_mutation_handler=localstack.aws.handlers.response:init_response_mutation_handler", "register_cloudformation_deploy_ui=localstack.services.cloudformation.plugins:register_cloudformation_deploy_ui", "apply_aws_runtime_patches=localstack.aws.patches:apply_aws_runtime_patches", "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", "eager_load_services=localstack.services.plugins:eager_load_services", "_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", "conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger", "setup_dns_configuration_on_host=localstack.dns.plugins:setup_dns_configuration_on_host", "start_dns_server=localstack.dns.plugins:start_dns_server"], "localstack.aws.provider": ["acm:default=localstack.services.providers:acm", "apigateway:default=localstack.services.providers:apigateway", "apigateway:legacy=localstack.services.providers:apigateway_legacy", "apigateway:next_gen=localstack.services.providers:apigateway_next_gen", "config:default=localstack.services.providers:awsconfig", "cloudformation:engine-legacy=localstack.services.providers:cloudformation", "cloudformation:default=localstack.services.providers:cloudformation_v2", "cloudwatch:default=localstack.services.providers:cloudwatch", "cloudwatch:v1=localstack.services.providers:cloudwatch_v1", "cloudwatch:v2=localstack.services.providers:cloudwatch_v2", "dynamodb:default=localstack.services.providers:dynamodb", "dynamodb:v2=localstack.services.providers:dynamodb_v2", "dynamodbstreams:default=localstack.services.providers:dynamodbstreams", "dynamodbstreams:v2=localstack.services.providers:dynamodbstreams_v2", "ec2:default=localstack.services.providers:ec2", "es:default=localstack.services.providers:es", "events:default=localstack.services.providers:events", "events:legacy=localstack.services.providers:events_legacy", "events:v1=localstack.services.providers:events_v1", "events:v2=localstack.services.providers:events_v2", "firehose:default=localstack.services.providers:firehose", "iam:default=localstack.services.providers:iam", "kinesis:default=localstack.services.providers:kinesis", "kms:default=localstack.services.providers:kms", "lambda:default=localstack.services.providers:lambda_", "lambda:asf=localstack.services.providers:lambda_asf", "lambda:v2=localstack.services.providers:lambda_v2", "logs:default=localstack.services.providers:logs", "opensearch:default=localstack.services.providers:opensearch", "redshift:default=localstack.services.providers:redshift", "resource-groups:default=localstack.services.providers:resource_groups", "resourcegroupstaggingapi:default=localstack.services.providers:resourcegroupstaggingapi", "route53:default=localstack.services.providers:route53", "route53resolver:default=localstack.services.providers:route53resolver", "s3:default=localstack.services.providers:s3", "s3control:default=localstack.services.providers:s3control", "scheduler:default=localstack.services.providers:scheduler", "secretsmanager:default=localstack.services.providers:secretsmanager", "ses:default=localstack.services.providers:ses", "sns:default=localstack.services.providers:sns", "sns:v2=localstack.services.providers:sns_v2", "sqs:default=localstack.services.providers:sqs", "ssm:default=localstack.services.providers:ssm", "stepfunctions:default=localstack.services.providers:stepfunctions", "stepfunctions:v2=localstack.services.providers:stepfunctions_v2", "sts:default=localstack.services.providers:sts", "support:default=localstack.services.providers:support", "swf:default=localstack.services.providers:swf", "transcribe:default=localstack.services.providers:transcribe"], "localstack.init.runner": ["py=localstack.runtime.init:PythonScriptRunner", "sh=localstack.runtime.init:ShellScriptRunner"], "localstack.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", "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", "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.server": ["hypercorn=localstack.runtime.server.plugins:HypercornRuntimeServerPlugin", "twisted=localstack.runtime.server.plugins:TwistedRuntimeServerPlugin"], "localstack.openapi.spec": ["localstack=localstack.plugins:CoreOASPlugin"], "localstack.runtime.components": ["aws=localstack.aws.components:AwsComponents"], "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.lambda.runtime_executor": ["docker=localstack.services.lambda_.invocation.plugins:DockerRuntimeExecutorPlugin"]}
@@ -1 +0,0 @@
1
- {"localstack.cloudformation.resource_providers": ["AWS::CertificateManager::Certificate=localstack.services.certificatemanager.resource_providers.aws_certificatemanager_certificate_plugin:CertificateManagerCertificateProviderPlugin", "AWS::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::CloudWatch::CompositeAlarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_compositealarm_plugin:CloudWatchCompositeAlarmProviderPlugin", "AWS::DynamoDB::GlobalTable=localstack.services.dynamodb.resource_providers.aws_dynamodb_globaltable_plugin:DynamoDBGlobalTableProviderPlugin", "AWS::SecretsManager::SecretTargetAttachment=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment_plugin:SecretsManagerSecretTargetAttachmentProviderPlugin", "AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::ApiGateway::DomainName=localstack.services.apigateway.resource_providers.aws_apigateway_domainname_plugin:ApiGatewayDomainNameProviderPlugin", "AWS::EC2::TransitGateway=localstack.services.ec2.resource_providers.aws_ec2_transitgateway_plugin:EC2TransitGatewayProviderPlugin", "AWS::Route53::HealthCheck=localstack.services.route53.resource_providers.aws_route53_healthcheck_plugin:Route53HealthCheckProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin", "AWS::EC2::RouteTable=localstack.services.ec2.resource_providers.aws_ec2_routetable_plugin:EC2RouteTableProviderPlugin", "AWS::KMS::Alias=localstack.services.kms.resource_providers.aws_kms_alias_plugin:KMSAliasProviderPlugin", "AWS::Kinesis::StreamConsumer=localstack.services.kinesis.resource_providers.aws_kinesis_streamconsumer_plugin:KinesisStreamConsumerProviderPlugin", "AWS::SNS::TopicPolicy=localstack.services.sns.resource_providers.aws_sns_topicpolicy_plugin:SNSTopicPolicyProviderPlugin", "AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "AWS::IAM::ServerCertificate=localstack.services.iam.resource_providers.aws_iam_servercertificate_plugin:IAMServerCertificateProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin", "AWS::Lambda::Version=localstack.services.lambda_.resource_providers.aws_lambda_version_plugin:LambdaVersionProviderPlugin", "AWS::EC2::PrefixList=localstack.services.ec2.resource_providers.aws_ec2_prefixlist_plugin:EC2PrefixListProviderPlugin", "AWS::Lambda::LayerVersionPermission=localstack.services.lambda_.resource_providers.aws_lambda_layerversionpermission_plugin:LambdaLayerVersionPermissionProviderPlugin", "AWS::KMS::Key=localstack.services.kms.resource_providers.aws_kms_key_plugin:KMSKeyProviderPlugin", "AWS::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "AWS::ApiGateway::RestApi=localstack.services.apigateway.resource_providers.aws_apigateway_restapi_plugin:ApiGatewayRestApiProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "AWS::EC2::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::DynamoDB::Table=localstack.services.dynamodb.resource_providers.aws_dynamodb_table_plugin:DynamoDBTableProviderPlugin", "AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin", "AWS::SQS::QueuePolicy=localstack.services.sqs.resource_providers.aws_sqs_queuepolicy_plugin:SQSQueuePolicyProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::EC2::VPCGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_vpcgatewayattachment_plugin:EC2VPCGatewayAttachmentProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::SNS::Subscription=localstack.services.sns.resource_providers.aws_sns_subscription_plugin:SNSSubscriptionProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::ApiGateway::Deployment=localstack.services.apigateway.resource_providers.aws_apigateway_deployment_plugin:ApiGatewayDeploymentProviderPlugin", "AWS::EC2::Subnet=localstack.services.ec2.resource_providers.aws_ec2_subnet_plugin:EC2SubnetProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::ApiGateway::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "AWS::Lambda::Function=localstack.services.lambda_.resource_providers.aws_lambda_function_plugin:LambdaFunctionProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "AWS::Events::ApiDestination=localstack.services.events.resource_providers.aws_events_apidestination_plugin:EventsApiDestinationProviderPlugin", "AWS::EC2::NetworkAcl=localstack.services.ec2.resource_providers.aws_ec2_networkacl_plugin:EC2NetworkAclProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::IAM::Policy=localstack.services.iam.resource_providers.aws_iam_policy_plugin:IAMPolicyProviderPlugin", "AWS::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::EC2::VPC=localstack.services.ec2.resource_providers.aws_ec2_vpc_plugin:EC2VPCProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "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::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::Lambda::Alias=localstack.services.lambda_.resource_providers.lambda_alias_plugin:LambdaAliasProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::IAM::Role=localstack.services.iam.resource_providers.aws_iam_role_plugin:IAMRoleProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::SNS::Topic=localstack.services.sns.resource_providers.aws_sns_topic_plugin:SNSTopicProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::Lambda::Permission=localstack.services.lambda_.resource_providers.aws_lambda_permission_plugin:LambdaPermissionProviderPlugin", "AWS::IAM::InstanceProfile=localstack.services.iam.resource_providers.aws_iam_instanceprofile_plugin:IAMInstanceProfileProviderPlugin", "AWS::OpenSearchService::Domain=localstack.services.opensearch.resource_providers.aws_opensearchservice_domain_plugin:OpenSearchServiceDomainProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::EC2::Route=localstack.services.ec2.resource_providers.aws_ec2_route_plugin:EC2RouteProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::Lambda::EventSourceMapping=localstack.services.lambda_.resource_providers.aws_lambda_eventsourcemapping_plugin:LambdaEventSourceMappingProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::ApiGateway::Method=localstack.services.apigateway.resource_providers.aws_apigateway_method_plugin:ApiGatewayMethodProviderPlugin", "AWS::Route53::RecordSet=localstack.services.route53.resource_providers.aws_route53_recordset_plugin:Route53RecordSetProviderPlugin", "AWS::IAM::ManagedPolicy=localstack.services.iam.resource_providers.aws_iam_managedpolicy_plugin:IAMManagedPolicyProviderPlugin", "AWS::Events::EventBusPolicy=localstack.services.events.resource_providers.aws_events_eventbuspolicy_plugin:EventsEventBusPolicyProviderPlugin", "AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::ApiGateway::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "AWS::Lambda::EventInvokeConfig=localstack.services.lambda_.resource_providers.aws_lambda_eventinvokeconfig_plugin:LambdaEventInvokeConfigProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin"], "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", "stop_server=localstack.dns.plugins:stop_server", "_run_init_scripts_on_shutdown=localstack.runtime.init:_run_init_scripts_on_shutdown", "remove_custom_endpoints=localstack.services.lambda_.plugins:remove_custom_endpoints", "publish_metrics=localstack.utils.analytics.metrics.publisher:publish_metrics"], "localstack.packages": ["kinesis-mock/community=localstack.services.kinesis.plugins:kinesismock_package", "vosk/community=localstack.services.transcribe.plugins:vosk_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", "ffmpeg/community=localstack.packages.plugins:ffmpeg_package", "java/community=localstack.packages.plugins:java_package", "terraform/community=localstack.packages.plugins:terraform_package", "opensearch/community=localstack.services.opensearch.plugins:opensearch_package", "dynamodb-local/community=localstack.services.dynamodb.plugins:dynamodb_local_package", "elasticsearch/community=localstack.services.es.plugins:elasticsearch_package"], "localstack.hooks.on_infra_start": ["setup_dns_configuration_on_host=localstack.dns.plugins:setup_dns_configuration_on_host", "start_dns_server=localstack.dns.plugins:start_dns_server", "conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger", "_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", "eager_load_services=localstack.services.plugins:eager_load_services", "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", "init_response_mutation_handler=localstack.aws.handlers.response:init_response_mutation_handler", "register_cloudformation_deploy_ui=localstack.services.cloudformation.plugins:register_cloudformation_deploy_ui", "apply_runtime_patches=localstack.runtime.patches:apply_runtime_patches", "register_swagger_endpoints=localstack.http.resources.swagger.plugins:register_swagger_endpoints", "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"], "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.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.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.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"]}