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,21 +1,36 @@
1
1
  import copy
2
+ import json
2
3
  import logging
3
4
  import os
4
- from typing import Any, Final, Optional, TypedDict
5
+ import re
6
+ from typing import Any, Final, TypedDict
5
7
 
6
8
  import boto3
9
+ import jsonpath_ng
10
+ from botocore.exceptions import ClientError, ParamValidationError
7
11
  from samtranslator.translator.transform import transform as transform_sam
8
12
 
13
+ from localstack.aws.connect import connect_to
14
+ from localstack.services.cloudformation.engine.parameters import StackParameter
9
15
  from localstack.services.cloudformation.engine.policy_loader import create_policy_loader
16
+ from localstack.services.cloudformation.engine.template_preparer import parse_template
10
17
  from localstack.services.cloudformation.engine.transformers import (
11
18
  FailedTransformationException,
12
- execute_macro,
19
+ ResolveRefsRecursivelyContext,
20
+ apply_language_extensions_transform,
13
21
  )
14
22
  from localstack.services.cloudformation.engine.v2.change_set_model import (
15
23
  ChangeType,
24
+ FnTransform,
16
25
  Maybe,
26
+ NodeForEach,
17
27
  NodeGlobalTransform,
18
- NodeParameter,
28
+ NodeIntrinsicFunction,
29
+ NodeIntrinsicFunctionFnTransform,
30
+ NodeProperties,
31
+ NodeProperty,
32
+ NodeResource,
33
+ NodeResources,
19
34
  NodeTransform,
20
35
  Nothing,
21
36
  Scope,
@@ -24,19 +39,39 @@ from localstack.services.cloudformation.engine.v2.change_set_model import (
24
39
  from localstack.services.cloudformation.engine.v2.change_set_model_preproc import (
25
40
  ChangeSetModelPreproc,
26
41
  PreprocEntityDelta,
42
+ PreprocProperties,
27
43
  )
44
+ from localstack.services.cloudformation.engine.validations import ValidationError
28
45
  from localstack.services.cloudformation.stores import get_cloudformation_store
29
46
  from localstack.services.cloudformation.v2.entities import ChangeSet
47
+ from localstack.services.cloudformation.v2.types import EngineParameter, engine_parameter_value
48
+ from localstack.utils import testutil
49
+ from localstack.utils.strings import long_uid
30
50
 
31
51
  LOG = logging.getLogger(__name__)
32
52
 
33
53
  SERVERLESS_TRANSFORM = "AWS::Serverless-2016-10-31"
34
54
  EXTENSIONS_TRANSFORM = "AWS::LanguageExtensions"
35
55
  SECRETSMANAGER_TRANSFORM = "AWS::SecretsManager-2020-07-23"
56
+ INCLUDE_TRANSFORM = "AWS::Include"
36
57
 
37
58
  _SCOPE_TRANSFORM_TEMPLATE_OUTCOME: Final[Scope] = Scope("TRANSFORM_TEMPLATE_OUTCOME")
38
59
 
39
60
 
61
+ def engine_parameters_to_stack_parameters(
62
+ engine_parameters: dict[str, EngineParameter],
63
+ ) -> dict[str, StackParameter]:
64
+ out = {}
65
+ for name, engine_param in engine_parameters.items():
66
+ out[name] = StackParameter(
67
+ ParameterKey=name,
68
+ ParameterValue=engine_parameter_value(engine_param),
69
+ ResolvedValue=engine_param.get("resolved_value"),
70
+ ParameterType=engine_param["type_"],
71
+ )
72
+ return out
73
+
74
+
40
75
  # TODO: evaluate the use of subtypes to represent and validate types of transforms
41
76
  class GlobalTransform:
42
77
  name: str
@@ -51,12 +86,12 @@ class TransformPreprocParameter(TypedDict):
51
86
  # TODO: expand
52
87
  ParameterKey: str
53
88
  ParameterValue: Any
54
- ParameterType: Optional[str]
89
+ ParameterType: str | None
55
90
 
56
91
 
57
92
  class ChangeSetModelTransform(ChangeSetModelPreproc):
58
- _before_parameters: Final[dict]
59
- _after_parameters: Final[dict]
93
+ _before_parameters: Final[dict[str, EngineParameter] | None]
94
+ _after_parameters: Final[dict[str, EngineParameter] | None]
60
95
  _before_template: Final[Maybe[dict]]
61
96
  _after_template: Final[Maybe[dict]]
62
97
 
@@ -65,8 +100,8 @@ class ChangeSetModelTransform(ChangeSetModelPreproc):
65
100
  change_set: ChangeSet,
66
101
  before_parameters: dict,
67
102
  after_parameters: dict,
68
- before_template: Optional[dict],
69
- after_template: Optional[dict],
103
+ before_template: dict | None,
104
+ after_template: dict | None,
70
105
  ):
71
106
  super().__init__(change_set=change_set)
72
107
  self._before_parameters = before_parameters
@@ -74,44 +109,13 @@ class ChangeSetModelTransform(ChangeSetModelPreproc):
74
109
  self._before_template = before_template or Nothing
75
110
  self._after_template = after_template or Nothing
76
111
 
77
- def visit_node_parameter(
78
- self, node_parameter: NodeParameter
79
- ) -> PreprocEntityDelta[
80
- dict[str, TransformPreprocParameter], dict[str, TransformPreprocParameter]
81
- ]:
82
- # Enable compatability with v1 util.
83
- # TODO: port v1's SSM parameter resolution
84
-
85
- parameter_value_delta = super().visit_node_parameter(node_parameter=node_parameter)
86
- parameter_value_before = parameter_value_delta.before
87
- parameter_value_after = parameter_value_delta.after
88
-
89
- parameter_type_delta = self.visit(node_parameter.type_)
90
- parameter_type_before = parameter_type_delta.before
91
- parameter_type_after = parameter_type_delta.after
92
-
93
- parameter_key = node_parameter.name
94
-
95
- before = Nothing
96
- if not is_nothing(parameter_value_before):
97
- before = TransformPreprocParameter(
98
- ParameterKey=parameter_key,
99
- ParameterValue=parameter_value_before,
100
- ParameterType=parameter_type_before
101
- if not is_nothing(parameter_type_before)
102
- else None,
103
- )
104
- after = Nothing
105
- if not is_nothing(parameter_value_after):
106
- after = TransformPreprocParameter(
107
- ParameterKey=parameter_key,
108
- ParameterValue=parameter_value_after,
109
- ParameterType=parameter_type_after
110
- if not is_nothing(parameter_type_after)
111
- else None,
112
- )
112
+ def transform(self) -> tuple[dict, dict]:
113
+ self._setup_runtime_cache()
114
+ self._execute_local_transforms()
115
+ transformed_before_template, transformed_after_template = self._execute_global_transforms()
116
+ self._save_runtime_cache()
113
117
 
114
- return PreprocEntityDelta(before=before, after=after)
118
+ return transformed_before_template, transformed_after_template
115
119
 
116
120
  # Ported from v1:
117
121
  @staticmethod
@@ -138,68 +142,92 @@ class ChangeSetModelTransform(ChangeSetModelPreproc):
138
142
  if region_before is not None:
139
143
  os.environ["AWS_DEFAULT_REGION"] = region_before
140
144
 
141
- @staticmethod
142
- def _apply_global_macro_transformation(
143
- account_id: str,
144
- region_name,
145
- global_transform: GlobalTransform,
146
- template: dict,
147
- parameters: dict,
148
- ) -> Optional[dict]:
149
- macro_name = global_transform.name
150
- macros_store = get_cloudformation_store(
151
- account_id=account_id, region_name=region_name
152
- ).macros
153
- macro = macros_store.get(macro_name)
154
- if macro is None:
155
- raise RuntimeError(f"No definitions for global transform '{macro_name}'")
156
- transformation_parameters = global_transform.parameters or dict()
157
- transformed_template = execute_macro(
158
- account_id,
159
- region_name,
160
- parsed_template=template,
161
- macro=macro,
162
- stack_parameters=parameters,
163
- transformation_parameters=transformation_parameters,
164
- )
165
- # The type annotation on the v1 util appears to be incorrect.
166
- return transformed_template # noqa
145
+ def _compute_include_transform(self, parameters: dict, fragment: dict) -> dict:
146
+ location = parameters.get("Location")
147
+ if not location or not location.startswith("s3://"):
148
+ raise FailedTransformationException(
149
+ transformation=INCLUDE_TRANSFORM,
150
+ message=f"Unexpected Location parameter for AWS::Include transformer: {location}",
151
+ )
152
+
153
+ s3_client = connect_to(
154
+ aws_access_key_id=self._change_set.account_id, region_name=self._change_set.region_name
155
+ ).s3
156
+ bucket, _, path = location.removeprefix("s3://").partition("/")
157
+ try:
158
+ content = testutil.download_s3_object(s3_client, bucket, path)
159
+ except ClientError:
160
+ raise FailedTransformationException(
161
+ transformation=INCLUDE_TRANSFORM,
162
+ message=f"Error downloading S3 object '{bucket}/{path}'",
163
+ )
164
+ try:
165
+ template_to_include = parse_template(content)
166
+ except Exception as e:
167
+ raise FailedTransformationException(transformation=INCLUDE_TRANSFORM, message=str(e))
168
+
169
+ return {**fragment, **template_to_include}
167
170
 
168
171
  def _apply_global_transform(
169
- self, global_transform: GlobalTransform, template: dict, parameters: dict
172
+ self,
173
+ global_transform: GlobalTransform,
174
+ template: dict,
175
+ parameters: dict[str, EngineParameter],
170
176
  ) -> dict:
171
177
  transform_name = global_transform.name
172
178
  if transform_name == EXTENSIONS_TRANSFORM:
173
- # Applied lazily in downstream tasks (see ChangeSetModelPreproc).
174
- transformed_template = template
179
+ resources = template["Resources"]
180
+ mappings = template.get("Mappings", {})
181
+ conditions = template.get("Conditions", {})
182
+
183
+ resolve_context = ResolveRefsRecursivelyContext(
184
+ self._change_set.account_id,
185
+ self._change_set.region_name,
186
+ self._change_set.stack.stack_name,
187
+ resources,
188
+ mappings,
189
+ conditions,
190
+ parameters=engine_parameters_to_stack_parameters(parameters),
191
+ )
192
+ transformed_template = apply_language_extensions_transform(template, resolve_context)
175
193
  elif transform_name == SERVERLESS_TRANSFORM:
194
+ # serverless transform just requires the key/value pairs
195
+ serverless_parameters = {}
196
+ for name, param in parameters.items():
197
+ serverless_parameters[name] = param.get("resolved_value") or engine_parameter_value(
198
+ param
199
+ )
176
200
  transformed_template = self._apply_global_serverless_transformation(
177
201
  region_name=self._change_set.region_name,
178
202
  template=template,
179
- parameters=parameters,
203
+ parameters=serverless_parameters,
180
204
  )
181
205
  elif transform_name == SECRETSMANAGER_TRANSFORM:
182
206
  # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/transform-aws-secretsmanager.html
183
207
  LOG.warning("%s is not yet supported. Ignoring.", SECRETSMANAGER_TRANSFORM)
184
208
  transformed_template = template
209
+ elif transform_name == INCLUDE_TRANSFORM:
210
+ transformed_template = self._compute_include_transform(
211
+ parameters=global_transform.parameters,
212
+ fragment=template,
213
+ )
185
214
  else:
186
- transformed_template = self._apply_global_macro_transformation(
187
- account_id=self._change_set.account_id,
188
- region_name=self._change_set.region_name,
189
- global_transform=global_transform,
190
- template=template,
191
- parameters=parameters,
215
+ transformed_template = self._invoke_macro(
216
+ name=global_transform.name,
217
+ parameters=global_transform.parameters
218
+ if not is_nothing(global_transform.parameters)
219
+ else {},
220
+ fragment=template,
221
+ allow_string=False,
192
222
  )
193
223
  return transformed_template
194
224
 
195
- def transform(self) -> tuple[dict, dict]:
196
- self._setup_runtime_cache()
197
-
225
+ def _execute_local_transforms(self):
198
226
  node_template = self._change_set.update_model.node_template
227
+ self.visit_node_resources(node_template.resources)
199
228
 
200
- parameters_delta = self.visit_node_parameters(node_template.parameters)
201
- parameters_before = parameters_delta.before
202
- parameters_after = parameters_delta.after
229
+ def _execute_global_transforms(self) -> tuple[dict, dict]:
230
+ node_template = self._change_set.update_model.node_template
203
231
 
204
232
  transform_delta: PreprocEntityDelta[list[GlobalTransform], list[GlobalTransform]] = (
205
233
  self.visit_node_transform(node_template.transform)
@@ -209,31 +237,36 @@ class ChangeSetModelTransform(ChangeSetModelPreproc):
209
237
 
210
238
  transformed_before_template = self._before_template
211
239
  if transform_before and not is_nothing(self._before_template):
212
- transformed_before_template = self._before_cache.get(_SCOPE_TRANSFORM_TEMPLATE_OUTCOME)
213
- if not transformed_before_template:
214
- transformed_before_template = self._before_template
240
+ if _SCOPE_TRANSFORM_TEMPLATE_OUTCOME in self._before_cache:
241
+ transformed_before_template = self._before_cache[_SCOPE_TRANSFORM_TEMPLATE_OUTCOME]
242
+ else:
215
243
  for before_global_transform in transform_before:
216
- transformed_before_template = self._apply_global_transform(
217
- global_transform=before_global_transform,
218
- parameters=parameters_before,
219
- template=transformed_before_template,
220
- )
244
+ if not is_nothing(before_global_transform.name):
245
+ transformed_before_template = self._apply_global_transform(
246
+ global_transform=before_global_transform,
247
+ parameters=self._before_parameters,
248
+ template=transformed_before_template,
249
+ )
250
+
251
+ # Macro transformations won't remove the transform from the template
252
+ if "Transform" in transformed_before_template:
253
+ transformed_before_template.pop("Transform")
221
254
  self._before_cache[_SCOPE_TRANSFORM_TEMPLATE_OUTCOME] = transformed_before_template
222
255
 
223
256
  transformed_after_template = self._after_template
224
257
  if transform_after and not is_nothing(self._after_template):
225
- transformed_after_template = self._after_cache.get(_SCOPE_TRANSFORM_TEMPLATE_OUTCOME)
226
- if not transformed_after_template:
227
- transformed_after_template = self._after_template
228
- for after_global_transform in transform_after:
258
+ transformed_after_template = self._after_template
259
+ for after_global_transform in transform_after:
260
+ if not is_nothing(after_global_transform.name):
229
261
  transformed_after_template = self._apply_global_transform(
230
262
  global_transform=after_global_transform,
231
- parameters=parameters_after,
263
+ parameters=self._after_parameters,
232
264
  template=transformed_after_template,
233
265
  )
234
- self._after_cache[_SCOPE_TRANSFORM_TEMPLATE_OUTCOME] = transformed_after_template
235
-
236
- self._save_runtime_cache()
266
+ # Macro transformations won't remove the transform from the template
267
+ if "Transform" in transformed_after_template:
268
+ transformed_after_template.pop("Transform")
269
+ self._after_cache[_SCOPE_TRANSFORM_TEMPLATE_OUTCOME] = transformed_after_template
237
270
 
238
271
  return transformed_before_template, transformed_after_template
239
272
 
@@ -257,9 +290,12 @@ class ChangeSetModelTransform(ChangeSetModelPreproc):
257
290
  self, node_transform: NodeTransform
258
291
  ) -> PreprocEntityDelta[list[GlobalTransform], list[GlobalTransform]]:
259
292
  change_type = node_transform.change_type
260
- before = list() if change_type != ChangeType.CREATED else Nothing
261
- after = list() if change_type != ChangeType.REMOVED else Nothing
293
+ before = [] if change_type != ChangeType.CREATED else Nothing
294
+ after = [] if change_type != ChangeType.REMOVED else Nothing
262
295
  for change_set_entity in node_transform.global_transforms:
296
+ if not isinstance(change_set_entity.name.value, str):
297
+ raise ValidationError("Key Name of transform definition must be a string.")
298
+
263
299
  delta: PreprocEntityDelta[GlobalTransform, GlobalTransform] = self.visit(
264
300
  change_set_entity=change_set_entity
265
301
  )
@@ -270,3 +306,242 @@ class ChangeSetModelTransform(ChangeSetModelPreproc):
270
306
  if not is_nothing(after) and not is_nothing(delta_after):
271
307
  after.append(delta_after)
272
308
  return PreprocEntityDelta(before=before, after=after)
309
+
310
+ def _compute_fn_transform(
311
+ self, macro_definition: Any, siblings: Any, allow_string: False
312
+ ) -> Any:
313
+ def _normalize_transform(obj):
314
+ transforms = []
315
+
316
+ if isinstance(obj, str):
317
+ transforms.append({"Name": obj, "Parameters": {}})
318
+
319
+ if isinstance(obj, dict):
320
+ transforms.append(obj)
321
+
322
+ if isinstance(obj, list):
323
+ for v in obj:
324
+ if isinstance(v, str):
325
+ transforms.append({"Name": v, "Parameters": {}})
326
+
327
+ if isinstance(v, dict):
328
+ if not v.get("Parameters"):
329
+ v["Parameters"] = {}
330
+ transforms.append(v)
331
+
332
+ return transforms
333
+
334
+ normalized_transforms = _normalize_transform(macro_definition)
335
+ transform_output = copy.deepcopy(siblings)
336
+ for transform in normalized_transforms:
337
+ transform_name = transform["Name"]
338
+ if transform_name == INCLUDE_TRANSFORM:
339
+ transform_output = self._compute_include_transform(
340
+ parameters=transform["Parameters"], fragment=transform_output
341
+ )
342
+ else:
343
+ transform_output: dict | str = self._invoke_macro(
344
+ fragment=transform_output,
345
+ name=transform["Name"],
346
+ parameters=transform.get("Parameters", {}),
347
+ allow_string=allow_string,
348
+ )
349
+
350
+ if isinstance(transform_output, dict) and FnTransform in transform_output:
351
+ transform_output.pop(FnTransform)
352
+
353
+ return transform_output
354
+
355
+ def _replace_at_jsonpath(self, template: dict, path: str, result: Any):
356
+ pattern = jsonpath_ng.parse(path)
357
+ result_template = pattern.update(template, result)
358
+
359
+ return result_template
360
+
361
+ def visit_node_for_each(self, node_foreach: NodeForEach) -> PreprocEntityDelta:
362
+ return PreprocEntityDelta()
363
+
364
+ def visit_node_intrinsic_function_fn_transform(
365
+ self, node_intrinsic_function: NodeIntrinsicFunctionFnTransform
366
+ ) -> PreprocEntityDelta:
367
+ arguments_delta = self.visit(node_intrinsic_function.arguments)
368
+ parent_json_path = node_intrinsic_function.scope.parent.jsonpath
369
+
370
+ # Only when a FnTransform is used as Property value the macro function is allowed to return a str
371
+ property_value_regex = r"\.(Properties)"
372
+ allow_string = False
373
+ if re.search(property_value_regex, parent_json_path):
374
+ allow_string = True
375
+
376
+ if not is_nothing(arguments_delta.before):
377
+ before = self._compute_fn_transform(
378
+ arguments_delta.before,
379
+ node_intrinsic_function.before_siblings,
380
+ allow_string=allow_string,
381
+ )
382
+ updated_before_template = self._replace_at_jsonpath(
383
+ self._before_template, parent_json_path, before
384
+ )
385
+ self._after_cache[_SCOPE_TRANSFORM_TEMPLATE_OUTCOME] = updated_before_template
386
+ else:
387
+ before = Nothing
388
+
389
+ if not is_nothing(arguments_delta.after):
390
+ after = self._compute_fn_transform(
391
+ arguments_delta.after,
392
+ node_intrinsic_function.after_siblings,
393
+ allow_string=allow_string,
394
+ )
395
+ updated_after_template = self._replace_at_jsonpath(
396
+ self._after_template, parent_json_path, after
397
+ )
398
+ self._after_cache[_SCOPE_TRANSFORM_TEMPLATE_OUTCOME] = updated_after_template
399
+ else:
400
+ after = Nothing
401
+
402
+ self._save_runtime_cache()
403
+ return PreprocEntityDelta(before=before, after=after)
404
+
405
+ def visit_node_properties(
406
+ self, node_properties: NodeProperties
407
+ ) -> PreprocEntityDelta[PreprocProperties, PreprocProperties]:
408
+ if not is_nothing(node_properties.fn_transform):
409
+ self.visit_node_intrinsic_function_fn_transform(node_properties.fn_transform)
410
+
411
+ return super().visit_node_properties(node_properties=node_properties)
412
+
413
+ def visit_node_resource(self, node_resource: NodeResource) -> PreprocEntityDelta:
414
+ if not is_nothing(node_resource.fn_transform):
415
+ self.visit_node_intrinsic_function_fn_transform(
416
+ node_intrinsic_function=node_resource.fn_transform
417
+ )
418
+
419
+ try:
420
+ if delta := super().visit_node_resource(node_resource):
421
+ return delta
422
+ return super().visit_node_properties(node_resource.properties)
423
+ except RuntimeError:
424
+ return super().visit_node_properties(node_resource.properties)
425
+
426
+ def visit_node_resources(self, node_resources: NodeResources) -> PreprocEntityDelta:
427
+ if not is_nothing(node_resources.fn_transform):
428
+ self.visit_node_intrinsic_function_fn_transform(
429
+ node_intrinsic_function=node_resources.fn_transform
430
+ )
431
+
432
+ return super().visit_node_resources(node_resources=node_resources)
433
+
434
+ def _invoke_macro(self, name: str, parameters: dict, fragment: dict, allow_string=False):
435
+ account_id = self._change_set.account_id
436
+ region_name = self._change_set.region_name
437
+ macro_definition = get_cloudformation_store(
438
+ account_id=account_id, region_name=region_name
439
+ ).macros.get(name)
440
+
441
+ if not macro_definition:
442
+ raise FailedTransformationException(name, f"Transformation {name} is not supported.")
443
+
444
+ simplified_parameters = {}
445
+ if resolved_parameters := self._change_set.resolved_parameters:
446
+ for key, resolved_parameter in resolved_parameters.items():
447
+ final_value = engine_parameter_value(resolved_parameter)
448
+ simplified_parameters[key] = (
449
+ final_value.split(",")
450
+ if resolved_parameter["type_"] == "CommaDelimitedList"
451
+ else final_value
452
+ )
453
+
454
+ transformation_id = f"{account_id}::{name}"
455
+ event = {
456
+ "region": region_name,
457
+ "accountId": account_id,
458
+ "fragment": fragment,
459
+ "transformId": transformation_id,
460
+ "params": parameters,
461
+ "requestId": long_uid(),
462
+ "templateParameterValues": simplified_parameters,
463
+ }
464
+
465
+ client = connect_to(aws_access_key_id=account_id, region_name=region_name).lambda_
466
+ try:
467
+ invocation = client.invoke(
468
+ FunctionName=macro_definition["FunctionName"], Payload=json.dumps(event)
469
+ )
470
+ except ClientError:
471
+ LOG.error(
472
+ "client error executing lambda function '%s' with payload '%s'",
473
+ macro_definition["FunctionName"],
474
+ json.dumps(event),
475
+ )
476
+ raise
477
+ if invocation.get("StatusCode") != 200 or invocation.get("FunctionError") == "Unhandled":
478
+ raise FailedTransformationException(
479
+ transformation=name,
480
+ message=f"Received malformed response from transform {transformation_id}. Rollback requested by user.",
481
+ )
482
+ result = json.loads(invocation["Payload"].read())
483
+
484
+ if result.get("status") != "success":
485
+ error_message = result.get("errorMessage")
486
+ message = (
487
+ f"Transform {transformation_id} failed with: {error_message}. Rollback requested by user."
488
+ if error_message
489
+ else f"Transform {transformation_id} failed without an error message.. Rollback requested by user."
490
+ )
491
+ raise FailedTransformationException(transformation=name, message=message)
492
+
493
+ if not isinstance(result.get("fragment"), dict) and not allow_string:
494
+ raise FailedTransformationException(
495
+ transformation=name,
496
+ message="Template format error: unsupported structure.. Rollback requested by user.",
497
+ )
498
+
499
+ return result.get("fragment")
500
+
501
+ def visit_node_intrinsic_function_fn_get_att(
502
+ self, node_intrinsic_function: NodeIntrinsicFunction
503
+ ) -> PreprocEntityDelta:
504
+ try:
505
+ return super().visit_node_intrinsic_function_fn_get_att(node_intrinsic_function)
506
+ except RuntimeError:
507
+ return self.visit(node_intrinsic_function.arguments)
508
+
509
+ def visit_node_intrinsic_function_fn_sub(
510
+ self, node_intrinsic_function: NodeIntrinsicFunction
511
+ ) -> PreprocEntityDelta:
512
+ try:
513
+ # If an argument is a Parameter it should be resolved, any other case, ignore it
514
+ return super().visit_node_intrinsic_function_fn_sub(node_intrinsic_function)
515
+ except RuntimeError:
516
+ return self.visit(node_intrinsic_function.arguments)
517
+
518
+ def visit_node_intrinsic_function_fn_split(
519
+ self, node_intrinsic_function: NodeIntrinsicFunction
520
+ ) -> PreprocEntityDelta:
521
+ try:
522
+ # If an argument is a Parameter it should be resolved, any other case, ignore it
523
+ return super().visit_node_intrinsic_function_fn_split(node_intrinsic_function)
524
+ except RuntimeError:
525
+ return self.visit(node_intrinsic_function.arguments)
526
+
527
+ def visit_node_intrinsic_function_fn_select(
528
+ self, node_intrinsic_function: NodeIntrinsicFunction
529
+ ) -> PreprocEntityDelta:
530
+ try:
531
+ # If an argument is a Parameter it should be resolved, any other case, ignore it
532
+ return super().visit_node_intrinsic_function_fn_select(node_intrinsic_function)
533
+ except RuntimeError:
534
+ return self.visit(node_intrinsic_function.arguments)
535
+
536
+ def visit_node_property(self, node_property: NodeProperty) -> PreprocEntityDelta:
537
+ try:
538
+ return super().visit_node_property(node_property)
539
+ except ParamValidationError:
540
+ return self.visit(node_property.value)
541
+
542
+ # ignore errors from dynamic replacements
543
+ def _maybe_perform_dynamic_replacements(self, delta: PreprocEntityDelta) -> PreprocEntityDelta:
544
+ try:
545
+ return super()._maybe_perform_dynamic_replacements(delta)
546
+ except Exception:
547
+ return delta