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
@@ -1,27 +1,31 @@
1
1
  import copy
2
2
  import logging
3
+ import os
4
+ import re
3
5
  import uuid
6
+ from collections.abc import Callable
4
7
  from dataclasses import dataclass
5
- from typing import Final, Optional
8
+ from datetime import UTC, datetime
9
+ from typing import Final, Protocol, TypeVar
6
10
 
7
11
  from localstack import config
8
12
  from localstack.aws.api.cloudformation import (
9
13
  ChangeAction,
14
+ Output,
10
15
  ResourceStatus,
11
16
  StackStatus,
12
17
  )
13
18
  from localstack.constants import INTERNAL_AWS_SECRET_ACCESS_KEY
14
19
  from localstack.services.cloudformation.analytics import track_resource_operation
15
20
  from localstack.services.cloudformation.deployment_utils import log_not_available_message
16
- from localstack.services.cloudformation.engine.parameters import resolve_ssm_parameter
17
21
  from localstack.services.cloudformation.engine.v2.change_set_model import (
18
22
  NodeDependsOn,
19
23
  NodeOutput,
20
- NodeParameter,
21
24
  NodeResource,
22
25
  is_nothing,
23
26
  )
24
27
  from localstack.services.cloudformation.engine.v2.change_set_model_preproc import (
28
+ _AWS_URL_SUFFIX,
25
29
  MOCKED_REFERENCE,
26
30
  ChangeSetModelPreproc,
27
31
  PreprocEntityDelta,
@@ -36,61 +40,100 @@ from localstack.services.cloudformation.resource_provider import (
36
40
  ResourceProviderExecutor,
37
41
  ResourceProviderPayload,
38
42
  )
39
- from localstack.services.cloudformation.v2.entities import ChangeSet
43
+ from localstack.services.cloudformation.v2.entities import ChangeSet, ResolvedResource
40
44
 
41
45
  LOG = logging.getLogger(__name__)
42
46
 
43
47
  EventOperationFromAction = {"Add": "CREATE", "Modify": "UPDATE", "Remove": "DELETE"}
44
48
 
49
+ REGEX_OUTPUT_APIGATEWAY = re.compile(
50
+ rf"^(https?://.+\.execute-api\.)(?:[^-]+-){{2,3}}\d\.(amazonaws\.com|{_AWS_URL_SUFFIX})/?(.*)$"
51
+ )
52
+
53
+ _T = TypeVar("_T")
54
+
45
55
 
46
56
  @dataclass
47
57
  class ChangeSetModelExecutorResult:
48
- resources: dict
49
- parameters: dict
50
- outputs: dict
58
+ resources: dict[str, ResolvedResource]
59
+ outputs: list[Output]
60
+ failure_message: str | None = None
61
+
62
+
63
+ class DeferredAction(Protocol):
64
+ def __call__(self) -> None: ...
65
+
66
+
67
+ @dataclass
68
+ class Deferred:
69
+ name: str
70
+ action: DeferredAction
71
+
72
+
73
+ class TriggerRollback(Exception):
74
+ """
75
+ Sentinel exception to signal that the deployment should be stopped for a reason
76
+ """
77
+
78
+ def __init__(self, logical_resource_id: str, reason: str | None):
79
+ self.logical_resource_id = logical_resource_id
80
+ self.reason = reason
51
81
 
52
82
 
53
83
  class ChangeSetModelExecutor(ChangeSetModelPreproc):
54
84
  # TODO: add typing for resolved resources and parameters.
55
- resources: Final[dict]
56
- outputs: Final[dict]
57
- resolved_parameters: Final[dict]
85
+ resources: Final[dict[str, ResolvedResource]]
86
+ outputs: Final[list[Output]]
87
+ _deferred_actions: list[Deferred]
58
88
 
59
89
  def __init__(self, change_set: ChangeSet):
60
90
  super().__init__(change_set=change_set)
61
- self.resources = dict()
62
- self.outputs = dict()
63
- self.resolved_parameters = dict()
91
+ self.resources = {}
92
+ self.outputs = []
93
+ self._deferred_actions = []
94
+ self.resource_provider_executor = ResourceProviderExecutor(
95
+ stack_name=change_set.stack.stack_name,
96
+ stack_id=change_set.stack.stack_id,
97
+ )
64
98
 
65
- # TODO: use a structured type for the return value
66
99
  def execute(self) -> ChangeSetModelExecutorResult:
67
- self.process()
100
+ # constructive process
101
+ failure_message = None
102
+ try:
103
+ self.process()
104
+ except TriggerRollback as e:
105
+ failure_message = e.reason
106
+ except Exception as e:
107
+ failure_message = str(e)
108
+
109
+ is_deletion = self._change_set.stack.status == StackStatus.DELETE_IN_PROGRESS
110
+ if self._deferred_actions:
111
+ if not is_deletion:
112
+ # TODO: correct status
113
+ # TODO: differentiate between update and create
114
+ self._change_set.stack.set_stack_status(
115
+ StackStatus.ROLLBACK_IN_PROGRESS
116
+ if failure_message
117
+ else StackStatus.UPDATE_COMPLETE_CLEANUP_IN_PROGRESS
118
+ )
119
+
120
+ # perform all deferred actions such as deletions. These must happen in reverse from their
121
+ # defined order so that resource dependencies are honoured
122
+ # TODO: errors will stop all rollbacks; get parity on this behaviour
123
+ for deferred in self._deferred_actions[::-1]:
124
+ LOG.debug("executing deferred action: '%s'", deferred.name)
125
+ deferred.action()
126
+
127
+ if failure_message and not is_deletion:
128
+ # TODO: differentiate between update and create
129
+ self._change_set.stack.set_stack_status(StackStatus.ROLLBACK_COMPLETE)
130
+
68
131
  return ChangeSetModelExecutorResult(
69
- resources=self.resources, parameters=self.resolved_parameters, outputs=self.outputs
132
+ resources=self.resources, outputs=self.outputs, failure_message=failure_message
70
133
  )
71
134
 
72
- def visit_node_parameter(self, node_parameter: NodeParameter) -> PreprocEntityDelta:
73
- delta = super().visit_node_parameter(node_parameter)
74
-
75
- # handle dynamic references, e.g. references to SSM parameters
76
- # TODO: support more parameter types
77
- parameter_type: str = node_parameter.type_.value
78
- if parameter_type.startswith("AWS::SSM"):
79
- if parameter_type in [
80
- "AWS::SSM::Parameter::Value<String>",
81
- "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>",
82
- "AWS::SSM::Parameter::Value<CommaDelimitedList>",
83
- ]:
84
- delta.after = resolve_ssm_parameter(
85
- account_id=self._change_set.account_id,
86
- region_name=self._change_set.region_name,
87
- stack_parameter_value=delta.after,
88
- )
89
- else:
90
- raise Exception(f"Unsupported stack parameter type: {parameter_type}")
91
-
92
- self.resolved_parameters[node_parameter.name] = delta.after
93
- return delta
135
+ def _defer_action(self, name: str, action: DeferredAction):
136
+ self._deferred_actions.append(Deferred(name=name, action=action))
94
137
 
95
138
  def _get_physical_id(self, logical_resource_id, strict: bool = True) -> str | None:
96
139
  physical_resource_id = None
@@ -112,12 +155,13 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
112
155
 
113
156
  def _process_event(
114
157
  self,
158
+ *,
115
159
  action: ChangeAction,
116
160
  logical_resource_id,
117
161
  event_status: OperationStatus,
162
+ resource_type: str,
118
163
  special_action: str = None,
119
164
  reason: str = None,
120
- resource_type=None,
121
165
  ):
122
166
  status_from_action = special_action or EventOperationFromAction[action.value]
123
167
  if event_status == OperationStatus.SUCCESS:
@@ -125,9 +169,10 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
125
169
  else:
126
170
  status = f"{status_from_action}_{event_status.name}"
127
171
 
172
+ physical_resource_id = self._get_physical_id(logical_resource_id, False)
128
173
  self._change_set.stack.set_resource_status(
129
174
  logical_resource_id=logical_resource_id,
130
- physical_resource_id=self._get_physical_id(logical_resource_id, False),
175
+ physical_resource_id=physical_resource_id,
131
176
  resource_type=resource_type,
132
177
  status=ResourceStatus(status),
133
178
  resource_status_reason=reason,
@@ -180,12 +225,18 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
180
225
  try:
181
226
  delta = super().visit_node_resource(node_resource=node_resource)
182
227
  except Exception as e:
183
- self._process_event(
184
- node_resource.change_type.to_change_action(),
228
+ LOG.debug(
229
+ "preprocessing resource '%s' failed: %s",
185
230
  node_resource.name,
186
- OperationStatus.FAILED,
187
- reason=str(e),
231
+ e,
232
+ exc_info=LOG.isEnabledFor(logging.DEBUG) and config.CFN_VERBOSE_ERRORS,
233
+ )
234
+ self._process_event(
235
+ action=node_resource.change_type.to_change_action(),
236
+ logical_resource_id=node_resource.name,
237
+ event_status=OperationStatus.FAILED,
188
238
  resource_type=node_resource.type_.value,
239
+ reason=str(e),
189
240
  )
190
241
  raise e
191
242
 
@@ -201,16 +252,30 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
201
252
  # references or other downstream operations.
202
253
  if not is_nothing(before):
203
254
  before_logical_id = delta.before.logical_id
204
- before_resource = self._before_resolved_resources.get(before_logical_id, dict())
255
+ before_resource = self._before_resolved_resources.get(before_logical_id, {})
205
256
  self.resources[before_logical_id] = before_resource
206
257
 
207
258
  # Update the latest version of this resource for downstream references.
208
259
  if not is_nothing(after):
209
260
  after_logical_id = after.logical_id
210
- after_physical_id: str = self._after_resource_physical_id(
211
- resource_logical_id=after_logical_id
212
- )
213
- after.physical_resource_id = after_physical_id
261
+ resource = self.resources[after_logical_id]
262
+ resource_failed_to_deploy = resource["ResourceStatus"] in {
263
+ ResourceStatus.CREATE_FAILED,
264
+ ResourceStatus.UPDATE_FAILED,
265
+ }
266
+ if not resource_failed_to_deploy:
267
+ after_physical_id: str = self._after_resource_physical_id(
268
+ resource_logical_id=after_logical_id
269
+ )
270
+ after.physical_resource_id = after_physical_id
271
+ after.status = resource["ResourceStatus"]
272
+
273
+ # terminate the deployment process
274
+ if resource_failed_to_deploy:
275
+ raise TriggerRollback(
276
+ logical_resource_id=after_logical_id,
277
+ reason=resource.get("ResourceStatusReason"),
278
+ )
214
279
  return delta
215
280
 
216
281
  def visit_node_output(
@@ -220,11 +285,20 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
220
285
  after = delta.after
221
286
  if is_nothing(after) or (isinstance(after, PreprocOutput) and after.condition is False):
222
287
  return delta
223
- self.outputs[delta.after.name] = delta.after.value
288
+
289
+ output = Output(
290
+ OutputKey=delta.after.name,
291
+ OutputValue=delta.after.value,
292
+ # TODO
293
+ # Description=delta.after.description
294
+ )
295
+ if after.export:
296
+ output["ExportName"] = after.export["Name"]
297
+ self.outputs.append(output)
224
298
  return delta
225
299
 
226
300
  def _execute_resource_change(
227
- self, name: str, before: Optional[PreprocResource], after: Optional[PreprocResource]
301
+ self, name: str, before: PreprocResource | None, after: PreprocResource | None
228
302
  ) -> None:
229
303
  # Changes are to be made about this resource.
230
304
  # TODO: this logic is a POC and should be revised.
@@ -235,21 +309,67 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
235
309
  # XXX hacky, stick the previous resources' properties into the payload
236
310
  before_properties = self._merge_before_properties(name, before)
237
311
 
238
- self._process_event(ChangeAction.Modify, name, OperationStatus.IN_PROGRESS)
239
- event = self._execute_resource_action(
312
+ self._process_event(
240
313
  action=ChangeAction.Modify,
241
314
  logical_resource_id=name,
242
- resource_type=before.resource_type,
243
- before_properties=before_properties,
244
- after_properties=after.properties,
245
- )
246
- self._process_event(
247
- ChangeAction.Modify,
248
- name,
249
- event.status,
250
- reason=event.message,
315
+ event_status=OperationStatus.IN_PROGRESS,
251
316
  resource_type=before.resource_type,
252
317
  )
318
+ if after.requires_replacement:
319
+ event = self._execute_resource_action(
320
+ action=ChangeAction.Add,
321
+ logical_resource_id=name,
322
+ resource_type=before.resource_type,
323
+ before_properties=None,
324
+ after_properties=after.properties,
325
+ )
326
+ self._process_event(
327
+ action=ChangeAction.Modify,
328
+ logical_resource_id=name,
329
+ event_status=event.status,
330
+ resource_type=before.resource_type,
331
+ reason=event.message,
332
+ )
333
+
334
+ def cleanup():
335
+ self._process_event(
336
+ action=ChangeAction.Remove,
337
+ logical_resource_id=name,
338
+ event_status=OperationStatus.IN_PROGRESS,
339
+ resource_type=before.resource_type,
340
+ )
341
+ event = self._execute_resource_action(
342
+ action=ChangeAction.Remove,
343
+ logical_resource_id=name,
344
+ resource_type=before.resource_type,
345
+ before_properties=before_properties,
346
+ after_properties=None,
347
+ part_of_replacement=True,
348
+ )
349
+ self._process_event(
350
+ action=ChangeAction.Remove,
351
+ logical_resource_id=name,
352
+ event_status=event.status,
353
+ resource_type=before.resource_type,
354
+ reason=event.message,
355
+ )
356
+
357
+ self._defer_action(f"cleanup-from-replacement-{name}", cleanup)
358
+ else:
359
+ event = self._execute_resource_action(
360
+ action=ChangeAction.Modify,
361
+ logical_resource_id=name,
362
+ resource_type=before.resource_type,
363
+ before_properties=before_properties,
364
+ after_properties=after.properties,
365
+ )
366
+ self._process_event(
367
+ action=ChangeAction.Modify,
368
+ logical_resource_id=name,
369
+ event_status=event.status,
370
+ resource_type=before.resource_type,
371
+ reason=event.message,
372
+ )
253
373
  # Case: type migration.
254
374
  # TODO: Add test to assert that on type change the resources are replaced.
255
375
  else:
@@ -257,21 +377,24 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
257
377
  before_properties = self._merge_before_properties(name, before)
258
378
  # Register a Removed for the previous type.
259
379
 
260
- event = self._execute_resource_action(
261
- action=ChangeAction.Remove,
262
- logical_resource_id=name,
263
- resource_type=before.resource_type,
264
- before_properties=before_properties,
265
- after_properties=None,
266
- )
267
- # Register a Create for the next type.
268
- self._process_event(
269
- ChangeAction.Modify,
270
- name,
271
- event.status,
272
- reason=event.message,
273
- resource_type=before.resource_type,
274
- )
380
+ def perform_deletion():
381
+ event = self._execute_resource_action(
382
+ action=ChangeAction.Remove,
383
+ logical_resource_id=name,
384
+ resource_type=before.resource_type,
385
+ before_properties=before_properties,
386
+ after_properties=None,
387
+ )
388
+ self._process_event(
389
+ action=ChangeAction.Modify,
390
+ logical_resource_id=name,
391
+ event_status=event.status,
392
+ resource_type=before.resource_type,
393
+ reason=event.message,
394
+ )
395
+
396
+ self._defer_action(f"type-migration-{name}", perform_deletion)
397
+
275
398
  event = self._execute_resource_action(
276
399
  action=ChangeAction.Add,
277
400
  logical_resource_id=name,
@@ -280,43 +403,47 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
280
403
  after_properties=after.properties,
281
404
  )
282
405
  self._process_event(
283
- ChangeAction.Modify,
284
- name,
285
- event.status,
286
- reason=event.message,
406
+ action=ChangeAction.Modify,
407
+ logical_resource_id=name,
408
+ event_status=event.status,
287
409
  resource_type=before.resource_type,
410
+ reason=event.message,
288
411
  )
289
412
  elif not is_nothing(before):
290
413
  # Case: removal
291
414
  # XXX hacky, stick the previous resources' properties into the payload
292
415
  # XXX hacky, stick the previous resources' properties into the payload
293
416
  before_properties = self._merge_before_properties(name, before)
294
- self._process_event(
295
- ChangeAction.Remove,
296
- name,
297
- OperationStatus.IN_PROGRESS,
298
- resource_type=before.resource_type,
299
- )
300
- event = self._execute_resource_action(
301
- action=ChangeAction.Remove,
302
- logical_resource_id=name,
303
- resource_type=before.resource_type,
304
- before_properties=before_properties,
305
- after_properties=None,
306
- )
307
- self._process_event(
308
- ChangeAction.Remove,
309
- name,
310
- event.status,
311
- reason=event.message,
312
- resource_type=before.resource_type,
313
- )
417
+
418
+ def perform_deletion():
419
+ self._process_event(
420
+ action=ChangeAction.Remove,
421
+ logical_resource_id=name,
422
+ resource_type=before.resource_type,
423
+ event_status=OperationStatus.IN_PROGRESS,
424
+ )
425
+ event = self._execute_resource_action(
426
+ action=ChangeAction.Remove,
427
+ logical_resource_id=name,
428
+ resource_type=before.resource_type,
429
+ before_properties=before_properties,
430
+ after_properties=None,
431
+ )
432
+ self._process_event(
433
+ action=ChangeAction.Remove,
434
+ logical_resource_id=name,
435
+ event_status=event.status,
436
+ resource_type=before.resource_type,
437
+ reason=event.message,
438
+ )
439
+
440
+ self._defer_action(f"remove-{name}", perform_deletion)
314
441
  elif not is_nothing(after):
315
442
  # Case: addition
316
443
  self._process_event(
317
- ChangeAction.Add,
318
- name,
319
- OperationStatus.IN_PROGRESS,
444
+ action=ChangeAction.Add,
445
+ logical_resource_id=name,
446
+ event_status=OperationStatus.IN_PROGRESS,
320
447
  resource_type=after.resource_type,
321
448
  )
322
449
  event = self._execute_resource_action(
@@ -327,11 +454,11 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
327
454
  after_properties=after.properties,
328
455
  )
329
456
  self._process_event(
330
- ChangeAction.Add,
331
- name,
332
- event.status,
333
- reason=event.message,
457
+ action=ChangeAction.Add,
458
+ logical_resource_id=name,
459
+ event_status=event.status,
334
460
  resource_type=after.resource_type,
461
+ reason=event.message,
335
462
  )
336
463
 
337
464
  def _merge_before_properties(
@@ -350,13 +477,11 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
350
477
  action: ChangeAction,
351
478
  logical_resource_id: str,
352
479
  resource_type: str,
353
- before_properties: Optional[PreprocProperties],
354
- after_properties: Optional[PreprocProperties],
480
+ before_properties: PreprocProperties | None,
481
+ after_properties: PreprocProperties | None,
482
+ part_of_replacement: bool = False,
355
483
  ) -> ProgressEvent:
356
484
  LOG.debug("Executing resource action: %s for resource '%s'", action, logical_resource_id)
357
- resource_provider_executor = ResourceProviderExecutor(
358
- stack_name=self._change_set.stack.stack_name, stack_id=self._change_set.stack.stack_id
359
- )
360
485
  payload = self.create_resource_provider_payload(
361
486
  action=action,
362
487
  logical_resource_id=logical_resource_id,
@@ -364,13 +489,15 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
364
489
  before_properties=before_properties,
365
490
  after_properties=after_properties,
366
491
  )
367
- resource_provider = resource_provider_executor.try_load_resource_provider(resource_type)
492
+ resource_provider = self.resource_provider_executor.try_load_resource_provider(
493
+ resource_type
494
+ )
368
495
  track_resource_operation(action, resource_type, missing=resource_provider is not None)
369
496
 
370
497
  extra_resource_properties = {}
371
498
  if resource_provider is not None:
372
499
  try:
373
- event = resource_provider_executor.deploy_loop(
500
+ event = self.resource_provider_executor.deploy_loop(
374
501
  resource_provider, extra_resource_properties, payload
375
502
  )
376
503
  except Exception as e:
@@ -378,7 +505,7 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
378
505
  LOG.warning(
379
506
  "Resource provider operation failed: '%s'",
380
507
  reason,
381
- exc_info=LOG.isEnabledFor(logging.DEBUG),
508
+ exc_info=LOG.isEnabledFor(logging.DEBUG) and config.CFN_VERBOSE_ERRORS,
382
509
  )
383
510
  event = ProgressEvent(
384
511
  OperationStatus.FAILED,
@@ -390,9 +517,11 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
390
517
  resource_type,
391
518
  f'No resource provider found for "{resource_type}"',
392
519
  )
393
- LOG.warning(
394
- "Deployment of resource type %s successful due to config CFN_IGNORE_UNSUPPORTED_RESOURCE_TYPES"
395
- )
520
+ if "CFN_IGNORE_UNSUPPORTED_RESOURCE_TYPES" not in os.environ:
521
+ LOG.warning(
522
+ "Deployment of resource type %s succeeded, but will fail in upcoming LocalStack releases unless CFN_IGNORE_UNSUPPORTED_RESOURCE_TYPES is explicitly enabled.",
523
+ resource_type,
524
+ )
396
525
  event = ProgressEvent(
397
526
  OperationStatus.SUCCESS,
398
527
  resource_model={},
@@ -409,7 +538,19 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
409
538
  message=f"Resource type {resource_type} not supported",
410
539
  )
411
540
 
412
- self.resources.setdefault(logical_resource_id, {"Properties": {}})
541
+ if part_of_replacement and action == ChangeAction.Remove:
542
+ # Early return as we don't want to update internal state of the executor if this is a
543
+ # cleanup of an old resource. The new resource has already been created and the state
544
+ # updated
545
+ return event
546
+
547
+ status_from_action = EventOperationFromAction[action.value]
548
+ resolved_resource = ResolvedResource(
549
+ Properties=event.resource_model,
550
+ LogicalResourceId=logical_resource_id,
551
+ Type=resource_type,
552
+ LastUpdatedTimestamp=datetime.now(UTC),
553
+ )
413
554
  match event.status:
414
555
  case OperationStatus.SUCCESS:
415
556
  # merge the resources state with the external state
@@ -422,27 +563,31 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
422
563
  # TODO: avoid the use of setdefault (debuggability/readability)
423
564
  # TODO: review the use of merge
424
565
 
425
- self.resources[logical_resource_id]["Properties"].update(event.resource_model)
426
- self.resources[logical_resource_id].update(extra_resource_properties)
427
- # XXX for legacy delete_stack compatibility
428
- self.resources[logical_resource_id]["LogicalResourceId"] = logical_resource_id
429
- self.resources[logical_resource_id]["Type"] = resource_type
430
-
431
- physical_resource_id = (
432
- self._get_physical_id(logical_resource_id)
433
- if resource_provider
434
- else MOCKED_REFERENCE
435
- )
436
- self.resources[logical_resource_id]["PhysicalResourceId"] = physical_resource_id
437
-
566
+ # Don't update the resolved resources if we have deleted that resource
567
+ if action != ChangeAction.Remove:
568
+ physical_resource_id = (
569
+ extra_resource_properties["PhysicalResourceId"]
570
+ if resource_provider
571
+ else MOCKED_REFERENCE
572
+ )
573
+ resolved_resource["PhysicalResourceId"] = physical_resource_id
574
+ resolved_resource["ResourceStatus"] = ResourceStatus(
575
+ f"{status_from_action}_COMPLETE"
576
+ )
577
+ # TODO: do we actually need this line?
578
+ resolved_resource.update(extra_resource_properties)
438
579
  case OperationStatus.FAILED:
439
580
  reason = event.message
440
581
  LOG.warning(
441
582
  "Resource provider operation failed: '%s'",
442
583
  reason,
443
584
  )
585
+ resolved_resource["ResourceStatus"] = ResourceStatus(f"{status_from_action}_FAILED")
586
+ resolved_resource["ResourceStatusReason"] = reason
444
587
  case other:
445
588
  raise NotImplementedError(f"Event status '{other}' not handled")
589
+
590
+ self.resources[logical_resource_id] = resolved_resource
446
591
  return event
447
592
 
448
593
  def create_resource_provider_payload(
@@ -450,9 +595,9 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
450
595
  action: ChangeAction,
451
596
  logical_resource_id: str,
452
597
  resource_type: str,
453
- before_properties: Optional[PreprocProperties],
454
- after_properties: Optional[PreprocProperties],
455
- ) -> Optional[ResourceProviderPayload]:
598
+ before_properties: PreprocProperties | None,
599
+ after_properties: PreprocProperties | None,
600
+ ) -> ResourceProviderPayload | None:
456
601
  # FIXME: use proper credentials
457
602
  creds: Credentials = {
458
603
  "accessKeyId": self._change_set.stack.account_id,
@@ -500,3 +645,11 @@ class ChangeSetModelExecutor(ChangeSetModelPreproc):
500
645
  },
501
646
  }
502
647
  return resource_provider_payload
648
+
649
+ def _maybe_perform_on_delta(
650
+ self, delta: PreprocEntityDelta, f: Callable[[_T], _T]
651
+ ) -> PreprocEntityDelta:
652
+ # we only care about the after state
653
+ if isinstance(delta.after, str):
654
+ delta.after = f(delta.after)
655
+ return delta