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,6 +1,6 @@
1
1
  import copy
2
2
  import time
3
- from typing import Generic, List, Optional, TypeVar, overload
3
+ from typing import Generic, TypeVar, overload
4
4
 
5
5
  from pydantic import Field
6
6
  from pydantic.dataclasses import dataclass
@@ -47,8 +47,8 @@ class Batcher(Generic[T]):
47
47
  assert batcher.flush() == ["item1", "item2", "item3", "item4"]
48
48
  """
49
49
 
50
- max_count: Optional[int] = Field(default=None, description="Maximum number of items", ge=0)
51
- max_window: Optional[float] = Field(
50
+ max_count: int | None = Field(default=None, description="Maximum number of items", ge=0)
51
+ max_window: float | None = Field(
52
52
  default=None, description="Maximum time window in seconds", ge=0
53
53
  )
54
54
 
@@ -76,7 +76,7 @@ class Batcher(Generic[T]):
76
76
  def add(self, item: T, *, deep_copy: bool = False) -> BatchPolicyTriggered: ...
77
77
 
78
78
  @overload
79
- def add(self, items: List[T], *, deep_copy: bool = False) -> BatchPolicyTriggered: ...
79
+ def add(self, items: list[T], *, deep_copy: bool = False) -> BatchPolicyTriggered: ...
80
80
 
81
81
  def add(self, item_or_items: T | list[T], *, deep_copy: bool = False) -> BatchPolicyTriggered:
82
82
  """
@@ -9,8 +9,9 @@ import shlex
9
9
  import signal
10
10
  import threading
11
11
  import time
12
+ from collections.abc import Callable, Iterable
12
13
  from functools import wraps
13
- from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Union
14
+ from typing import Any
14
15
 
15
16
  from localstack import config, constants
16
17
  from localstack.config import (
@@ -156,7 +157,7 @@ def log_duration(name=None, min_ms=500):
156
157
  return wrapper
157
158
 
158
159
 
159
- def get_docker_image_details(image_name: str = None) -> Dict[str, str]:
160
+ def get_docker_image_details(image_name: str = None) -> dict[str, str]:
160
161
  image_name = image_name or get_docker_image_to_start()
161
162
  try:
162
163
  result = DOCKER_CLIENT.inspect_image(image_name)
@@ -174,7 +175,7 @@ def get_docker_image_details(image_name: str = None) -> Dict[str, str]:
174
175
  return result
175
176
 
176
177
 
177
- def get_image_environment_variable(env_name: str) -> Optional[str]:
178
+ def get_image_environment_variable(env_name: str) -> str | None:
178
179
  image_name = get_docker_image_to_start()
179
180
  image_info = DOCKER_CLIENT.inspect_image(image_name)
180
181
  image_envs = image_info["Config"]["Env"]
@@ -249,7 +250,7 @@ def setup_logging():
249
250
  # --------------
250
251
 
251
252
 
252
- def resolve_apis(services: Iterable[str]) -> Set[str]:
253
+ def resolve_apis(services: Iterable[str]) -> set[str]:
253
254
  """
254
255
  Resolves recursively for the given collection of services (e.g., ["serverless", "cognito"]) the list of actual
255
256
  API services that need to be included (e.g., {'dynamodb', 'cloudformation', 'logs', 'kinesis', 'sts',
@@ -289,8 +290,8 @@ def resolve_apis(services: Iterable[str]) -> Set[str]:
289
290
  return result
290
291
 
291
292
 
292
- @functools.lru_cache()
293
- def get_enabled_apis() -> Set[str]:
293
+ @functools.lru_cache
294
+ def get_enabled_apis() -> set[str]:
294
295
  """
295
296
  Returns the list of APIs that are enabled through the combination of the SERVICES variable and
296
297
  STRICT_SERVICE_LOADING variable. If the SERVICES variable is empty, then it will return all available services.
@@ -324,8 +325,8 @@ def is_api_enabled(api: str) -> bool:
324
325
  return api in get_enabled_apis()
325
326
 
326
327
 
327
- @functools.lru_cache()
328
- def get_preloaded_services() -> Set[str]:
328
+ @functools.lru_cache
329
+ def get_preloaded_services() -> set[str]:
329
330
  """
330
331
  Returns the list of APIs that are marked to be eager loaded through the combination of SERVICES variable and
331
332
  EAGER_SERVICE_LOADING. If the SERVICES variable is empty, then it will return all available services.
@@ -426,15 +427,13 @@ def validate_localstack_config(name: str):
426
427
 
427
428
  def port_exposed(port):
428
429
  for exposed in docker_ports:
429
- if re.match(r"^([0-9]+-)?%s(-[0-9]+)?$" % port, exposed):
430
+ if re.match(rf"^([0-9]+-)?{port}(-[0-9]+)?$", exposed):
430
431
  return True
431
432
 
432
433
  if not port_exposed(edge_port):
433
434
  warns.append(
434
- (
435
- f"Edge port {edge_port} is not exposed. You may have to add the entry "
436
- 'to the "ports" section of the docker-compose file.'
437
- )
435
+ f"Edge port {edge_port} is not exposed. You may have to add the entry "
436
+ 'to the "ports" section of the docker-compose file.'
438
437
  )
439
438
 
440
439
  # print warning/info messages
@@ -456,7 +455,7 @@ def get_docker_image_to_start():
456
455
 
457
456
  def extract_port_flags(user_flags, port_mappings: PortMappings):
458
457
  regex = r"-p\s+([0-9]+)(\-([0-9]+))?:([0-9]+)(\-([0-9]+))?"
459
- matches = re.match(".*%s" % regex, user_flags)
458
+ matches = re.match(f".*{regex}", user_flags)
460
459
  if matches:
461
460
  for match in re.findall(regex, user_flags):
462
461
  start = int(match[0])
@@ -545,7 +544,7 @@ class ContainerConfigurators:
545
544
 
546
545
  @staticmethod
547
546
  def gateway_listen(
548
- port: Union[int, Iterable[int], HostAndPort, Iterable[HostAndPort]],
547
+ port: int | Iterable[int] | HostAndPort | Iterable[HostAndPort],
549
548
  ):
550
549
  """
551
550
  Uses the given ports to configure GATEWAY_LISTEN. For instance, ``gateway_listen([4566, 443])`` would
@@ -638,7 +637,7 @@ class ContainerConfigurators:
638
637
  return _cfg
639
638
 
640
639
  @staticmethod
641
- def custom_command(cmd: List[str]):
640
+ def custom_command(cmd: list[str]):
642
641
  """
643
642
  Overwrites the container command and unsets the default entrypoint.
644
643
 
@@ -653,7 +652,7 @@ class ContainerConfigurators:
653
652
  return _cfg
654
653
 
655
654
  @staticmethod
656
- def env_vars(env_vars: Dict[str, str]):
655
+ def env_vars(env_vars: dict[str, str]):
657
656
  def _cfg(cfg: ContainerConfiguration):
658
657
  cfg.env_vars.update(env_vars)
659
658
 
@@ -674,7 +673,7 @@ class ContainerConfigurators:
674
673
  return _cfg
675
674
 
676
675
  @staticmethod
677
- def cli_params(params: Dict[str, Any]):
676
+ def cli_params(params: dict[str, Any]):
678
677
  """
679
678
  Parse docker CLI parameters and add them to the config. The currently known CLI params are::
680
679
 
@@ -808,7 +807,7 @@ def get_gateway_port(container: Container) -> int:
808
807
  :param container: the localstack container
809
808
  :return: the gateway port reachable from the host
810
809
  """
811
- candidates: List[int]
810
+ candidates: list[int]
812
811
 
813
812
  gateway_listen = container.config.env_vars.get("GATEWAY_LISTEN")
814
813
  if gateway_listen:
@@ -1001,7 +1000,7 @@ class RunningContainer:
1001
1000
  return
1002
1001
  raise
1003
1002
 
1004
- def inspect(self) -> Dict[str, Union[Dict, str]]:
1003
+ def inspect(self) -> dict[str, dict | str]:
1005
1004
  return self.container_client.inspect_container(container_name_or_id=self.id)
1006
1005
 
1007
1006
  def attach(self):
@@ -1029,11 +1028,11 @@ class ContainerLogPrinter:
1029
1028
  self.callback = callback
1030
1029
 
1031
1030
  self._closed = threading.Event()
1032
- self._stream: Optional[CancellableStream] = None
1031
+ self._stream: CancellableStream | None = None
1033
1032
 
1034
1033
  def _can_start_streaming(self):
1035
1034
  if self._closed.is_set():
1036
- raise IOError("Already stopped")
1035
+ raise OSError("Already stopped")
1037
1036
  if not self.container.running_container:
1038
1037
  return False
1039
1038
  return self.container.running_container.is_running()
@@ -1041,7 +1040,7 @@ class ContainerLogPrinter:
1041
1040
  def run(self):
1042
1041
  try:
1043
1042
  poll_condition(self._can_start_streaming)
1044
- except IOError:
1043
+ except OSError:
1045
1044
  return
1046
1045
  self._stream = self.container.running_container.stream_logs()
1047
1046
  for line in self._stream:
@@ -1115,8 +1114,8 @@ class LocalstackContainerServer(Server):
1115
1114
 
1116
1115
  def do_run(self):
1117
1116
  if self.is_container_running():
1118
- raise ContainerExists(
1119
- 'LocalStack container named "%s" is already running' % self.container.name
1117
+ raise ContainerRunning(
1118
+ f'LocalStack container named "{self.container.name}" is already running'
1120
1119
  )
1121
1120
 
1122
1121
  config.dirs.mkdirs()
@@ -1152,12 +1151,19 @@ class ContainerExists(Exception):
1152
1151
  pass
1153
1152
 
1154
1153
 
1154
+ class ContainerRunning(Exception):
1155
+ pass
1156
+
1157
+
1155
1158
  def prepare_docker_start():
1156
1159
  # prepare environment for docker start
1157
1160
  container_name = config.MAIN_CONTAINER_NAME
1158
1161
 
1159
1162
  if DOCKER_CLIENT.is_container_running(container_name):
1160
- raise ContainerExists('LocalStack container named "%s" is already running' % container_name)
1163
+ raise ContainerRunning(f'LocalStack container named "{container_name}" is already running')
1164
+
1165
+ if container_name in DOCKER_CLIENT.get_all_container_names():
1166
+ raise ContainerExists(f'LocalStack container named "{container_name}" already exists')
1161
1167
 
1162
1168
  config.dirs.mkdirs()
1163
1169
 
@@ -1227,7 +1233,7 @@ def prepare_host(console):
1227
1233
  hooks.prepare_host.run()
1228
1234
 
1229
1235
 
1230
- def start_infra_in_docker(console, cli_params: Dict[str, Any] = None):
1236
+ def start_infra_in_docker(console, cli_params: dict[str, Any] = None):
1231
1237
  prepare_docker_start()
1232
1238
 
1233
1239
  # create and prepare container
@@ -1302,14 +1308,15 @@ def ensure_container_image(console, container: Container):
1302
1308
  console.log("download complete")
1303
1309
 
1304
1310
 
1305
- def start_infra_in_docker_detached(console, cli_params: Dict[str, Any] = None):
1311
+ def start_infra_in_docker_detached(console, cli_params: dict[str, Any] = None):
1306
1312
  """
1307
1313
  An alternative to start_infra_in_docker where the terminal is not blocked by the follow on the logfile.
1308
1314
  """
1309
1315
  console.log("preparing environment")
1310
1316
  try:
1311
1317
  prepare_docker_start()
1312
- except ContainerExists as e:
1318
+ except ContainerRunning as e:
1319
+ # starting in detached mode is idempotent, return if container is already running
1313
1320
  console.print(str(e))
1314
1321
  return
1315
1322
 
@@ -1331,7 +1338,7 @@ def start_infra_in_docker_detached(console, cli_params: Dict[str, Any] = None):
1331
1338
  console.log("detaching")
1332
1339
 
1333
1340
 
1334
- def wait_container_is_ready(timeout: Optional[float] = None):
1341
+ def wait_container_is_ready(timeout: float | None = None):
1335
1342
  """Blocks until the localstack main container is running and the ready marker has been printed."""
1336
1343
  container_name = config.MAIN_CONTAINER_NAME
1337
1344
  started = time.time()
@@ -0,0 +1,139 @@
1
+ import logging
2
+ from abc import abstractmethod
3
+
4
+ from plux import Plugin
5
+
6
+ from localstack.services.cloudformation.resource_provider import (
7
+ plugin_manager as cfn_plugin_manager,
8
+ )
9
+ from localstack.utils.catalog.catalog_loader import RemoteCatalogLoader
10
+ from localstack.utils.catalog.common import (
11
+ AwsServiceOperationsSupportInLatest,
12
+ AwsServicesSupportInLatest,
13
+ AwsServiceSupportAtRuntime,
14
+ CloudFormationResourcesSupportAtRuntime,
15
+ CloudFormationResourcesSupportInLatest,
16
+ LocalstackEmulatorType,
17
+ )
18
+
19
+ ServiceName = str
20
+ ServiceOperations = set[str]
21
+ ProviderName = str
22
+ CfnResourceName = str
23
+ CfnResourceMethodName = str
24
+ AwsServicesSupportStatus = (
25
+ AwsServiceSupportAtRuntime | AwsServicesSupportInLatest | AwsServiceOperationsSupportInLatest
26
+ )
27
+ CfnResourceSupportStatus = (
28
+ CloudFormationResourcesSupportInLatest | CloudFormationResourcesSupportAtRuntime
29
+ )
30
+ CfnResourceCatalog = dict[LocalstackEmulatorType, dict[CfnResourceName, set[CfnResourceMethodName]]]
31
+
32
+ LOG = logging.getLogger(__name__)
33
+
34
+
35
+ class CatalogPlugin(Plugin):
36
+ namespace = "localstack.utils.catalog"
37
+
38
+ @staticmethod
39
+ def _get_cfn_resources_catalog(cloudformation_resources: dict) -> CfnResourceCatalog:
40
+ cfn_resources_catalog = {}
41
+ for emulator_type, resources in cloudformation_resources.items():
42
+ cfn_resources_catalog[emulator_type] = {}
43
+ for resource_name, resource in resources.items():
44
+ cfn_resources_catalog[emulator_type][resource_name] = set(resource.methods)
45
+ return cfn_resources_catalog
46
+
47
+ @staticmethod
48
+ def _get_services_at_runtime() -> set[ServiceName]:
49
+ from localstack.services.plugins import SERVICE_PLUGINS
50
+
51
+ return set(SERVICE_PLUGINS.list_available())
52
+
53
+ @staticmethod
54
+ def _get_cfn_resources_available_at_runtime() -> set[CfnResourceName]:
55
+ return set(cfn_plugin_manager.list_names())
56
+
57
+ @abstractmethod
58
+ def get_aws_service_status(
59
+ self, service_name: str, operation_name: str | None = None
60
+ ) -> AwsServicesSupportStatus | None:
61
+ pass
62
+
63
+ @abstractmethod
64
+ def get_cloudformation_resource_status(
65
+ self, resource_name: str, service_name: str, is_pro_resource: bool = False
66
+ ) -> CfnResourceSupportStatus | AwsServicesSupportInLatest | None:
67
+ pass
68
+
69
+
70
+ class AwsCatalogRuntimePlugin(CatalogPlugin):
71
+ name = "aws-catalog-runtime-only"
72
+
73
+ def get_aws_service_status(
74
+ self, service_name: str, operation_name: str | None = None
75
+ ) -> AwsServicesSupportStatus | None:
76
+ return None
77
+
78
+ def get_cloudformation_resource_status(
79
+ self, resource_name: str, service_name: str, is_pro_resource: bool = False
80
+ ) -> CfnResourceSupportStatus | AwsServicesSupportInLatest | None:
81
+ return None
82
+
83
+
84
+ class AwsCatalogRemoteStatePlugin(CatalogPlugin):
85
+ name = "aws-catalog-remote-state"
86
+ current_emulator_type: LocalstackEmulatorType = LocalstackEmulatorType.COMMUNITY
87
+ services_in_latest: dict[ServiceName, dict[LocalstackEmulatorType, ServiceOperations]] = {}
88
+ services_at_runtime: set[ServiceName] = set()
89
+ cfn_resources_in_latest: CfnResourceCatalog = {}
90
+ cfn_resources_at_runtime: set[CfnResourceName] = set()
91
+
92
+ def __init__(self, remote_catalog_loader: RemoteCatalogLoader | None = None) -> None:
93
+ catalog_loader = remote_catalog_loader or RemoteCatalogLoader()
94
+ remote_catalog = catalog_loader.get_remote_catalog()
95
+ for service_name, emulators in remote_catalog.services.items():
96
+ for emulator_type, service_provider in emulators.items():
97
+ self.services_in_latest.setdefault(service_name, {})[emulator_type] = set(
98
+ service_provider.operations
99
+ )
100
+
101
+ self.cfn_resources_in_latest = self._get_cfn_resources_catalog(
102
+ remote_catalog.cloudformation_resources
103
+ )
104
+ self.cfn_resources_at_runtime = self._get_cfn_resources_available_at_runtime()
105
+ self.services_at_runtime = self._get_services_at_runtime()
106
+
107
+ def get_aws_service_status(
108
+ self, service_name: str, operation_name: str | None = None
109
+ ) -> AwsServicesSupportStatus | None:
110
+ if not self.services_in_latest:
111
+ return None
112
+ if service_name not in self.services_in_latest:
113
+ return AwsServicesSupportInLatest.NOT_SUPPORTED
114
+ if self.current_emulator_type not in self.services_in_latest[service_name]:
115
+ return AwsServicesSupportInLatest.SUPPORTED_WITH_LICENSE_UPGRADE
116
+ if not operation_name:
117
+ return AwsServicesSupportInLatest.SUPPORTED
118
+ if operation_name in self.services_in_latest[service_name][self.current_emulator_type]:
119
+ return AwsServiceOperationsSupportInLatest.SUPPORTED
120
+ for emulator_type in self.services_in_latest[service_name]:
121
+ if emulator_type is self.current_emulator_type:
122
+ continue
123
+ if operation_name in self.services_in_latest[service_name][emulator_type]:
124
+ return AwsServiceOperationsSupportInLatest.SUPPORTED_WITH_LICENSE_UPGRADE
125
+ return AwsServiceOperationsSupportInLatest.NOT_SUPPORTED
126
+
127
+ def get_cloudformation_resource_status(
128
+ self, resource_name: str, service_name: str, is_pro_resource: bool = False
129
+ ) -> CfnResourceSupportStatus | AwsServicesSupportInLatest | None:
130
+ if resource_name in self.cfn_resources_at_runtime:
131
+ return CloudFormationResourcesSupportAtRuntime.AVAILABLE
132
+ if service_name in self.services_at_runtime:
133
+ if resource_name in self.cfn_resources_in_latest[self.current_emulator_type]:
134
+ return CloudFormationResourcesSupportInLatest.SUPPORTED
135
+ else:
136
+ return CloudFormationResourcesSupportInLatest.NOT_SUPPORTED
137
+ if service_name in self.services_in_latest:
138
+ return self.get_aws_service_status(service_name, operation_name=None)
139
+ return AwsServicesSupportInLatest.NOT_SUPPORTED
@@ -0,0 +1,119 @@
1
+ import json
2
+ import logging
3
+ from json import JSONDecodeError
4
+ from pathlib import Path
5
+
6
+ import requests
7
+ from pydantic import BaseModel
8
+
9
+ from localstack import config, constants
10
+ from localstack.utils.catalog.common import AwsRemoteCatalog
11
+ from localstack.utils.http import get_proxies
12
+ from localstack.utils.json import FileMappedDocument
13
+
14
+ LOG = logging.getLogger(__name__)
15
+
16
+ AWS_CATALOG_FILE_NAME = "aws_catalog.json"
17
+
18
+
19
+ class RemoteCatalogVersionResponse(BaseModel):
20
+ emulator_type: str
21
+ version: str
22
+
23
+
24
+ class AwsCatalogLoaderException(Exception):
25
+ def __init__(self, msg: str, *args):
26
+ super().__init__(msg, *args)
27
+
28
+
29
+ class RemoteCatalogLoader:
30
+ supported_schema_version = "v1"
31
+ api_endpoint_catalog = f"{constants.API_ENDPOINT}/license/catalog"
32
+ catalog_file_path = Path(config.dirs.cache) / AWS_CATALOG_FILE_NAME
33
+
34
+ def get_remote_catalog(self) -> AwsRemoteCatalog:
35
+ catalog_doc = FileMappedDocument(self.catalog_file_path)
36
+ cached_catalog = AwsRemoteCatalog(**catalog_doc) if catalog_doc else None
37
+ if cached_catalog:
38
+ cached_catalog_version = cached_catalog.localstack.version
39
+ if not self._should_update_cached_catalog(cached_catalog_version):
40
+ return cached_catalog
41
+ catalog = self._get_catalog_from_platform()
42
+ self._save_catalog_to_cache(catalog_doc, catalog)
43
+ return catalog
44
+
45
+ def _get_latest_localstack_version(self) -> str:
46
+ try:
47
+ proxies = get_proxies()
48
+ response = requests.get(
49
+ f"{self.api_endpoint_catalog}/aws/version",
50
+ verify=not config.is_env_true("SSL_NO_VERIFY"),
51
+ proxies=proxies,
52
+ )
53
+ if response.ok:
54
+ return RemoteCatalogVersionResponse.model_validate(response.content).version
55
+ self._raise_server_error(response)
56
+ except requests.exceptions.RequestException as e:
57
+ raise AwsCatalogLoaderException(
58
+ f"An unexpected network error occurred when trying to fetch latest localstack version: {e}"
59
+ ) from e
60
+
61
+ def _should_update_cached_catalog(self, current_catalog_version: str) -> bool:
62
+ try:
63
+ latest_version = self._get_latest_localstack_version()
64
+ return latest_version != current_catalog_version
65
+ except Exception as e:
66
+ LOG.warning(
67
+ "Failed to retrieve the latest catalog version, cached catalog update skipped: %s",
68
+ e,
69
+ )
70
+ return False
71
+
72
+ def _save_catalog_to_cache(self, catalog_doc: FileMappedDocument, catalog: AwsRemoteCatalog):
73
+ catalog_doc.clear()
74
+ catalog_doc.update(catalog.model_dump())
75
+ catalog_doc.save()
76
+
77
+ def _get_catalog_from_platform(self) -> AwsRemoteCatalog:
78
+ try:
79
+ proxies = get_proxies()
80
+ response = requests.post(
81
+ self.api_endpoint_catalog,
82
+ verify=not config.is_env_true("SSL_NO_VERIFY"),
83
+ proxies=proxies,
84
+ )
85
+
86
+ if response.ok:
87
+ return self._parse_catalog(response.content)
88
+ self._raise_server_error(response)
89
+ except requests.exceptions.RequestException as e:
90
+ raise AwsCatalogLoaderException(
91
+ f"An unexpected network error occurred when trying to fetch remote catalog: {e}"
92
+ ) from e
93
+
94
+ def _parse_catalog(self, document: bytes) -> AwsRemoteCatalog | None:
95
+ try:
96
+ catalog_json = json.loads(document)
97
+ except JSONDecodeError as e:
98
+ raise AwsCatalogLoaderException(f"Could not de-serialize json catalog: {e}") from e
99
+ remote_catalog = AwsRemoteCatalog.model_validate(catalog_json)
100
+ if remote_catalog.schema_version != self.supported_schema_version:
101
+ raise AwsCatalogLoaderException(
102
+ f"Unsupported schema version: '{remote_catalog.schema_version}'. Only '{self.supported_schema_version}' is supported"
103
+ )
104
+ return remote_catalog
105
+
106
+ def _raise_server_error(self, response: requests.Response):
107
+ try:
108
+ server_error = response.json()
109
+ if error_message := server_error.get("message"):
110
+ raise AwsCatalogLoaderException(
111
+ f"Unexpected AWS catalog server error: {response.text}"
112
+ )
113
+ raise AwsCatalogLoaderException(
114
+ f"A server error occurred while calling remote catalog API (HTTP {response.status_code}): {error_message}"
115
+ )
116
+ except Exception:
117
+ raise AwsCatalogLoaderException(
118
+ f"An unexpected server error occurred while calling remote catalog API (HTTP {response.status_code}): {response.text}"
119
+ )
@@ -0,0 +1,58 @@
1
+ from enum import StrEnum
2
+
3
+ from pydantic import BaseModel
4
+
5
+
6
+ class CloudFormationResource(BaseModel):
7
+ methods: list[str]
8
+
9
+
10
+ class AwsServiceCatalog(BaseModel):
11
+ provider: str
12
+ operations: list[str]
13
+ plans: list[str]
14
+
15
+
16
+ class LocalStackMetadata(BaseModel):
17
+ version: str
18
+
19
+
20
+ class AwsRemoteCatalog(BaseModel):
21
+ schema_version: str
22
+ localstack: LocalStackMetadata
23
+ services: dict[str, dict[str, AwsServiceCatalog]]
24
+ cloudformation_resources: dict[str, dict[str, CloudFormationResource]]
25
+
26
+
27
+ class LocalstackEmulatorType(StrEnum):
28
+ COMMUNITY = "community"
29
+ PRO = "pro"
30
+
31
+
32
+ class AwsServiceSupportAtRuntime(StrEnum):
33
+ AVAILABLE = "AVAILABLE"
34
+ AVAILABLE_WITH_LICENSE_UPGRADE = "AVAILABLE_WITH_LICENSE_UPGRADE"
35
+ NOT_IMPLEMENTED = "NOT_IMPLEMENTED"
36
+
37
+
38
+ class AwsServicesSupportInLatest(StrEnum):
39
+ SUPPORTED = "SUPPORTED"
40
+ SUPPORTED_WITH_LICENSE_UPGRADE = "SUPPORTED_WITH_LICENSE_UPGRADE"
41
+ NOT_SUPPORTED = "NOT_SUPPORTED"
42
+ NON_DEFAULT_PROVIDER = "NON_DEFAULT_PROVIDER"
43
+
44
+
45
+ class AwsServiceOperationsSupportInLatest(StrEnum):
46
+ SUPPORTED = "SUPPORTED"
47
+ SUPPORTED_WITH_LICENSE_UPGRADE = "SUPPORTED_WITH_LICENSE_UPGRADE"
48
+ NOT_SUPPORTED = "NOT_SUPPORTED"
49
+
50
+
51
+ class CloudFormationResourcesSupportInLatest(StrEnum):
52
+ SUPPORTED = "SUPPORTED"
53
+ NOT_SUPPORTED = "NOT_SUPPORTED"
54
+
55
+
56
+ class CloudFormationResourcesSupportAtRuntime(StrEnum):
57
+ AVAILABLE = "AVAILABLE"
58
+ NOT_IMPLEMENTED = "NOT_IMPLEMENTED"
@@ -0,0 +1,28 @@
1
+ import logging
2
+
3
+ from plux import PluginManager
4
+
5
+ from localstack.utils.catalog.catalog import CatalogPlugin
6
+ from localstack.utils.objects import singleton_factory
7
+
8
+ LOG = logging.getLogger(__name__)
9
+
10
+
11
+ @singleton_factory
12
+ def get_aws_catalog() -> CatalogPlugin:
13
+ plugin_manager = PluginManager(CatalogPlugin.namespace)
14
+ try:
15
+ plugin_name = "aws-catalog-remote-state-with-license"
16
+ if not plugin_manager.exists(plugin_name):
17
+ plugin_name = "aws-catalog-remote-state"
18
+ return plugin_manager.load(plugin_name)
19
+ except Exception as e:
20
+ LOG.debug(
21
+ "Failed to load catalog plugin with the latest LocalStack services support data, falling back to catalog without remote state: %s",
22
+ e,
23
+ )
24
+ # Try to load runtime catalog from pro version first
25
+ fallback_plugin_name = "aws-catalog-runtime-only-with-license"
26
+ if not plugin_manager.exists(fallback_plugin_name):
27
+ fallback_plugin_name = "aws-catalog-runtime-only"
28
+ return plugin_manager.load(fallback_plugin_name)
@@ -2,7 +2,7 @@ import logging
2
2
  import time
3
3
  from datetime import datetime, timezone
4
4
  from itertools import islice
5
- from typing import Optional, TypedDict
5
+ from typing import TypedDict
6
6
 
7
7
  from werkzeug import Response as WerkzeugResponse
8
8
 
@@ -20,8 +20,8 @@ LOG = logging.getLogger(__name__)
20
20
  class SqsMetricBatchData(TypedDict, total=False):
21
21
  MetricName: str
22
22
  QueueName: str
23
- Value: Optional[int]
24
- Unit: Optional[str]
23
+ Value: int | None
24
+ Unit: str | None
25
25
 
26
26
 
27
27
  def dimension_lambda(kwargs):
@@ -30,7 +30,7 @@ def dimension_lambda(kwargs):
30
30
 
31
31
 
32
32
  def publish_lambda_metric(
33
- metric, value, kwargs, account_id: Optional[str] = None, region_name: Optional[str] = None
33
+ metric, value, kwargs, account_id: str | None = None, region_name: str | None = None
34
34
  ):
35
35
  # publish metric only if CloudWatch service is available
36
36
  if not is_api_enabled("cloudwatch"):
@@ -155,7 +155,7 @@ def store_cloudwatch_logs(
155
155
  log_stream_name,
156
156
  log_output,
157
157
  start_time=None,
158
- auto_create_group: Optional[bool] = True,
158
+ auto_create_group: bool | None = True,
159
159
  ):
160
160
  if not is_api_enabled("logs"):
161
161
  return