localstack-core 4.10.1.dev7__py3-none-any.whl → 4.11.2.dev14__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. localstack/aws/api/acm/__init__.py +122 -122
  2. localstack/aws/api/apigateway/__init__.py +604 -561
  3. localstack/aws/api/cloudcontrol/__init__.py +63 -63
  4. localstack/aws/api/cloudformation/__init__.py +1201 -969
  5. localstack/aws/api/cloudwatch/__init__.py +375 -375
  6. localstack/aws/api/config/__init__.py +784 -786
  7. localstack/aws/api/dynamodb/__init__.py +753 -759
  8. localstack/aws/api/dynamodbstreams/__init__.py +74 -74
  9. localstack/aws/api/ec2/__init__.py +10062 -8826
  10. localstack/aws/api/es/__init__.py +453 -453
  11. localstack/aws/api/events/__init__.py +552 -552
  12. localstack/aws/api/firehose/__init__.py +541 -543
  13. localstack/aws/api/iam/__init__.py +866 -572
  14. localstack/aws/api/kinesis/__init__.py +235 -147
  15. localstack/aws/api/kms/__init__.py +341 -336
  16. localstack/aws/api/lambda_/__init__.py +974 -621
  17. localstack/aws/api/logs/__init__.py +988 -675
  18. localstack/aws/api/opensearch/__init__.py +903 -785
  19. localstack/aws/api/pipes/__init__.py +336 -336
  20. localstack/aws/api/redshift/__init__.py +1257 -1166
  21. localstack/aws/api/resource_groups/__init__.py +175 -175
  22. localstack/aws/api/resourcegroupstaggingapi/__init__.py +103 -67
  23. localstack/aws/api/route53/__init__.py +296 -254
  24. localstack/aws/api/route53resolver/__init__.py +397 -396
  25. localstack/aws/api/s3/__init__.py +1412 -1349
  26. localstack/aws/api/s3control/__init__.py +594 -594
  27. localstack/aws/api/scheduler/__init__.py +118 -118
  28. localstack/aws/api/secretsmanager/__init__.py +221 -216
  29. localstack/aws/api/ses/__init__.py +227 -227
  30. localstack/aws/api/sns/__init__.py +115 -115
  31. localstack/aws/api/sqs/__init__.py +100 -100
  32. localstack/aws/api/ssm/__init__.py +1977 -1971
  33. localstack/aws/api/stepfunctions/__init__.py +375 -333
  34. localstack/aws/api/sts/__init__.py +142 -66
  35. localstack/aws/api/support/__init__.py +112 -112
  36. localstack/aws/api/swf/__init__.py +378 -386
  37. localstack/aws/api/transcribe/__init__.py +425 -425
  38. localstack/aws/handlers/logging.py +8 -4
  39. localstack/aws/handlers/service.py +22 -3
  40. localstack/aws/protocol/parser.py +1 -1
  41. localstack/aws/protocol/serializer.py +1 -1
  42. localstack/aws/scaffold.py +15 -17
  43. localstack/cli/localstack.py +6 -1
  44. localstack/deprecations.py +0 -6
  45. localstack/dev/kubernetes/__main__.py +38 -3
  46. localstack/services/acm/provider.py +4 -0
  47. localstack/services/apigateway/helpers.py +5 -9
  48. localstack/services/apigateway/legacy/provider.py +60 -24
  49. localstack/services/apigateway/patches.py +0 -9
  50. localstack/services/cloudformation/engine/template_preparer.py +6 -2
  51. localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +12 -0
  52. localstack/services/cloudformation/provider.py +2 -2
  53. localstack/services/cloudformation/v2/provider.py +6 -6
  54. localstack/services/cloudwatch/provider.py +10 -3
  55. localstack/services/cloudwatch/provider_v2.py +6 -3
  56. localstack/services/configservice/provider.py +5 -1
  57. localstack/services/dynamodb/provider.py +1 -0
  58. localstack/services/dynamodb/v2/provider.py +1 -0
  59. localstack/services/dynamodbstreams/provider.py +6 -0
  60. localstack/services/dynamodbstreams/v2/provider.py +6 -0
  61. localstack/services/ec2/provider.py +6 -0
  62. localstack/services/es/provider.py +6 -0
  63. localstack/services/events/provider.py +4 -0
  64. localstack/services/events/v1/provider.py +9 -0
  65. localstack/services/firehose/provider.py +5 -0
  66. localstack/services/iam/provider.py +4 -0
  67. localstack/services/kinesis/packages.py +1 -1
  68. localstack/services/kms/models.py +44 -24
  69. localstack/services/kms/provider.py +97 -16
  70. localstack/services/lambda_/api_utils.py +40 -21
  71. localstack/services/lambda_/event_source_mapping/pollers/stream_poller.py +1 -1
  72. localstack/services/lambda_/invocation/assignment.py +4 -1
  73. localstack/services/lambda_/invocation/execution_environment.py +21 -2
  74. localstack/services/lambda_/invocation/lambda_models.py +27 -2
  75. localstack/services/lambda_/invocation/lambda_service.py +51 -3
  76. localstack/services/lambda_/invocation/models.py +9 -1
  77. localstack/services/lambda_/invocation/version_manager.py +18 -3
  78. localstack/services/lambda_/packages.py +1 -1
  79. localstack/services/lambda_/provider.py +240 -96
  80. localstack/services/lambda_/resource_providers/aws_lambda_function.py +33 -1
  81. localstack/services/lambda_/runtimes.py +10 -3
  82. localstack/services/logs/provider.py +45 -19
  83. localstack/services/opensearch/provider.py +53 -3
  84. localstack/services/resource_groups/provider.py +5 -1
  85. localstack/services/resourcegroupstaggingapi/provider.py +6 -1
  86. localstack/services/s3/provider.py +29 -16
  87. localstack/services/s3/utils.py +35 -14
  88. localstack/services/s3control/provider.py +101 -2
  89. localstack/services/s3control/validation.py +50 -0
  90. localstack/services/sns/constants.py +3 -1
  91. localstack/services/sns/publisher.py +15 -6
  92. localstack/services/sns/v2/models.py +30 -1
  93. localstack/services/sns/v2/provider.py +794 -31
  94. localstack/services/sns/v2/utils.py +20 -0
  95. localstack/services/sqs/models.py +37 -10
  96. localstack/services/stepfunctions/asl/component/common/path/result_path.py +1 -1
  97. localstack/services/stepfunctions/asl/component/state/state_execution/execute_state.py +0 -1
  98. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/state_map.py +0 -1
  99. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/lambda_eval_utils.py +8 -8
  100. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/{mock_eval_utils.py → local_mock_eval_utils.py} +13 -9
  101. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service.py +6 -6
  102. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_callback.py +1 -1
  103. localstack/services/stepfunctions/asl/component/state/state_fail/state_fail.py +4 -0
  104. localstack/services/stepfunctions/asl/component/test_state/state/base_mock.py +118 -0
  105. localstack/services/stepfunctions/asl/component/test_state/state/common.py +82 -0
  106. localstack/services/stepfunctions/asl/component/test_state/state/execution.py +139 -0
  107. localstack/services/stepfunctions/asl/component/test_state/state/map.py +77 -0
  108. localstack/services/stepfunctions/asl/component/test_state/state/task.py +44 -0
  109. localstack/services/stepfunctions/asl/eval/environment.py +30 -22
  110. localstack/services/stepfunctions/asl/eval/states.py +1 -1
  111. localstack/services/stepfunctions/asl/eval/test_state/environment.py +49 -9
  112. localstack/services/stepfunctions/asl/eval/test_state/program_state.py +22 -0
  113. localstack/services/stepfunctions/asl/jsonata/jsonata.py +5 -1
  114. localstack/services/stepfunctions/asl/parse/preprocessor.py +67 -24
  115. localstack/services/stepfunctions/asl/parse/test_state/asl_parser.py +5 -4
  116. localstack/services/stepfunctions/asl/parse/test_state/preprocessor.py +222 -31
  117. localstack/services/stepfunctions/asl/static_analyser/test_state/test_state_analyser.py +170 -22
  118. localstack/services/stepfunctions/backend/execution.py +6 -6
  119. localstack/services/stepfunctions/backend/execution_worker.py +5 -5
  120. localstack/services/stepfunctions/backend/test_state/execution.py +36 -0
  121. localstack/services/stepfunctions/backend/test_state/execution_worker.py +33 -1
  122. localstack/services/stepfunctions/backend/test_state/test_state_mock.py +127 -0
  123. localstack/services/stepfunctions/local_mocking/__init__.py +9 -0
  124. localstack/services/stepfunctions/{mocking → local_mocking}/mock_config.py +24 -17
  125. localstack/services/stepfunctions/provider.py +78 -27
  126. localstack/services/stepfunctions/test_state/mock_config.py +47 -0
  127. localstack/testing/pytest/fixtures.py +28 -0
  128. localstack/testing/snapshots/transformer_utility.py +7 -0
  129. localstack/testing/testselection/matching.py +0 -1
  130. localstack/utils/analytics/publisher.py +37 -155
  131. localstack/utils/analytics/service_request_aggregator.py +6 -4
  132. localstack/utils/aws/arns.py +7 -0
  133. localstack/utils/aws/client_types.py +0 -8
  134. localstack/utils/batching.py +258 -0
  135. localstack/utils/catalog/catalog_loader.py +111 -3
  136. localstack/utils/collections.py +23 -11
  137. localstack/utils/crypto.py +109 -0
  138. localstack/version.py +2 -2
  139. {localstack_core-4.10.1.dev7.dist-info → localstack_core-4.11.2.dev14.dist-info}/METADATA +7 -6
  140. {localstack_core-4.10.1.dev7.dist-info → localstack_core-4.11.2.dev14.dist-info}/RECORD +149 -141
  141. localstack_core-4.11.2.dev14.dist-info/plux.json +1 -0
  142. localstack/services/stepfunctions/mocking/__init__.py +0 -0
  143. localstack/utils/batch_policy.py +0 -124
  144. localstack_core-4.10.1.dev7.dist-info/plux.json +0 -1
  145. /localstack/services/stepfunctions/{mocking → local_mocking}/mock_config_file.py +0 -0
  146. {localstack_core-4.10.1.dev7.data → localstack_core-4.11.2.dev14.data}/scripts/localstack +0 -0
  147. {localstack_core-4.10.1.dev7.data → localstack_core-4.11.2.dev14.data}/scripts/localstack-supervisor +0 -0
  148. {localstack_core-4.10.1.dev7.data → localstack_core-4.11.2.dev14.data}/scripts/localstack.bat +0 -0
  149. {localstack_core-4.10.1.dev7.dist-info → localstack_core-4.11.2.dev14.dist-info}/WHEEL +0 -0
  150. {localstack_core-4.10.1.dev7.dist-info → localstack_core-4.11.2.dev14.dist-info}/entry_points.txt +0 -0
  151. {localstack_core-4.10.1.dev7.dist-info → localstack_core-4.11.2.dev14.dist-info}/licenses/LICENSE.txt +0 -0
  152. {localstack_core-4.10.1.dev7.dist-info → localstack_core-4.11.2.dev14.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,119 @@
1
1
  import json
2
+ import logging
3
+ from json import JSONDecodeError
4
+ from pathlib import Path
2
5
 
6
+ import requests
7
+ from pydantic import BaseModel
8
+
9
+ from localstack import config, constants
3
10
  from localstack.utils.catalog.common import AwsRemoteCatalog
11
+ from localstack.utils.http import get_proxies
12
+ from localstack.utils.json import FileMappedDocument
13
+
14
+ LOG = logging.getLogger(__name__)
15
+
16
+ AWS_CATALOG_FILE_NAME = "aws_catalog.json"
17
+
4
18
 
5
- LICENSE_CATALOG_PATH = ""
19
+ class RemoteCatalogVersionResponse(BaseModel):
20
+ emulator_type: str
21
+ version: str
22
+
23
+
24
+ class AwsCatalogLoaderException(Exception):
25
+ def __init__(self, msg: str, *args):
26
+ super().__init__(msg, *args)
6
27
 
7
28
 
8
29
  class RemoteCatalogLoader:
30
+ supported_schema_version = "v1"
31
+ api_endpoint_catalog = f"{constants.API_ENDPOINT}/license/catalog"
32
+ catalog_file_path = Path(config.dirs.cache) / AWS_CATALOG_FILE_NAME
33
+
9
34
  def get_remote_catalog(self) -> AwsRemoteCatalog:
10
- with open(LICENSE_CATALOG_PATH) as f:
11
- return AwsRemoteCatalog(**json.load(f))
35
+ catalog_doc = FileMappedDocument(self.catalog_file_path)
36
+ cached_catalog = AwsRemoteCatalog(**catalog_doc) if catalog_doc else None
37
+ if cached_catalog:
38
+ cached_catalog_version = cached_catalog.localstack.version
39
+ if not self._should_update_cached_catalog(cached_catalog_version):
40
+ return cached_catalog
41
+ catalog = self._get_catalog_from_platform()
42
+ self._save_catalog_to_cache(catalog_doc, catalog)
43
+ return catalog
44
+
45
+ def _get_latest_localstack_version(self) -> str:
46
+ try:
47
+ proxies = get_proxies()
48
+ response = requests.get(
49
+ f"{self.api_endpoint_catalog}/aws/version",
50
+ verify=not config.is_env_true("SSL_NO_VERIFY"),
51
+ proxies=proxies,
52
+ )
53
+ if response.ok:
54
+ return RemoteCatalogVersionResponse.model_validate(response.content).version
55
+ self._raise_server_error(response)
56
+ except requests.exceptions.RequestException as e:
57
+ raise AwsCatalogLoaderException(
58
+ f"An unexpected network error occurred when trying to fetch latest localstack version: {e}"
59
+ ) from e
60
+
61
+ def _should_update_cached_catalog(self, current_catalog_version: str) -> bool:
62
+ try:
63
+ latest_version = self._get_latest_localstack_version()
64
+ return latest_version != current_catalog_version
65
+ except Exception as e:
66
+ LOG.warning(
67
+ "Failed to retrieve the latest catalog version, cached catalog update skipped: %s",
68
+ e,
69
+ )
70
+ return False
71
+
72
+ def _save_catalog_to_cache(self, catalog_doc: FileMappedDocument, catalog: AwsRemoteCatalog):
73
+ catalog_doc.clear()
74
+ catalog_doc.update(catalog.model_dump())
75
+ catalog_doc.save()
76
+
77
+ def _get_catalog_from_platform(self) -> AwsRemoteCatalog:
78
+ try:
79
+ proxies = get_proxies()
80
+ response = requests.post(
81
+ self.api_endpoint_catalog,
82
+ verify=not config.is_env_true("SSL_NO_VERIFY"),
83
+ proxies=proxies,
84
+ )
85
+
86
+ if response.ok:
87
+ return self._parse_catalog(response.content)
88
+ self._raise_server_error(response)
89
+ except requests.exceptions.RequestException as e:
90
+ raise AwsCatalogLoaderException(
91
+ f"An unexpected network error occurred when trying to fetch remote catalog: {e}"
92
+ ) from e
93
+
94
+ def _parse_catalog(self, document: bytes) -> AwsRemoteCatalog | None:
95
+ try:
96
+ catalog_json = json.loads(document)
97
+ except JSONDecodeError as e:
98
+ raise AwsCatalogLoaderException(f"Could not de-serialize json catalog: {e}") from e
99
+ remote_catalog = AwsRemoteCatalog.model_validate(catalog_json)
100
+ if remote_catalog.schema_version != self.supported_schema_version:
101
+ raise AwsCatalogLoaderException(
102
+ f"Unsupported schema version: '{remote_catalog.schema_version}'. Only '{self.supported_schema_version}' is supported"
103
+ )
104
+ return remote_catalog
105
+
106
+ def _raise_server_error(self, response: requests.Response):
107
+ try:
108
+ server_error = response.json()
109
+ if error_message := server_error.get("message"):
110
+ raise AwsCatalogLoaderException(
111
+ f"Unexpected AWS catalog server error: {response.text}"
112
+ )
113
+ raise AwsCatalogLoaderException(
114
+ f"A server error occurred while calling remote catalog API (HTTP {response.status_code}): {error_message}"
115
+ )
116
+ except Exception:
117
+ raise AwsCatalogLoaderException(
118
+ f"An unexpected server error occurred while calling remote catalog API (HTTP {response.status_code}): {response.text}"
119
+ )
@@ -5,7 +5,7 @@ and manipulate python collection (dicts, list, sets).
5
5
 
6
6
  import logging
7
7
  import re
8
- from collections.abc import Callable, Iterable, Iterator, Mapping, Sized
8
+ from collections.abc import Callable, Generator, Iterable, Iterator, Mapping, Sized
9
9
  from typing import (
10
10
  Any,
11
11
  Optional,
@@ -24,6 +24,9 @@ LOG = logging.getLogger(__name__)
24
24
  # default regex to match an item in a comma-separated list string
25
25
  DEFAULT_REGEX_LIST_ITEM = r"[\w-]+"
26
26
 
27
+ _E = TypeVar("_E")
28
+ """TypeVar var used internally for container type parameters."""
29
+
27
30
 
28
31
  class AccessTrackingDict(dict):
29
32
  """
@@ -101,21 +104,18 @@ class HashableJsonDict(ImmutableDict):
101
104
  return hash(canonical_json(self._dict))
102
105
 
103
106
 
104
- _ListType = TypeVar("_ListType")
105
-
106
-
107
- class PaginatedList(list[_ListType]):
107
+ class PaginatedList(list[_E]):
108
108
  """List which can be paginated and filtered. For usage in AWS APIs with paginated responses"""
109
109
 
110
110
  DEFAULT_PAGE_SIZE = 50
111
111
 
112
112
  def get_page(
113
113
  self,
114
- token_generator: Callable[[_ListType], str],
114
+ token_generator: Callable[[_E], str],
115
115
  next_token: str = None,
116
116
  page_size: int = None,
117
- filter_function: Callable[[_ListType], bool] = None,
118
- ) -> tuple[list[_ListType], str | None]:
117
+ filter_function: Callable[[_E], bool] = None,
118
+ ) -> tuple[list[_E], str | None]:
119
119
  if filter_function is not None:
120
120
  result_list = list(filter(filter_function, self))
121
121
  else:
@@ -528,9 +528,6 @@ def is_comma_delimited_list(string: str, item_regex: str | None = None) -> bool:
528
528
  return True
529
529
 
530
530
 
531
- _E = TypeVar("_E")
532
-
533
-
534
531
  def optional_list(condition: bool, items: Iterable[_E]) -> list[_E]:
535
532
  """
536
533
  Given an iterable, either create a list out of the entire iterable (if `condition` is `True`), or return the empty list.
@@ -540,3 +537,18 @@ def optional_list(condition: bool, items: Iterable[_E]) -> list[_E]:
540
537
  []
541
538
  """
542
539
  return list(filter(lambda _: condition, items))
540
+
541
+
542
+ def iter_chunks(items: list[_E], chunk_size: int) -> Generator[list[_E], None, None]:
543
+ """
544
+ Split a list into smaller chunks of a specified size and iterate over them.
545
+
546
+ It is implemented as a generator and yields each chunk as needed, making it memory-efficient for large lists.
547
+
548
+ :param items: A list of elements to be divided into chunks.
549
+ :param chunk_size: The maximum number of elements that a single chunk can contain.
550
+ :return: A generator that yields chunks (sublists) of the original list. Each chunk contains up to `chunk_size`
551
+ elements.
552
+ """
553
+ for i in range(0, len(items), chunk_size):
554
+ yield items[i : i + chunk_size]
@@ -4,7 +4,13 @@ import os
4
4
  import re
5
5
  import threading
6
6
 
7
+ from asn1crypto import algos, cms, core
8
+ from asn1crypto import x509 as asn1_x509
7
9
  from cryptography.hazmat.backends import default_backend
10
+ from cryptography.hazmat.primitives import hashes
11
+ from cryptography.hazmat.primitives import padding as sym_padding
12
+ from cryptography.hazmat.primitives.asymmetric import padding
13
+ from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
8
14
  from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
9
15
 
10
16
  from .files import TMP_FILES, file_exists_not_empty, load_file, new_tmp_file, save_file
@@ -26,6 +32,11 @@ PEM_CERT_END = "-----END CERTIFICATE-----"
26
32
  PEM_KEY_START_REGEX = r"-----BEGIN(.*)PRIVATE KEY-----"
27
33
  PEM_KEY_END_REGEX = r"-----END(.*)PRIVATE KEY-----"
28
34
 
35
+ OID_AES256_CBC = "2.16.840.1.101.3.4.1.42"
36
+ OID_MGF1 = "1.2.840.113549.1.1.8"
37
+ OID_RSAES_OAEP = "1.2.840.113549.1.1.7"
38
+ OID_SHA256 = "2.16.840.1.101.3.4.2.1"
39
+
29
40
 
30
41
  @synchronized(lock=SSL_CERT_LOCK)
31
42
  def generate_ssl_cert(
@@ -183,3 +194,101 @@ def decrypt(
183
194
  decrypted = decryptor.update(encrypted) + decryptor.finalize()
184
195
  decrypted = unpad(decrypted)
185
196
  return decrypted
197
+
198
+
199
+ def pkcs7_envelope_encrypt(plaintext: bytes, recipient_pubkey: RSAPublicKey) -> bytes:
200
+ """
201
+ Create a PKCS7 wrapper of some plaintext decryptable by recipient_pubkey. Uses RSA-OAEP with SHA-256
202
+ to encrypt the AES-256-CBC content key. Hazmat's PKCS7EnvelopeBuilder doesn't support RSA-OAEP with SHA-256,
203
+ so we need to build the pieces manually and then put them together in an envelope with asn1crypto.
204
+ """
205
+
206
+ # Encrypt the plaintext with an AES session key, then encrypt the session key to the recipient_pubkey
207
+ session_key = os.urandom(32)
208
+ iv = os.urandom(16)
209
+ encrypted_session_key = recipient_pubkey.encrypt(
210
+ session_key,
211
+ padding.OAEP(
212
+ mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None
213
+ ),
214
+ )
215
+ cipher = Cipher(algorithms.AES(session_key), modes.CBC(iv), backend=default_backend())
216
+ encryptor = cipher.encryptor()
217
+ padder = sym_padding.PKCS7(algorithms.AES.block_size).padder()
218
+ padded_plaintext = padder.update(plaintext) + padder.finalize()
219
+ encrypted_content = encryptor.update(padded_plaintext) + encryptor.finalize()
220
+
221
+ # Now put together the envelope.
222
+ # Add the recipient with their copy of the session key
223
+ recipient_identifier = cms.RecipientIdentifier(
224
+ name="issuer_and_serial_number",
225
+ value=cms.IssuerAndSerialNumber(
226
+ {
227
+ "issuer": asn1_x509.Name.build({"common_name": "recipient"}),
228
+ "serial_number": 1,
229
+ }
230
+ ),
231
+ )
232
+ key_enc_algorithm = cms.KeyEncryptionAlgorithm(
233
+ {
234
+ "algorithm": OID_RSAES_OAEP,
235
+ "parameters": algos.RSAESOAEPParams(
236
+ {
237
+ "hash_algorithm": algos.DigestAlgorithm(
238
+ {
239
+ "algorithm": OID_SHA256,
240
+ }
241
+ ),
242
+ "mask_gen_algorithm": algos.MaskGenAlgorithm(
243
+ {
244
+ "algorithm": OID_MGF1,
245
+ "parameters": algos.DigestAlgorithm(
246
+ {
247
+ "algorithm": OID_SHA256,
248
+ }
249
+ ),
250
+ }
251
+ ),
252
+ }
253
+ ),
254
+ }
255
+ )
256
+ recipient_info = cms.KeyTransRecipientInfo(
257
+ {
258
+ "version": "v0",
259
+ "rid": recipient_identifier,
260
+ "key_encryption_algorithm": key_enc_algorithm,
261
+ "encrypted_key": encrypted_session_key,
262
+ }
263
+ )
264
+
265
+ # Add the encrypted content
266
+ content_enc_algorithm = cms.EncryptionAlgorithm(
267
+ {
268
+ "algorithm": OID_AES256_CBC,
269
+ "parameters": core.OctetString(iv),
270
+ }
271
+ )
272
+ encrypted_content_info = cms.EncryptedContentInfo(
273
+ {
274
+ "content_type": "data",
275
+ "content_encryption_algorithm": content_enc_algorithm,
276
+ "encrypted_content": encrypted_content,
277
+ }
278
+ )
279
+ enveloped_data = cms.EnvelopedData(
280
+ {
281
+ "version": "v0",
282
+ "recipient_infos": [recipient_info],
283
+ "encrypted_content_info": encrypted_content_info,
284
+ }
285
+ )
286
+
287
+ # Finally add a wrapper and return its bytes
288
+ content_info = cms.ContentInfo(
289
+ {
290
+ "content_type": "enveloped_data",
291
+ "content": enveloped_data,
292
+ }
293
+ )
294
+ return content_info.dump()
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.10.1.dev7'
32
- __version_tuple__ = version_tuple = (4, 10, 1, 'dev7')
31
+ __version__ = version = '4.11.2.dev14'
32
+ __version_tuple__ = version_tuple = (4, 11, 2, 'dev14')
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.10.1.dev7
3
+ Version: 4.11.2.dev14
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
@@ -15,7 +15,8 @@ Classifier: Topic :: Software Development :: Testing
15
15
  Classifier: Topic :: System :: Emulators
16
16
  Requires-Python: >=3.10
17
17
  License-File: LICENSE.txt
18
- Requires-Dist: click>=7.1
18
+ Requires-Dist: asn1crypto>=1.5.1
19
+ Requires-Dist: click>=8.2.0
19
20
  Requires-Dist: cachetools>=5.0
20
21
  Requires-Dist: cryptography
21
22
  Requires-Dist: dill==0.3.6
@@ -29,8 +30,8 @@ Requires-Dist: rich>=12.3.0
29
30
  Requires-Dist: requests>=2.20.0
30
31
  Requires-Dist: semver>=2.10
31
32
  Provides-Extra: base-runtime
32
- Requires-Dist: boto3==1.40.64; extra == "base-runtime"
33
- Requires-Dist: botocore==1.40.64; extra == "base-runtime"
33
+ Requires-Dist: boto3==1.42.0; extra == "base-runtime"
34
+ Requires-Dist: botocore==1.41.6; extra == "base-runtime"
34
35
  Requires-Dist: awscrt!=0.27.1,>=0.13.14; extra == "base-runtime"
35
36
  Requires-Dist: cbor2>=5.5.0; extra == "base-runtime"
36
37
  Requires-Dist: dnspython>=1.16.0; extra == "base-runtime"
@@ -52,7 +53,7 @@ Requires-Dist: xmltodict>=0.13.0; extra == "base-runtime"
52
53
  Requires-Dist: rolo>=0.7; extra == "base-runtime"
53
54
  Provides-Extra: runtime
54
55
  Requires-Dist: localstack-core[base-runtime]; extra == "runtime"
55
- Requires-Dist: awscli==1.42.64; extra == "runtime"
56
+ Requires-Dist: awscli==1.43.6; extra == "runtime"
56
57
  Requires-Dist: airspeed-ext>=0.6.3; extra == "runtime"
57
58
  Requires-Dist: antlr4-python3-runtime==4.13.2; extra == "runtime"
58
59
  Requires-Dist: apispec>=5.1.1; extra == "runtime"
@@ -99,5 +100,5 @@ Requires-Dist: rstr>=3.2.0; extra == "dev"
99
100
  Requires-Dist: mypy; extra == "dev"
100
101
  Provides-Extra: typehint
101
102
  Requires-Dist: localstack-core[dev]; extra == "typehint"
102
- Requires-Dist: boto3-stubs[acm,acm-pca,amplify,apigateway,apigatewayv2,appconfig,appconfigdata,application-autoscaling,appsync,athena,autoscaling,backup,batch,ce,cloudcontrol,cloudformation,cloudfront,cloudtrail,cloudwatch,codebuild,codecommit,codeconnections,codedeploy,codepipeline,codestar-connections,cognito-identity,cognito-idp,dms,docdb,dynamodb,dynamodbstreams,ec2,ecr,ecs,efs,eks,elasticache,elasticbeanstalk,elbv2,emr,emr-serverless,es,events,firehose,fis,glacier,glue,iam,identitystore,iot,iot-data,iotanalytics,iotwireless,kafka,kinesis,kinesisanalytics,kinesisanalyticsv2,kms,lakeformation,lambda,logs,managedblockchain,mediaconvert,mediastore,mq,mwaa,neptune,opensearch,organizations,pi,pinpoint,pipes,qldb,qldb-session,rds,rds-data,redshift,redshift-data,resource-groups,resourcegroupstaggingapi,route53,route53resolver,s3,s3control,sagemaker,sagemaker-runtime,secretsmanager,serverlessrepo,servicediscovery,ses,sesv2,sns,sqs,ssm,sso-admin,stepfunctions,sts,timestream-query,timestream-write,transcribe,verifiedpermissions,wafv2,xray]; extra == "typehint"
103
+ Requires-Dist: boto3-stubs[acm,acm-pca,amplify,apigateway,apigatewayv2,appconfig,appconfigdata,application-autoscaling,appsync,athena,autoscaling,backup,batch,ce,cloudcontrol,cloudformation,cloudfront,cloudtrail,cloudwatch,codebuild,codecommit,codeconnections,codedeploy,codepipeline,codestar-connections,cognito-identity,cognito-idp,dms,docdb,dynamodb,dynamodbstreams,ec2,ecr,ecs,efs,eks,elasticache,elasticbeanstalk,elbv2,emr,emr-serverless,es,events,firehose,fis,glacier,glue,iam,identitystore,iot,iot-data,iotanalytics,iotwireless,kafka,kinesis,kinesisanalyticsv2,kms,lakeformation,lambda,logs,managedblockchain,mediaconvert,mediastore,mq,mwaa,neptune,opensearch,organizations,pi,pinpoint,pipes,rds,rds-data,redshift,redshift-data,resource-groups,resourcegroupstaggingapi,route53,route53resolver,s3,s3control,sagemaker,sagemaker-runtime,secretsmanager,serverlessrepo,servicediscovery,ses,sesv2,sns,sqs,ssm,sso-admin,stepfunctions,sts,timestream-query,timestream-write,transcribe,verifiedpermissions,wafv2,xray]; extra == "typehint"
103
104
  Dynamic: license-file