localstack-core 4.6.1.dev60__py3-none-any.whl → 4.10.1.dev12__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 (672) hide show
  1. localstack/aws/api/apigateway/__init__.py +87 -110
  2. localstack/aws/api/cloudformation/__init__.py +18 -4
  3. localstack/aws/api/cloudwatch/__init__.py +41 -1
  4. localstack/aws/api/config/__init__.py +4 -0
  5. localstack/aws/api/core.py +8 -5
  6. localstack/aws/api/dynamodb/__init__.py +30 -0
  7. localstack/aws/api/ec2/__init__.py +1545 -66
  8. localstack/aws/api/events/__init__.py +12 -16
  9. localstack/aws/api/iam/__init__.py +7 -0
  10. localstack/aws/api/kinesis/__init__.py +19 -0
  11. localstack/aws/api/kms/__init__.py +6 -0
  12. localstack/aws/api/lambda_/__init__.py +36 -23
  13. localstack/aws/api/logs/__init__.py +20 -8
  14. localstack/aws/api/opensearch/__init__.py +16 -0
  15. localstack/aws/api/pipes/__init__.py +24 -32
  16. localstack/aws/api/redshift/__init__.py +9 -3
  17. localstack/aws/api/route53/__init__.py +5 -0
  18. localstack/aws/api/s3/__init__.py +12 -0
  19. localstack/aws/api/s3control/__init__.py +56 -0
  20. localstack/aws/api/scheduler/__init__.py +14 -16
  21. localstack/aws/api/ssm/__init__.py +2 -0
  22. localstack/aws/api/stepfunctions/__init__.py +88 -114
  23. localstack/aws/api/support/__init__.py +8 -9
  24. localstack/aws/api/transcribe/__init__.py +17 -0
  25. localstack/aws/chain.py +2 -2
  26. localstack/aws/client.py +14 -11
  27. localstack/aws/connect.py +42 -41
  28. localstack/aws/forwarder.py +57 -9
  29. localstack/aws/gateway.py +1 -3
  30. localstack/aws/handlers/analytics.py +2 -3
  31. localstack/aws/handlers/cors.py +4 -5
  32. localstack/aws/handlers/internal_requests.py +6 -1
  33. localstack/aws/handlers/logging.py +13 -4
  34. localstack/aws/handlers/metric_handler.py +44 -5
  35. localstack/aws/handlers/service.py +48 -28
  36. localstack/aws/mocking.py +18 -27
  37. localstack/aws/patches.py +2 -2
  38. localstack/aws/protocol/op_router.py +11 -10
  39. localstack/aws/protocol/parser.py +475 -49
  40. localstack/aws/protocol/serializer.py +723 -106
  41. localstack/aws/protocol/service_router.py +133 -33
  42. localstack/aws/protocol/validate.py +6 -6
  43. localstack/aws/scaffold.py +9 -10
  44. localstack/aws/serving/edge.py +5 -6
  45. localstack/aws/serving/hypercorn.py +2 -2
  46. localstack/aws/serving/twisted.py +1 -2
  47. localstack/aws/serving/werkzeug.py +2 -2
  48. localstack/aws/skeleton.py +12 -11
  49. localstack/aws/spec-patches.json +58 -0
  50. localstack/aws/spec.py +66 -46
  51. localstack/cli/exceptions.py +1 -1
  52. localstack/cli/localstack.py +11 -11
  53. localstack/cli/lpm.py +4 -5
  54. localstack/cli/plugins.py +1 -1
  55. localstack/cli/profiles.py +1 -2
  56. localstack/config.py +44 -30
  57. localstack/constants.py +4 -29
  58. localstack/deprecations.py +5 -5
  59. localstack/dev/kubernetes/__main__.py +130 -7
  60. localstack/dev/run/__main__.py +5 -5
  61. localstack/dev/run/configurators.py +1 -4
  62. localstack/dev/run/paths.py +6 -6
  63. localstack/dns/models.py +2 -1
  64. localstack/dns/plugins.py +5 -1
  65. localstack/dns/server.py +16 -6
  66. localstack/http/dispatcher.py +1 -2
  67. localstack/http/response.py +2 -2
  68. localstack/http/router.py +1 -1
  69. localstack/http/trace.py +2 -1
  70. localstack/logging/format.py +6 -6
  71. localstack/packages/api.py +13 -12
  72. localstack/packages/core.py +4 -4
  73. localstack/packages/debugpy.py +1 -3
  74. localstack/packages/ffmpeg.py +1 -2
  75. localstack/packages/java.py +38 -12
  76. localstack/packages/plugins.py +0 -8
  77. localstack/runtime/analytics.py +3 -0
  78. localstack/runtime/hooks.py +1 -1
  79. localstack/runtime/init.py +8 -9
  80. localstack/runtime/main.py +5 -5
  81. localstack/runtime/patches.py +2 -2
  82. localstack/runtime/shutdown.py +2 -1
  83. localstack/services/apigateway/exporter.py +1 -2
  84. localstack/services/apigateway/helpers.py +7 -10
  85. localstack/services/apigateway/legacy/context.py +21 -21
  86. localstack/services/apigateway/legacy/helpers.py +27 -28
  87. localstack/services/apigateway/legacy/integration.py +11 -10
  88. localstack/services/apigateway/legacy/invocations.py +6 -5
  89. localstack/services/apigateway/legacy/provider.py +148 -68
  90. localstack/services/apigateway/legacy/router_asf.py +2 -2
  91. localstack/services/apigateway/legacy/templates.py +6 -6
  92. localstack/services/apigateway/models.py +16 -16
  93. localstack/services/apigateway/next_gen/execute_api/api.py +2 -2
  94. localstack/services/apigateway/next_gen/execute_api/context.py +25 -25
  95. localstack/services/apigateway/next_gen/execute_api/handlers/api_key_validation.py +2 -5
  96. localstack/services/apigateway/next_gen/execute_api/handlers/method_request.py +7 -2
  97. localstack/services/apigateway/next_gen/execute_api/handlers/parse.py +1 -2
  98. localstack/services/apigateway/next_gen/execute_api/handlers/resource_router.py +2 -3
  99. localstack/services/apigateway/next_gen/execute_api/header_utils.py +1 -1
  100. localstack/services/apigateway/next_gen/execute_api/helpers.py +2 -2
  101. localstack/services/apigateway/next_gen/execute_api/integrations/aws.py +9 -6
  102. localstack/services/apigateway/next_gen/execute_api/integrations/http.py +12 -12
  103. localstack/services/apigateway/next_gen/execute_api/router.py +31 -0
  104. localstack/services/apigateway/next_gen/execute_api/template_mapping.py +2 -2
  105. localstack/services/apigateway/next_gen/execute_api/test_invoke.py +114 -9
  106. localstack/services/apigateway/next_gen/execute_api/variables.py +63 -63
  107. localstack/services/apigateway/next_gen/provider.py +5 -0
  108. localstack/services/apigateway/resource_providers/aws_apigateway_account.py +3 -3
  109. localstack/services/apigateway/resource_providers/aws_apigateway_account_plugin.py +1 -3
  110. localstack/services/apigateway/resource_providers/aws_apigateway_apikey.py +14 -14
  111. localstack/services/apigateway/resource_providers/aws_apigateway_apikey_plugin.py +1 -3
  112. localstack/services/apigateway/resource_providers/aws_apigateway_basepathmapping.py +5 -5
  113. localstack/services/apigateway/resource_providers/aws_apigateway_basepathmapping_plugin.py +1 -3
  114. localstack/services/apigateway/resource_providers/aws_apigateway_deployment.py +46 -46
  115. localstack/services/apigateway/resource_providers/aws_apigateway_deployment_plugin.py +1 -3
  116. localstack/services/apigateway/resource_providers/aws_apigateway_domainname.py +18 -18
  117. localstack/services/apigateway/resource_providers/aws_apigateway_domainname_plugin.py +1 -3
  118. localstack/services/apigateway/resource_providers/aws_apigateway_gatewayresponse.py +7 -7
  119. localstack/services/apigateway/resource_providers/aws_apigateway_gatewayresponse_plugin.py +1 -3
  120. localstack/services/apigateway/resource_providers/aws_apigateway_method.py +36 -36
  121. localstack/services/apigateway/resource_providers/aws_apigateway_method_plugin.py +1 -3
  122. localstack/services/apigateway/resource_providers/aws_apigateway_model.py +6 -6
  123. localstack/services/apigateway/resource_providers/aws_apigateway_model_plugin.py +1 -3
  124. localstack/services/apigateway/resource_providers/aws_apigateway_requestvalidator.py +6 -6
  125. localstack/services/apigateway/resource_providers/aws_apigateway_requestvalidator_plugin.py +1 -3
  126. localstack/services/apigateway/resource_providers/aws_apigateway_resource.py +6 -6
  127. localstack/services/apigateway/resource_providers/aws_apigateway_resource_plugin.py +1 -3
  128. localstack/services/apigateway/resource_providers/aws_apigateway_restapi.py +26 -26
  129. localstack/services/apigateway/resource_providers/aws_apigateway_restapi_plugin.py +1 -3
  130. localstack/services/apigateway/resource_providers/aws_apigateway_stage.py +33 -33
  131. localstack/services/apigateway/resource_providers/aws_apigateway_stage_plugin.py +1 -3
  132. localstack/services/apigateway/resource_providers/aws_apigateway_usageplan.py +18 -18
  133. localstack/services/apigateway/resource_providers/aws_apigateway_usageplan_plugin.py +1 -3
  134. localstack/services/apigateway/resource_providers/aws_apigateway_usageplankey.py +5 -5
  135. localstack/services/apigateway/resource_providers/aws_apigateway_usageplankey_plugin.py +1 -3
  136. localstack/services/cdk/resource_providers/cdk_metadata.py +4 -3
  137. localstack/services/cdk/resource_providers/cdk_metadata_plugin.py +1 -3
  138. localstack/services/certificatemanager/resource_providers/aws_certificatemanager_certificate.py +14 -14
  139. localstack/services/certificatemanager/resource_providers/aws_certificatemanager_certificate_plugin.py +1 -3
  140. localstack/services/cloudformation/api_utils.py +4 -8
  141. localstack/services/cloudformation/cfn_utils.py +2 -2
  142. localstack/services/cloudformation/deployment_utils.py +14 -12
  143. localstack/services/cloudformation/engine/changes.py +3 -3
  144. localstack/services/cloudformation/engine/entities.py +27 -17
  145. localstack/services/cloudformation/engine/parameters.py +4 -4
  146. localstack/services/cloudformation/engine/template_deployer.py +15 -14
  147. localstack/services/cloudformation/engine/template_utils.py +34 -12
  148. localstack/services/cloudformation/engine/transformers.py +11 -8
  149. localstack/services/cloudformation/engine/types.py +5 -4
  150. localstack/services/cloudformation/engine/v2/change_set_model.py +336 -39
  151. localstack/services/cloudformation/engine/v2/change_set_model_describer.py +96 -17
  152. localstack/services/cloudformation/engine/v2/change_set_model_executor.py +289 -136
  153. localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +315 -146
  154. localstack/services/cloudformation/engine/v2/change_set_model_transform.py +380 -105
  155. localstack/services/cloudformation/engine/v2/change_set_model_validator.py +183 -0
  156. localstack/services/cloudformation/engine/v2/change_set_model_visitor.py +6 -0
  157. localstack/services/cloudformation/engine/v2/resolving.py +102 -0
  158. localstack/services/cloudformation/engine/yaml_parser.py +9 -2
  159. localstack/services/cloudformation/provider.py +11 -6
  160. localstack/services/cloudformation/provider_utils.py +34 -4
  161. localstack/services/cloudformation/resource_provider.py +31 -21
  162. localstack/services/cloudformation/resource_providers/aws_cloudformation_macro.py +7 -7
  163. localstack/services/cloudformation/resource_providers/aws_cloudformation_macro_plugin.py +1 -3
  164. localstack/services/cloudformation/resource_providers/aws_cloudformation_stack.py +9 -9
  165. localstack/services/cloudformation/resource_providers/aws_cloudformation_stack_plugin.py +1 -3
  166. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitcondition.py +6 -6
  167. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitcondition_plugin.py +1 -3
  168. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitconditionhandle.py +2 -2
  169. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitconditionhandle_plugin.py +1 -3
  170. localstack/services/cloudformation/resources.py +24149 -0
  171. localstack/services/cloudformation/scaffolding/__main__.py +13 -12
  172. localstack/services/cloudformation/scaffolding/propgen.py +2 -2
  173. localstack/services/cloudformation/service_models.py +2 -2
  174. localstack/services/cloudformation/stores.py +33 -22
  175. localstack/services/cloudformation/v2/entities.py +103 -88
  176. localstack/services/cloudformation/v2/provider.py +872 -131
  177. localstack/services/cloudformation/v2/types.py +38 -0
  178. localstack/services/cloudformation/v2/utils.py +4 -1
  179. localstack/services/cloudwatch/alarm_scheduler.py +11 -8
  180. localstack/services/cloudwatch/cloudwatch_database_helper.py +4 -5
  181. localstack/services/cloudwatch/models.py +5 -7
  182. localstack/services/cloudwatch/provider.py +30 -25
  183. localstack/services/cloudwatch/provider_v2.py +27 -32
  184. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm.py +40 -40
  185. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm_plugin.py +1 -3
  186. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_compositealarm.py +12 -12
  187. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_compositealarm_plugin.py +1 -3
  188. localstack/services/dynamodb/packages.py +3 -3
  189. localstack/services/dynamodb/provider.py +159 -18
  190. localstack/services/dynamodb/resource_providers/aws_dynamodb_globaltable.py +63 -63
  191. localstack/services/dynamodb/resource_providers/aws_dynamodb_globaltable_plugin.py +1 -3
  192. localstack/services/dynamodb/resource_providers/aws_dynamodb_table.py +57 -57
  193. localstack/services/dynamodb/resource_providers/aws_dynamodb_table_plugin.py +1 -3
  194. localstack/services/dynamodb/server.py +2 -2
  195. localstack/services/dynamodb/utils.py +13 -14
  196. localstack/services/dynamodb/v2/provider.py +157 -18
  197. localstack/services/dynamodbstreams/dynamodbstreams_api.py +2 -2
  198. localstack/services/dynamodbstreams/models.py +1 -3
  199. localstack/services/ec2/patches.py +26 -5
  200. localstack/services/ec2/provider.py +3 -3
  201. localstack/services/ec2/resource_providers/aws_ec2_dhcpoptions.py +10 -10
  202. localstack/services/ec2/resource_providers/aws_ec2_dhcpoptions_plugin.py +1 -3
  203. localstack/services/ec2/resource_providers/aws_ec2_instance.py +96 -96
  204. localstack/services/ec2/resource_providers/aws_ec2_instance_plugin.py +1 -3
  205. localstack/services/ec2/resource_providers/aws_ec2_internetgateway.py +5 -5
  206. localstack/services/ec2/resource_providers/aws_ec2_internetgateway_plugin.py +1 -3
  207. localstack/services/ec2/resource_providers/aws_ec2_keypair.py +10 -10
  208. localstack/services/ec2/resource_providers/aws_ec2_keypair_plugin.py +1 -3
  209. localstack/services/ec2/resource_providers/aws_ec2_natgateway.py +13 -13
  210. localstack/services/ec2/resource_providers/aws_ec2_natgateway_plugin.py +1 -3
  211. localstack/services/ec2/resource_providers/aws_ec2_networkacl.py +6 -6
  212. localstack/services/ec2/resource_providers/aws_ec2_networkacl_plugin.py +1 -3
  213. localstack/services/ec2/resource_providers/aws_ec2_prefixlist.py +14 -14
  214. localstack/services/ec2/resource_providers/aws_ec2_prefixlist_plugin.py +1 -3
  215. localstack/services/ec2/resource_providers/aws_ec2_route.py +15 -15
  216. localstack/services/ec2/resource_providers/aws_ec2_route_plugin.py +1 -3
  217. localstack/services/ec2/resource_providers/aws_ec2_routetable.py +6 -6
  218. localstack/services/ec2/resource_providers/aws_ec2_routetable_plugin.py +1 -3
  219. localstack/services/ec2/resource_providers/aws_ec2_securitygroup.py +29 -29
  220. localstack/services/ec2/resource_providers/aws_ec2_securitygroup_plugin.py +1 -3
  221. localstack/services/ec2/resource_providers/aws_ec2_subnet.py +19 -19
  222. localstack/services/ec2/resource_providers/aws_ec2_subnet_plugin.py +1 -3
  223. localstack/services/ec2/resource_providers/aws_ec2_subnetroutetableassociation.py +4 -4
  224. localstack/services/ec2/resource_providers/aws_ec2_subnetroutetableassociation_plugin.py +1 -3
  225. localstack/services/ec2/resource_providers/aws_ec2_transitgateway.py +16 -16
  226. localstack/services/ec2/resource_providers/aws_ec2_transitgateway_plugin.py +1 -3
  227. localstack/services/ec2/resource_providers/aws_ec2_transitgatewayattachment.py +9 -9
  228. localstack/services/ec2/resource_providers/aws_ec2_transitgatewayattachment_plugin.py +1 -3
  229. localstack/services/ec2/resource_providers/aws_ec2_vpc.py +15 -15
  230. localstack/services/ec2/resource_providers/aws_ec2_vpc_plugin.py +1 -3
  231. localstack/services/ec2/resource_providers/aws_ec2_vpcendpoint.py +29 -22
  232. localstack/services/ec2/resource_providers/aws_ec2_vpcendpoint_plugin.py +1 -3
  233. localstack/services/ec2/resource_providers/aws_ec2_vpcgatewayattachment.py +5 -5
  234. localstack/services/ec2/resource_providers/aws_ec2_vpcgatewayattachment_plugin.py +1 -3
  235. localstack/services/ecr/resource_providers/aws_ecr_repository.py +22 -19
  236. localstack/services/ecr/resource_providers/aws_ecr_repository_plugin.py +1 -3
  237. localstack/services/edge.py +6 -6
  238. localstack/services/es/provider.py +21 -21
  239. localstack/services/events/archive.py +2 -2
  240. localstack/services/events/connection.py +5 -5
  241. localstack/services/events/event_bus.py +9 -9
  242. localstack/services/events/event_rule_engine.py +31 -13
  243. localstack/services/events/models.py +29 -30
  244. localstack/services/events/provider.py +29 -26
  245. localstack/services/events/replay.py +3 -3
  246. localstack/services/events/resource_providers/aws_events_apidestination.py +8 -8
  247. localstack/services/events/resource_providers/aws_events_apidestination_plugin.py +1 -3
  248. localstack/services/events/resource_providers/aws_events_connection.py +27 -27
  249. localstack/services/events/resource_providers/aws_events_connection_plugin.py +1 -3
  250. localstack/services/events/resource_providers/aws_events_eventbus.py +9 -9
  251. localstack/services/events/resource_providers/aws_events_eventbus_plugin.py +1 -3
  252. localstack/services/events/resource_providers/aws_events_eventbuspolicy.py +11 -11
  253. localstack/services/events/resource_providers/aws_events_eventbuspolicy_plugin.py +1 -3
  254. localstack/services/events/resource_providers/aws_events_rule.py +82 -82
  255. localstack/services/events/resource_providers/aws_events_rule_plugin.py +1 -3
  256. localstack/services/events/rule.py +15 -15
  257. localstack/services/events/target.py +21 -13
  258. localstack/services/events/utils.py +7 -7
  259. localstack/services/events/v1/models.py +1 -3
  260. localstack/services/events/v1/provider.py +15 -15
  261. localstack/services/firehose/models.py +1 -3
  262. localstack/services/firehose/provider.py +25 -16
  263. localstack/services/iam/iam_patches.py +5 -6
  264. localstack/services/iam/provider.py +14 -119
  265. localstack/services/iam/resource_providers/aws_iam_accesskey.py +6 -6
  266. localstack/services/iam/resource_providers/aws_iam_accesskey_plugin.py +1 -3
  267. localstack/services/iam/resource_providers/aws_iam_group.py +9 -9
  268. localstack/services/iam/resource_providers/aws_iam_group_plugin.py +1 -3
  269. localstack/services/iam/resource_providers/aws_iam_instanceprofile.py +5 -5
  270. localstack/services/iam/resource_providers/aws_iam_instanceprofile_plugin.py +1 -3
  271. localstack/services/iam/resource_providers/aws_iam_managedpolicy.py +9 -9
  272. localstack/services/iam/resource_providers/aws_iam_managedpolicy_plugin.py +1 -3
  273. localstack/services/iam/resource_providers/aws_iam_policy.py +7 -7
  274. localstack/services/iam/resource_providers/aws_iam_policy_plugin.py +1 -3
  275. localstack/services/iam/resource_providers/aws_iam_role.py +16 -16
  276. localstack/services/iam/resource_providers/aws_iam_role_plugin.py +1 -3
  277. localstack/services/iam/resource_providers/aws_iam_servercertificate.py +10 -10
  278. localstack/services/iam/resource_providers/aws_iam_servercertificate_plugin.py +1 -3
  279. localstack/services/iam/resource_providers/aws_iam_servicelinkedrole.py +5 -5
  280. localstack/services/iam/resource_providers/aws_iam_servicelinkedrole_plugin.py +1 -3
  281. localstack/services/iam/resource_providers/aws_iam_user.py +17 -17
  282. localstack/services/iam/resource_providers/aws_iam_user_plugin.py +1 -3
  283. localstack/services/iam/resources/policy_simulator.py +133 -0
  284. localstack/services/kinesis/kinesis_mock_server.py +7 -8
  285. localstack/services/kinesis/models.py +17 -5
  286. localstack/services/kinesis/packages.py +3 -3
  287. localstack/services/kinesis/provider.py +86 -3
  288. localstack/services/kinesis/resource_providers/aws_kinesis_stream.py +13 -13
  289. localstack/services/kinesis/resource_providers/aws_kinesis_stream_plugin.py +1 -3
  290. localstack/services/kinesis/resource_providers/aws_kinesis_streamconsumer.py +7 -7
  291. localstack/services/kinesis/resource_providers/aws_kinesis_streamconsumer_plugin.py +1 -3
  292. localstack/services/kinesisfirehose/resource_providers/aws_kinesisfirehose_deliverystream.py +191 -191
  293. localstack/services/kinesisfirehose/resource_providers/aws_kinesisfirehose_deliverystream_plugin.py +1 -3
  294. localstack/services/kms/models.py +21 -18
  295. localstack/services/kms/provider.py +62 -26
  296. localstack/services/kms/resource_providers/aws_kms_alias.py +3 -3
  297. localstack/services/kms/resource_providers/aws_kms_alias_plugin.py +1 -3
  298. localstack/services/kms/resource_providers/aws_kms_key.py +14 -14
  299. localstack/services/kms/resource_providers/aws_kms_key_plugin.py +1 -3
  300. localstack/services/kms/utils.py +4 -3
  301. localstack/services/lambda_/api_utils.py +19 -16
  302. localstack/services/lambda_/custom_endpoints.py +2 -2
  303. localstack/services/lambda_/event_source_mapping/esm_worker_factory.py +4 -7
  304. localstack/services/lambda_/event_source_mapping/pipe_utils.py +2 -2
  305. localstack/services/lambda_/event_source_mapping/pollers/stream_poller.py +1 -1
  306. localstack/services/lambda_/event_source_mapping/senders/sender_utils.py +2 -1
  307. localstack/services/lambda_/hooks.py +6 -1
  308. localstack/services/lambda_/invocation/assignment.py +1 -2
  309. localstack/services/lambda_/invocation/docker_runtime_executor.py +7 -11
  310. localstack/services/lambda_/invocation/event_manager.py +1 -1
  311. localstack/services/lambda_/invocation/execution_environment.py +4 -4
  312. localstack/services/lambda_/invocation/executor_endpoint.py +8 -11
  313. localstack/services/lambda_/invocation/internal_sqs_queue.py +6 -10
  314. localstack/services/lambda_/invocation/lambda_models.py +33 -30
  315. localstack/services/lambda_/invocation/lambda_service.py +12 -5
  316. localstack/services/lambda_/invocation/logs.py +2 -3
  317. localstack/services/lambda_/invocation/runtime_executor.py +3 -3
  318. localstack/services/lambda_/invocation/version_manager.py +31 -8
  319. localstack/services/lambda_/ldm.py +14 -0
  320. localstack/services/lambda_/packages.py +3 -4
  321. localstack/services/lambda_/provider.py +9 -26
  322. localstack/services/lambda_/provider_utils.py +1 -1
  323. localstack/services/lambda_/resource_providers/aws_lambda_codesigningconfig.py +8 -8
  324. localstack/services/lambda_/resource_providers/aws_lambda_codesigningconfig_plugin.py +1 -3
  325. localstack/services/lambda_/resource_providers/aws_lambda_eventinvokeconfig.py +11 -11
  326. localstack/services/lambda_/resource_providers/aws_lambda_eventinvokeconfig_plugin.py +1 -3
  327. localstack/services/lambda_/resource_providers/aws_lambda_eventsourcemapping.py +39 -39
  328. localstack/services/lambda_/resource_providers/aws_lambda_eventsourcemapping_plugin.py +1 -3
  329. localstack/services/lambda_/resource_providers/aws_lambda_function.py +54 -54
  330. localstack/services/lambda_/resource_providers/aws_lambda_function_plugin.py +1 -3
  331. localstack/services/lambda_/resource_providers/aws_lambda_layerversion.py +11 -11
  332. localstack/services/lambda_/resource_providers/aws_lambda_layerversion_plugin.py +1 -3
  333. localstack/services/lambda_/resource_providers/aws_lambda_layerversionpermission.py +6 -6
  334. localstack/services/lambda_/resource_providers/aws_lambda_layerversionpermission_plugin.py +1 -3
  335. localstack/services/lambda_/resource_providers/aws_lambda_permission.py +10 -10
  336. localstack/services/lambda_/resource_providers/aws_lambda_permission_plugin.py +1 -3
  337. localstack/services/lambda_/resource_providers/aws_lambda_url.py +15 -15
  338. localstack/services/lambda_/resource_providers/aws_lambda_url_plugin.py +1 -3
  339. localstack/services/lambda_/resource_providers/aws_lambda_version.py +8 -8
  340. localstack/services/lambda_/resource_providers/aws_lambda_version_plugin.py +1 -3
  341. localstack/services/lambda_/resource_providers/lambda_alias.py +12 -12
  342. localstack/services/lambda_/resource_providers/lambda_alias_plugin.py +1 -3
  343. localstack/services/lambda_/runtimes.py +1 -3
  344. localstack/services/lambda_/urlrouter.py +14 -1
  345. localstack/services/logs/models.py +1 -3
  346. localstack/services/logs/provider.py +39 -22
  347. localstack/services/logs/resource_providers/aws_logs_loggroup.py +9 -9
  348. localstack/services/logs/resource_providers/aws_logs_loggroup_plugin.py +1 -3
  349. localstack/services/logs/resource_providers/aws_logs_logstream.py +4 -4
  350. localstack/services/logs/resource_providers/aws_logs_logstream_plugin.py +1 -3
  351. localstack/services/logs/resource_providers/aws_logs_subscriptionfilter.py +7 -7
  352. localstack/services/logs/resource_providers/aws_logs_subscriptionfilter_plugin.py +1 -3
  353. localstack/services/moto.py +5 -4
  354. localstack/services/opensearch/cluster.py +28 -20
  355. localstack/services/opensearch/cluster_manager.py +13 -14
  356. localstack/services/opensearch/models.py +1 -3
  357. localstack/services/opensearch/packages.py +27 -9
  358. localstack/services/opensearch/provider.py +15 -10
  359. localstack/services/opensearch/resource_providers/aws_elasticsearch_domain.py +61 -61
  360. localstack/services/opensearch/resource_providers/aws_elasticsearch_domain_plugin.py +1 -3
  361. localstack/services/opensearch/resource_providers/aws_opensearchservice_domain.py +89 -89
  362. localstack/services/opensearch/resource_providers/aws_opensearchservice_domain_plugin.py +1 -3
  363. localstack/services/opensearch/versions.py +57 -10
  364. localstack/services/plugins.py +37 -32
  365. localstack/services/providers.py +10 -2
  366. localstack/services/redshift/provider.py +0 -21
  367. localstack/services/redshift/resource_providers/aws_redshift_cluster.py +57 -57
  368. localstack/services/redshift/resource_providers/aws_redshift_cluster_plugin.py +1 -3
  369. localstack/services/resource_groups/resource_providers/aws_resourcegroups_group.py +21 -21
  370. localstack/services/resource_groups/resource_providers/aws_resourcegroups_group_plugin.py +1 -3
  371. localstack/services/route53/models.py +1 -3
  372. localstack/services/route53/provider.py +1 -2
  373. localstack/services/route53/resource_providers/aws_route53_healthcheck.py +6 -6
  374. localstack/services/route53/resource_providers/aws_route53_healthcheck_plugin.py +1 -3
  375. localstack/services/route53/resource_providers/aws_route53_recordset.py +27 -27
  376. localstack/services/route53/resource_providers/aws_route53_recordset_plugin.py +1 -3
  377. localstack/services/route53resolver/models.py +8 -10
  378. localstack/services/route53resolver/provider.py +12 -12
  379. localstack/services/s3/codec.py +2 -2
  380. localstack/services/s3/constants.py +5 -2
  381. localstack/services/s3/cors.py +8 -8
  382. localstack/services/s3/models.py +73 -73
  383. localstack/services/s3/notifications.py +74 -58
  384. localstack/services/s3/presigned_url.py +41 -59
  385. localstack/services/s3/provider.py +86 -29
  386. localstack/services/s3/resource_providers/aws_s3_bucket.py +180 -180
  387. localstack/services/s3/resource_providers/aws_s3_bucket_plugin.py +1 -3
  388. localstack/services/s3/resource_providers/aws_s3_bucketpolicy.py +4 -4
  389. localstack/services/s3/resource_providers/aws_s3_bucketpolicy_plugin.py +1 -3
  390. localstack/services/s3/storage/core.py +4 -3
  391. localstack/services/s3/storage/ephemeral.py +7 -6
  392. localstack/services/s3/utils.py +51 -31
  393. localstack/services/s3/validation.py +47 -33
  394. localstack/services/s3/website_hosting.py +9 -7
  395. localstack/services/scheduler/resource_providers/aws_scheduler_schedule.py +60 -60
  396. localstack/services/scheduler/resource_providers/aws_scheduler_schedule_plugin.py +1 -3
  397. localstack/services/scheduler/resource_providers/aws_scheduler_schedulegroup.py +9 -9
  398. localstack/services/scheduler/resource_providers/aws_scheduler_schedulegroup_plugin.py +1 -3
  399. localstack/services/secretsmanager/provider.py +10 -12
  400. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_resourcepolicy.py +5 -5
  401. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_resourcepolicy_plugin.py +1 -3
  402. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_rotationschedule.py +21 -21
  403. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_rotationschedule_plugin.py +1 -3
  404. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secret.py +23 -23
  405. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secret_plugin.py +1 -3
  406. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secrettargetattachment.py +5 -5
  407. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secrettargetattachment_plugin.py +1 -3
  408. localstack/services/ses/models.py +8 -1
  409. localstack/services/ses/provider.py +128 -55
  410. localstack/services/ses/resource_providers/aws_ses_emailidentity.py +21 -21
  411. localstack/services/ses/resource_providers/aws_ses_emailidentity_plugin.py +1 -3
  412. localstack/services/sns/constants.py +7 -1
  413. localstack/services/sns/executor.py +9 -2
  414. localstack/services/sns/models.py +25 -25
  415. localstack/services/sns/provider.py +9 -7
  416. localstack/services/sns/publisher.py +37 -23
  417. localstack/services/sns/resource_providers/aws_sns_subscription.py +13 -13
  418. localstack/services/sns/resource_providers/aws_sns_subscription_plugin.py +1 -3
  419. localstack/services/sns/resource_providers/aws_sns_topic.py +16 -16
  420. localstack/services/sns/resource_providers/aws_sns_topic_plugin.py +1 -3
  421. localstack/services/sns/resource_providers/aws_sns_topicpolicy.py +4 -4
  422. localstack/services/sns/resource_providers/aws_sns_topicpolicy_plugin.py +1 -3
  423. localstack/services/sns/v2/models.py +167 -0
  424. localstack/services/sns/v2/provider.py +867 -0
  425. localstack/services/sns/v2/utils.py +130 -0
  426. localstack/services/sqs/constants.py +2 -2
  427. localstack/services/sqs/developer_api.py +205 -0
  428. localstack/services/sqs/models.py +71 -36
  429. localstack/services/sqs/provider.py +56 -332
  430. localstack/services/sqs/query_api.py +8 -5
  431. localstack/services/sqs/resource_providers/aws_sqs_queue.py +21 -21
  432. localstack/services/sqs/resource_providers/aws_sqs_queue_plugin.py +1 -3
  433. localstack/services/sqs/resource_providers/aws_sqs_queuepolicy.py +7 -5
  434. localstack/services/sqs/resource_providers/aws_sqs_queuepolicy_plugin.py +1 -3
  435. localstack/services/sqs/utils.py +123 -4
  436. localstack/services/ssm/provider.py +3 -4
  437. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindow.py +15 -15
  438. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindow_plugin.py +1 -3
  439. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtarget.py +10 -10
  440. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtarget_plugin.py +1 -3
  441. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtask.py +48 -48
  442. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtask_plugin.py +1 -3
  443. localstack/services/ssm/resource_providers/aws_ssm_parameter.py +10 -10
  444. localstack/services/ssm/resource_providers/aws_ssm_parameter_plugin.py +1 -3
  445. localstack/services/ssm/resource_providers/aws_ssm_patchbaseline.py +29 -29
  446. localstack/services/ssm/resource_providers/aws_ssm_patchbaseline_plugin.py +1 -3
  447. localstack/services/stepfunctions/asl/antlt4utils/antlr4utils.py +3 -4
  448. localstack/services/stepfunctions/asl/component/common/assign/assign_decl.py +1 -1
  449. localstack/services/stepfunctions/asl/component/common/assign/assign_decl_binding.py +1 -1
  450. localstack/services/stepfunctions/asl/component/common/assign/assign_template_value_array.py +1 -1
  451. localstack/services/stepfunctions/asl/component/common/assign/assign_template_value_object.py +1 -1
  452. localstack/services/stepfunctions/asl/component/common/catch/catcher_decl.py +9 -9
  453. localstack/services/stepfunctions/asl/component/common/error_name/custom_error_name.py +2 -2
  454. localstack/services/stepfunctions/asl/component/common/error_name/error_name.py +4 -4
  455. localstack/services/stepfunctions/asl/component/common/error_name/failure_event.py +8 -8
  456. localstack/services/stepfunctions/asl/component/common/error_name/states_error_name_type.py +1 -1
  457. localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_binding.py +2 -2
  458. localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_value_array.py +1 -1
  459. localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_value_object.py +1 -1
  460. localstack/services/stepfunctions/asl/component/common/path/input_path.py +4 -4
  461. localstack/services/stepfunctions/asl/component/common/path/output_path.py +4 -4
  462. localstack/services/stepfunctions/asl/component/common/path/result_path.py +3 -3
  463. localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadarr/payload_arr.py +1 -1
  464. localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding.py +3 -3
  465. localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadtmpl/payload_tmpl.py +1 -1
  466. localstack/services/stepfunctions/asl/component/common/retry/retrier_decl.py +8 -8
  467. localstack/services/stepfunctions/asl/component/common/string/string_expression.py +3 -3
  468. localstack/services/stepfunctions/asl/component/common/timeouts/timeout.py +3 -3
  469. localstack/services/stepfunctions/asl/component/eval_component.py +2 -3
  470. localstack/services/stepfunctions/asl/component/intrinsic/argument/argument.py +4 -4
  471. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/array/array_partition.py +1 -1
  472. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/generic/string_format.py +1 -1
  473. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/states_function_array.py +1 -1
  474. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/states_function_format.py +1 -1
  475. localstack/services/stepfunctions/asl/component/intrinsic/jsonata.py +3 -3
  476. localstack/services/stepfunctions/asl/component/intrinsic/member.py +1 -1
  477. localstack/services/stepfunctions/asl/component/program/program.py +9 -9
  478. localstack/services/stepfunctions/asl/component/program/states.py +1 -1
  479. localstack/services/stepfunctions/asl/component/state/state.py +10 -11
  480. localstack/services/stepfunctions/asl/component/state/state_choice/choice_rule.py +11 -11
  481. localstack/services/stepfunctions/asl/component/state/state_choice/comparison/comparison.py +5 -11
  482. localstack/services/stepfunctions/asl/component/state/state_choice/comparison/operator/implementations/is_operator.py +2 -2
  483. localstack/services/stepfunctions/asl/component/state/state_choice/state_choice.py +3 -5
  484. localstack/services/stepfunctions/asl/component/state/state_execution/execute_state.py +9 -9
  485. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/item_reader_decl.py +7 -7
  486. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/reader_config/reader_config_decl.py +5 -5
  487. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/resource_eval/resource_eval_s3.py +2 -1
  488. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/resource_eval/resource_output_transformer/resource_output_transformer_csv.py +2 -2
  489. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/distributed_iteration_component.py +8 -8
  490. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/inline_iteration_component.py +7 -7
  491. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/distributed_item_processor_worker.py +4 -4
  492. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/inline_item_processor_worker.py +5 -5
  493. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/map_run_record.py +10 -10
  494. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_component.py +3 -3
  495. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_declaration.py +3 -3
  496. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_worker.py +2 -2
  497. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/distributed_iterator_worker.py +3 -5
  498. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/inline_iterator.py +1 -2
  499. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/inline_iterator_worker.py +5 -5
  500. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/job.py +9 -9
  501. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/result_writer/resource_eval/resource_eval_s3.py +2 -1
  502. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/state_map.py +12 -13
  503. localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/branch_worker.py +3 -3
  504. localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/branches_decl.py +7 -7
  505. localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/state_parallel.py +2 -3
  506. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/lambda_eval_utils.py +7 -7
  507. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/resource.py +3 -3
  508. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service.py +10 -10
  509. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_api_gateway.py +18 -18
  510. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_aws_sdk.py +1 -1
  511. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_batch.py +8 -7
  512. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_callback.py +18 -17
  513. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_dynamodb.py +2 -2
  514. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_ecs.py +5 -4
  515. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_events.py +4 -4
  516. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_glue.py +7 -6
  517. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_lambda.py +4 -4
  518. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sfn.py +9 -8
  519. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sns.py +2 -2
  520. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sqs.py +4 -4
  521. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/state_task.py +5 -5
  522. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/state_task_lambda.py +2 -2
  523. localstack/services/stepfunctions/asl/component/state/state_fail/state_fail.py +3 -5
  524. localstack/services/stepfunctions/asl/component/state/state_pass/state_pass.py +5 -7
  525. localstack/services/stepfunctions/asl/component/state/state_succeed/state_succeed.py +1 -1
  526. localstack/services/stepfunctions/asl/component/state/state_wait/state_wait.py +1 -1
  527. localstack/services/stepfunctions/asl/component/state/state_wait/wait_function/timestamp.py +2 -2
  528. localstack/services/stepfunctions/asl/eval/callback/callback.py +18 -18
  529. localstack/services/stepfunctions/asl/eval/environment.py +22 -24
  530. localstack/services/stepfunctions/asl/eval/evaluation_details.py +3 -5
  531. localstack/services/stepfunctions/asl/eval/event/event_manager.py +10 -10
  532. localstack/services/stepfunctions/asl/eval/event/logging.py +3 -3
  533. localstack/services/stepfunctions/asl/eval/program_state.py +8 -8
  534. localstack/services/stepfunctions/asl/eval/states.py +12 -12
  535. localstack/services/stepfunctions/asl/eval/test_state/environment.py +3 -5
  536. localstack/services/stepfunctions/asl/eval/variable_store.py +6 -6
  537. localstack/services/stepfunctions/asl/jsonata/jsonata.py +7 -6
  538. localstack/services/stepfunctions/asl/parse/asl_parser.py +1 -1
  539. localstack/services/stepfunctions/asl/parse/intrinsic/preprocessor.py +2 -3
  540. localstack/services/stepfunctions/asl/parse/preprocessor.py +44 -44
  541. localstack/services/stepfunctions/asl/parse/typed_props.py +2 -2
  542. localstack/services/stepfunctions/asl/static_analyser/intrinsic/variable_names_intrinsic_static_analyser.py +1 -1
  543. localstack/services/stepfunctions/asl/static_analyser/variable_references_static_analyser.py +2 -2
  544. localstack/services/stepfunctions/asl/utils/encoding.py +2 -2
  545. localstack/services/stepfunctions/asl/utils/json_path.py +2 -2
  546. localstack/services/stepfunctions/backend/activity.py +4 -4
  547. localstack/services/stepfunctions/backend/alias.py +8 -8
  548. localstack/services/stepfunctions/backend/execution.py +29 -30
  549. localstack/services/stepfunctions/backend/execution_worker.py +7 -7
  550. localstack/services/stepfunctions/backend/state_machine.py +28 -28
  551. localstack/services/stepfunctions/backend/test_state/execution.py +3 -4
  552. localstack/services/stepfunctions/backend/test_state/execution_worker.py +1 -3
  553. localstack/services/stepfunctions/mocking/mock_config.py +9 -9
  554. localstack/services/stepfunctions/mocking/mock_config_file.py +10 -10
  555. localstack/services/stepfunctions/packages.py +14 -5
  556. localstack/services/stepfunctions/provider.py +34 -44
  557. localstack/services/stepfunctions/quotas.py +2 -3
  558. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_activity.py +6 -6
  559. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_activity_plugin.py +1 -3
  560. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine.py +25 -25
  561. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine_plugin.py +1 -3
  562. localstack/services/stepfunctions/stepfunctions_utils.py +1 -2
  563. localstack/services/stores.py +8 -8
  564. localstack/services/transcribe/packages.py +1 -3
  565. localstack/services/transcribe/provider.py +8 -3
  566. localstack/state/codecs.py +61 -0
  567. localstack/state/core.py +11 -5
  568. localstack/state/inspect.py +4 -4
  569. localstack/state/pickle.py +36 -23
  570. localstack/testing/aws/asf_utils.py +3 -2
  571. localstack/testing/aws/cloudformation_utils.py +1 -1
  572. localstack/testing/aws/lambda_utils.py +15 -14
  573. localstack/testing/aws/util.py +3 -2
  574. localstack/testing/pytest/cloudformation/fixtures.py +68 -18
  575. localstack/testing/pytest/container.py +5 -5
  576. localstack/testing/pytest/filters.py +1 -3
  577. localstack/testing/pytest/fixtures.py +188 -49
  578. localstack/testing/pytest/in_memory_localstack.py +1 -3
  579. localstack/testing/pytest/marking.py +42 -15
  580. localstack/testing/pytest/path_filter.py +1 -1
  581. localstack/testing/pytest/stepfunctions/fixtures.py +4 -4
  582. localstack/testing/pytest/stepfunctions/utils.py +11 -10
  583. localstack/testing/pytest/util.py +1 -1
  584. localstack/testing/pytest/validation_tracking.py +3 -4
  585. localstack/testing/scenario/provisioning.py +11 -10
  586. localstack/testing/snapshots/transformer_utility.py +8 -3
  587. localstack/testing/testselection/matching.py +2 -2
  588. localstack/testing/testselection/opt_out.py +1 -1
  589. localstack/testing/testselection/scripts/filter_by_test_selection.py +1 -1
  590. localstack/testing/testselection/scripts/generate_test_selection.py +1 -1
  591. localstack/testing/testselection/testselection.py +2 -2
  592. localstack/utils/analytics/cli.py +2 -3
  593. localstack/utils/analytics/client.py +5 -5
  594. localstack/utils/analytics/events.py +2 -2
  595. localstack/utils/analytics/metadata.py +6 -4
  596. localstack/utils/analytics/metrics/counter.py +11 -18
  597. localstack/utils/analytics/metrics/registry.py +2 -2
  598. localstack/utils/analytics/publisher.py +4 -5
  599. localstack/utils/analytics/service_providers.py +19 -0
  600. localstack/utils/analytics/service_request_aggregator.py +4 -4
  601. localstack/utils/archives.py +12 -12
  602. localstack/utils/asyncio.py +2 -2
  603. localstack/utils/aws/arns.py +26 -31
  604. localstack/utils/aws/aws_responses.py +21 -28
  605. localstack/utils/aws/aws_stack.py +7 -12
  606. localstack/utils/aws/dead_letter_queue.py +4 -9
  607. localstack/utils/aws/message_forwarding.py +8 -11
  608. localstack/utils/aws/request_context.py +5 -6
  609. localstack/utils/aws/resources.py +1 -1
  610. localstack/utils/aws/templating.py +4 -4
  611. localstack/utils/batch_policy.py +4 -4
  612. localstack/utils/bootstrap.py +37 -30
  613. localstack/utils/catalog/catalog.py +139 -0
  614. localstack/utils/catalog/catalog_loader.py +119 -0
  615. localstack/utils/catalog/common.py +58 -0
  616. localstack/utils/catalog/plugins.py +28 -0
  617. localstack/utils/cloudwatch/cloudwatch_util.py +5 -5
  618. localstack/utils/collections.py +33 -27
  619. localstack/utils/config_listener.py +2 -2
  620. localstack/utils/container_networking.py +5 -6
  621. localstack/utils/container_utils/container_client.py +156 -160
  622. localstack/utils/container_utils/docker_cmd_client.py +97 -81
  623. localstack/utils/container_utils/docker_sdk_client.py +75 -72
  624. localstack/utils/crypto.py +12 -13
  625. localstack/utils/diagnose.py +11 -12
  626. localstack/utils/docker_utils.py +11 -7
  627. localstack/utils/files.py +34 -15
  628. localstack/utils/functions.py +5 -4
  629. localstack/utils/http.py +14 -14
  630. localstack/utils/iputils.py +2 -1
  631. localstack/utils/json.py +21 -7
  632. localstack/utils/kinesis/kinesis_connector.py +2 -1
  633. localstack/utils/net.py +25 -17
  634. localstack/utils/no_exit_argument_parser.py +2 -2
  635. localstack/utils/numbers.py +9 -2
  636. localstack/utils/objects.py +15 -14
  637. localstack/utils/patch.py +14 -7
  638. localstack/utils/platform.py +2 -2
  639. localstack/utils/run.py +15 -14
  640. localstack/utils/scheduler.py +13 -12
  641. localstack/utils/server/tcp_proxy.py +2 -2
  642. localstack/utils/serving.py +3 -4
  643. localstack/utils/strings.py +15 -16
  644. localstack/utils/sync.py +126 -1
  645. localstack/utils/tagging.py +10 -8
  646. localstack/utils/testutil.py +17 -17
  647. localstack/utils/threads.py +3 -3
  648. localstack/utils/time.py +12 -4
  649. localstack/utils/urls.py +1 -3
  650. localstack/utils/xml.py +1 -1
  651. localstack/utils/xray/traceid.py +1 -1
  652. localstack/version.py +16 -3
  653. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/METADATA +18 -13
  654. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/RECORD +663 -655
  655. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/entry_points.txt +8 -4
  656. localstack_core-4.10.1.dev12.dist-info/plux.json +1 -0
  657. localstack/packages/terraform.py +0 -47
  658. localstack/services/cloudformation/deploy.html +0 -144
  659. localstack/services/cloudformation/deploy_ui.py +0 -47
  660. localstack/services/cloudformation/plugins.py +0 -12
  661. localstack/services/lambda_/lambda_debug_mode/ldm.py +0 -375
  662. localstack/services/lambda_/lambda_debug_mode/ldm_config_file.py +0 -178
  663. localstack/services/lambda_/lambda_debug_mode/ldm_types.py +0 -11
  664. localstack/services/lambda_/lambda_debug_mode/ldm_utils.py +0 -43
  665. localstack_core-4.6.1.dev60.dist-info/plux.json +0 -1
  666. /localstack/{services/lambda_/lambda_debug_mode/__init__.py → testing/pytest/cloudformation/transformers.py} +0 -0
  667. {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack +0 -0
  668. {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack-supervisor +0 -0
  669. {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack.bat +0 -0
  670. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/WHEEL +0 -0
  671. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/licenses/LICENSE.txt +0 -0
  672. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/top_level.txt +0 -0
@@ -5,7 +5,7 @@ import json
5
5
  import logging
6
6
  import re
7
7
  import time
8
- from typing import Any, Final, Optional, Union
8
+ from typing import Any, Final
9
9
 
10
10
  import moto.secretsmanager.exceptions as moto_exception
11
11
  from botocore.utils import InvalidArnException
@@ -135,7 +135,7 @@ class SecretsmanagerProvider(SecretsmanagerApi):
135
135
  return bool(re.match(r"^[A-Za-z0-9/_+=.@-]+\Z", secret_id))
136
136
 
137
137
  @staticmethod
138
- def _raise_if_invalid_secret_id(secret_id: Union[SecretIdType, NameType]):
138
+ def _raise_if_invalid_secret_id(secret_id: SecretIdType | NameType):
139
139
  # Patches moto's implementation for which secret_ids are not validated, by raising a ValidationException.
140
140
  # Skips this check if the secret_id provided appears to be an arn (starting with 'arn:').
141
141
  if not re.match(
@@ -149,12 +149,10 @@ class SecretsmanagerProvider(SecretsmanagerApi):
149
149
 
150
150
  @staticmethod
151
151
  def _raise_if_missing_client_req_token(
152
- request: Union[
153
- CreateSecretRequest,
154
- PutSecretValueRequest,
155
- RotateSecretRequest,
156
- UpdateSecretRequest,
157
- ],
152
+ request: CreateSecretRequest
153
+ | PutSecretValueRequest
154
+ | RotateSecretRequest
155
+ | UpdateSecretRequest,
158
156
  ):
159
157
  if "ClientRequestToken" not in request:
160
158
  raise InvalidRequestException(
@@ -201,8 +199,8 @@ class SecretsmanagerProvider(SecretsmanagerApi):
201
199
  ) -> DeleteSecretResponse:
202
200
  secret_id: str = request["SecretId"]
203
201
  self._raise_if_invalid_secret_id(secret_id)
204
- recovery_window_in_days: Optional[int] = request.get("RecoveryWindowInDays")
205
- force_delete_without_recovery: Optional[bool] = request.get("ForceDeleteWithoutRecovery")
202
+ recovery_window_in_days: int | None = request.get("RecoveryWindowInDays")
203
+ force_delete_without_recovery: bool | None = request.get("ForceDeleteWithoutRecovery")
206
204
 
207
205
  backend = SecretsmanagerProvider.get_moto_backend_for_resource(secret_id, context)
208
206
  try:
@@ -495,7 +493,7 @@ def moto_smb_get_secret_value(fn, self, secret_id, version_id, version_stage):
495
493
  def moto_smb_create_secret(fn, self, name, *args, **kwargs):
496
494
  # Creating a secret with a SecretId equal to one that is scheduled for
497
495
  # deletion should raise an 'InvalidRequestException'.
498
- secret: Optional[FakeSecret] = self.secrets.get(name)
496
+ secret: FakeSecret | None = self.secrets.get(name)
499
497
  if secret is not None and secret.deleted_date is not None:
500
498
  raise InvalidRequestException(AWS_INVALID_REQUEST_MESSAGE_CREATE_WITH_SCHEDULED_DELETION)
501
499
 
@@ -523,7 +521,7 @@ def moto_smb_list_secret_version_ids(
523
521
  secret = self.secrets[secret_id]
524
522
 
525
523
  # Patch: output format, report exact createdate instead of current time.
526
- versions: list[SecretVersionsListEntry] = list()
524
+ versions: list[SecretVersionsListEntry] = []
527
525
  for version_id, version in secret.versions.items():
528
526
  version_stages = version["version_stages"]
529
527
  # Patch: include deprecated versions if include_deprecated is True.
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
 
4
4
  import json
5
5
  from pathlib import Path
6
- from typing import Optional, TypedDict
6
+ from typing import TypedDict
7
7
 
8
8
  import localstack.services.cloudformation.provider_utils as util
9
9
  from localstack.services.cloudformation.resource_provider import (
@@ -15,10 +15,10 @@ from localstack.services.cloudformation.resource_provider import (
15
15
 
16
16
 
17
17
  class SecretsManagerResourcePolicyProperties(TypedDict):
18
- ResourcePolicy: Optional[dict]
19
- SecretId: Optional[str]
20
- BlockPublicPolicy: Optional[bool]
21
- Id: Optional[str]
18
+ ResourcePolicy: dict | None
19
+ SecretId: str | None
20
+ BlockPublicPolicy: bool | None
21
+ Id: str | None
22
22
 
23
23
 
24
24
  REPEATED_INVOCATION = "repeated_invocation"
@@ -1,5 +1,3 @@
1
- from typing import Optional, Type
2
-
3
1
  from localstack.services.cloudformation.resource_provider import (
4
2
  CloudFormationResourceProviderPlugin,
5
3
  ResourceProvider,
@@ -10,7 +8,7 @@ class SecretsManagerResourcePolicyProviderPlugin(CloudFormationResourceProviderP
10
8
  name = "AWS::SecretsManager::ResourcePolicy"
11
9
 
12
10
  def __init__(self):
13
- self.factory: Optional[Type[ResourceProvider]] = None
11
+ self.factory: type[ResourceProvider] | None = None
14
12
 
15
13
  def load(self):
16
14
  from localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy import (
@@ -2,7 +2,7 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  from pathlib import Path
5
- from typing import Optional, TypedDict
5
+ from typing import TypedDict
6
6
 
7
7
  import localstack.services.cloudformation.provider_utils as util
8
8
  from localstack.services.cloudformation.resource_provider import (
@@ -14,32 +14,32 @@ from localstack.services.cloudformation.resource_provider import (
14
14
 
15
15
 
16
16
  class SecretsManagerRotationScheduleProperties(TypedDict):
17
- SecretId: Optional[str]
18
- HostedRotationLambda: Optional[HostedRotationLambda]
19
- Id: Optional[str]
20
- RotateImmediatelyOnUpdate: Optional[bool]
21
- RotationLambdaARN: Optional[str]
22
- RotationRules: Optional[RotationRules]
17
+ SecretId: str | None
18
+ HostedRotationLambda: HostedRotationLambda | None
19
+ Id: str | None
20
+ RotateImmediatelyOnUpdate: bool | None
21
+ RotationLambdaARN: str | None
22
+ RotationRules: RotationRules | None
23
23
 
24
24
 
25
25
  class RotationRules(TypedDict):
26
- AutomaticallyAfterDays: Optional[int]
27
- Duration: Optional[str]
28
- ScheduleExpression: Optional[str]
26
+ AutomaticallyAfterDays: int | None
27
+ Duration: str | None
28
+ ScheduleExpression: str | None
29
29
 
30
30
 
31
31
  class HostedRotationLambda(TypedDict):
32
- RotationType: Optional[str]
33
- ExcludeCharacters: Optional[str]
34
- KmsKeyArn: Optional[str]
35
- MasterSecretArn: Optional[str]
36
- MasterSecretKmsKeyArn: Optional[str]
37
- RotationLambdaName: Optional[str]
38
- Runtime: Optional[str]
39
- SuperuserSecretArn: Optional[str]
40
- SuperuserSecretKmsKeyArn: Optional[str]
41
- VpcSecurityGroupIds: Optional[str]
42
- VpcSubnetIds: Optional[str]
32
+ RotationType: str | None
33
+ ExcludeCharacters: str | None
34
+ KmsKeyArn: str | None
35
+ MasterSecretArn: str | None
36
+ MasterSecretKmsKeyArn: str | None
37
+ RotationLambdaName: str | None
38
+ Runtime: str | None
39
+ SuperuserSecretArn: str | None
40
+ SuperuserSecretKmsKeyArn: str | None
41
+ VpcSecurityGroupIds: str | None
42
+ VpcSubnetIds: str | None
43
43
 
44
44
 
45
45
  REPEATED_INVOCATION = "repeated_invocation"
@@ -1,5 +1,3 @@
1
- from typing import Optional, Type
2
-
3
1
  from localstack.services.cloudformation.resource_provider import (
4
2
  CloudFormationResourceProviderPlugin,
5
3
  ResourceProvider,
@@ -10,7 +8,7 @@ class SecretsManagerRotationScheduleProviderPlugin(CloudFormationResourceProvide
10
8
  name = "AWS::SecretsManager::RotationSchedule"
11
9
 
12
10
  def __init__(self):
13
- self.factory: Optional[Type[ResourceProvider]] = None
11
+ self.factory: type[ResourceProvider] | None = None
14
12
 
15
13
  def load(self):
16
14
  from localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule import (
@@ -6,7 +6,7 @@ import logging
6
6
  import random
7
7
  import string
8
8
  from pathlib import Path
9
- from typing import Optional, TypedDict
9
+ from typing import TypedDict
10
10
 
11
11
  import localstack.services.cloudformation.provider_utils as util
12
12
  from localstack.services.cloudformation.resource_provider import (
@@ -20,37 +20,37 @@ LOG = logging.getLogger(__name__)
20
20
 
21
21
 
22
22
  class SecretsManagerSecretProperties(TypedDict):
23
- Description: Optional[str]
24
- GenerateSecretString: Optional[GenerateSecretString]
25
- Id: Optional[str]
26
- KmsKeyId: Optional[str]
27
- Name: Optional[str]
28
- ReplicaRegions: Optional[list[ReplicaRegion]]
29
- SecretString: Optional[str]
30
- Tags: Optional[list[Tag]]
23
+ Description: str | None
24
+ GenerateSecretString: GenerateSecretString | None
25
+ Id: str | None
26
+ KmsKeyId: str | None
27
+ Name: str | None
28
+ ReplicaRegions: list[ReplicaRegion] | None
29
+ SecretString: str | None
30
+ Tags: list[Tag] | None
31
31
 
32
32
 
33
33
  class GenerateSecretString(TypedDict):
34
- ExcludeCharacters: Optional[str]
35
- ExcludeLowercase: Optional[bool]
36
- ExcludeNumbers: Optional[bool]
37
- ExcludePunctuation: Optional[bool]
38
- ExcludeUppercase: Optional[bool]
39
- GenerateStringKey: Optional[str]
40
- IncludeSpace: Optional[bool]
41
- PasswordLength: Optional[int]
42
- RequireEachIncludedType: Optional[bool]
43
- SecretStringTemplate: Optional[str]
34
+ ExcludeCharacters: str | None
35
+ ExcludeLowercase: bool | None
36
+ ExcludeNumbers: bool | None
37
+ ExcludePunctuation: bool | None
38
+ ExcludeUppercase: bool | None
39
+ GenerateStringKey: str | None
40
+ IncludeSpace: bool | None
41
+ PasswordLength: int | None
42
+ RequireEachIncludedType: bool | None
43
+ SecretStringTemplate: str | None
44
44
 
45
45
 
46
46
  class ReplicaRegion(TypedDict):
47
- Region: Optional[str]
48
- KmsKeyId: Optional[str]
47
+ Region: str | None
48
+ KmsKeyId: str | None
49
49
 
50
50
 
51
51
  class Tag(TypedDict):
52
- Key: Optional[str]
53
- Value: Optional[str]
52
+ Key: str | None
53
+ Value: str | None
54
54
 
55
55
 
56
56
  REPEATED_INVOCATION = "repeated_invocation"
@@ -1,5 +1,3 @@
1
- from typing import Optional, Type
2
-
3
1
  from localstack.services.cloudformation.resource_provider import (
4
2
  CloudFormationResourceProviderPlugin,
5
3
  ResourceProvider,
@@ -10,7 +8,7 @@ class SecretsManagerSecretProviderPlugin(CloudFormationResourceProviderPlugin):
10
8
  name = "AWS::SecretsManager::Secret"
11
9
 
12
10
  def __init__(self):
13
- self.factory: Optional[Type[ResourceProvider]] = None
11
+ self.factory: type[ResourceProvider] | None = None
14
12
 
15
13
  def load(self):
16
14
  from localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret import (
@@ -2,7 +2,7 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  from pathlib import Path
5
- from typing import Optional, TypedDict
5
+ from typing import TypedDict
6
6
 
7
7
  import localstack.services.cloudformation.provider_utils as util
8
8
  from localstack.services.cloudformation.resource_provider import (
@@ -14,10 +14,10 @@ from localstack.services.cloudformation.resource_provider import (
14
14
 
15
15
 
16
16
  class SecretsManagerSecretTargetAttachmentProperties(TypedDict):
17
- SecretId: Optional[str]
18
- TargetId: Optional[str]
19
- TargetType: Optional[str]
20
- Id: Optional[str]
17
+ SecretId: str | None
18
+ TargetId: str | None
19
+ TargetType: str | None
20
+ Id: str | None
21
21
 
22
22
 
23
23
  REPEATED_INVOCATION = "repeated_invocation"
@@ -1,5 +1,3 @@
1
- from typing import Optional, Type
2
-
3
1
  from localstack.services.cloudformation.resource_provider import (
4
2
  CloudFormationResourceProviderPlugin,
5
3
  ResourceProvider,
@@ -10,7 +8,7 @@ class SecretsManagerSecretTargetAttachmentProviderPlugin(CloudFormationResourceP
10
8
  name = "AWS::SecretsManager::SecretTargetAttachment"
11
9
 
12
10
  def __init__(self):
13
- self.factory: Optional[Type[ResourceProvider]] = None
11
+ self.factory: type[ResourceProvider] | None = None
14
12
 
15
13
  def load(self):
16
14
  from localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment import (
@@ -1,3 +1,4 @@
1
+ from enum import StrEnum
1
2
  from typing import TypedDict
2
3
 
3
4
  from localstack.aws.api.ses import Address, Destination, Subject, TemplateData, TemplateName
@@ -8,7 +9,7 @@ class SentEmailBody(TypedDict):
8
9
  text_part: str
9
10
 
10
11
 
11
- class SentEmail(TypedDict):
12
+ class SentEmail(TypedDict, total=False):
12
13
  Id: str
13
14
  Region: str
14
15
  Timestamp: str
@@ -19,3 +20,9 @@ class SentEmail(TypedDict):
19
20
  Template: TemplateName
20
21
  TemplateData: TemplateData
21
22
  Body: SentEmailBody
23
+
24
+
25
+ class EmailType(StrEnum):
26
+ TEMPLATED = "templated"
27
+ RAW = "raw"
28
+ EMAIL = "email"
@@ -4,8 +4,8 @@ import logging
4
4
  import os
5
5
  import re
6
6
  from collections import defaultdict
7
- from datetime import date, datetime, time, timezone
8
- from typing import TYPE_CHECKING, Any, Dict, List, Optional
7
+ from datetime import UTC, date, datetime, time
8
+ from typing import TYPE_CHECKING, Any
9
9
 
10
10
  from botocore.exceptions import ClientError
11
11
  from moto.ses import ses_backends
@@ -26,10 +26,13 @@ from localstack.aws.api.ses import (
26
26
  DeleteConfigurationSetResponse,
27
27
  DeleteTemplateResponse,
28
28
  Destination,
29
+ Enabled,
29
30
  EventDestination,
30
31
  EventDestinationDoesNotExistException,
31
32
  EventDestinationName,
33
+ EventType,
32
34
  GetIdentityVerificationAttributesResponse,
35
+ Identity,
33
36
  IdentityList,
34
37
  IdentityVerificationAttributes,
35
38
  InvalidSNSDestinationException,
@@ -40,12 +43,14 @@ from localstack.aws.api.ses import (
40
43
  MessageRejected,
41
44
  MessageTagList,
42
45
  NextToken,
46
+ NotificationType,
43
47
  RawMessage,
44
48
  ReceiptRuleSetName,
45
49
  SendEmailResponse,
46
50
  SendRawEmailResponse,
47
51
  SendTemplatedEmailResponse,
48
52
  SesApi,
53
+ SetIdentityHeadersInNotificationsEnabledResponse,
49
54
  TemplateData,
50
55
  TemplateName,
51
56
  VerificationAttributes,
@@ -56,7 +61,7 @@ from localstack.constants import INTERNAL_AWS_SECRET_ACCESS_KEY
56
61
  from localstack.http import Resource, Response
57
62
  from localstack.services.moto import call_moto
58
63
  from localstack.services.plugins import ServiceLifecycleHook
59
- from localstack.services.ses.models import SentEmail, SentEmailBody
64
+ from localstack.services.ses.models import EmailType, SentEmail, SentEmailBody
60
65
  from localstack.utils.aws import arns
61
66
  from localstack.utils.files import mkdir
62
67
  from localstack.utils.strings import long_uid, to_str
@@ -69,7 +74,7 @@ LOGGER = logging.getLogger(__name__)
69
74
 
70
75
  # Keep record of all sent emails
71
76
  # These can be retrieved via a service endpoint
72
- EMAILS: Dict[MessageId, Dict[str, Any]] = {}
77
+ EMAILS: dict[MessageId, dict[str, Any]] = {}
73
78
 
74
79
  # Endpoint to access all the sent emails
75
80
  # (relative to LocalStack internal HTTP resources base endpoint)
@@ -112,7 +117,7 @@ def save_for_retrospection(sent_email: SentEmail):
112
117
  LOGGER.debug("Email saved at: %s", path)
113
118
 
114
119
 
115
- def recipients_from_destination(destination: Destination) -> List[str]:
120
+ def recipients_from_destination(destination: Destination) -> list[str]:
116
121
  """Get list of recipient email addresses from a Destination object."""
117
122
  return (
118
123
  destination.get("ToAddresses", [])
@@ -177,6 +182,8 @@ class SesProvider(SesApi, ServiceLifecycleHook):
177
182
  #
178
183
 
179
184
  def on_after_init(self):
185
+ self._apply_patches()
186
+
180
187
  # Allow sent emails to be retrieved from the SES emails endpoint
181
188
  register_ses_api_resource()
182
189
 
@@ -184,7 +191,7 @@ class SesProvider(SesApi, ServiceLifecycleHook):
184
191
  # Helpers
185
192
  #
186
193
 
187
- def get_source_from_raw(self, raw_data: str) -> Optional[str]:
194
+ def get_source_from_raw(self, raw_data: str) -> str | None:
188
195
  """Given a raw representation of email, return the source/from field."""
189
196
  entities = raw_data.split("\n")
190
197
  for entity in entities:
@@ -192,6 +199,12 @@ class SesProvider(SesApi, ServiceLifecycleHook):
192
199
  return entity.replace("From:", "").strip()
193
200
  return None
194
201
 
202
+ def _apply_patches(self) -> None:
203
+ # Suppress Moto's validation of receipt rule actions. These validations use Moto's implementation of S3, Lambda
204
+ # and SQS, which fail because these services have been internalised in LocalStack.
205
+ # Besides, AWS does not run the same validations as evidenced by our AWS-validated tests.
206
+ SESBackend._validate_receipt_rule_actions = lambda *_: None
207
+
195
208
  #
196
209
  # Implementations for SES operations
197
210
  #
@@ -210,7 +223,9 @@ class SesProvider(SesApi, ServiceLifecycleHook):
210
223
  emitter = SNSEmitter(context)
211
224
  emitter.emit_create_configuration_set_event_destination_test_message(sns_topic_arn)
212
225
 
213
- # only register the event destiation if emitting the message worked
226
+ # FIXME: Moto stores the Event Destinations as a single value when it should be a list
227
+ # it only considers the last Event Destination created, when AWS is able to store multiple configurations
228
+ # only register the event destination if emitting the message worked
214
229
  try:
215
230
  result = call_moto(context)
216
231
  except CommonServiceException as e:
@@ -269,6 +284,9 @@ class SesProvider(SesApi, ServiceLifecycleHook):
269
284
  # FIXME: inconsistent state
270
285
  LOGGER.warning("inconsistent state encountered in ses backend")
271
286
 
287
+ # FIXME: Moto stores the Event Destinations as a single value when it should be a list
288
+ # it only considers the last Event Destination created, when AWS is able to store multiple configurations
289
+ # don't pop the whole value which should be a list but is currently a dict
272
290
  backend.config_set_event_destination.pop(configuration_set_name)
273
291
 
274
292
  return DeleteConfigurationSetEventDestinationResponse()
@@ -358,25 +376,21 @@ class SesProvider(SesApi, ServiceLifecycleHook):
358
376
  response = call_moto(context)
359
377
 
360
378
  backend = get_ses_backend(context)
361
- emitter = SNSEmitter(context)
362
- recipients = recipients_from_destination(destination)
363
-
364
- for event_destination in backend.config_set_event_destination.values():
365
- if not event_destination["Enabled"]:
366
- continue
367
-
368
- sns_destination_arn = event_destination.get("SNSDestination")
369
- if not sns_destination_arn:
370
- continue
371
379
 
372
- payload = SNSPayload(
380
+ if event_destinations := backend.config_set_event_destination.get(configuration_set_name):
381
+ recipients = recipients_from_destination(destination)
382
+ payload = EventDestinationPayload(
373
383
  message_id=response["MessageId"],
374
384
  sender_email=source,
375
385
  destination_addresses=recipients,
376
386
  tags=tags,
377
387
  )
378
- emitter.emit_send_event(payload, sns_destination_arn)
379
- emitter.emit_delivery_event(payload, sns_destination_arn)
388
+ notify_event_destinations(
389
+ context=context,
390
+ event_destinations=event_destinations,
391
+ payload=payload,
392
+ email_type=EmailType.EMAIL,
393
+ )
380
394
 
381
395
  text_part = message["Body"].get("Text", {}).get("Data")
382
396
  html_part = message["Body"].get("Html", {}).get("Data")
@@ -414,25 +428,21 @@ class SesProvider(SesApi, ServiceLifecycleHook):
414
428
  response = call_moto(context)
415
429
 
416
430
  backend = get_ses_backend(context)
417
- emitter = SNSEmitter(context)
418
- recipients = recipients_from_destination(destination)
419
-
420
- for event_destination in backend.config_set_event_destination.values():
421
- if not event_destination["Enabled"]:
422
- continue
423
-
424
- sns_destination_arn = event_destination.get("SNSDestination")
425
- if not sns_destination_arn:
426
- continue
427
431
 
428
- payload = SNSPayload(
432
+ if event_destinations := backend.config_set_event_destination.get(configuration_set_name):
433
+ recipients = recipients_from_destination(destination)
434
+ payload = EventDestinationPayload(
429
435
  message_id=response["MessageId"],
430
436
  sender_email=source,
431
437
  destination_addresses=recipients,
432
438
  tags=tags,
433
439
  )
434
- emitter.emit_send_event(payload, sns_destination_arn, emit_source_arn=False)
435
- emitter.emit_delivery_event(payload, sns_destination_arn)
440
+ notify_event_destinations(
441
+ context=context,
442
+ event_destinations=event_destinations,
443
+ payload=payload,
444
+ email_type=EmailType.TEMPLATED,
445
+ )
436
446
 
437
447
  save_for_retrospection(
438
448
  SentEmail(
@@ -477,23 +487,19 @@ class SesProvider(SesApi, ServiceLifecycleHook):
477
487
  backend = get_ses_backend(context)
478
488
  message = backend.send_raw_email(source, destinations, raw_data)
479
489
 
480
- emitter = SNSEmitter(context)
481
- for event_destination in backend.config_set_event_destination.values():
482
- if not event_destination["Enabled"]:
483
- continue
484
-
485
- sns_destination_arn = event_destination.get("SNSDestination")
486
- if not sns_destination_arn:
487
- continue
488
-
489
- payload = SNSPayload(
490
+ if event_destinations := backend.config_set_event_destination.get(configuration_set_name):
491
+ payload = EventDestinationPayload(
490
492
  message_id=message.id,
491
493
  sender_email=source,
492
494
  destination_addresses=destinations,
493
495
  tags=tags,
494
496
  )
495
- emitter.emit_send_event(payload, sns_destination_arn)
496
- emitter.emit_delivery_event(payload, sns_destination_arn)
497
+ notify_event_destinations(
498
+ context=context,
499
+ event_destinations=event_destinations,
500
+ payload=payload,
501
+ email_type=EmailType.RAW,
502
+ )
497
503
 
498
504
  save_for_retrospection(
499
505
  SentEmail(
@@ -519,18 +525,56 @@ class SesProvider(SesApi, ServiceLifecycleHook):
519
525
  backend.create_receipt_rule_set(rule_set_name)
520
526
  original_rule_set = backend.describe_receipt_rule_set(original_rule_set_name)
521
527
 
522
- for rule in original_rule_set:
523
- backend.create_receipt_rule(rule_set_name, rule)
528
+ after = None
529
+ for rule in original_rule_set.rules:
530
+ backend.create_receipt_rule(rule_set_name, rule, after)
531
+ after = rule["Name"]
524
532
 
525
533
  return CloneReceiptRuleSetResponse()
526
534
 
535
+ @handler("SetIdentityHeadersInNotificationsEnabled")
536
+ def set_identity_headers_in_notifications_enabled(
537
+ self,
538
+ context: RequestContext,
539
+ identity: Identity,
540
+ notification_type: NotificationType,
541
+ enabled: Enabled,
542
+ **kwargs,
543
+ ) -> SetIdentityHeadersInNotificationsEnabledResponse:
544
+ """
545
+ Sets whether Amazon SES includes the original email headers in the Amazon SNS notifications
546
+ for a specified identity and notification type.
547
+ """
548
+ # Validate notification_type
549
+ if notification_type not in (
550
+ NotificationType.Bounce,
551
+ NotificationType.Complaint,
552
+ NotificationType.Delivery,
553
+ ):
554
+ raise InvalidParameterValue(
555
+ f"Invalid notification type: {notification_type}. "
556
+ "Valid values are: Bounce, Complaint, Delivery."
557
+ )
558
+
559
+ backend = get_ses_backend(context)
560
+ if identity not in backend.email_identities:
561
+ raise MessageRejected(f"Identity {identity} is not verified or does not exist.")
562
+
563
+ # Store the setting in the backend
564
+ if not hasattr(backend, "identity_headers_in_notifications_enabled"):
565
+ backend.identity_headers_in_notifications_enabled = {}
566
+ backend.identity_headers_in_notifications_enabled.setdefault(identity, {})[
567
+ notification_type
568
+ ] = enabled
569
+ return SetIdentityHeadersInNotificationsEnabledResponse()
570
+
527
571
 
528
572
  @dataclasses.dataclass(frozen=True)
529
- class SNSPayload:
573
+ class EventDestinationPayload:
530
574
  message_id: str
531
575
  sender_email: Address
532
576
  destination_addresses: AddressList
533
- tags: Optional[MessageTagList]
577
+ tags: MessageTagList | None
534
578
 
535
579
 
536
580
  class SNSEmitter:
@@ -558,9 +602,9 @@ class SNSEmitter:
558
602
  )
559
603
 
560
604
  def emit_send_event(
561
- self, payload: SNSPayload, sns_topic_arn: str, emit_source_arn: bool = True
605
+ self, payload: EventDestinationPayload, sns_topic_arn: str, emit_source_arn: bool = True
562
606
  ):
563
- now = datetime.now(tz=timezone.utc)
607
+ now = datetime.now(tz=UTC)
564
608
 
565
609
  tags = defaultdict(list)
566
610
  for every in payload.tags or []:
@@ -592,10 +636,10 @@ class SNSEmitter:
592
636
  Subject="Amazon SES Email Event Notification",
593
637
  )
594
638
  except ClientError:
595
- LOGGER.exception("sending SNS message")
639
+ LOGGER.error("sending SNS message", exc_info=LOGGER.isEnabledFor(logging.DEBUG))
596
640
 
597
- def emit_delivery_event(self, payload: SNSPayload, sns_topic_arn: str):
598
- now = datetime.now(tz=timezone.utc)
641
+ def emit_delivery_event(self, payload: EventDestinationPayload, sns_topic_arn: str):
642
+ now = datetime.now(tz=UTC)
599
643
 
600
644
  tags = defaultdict(list)
601
645
  for every in payload.tags or []:
@@ -625,7 +669,7 @@ class SNSEmitter:
625
669
  Subject="Amazon SES Email Event Notification",
626
670
  )
627
671
  except ClientError:
628
- LOGGER.exception("sending SNS message")
672
+ LOGGER.error("sending SNS message", exc_info=LOGGER.isEnabledFor(logging.DEBUG))
629
673
 
630
674
  @staticmethod
631
675
  def _client_for_topic(topic_arn: str) -> "SNSClient":
@@ -640,6 +684,35 @@ class SNSEmitter:
640
684
  ).sns
641
685
 
642
686
 
687
+ def notify_event_destinations(
688
+ context: RequestContext,
689
+ # FIXME: Moto stores the Event Destinations as a single value when it should be a list
690
+ event_destinations: EventDestination | list[EventDestination],
691
+ payload: EventDestinationPayload,
692
+ email_type: EmailType,
693
+ ):
694
+ emitter = SNSEmitter(context)
695
+
696
+ if not isinstance(event_destinations, list):
697
+ event_destinations = [event_destinations]
698
+
699
+ for event_destination in event_destinations:
700
+ if not event_destination["Enabled"]:
701
+ continue
702
+
703
+ sns_destination_arn = event_destination.get("SNSDestination", {}).get("TopicARN")
704
+ if not sns_destination_arn:
705
+ continue
706
+
707
+ matching_event_types = event_destination.get("MatchingEventTypes") or []
708
+ if EventType.send in matching_event_types:
709
+ emitter.emit_send_event(
710
+ payload, sns_destination_arn, emit_source_arn=email_type != EmailType.TEMPLATED
711
+ )
712
+ if EventType.delivery in matching_event_types:
713
+ emitter.emit_delivery_event(payload, sns_destination_arn)
714
+
715
+
643
716
  class InvalidParameterValue(CommonServiceException):
644
717
  def __init__(self, message=None):
645
718
  super().__init__(