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.
- localstack/aws/api/apigateway/__init__.py +87 -110
- localstack/aws/api/cloudformation/__init__.py +18 -4
- localstack/aws/api/cloudwatch/__init__.py +41 -1
- localstack/aws/api/config/__init__.py +4 -0
- localstack/aws/api/core.py +8 -5
- localstack/aws/api/dynamodb/__init__.py +30 -0
- localstack/aws/api/ec2/__init__.py +1545 -66
- localstack/aws/api/events/__init__.py +12 -16
- localstack/aws/api/iam/__init__.py +7 -0
- localstack/aws/api/kinesis/__init__.py +19 -0
- localstack/aws/api/kms/__init__.py +6 -0
- localstack/aws/api/lambda_/__init__.py +36 -23
- localstack/aws/api/logs/__init__.py +20 -8
- localstack/aws/api/opensearch/__init__.py +16 -0
- localstack/aws/api/pipes/__init__.py +24 -32
- localstack/aws/api/redshift/__init__.py +9 -3
- localstack/aws/api/route53/__init__.py +5 -0
- localstack/aws/api/s3/__init__.py +12 -0
- localstack/aws/api/s3control/__init__.py +56 -0
- localstack/aws/api/scheduler/__init__.py +14 -16
- localstack/aws/api/ssm/__init__.py +2 -0
- localstack/aws/api/stepfunctions/__init__.py +88 -114
- localstack/aws/api/support/__init__.py +8 -9
- localstack/aws/api/transcribe/__init__.py +17 -0
- localstack/aws/chain.py +2 -2
- localstack/aws/client.py +14 -11
- localstack/aws/connect.py +42 -41
- localstack/aws/forwarder.py +57 -9
- localstack/aws/gateway.py +1 -3
- localstack/aws/handlers/analytics.py +2 -3
- localstack/aws/handlers/cors.py +4 -5
- localstack/aws/handlers/internal_requests.py +6 -1
- localstack/aws/handlers/logging.py +13 -4
- localstack/aws/handlers/metric_handler.py +44 -5
- localstack/aws/handlers/service.py +48 -28
- localstack/aws/mocking.py +18 -27
- localstack/aws/patches.py +2 -2
- localstack/aws/protocol/op_router.py +11 -10
- localstack/aws/protocol/parser.py +475 -49
- localstack/aws/protocol/serializer.py +723 -106
- localstack/aws/protocol/service_router.py +133 -33
- localstack/aws/protocol/validate.py +6 -6
- localstack/aws/scaffold.py +9 -10
- localstack/aws/serving/edge.py +5 -6
- localstack/aws/serving/hypercorn.py +2 -2
- localstack/aws/serving/twisted.py +1 -2
- localstack/aws/serving/werkzeug.py +2 -2
- localstack/aws/skeleton.py +12 -11
- localstack/aws/spec-patches.json +58 -0
- localstack/aws/spec.py +66 -46
- localstack/cli/exceptions.py +1 -1
- localstack/cli/localstack.py +11 -11
- localstack/cli/lpm.py +4 -5
- localstack/cli/plugins.py +1 -1
- localstack/cli/profiles.py +1 -2
- localstack/config.py +44 -30
- localstack/constants.py +4 -29
- localstack/deprecations.py +5 -5
- localstack/dev/kubernetes/__main__.py +130 -7
- localstack/dev/run/__main__.py +5 -5
- localstack/dev/run/configurators.py +1 -4
- localstack/dev/run/paths.py +6 -6
- localstack/dns/models.py +2 -1
- localstack/dns/plugins.py +5 -1
- localstack/dns/server.py +16 -6
- localstack/http/dispatcher.py +1 -2
- localstack/http/response.py +2 -2
- localstack/http/router.py +1 -1
- localstack/http/trace.py +2 -1
- localstack/logging/format.py +6 -6
- localstack/packages/api.py +13 -12
- localstack/packages/core.py +4 -4
- localstack/packages/debugpy.py +1 -3
- localstack/packages/ffmpeg.py +1 -2
- localstack/packages/java.py +38 -12
- localstack/packages/plugins.py +0 -8
- localstack/runtime/analytics.py +3 -0
- localstack/runtime/hooks.py +1 -1
- localstack/runtime/init.py +8 -9
- localstack/runtime/main.py +5 -5
- localstack/runtime/patches.py +2 -2
- localstack/runtime/shutdown.py +2 -1
- localstack/services/apigateway/exporter.py +1 -2
- localstack/services/apigateway/helpers.py +7 -10
- localstack/services/apigateway/legacy/context.py +21 -21
- localstack/services/apigateway/legacy/helpers.py +27 -28
- localstack/services/apigateway/legacy/integration.py +11 -10
- localstack/services/apigateway/legacy/invocations.py +6 -5
- localstack/services/apigateway/legacy/provider.py +148 -68
- localstack/services/apigateway/legacy/router_asf.py +2 -2
- localstack/services/apigateway/legacy/templates.py +6 -6
- localstack/services/apigateway/models.py +16 -16
- localstack/services/apigateway/next_gen/execute_api/api.py +2 -2
- localstack/services/apigateway/next_gen/execute_api/context.py +25 -25
- localstack/services/apigateway/next_gen/execute_api/handlers/api_key_validation.py +2 -5
- localstack/services/apigateway/next_gen/execute_api/handlers/method_request.py +7 -2
- localstack/services/apigateway/next_gen/execute_api/handlers/parse.py +1 -2
- localstack/services/apigateway/next_gen/execute_api/handlers/resource_router.py +2 -3
- localstack/services/apigateway/next_gen/execute_api/header_utils.py +1 -1
- localstack/services/apigateway/next_gen/execute_api/helpers.py +2 -2
- localstack/services/apigateway/next_gen/execute_api/integrations/aws.py +9 -6
- localstack/services/apigateway/next_gen/execute_api/integrations/http.py +12 -12
- localstack/services/apigateway/next_gen/execute_api/router.py +31 -0
- localstack/services/apigateway/next_gen/execute_api/template_mapping.py +2 -2
- localstack/services/apigateway/next_gen/execute_api/test_invoke.py +114 -9
- localstack/services/apigateway/next_gen/execute_api/variables.py +63 -63
- localstack/services/apigateway/next_gen/provider.py +5 -0
- localstack/services/apigateway/resource_providers/aws_apigateway_account.py +3 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_account_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_apikey.py +14 -14
- localstack/services/apigateway/resource_providers/aws_apigateway_apikey_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_basepathmapping.py +5 -5
- localstack/services/apigateway/resource_providers/aws_apigateway_basepathmapping_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_deployment.py +46 -46
- localstack/services/apigateway/resource_providers/aws_apigateway_deployment_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_domainname.py +18 -18
- localstack/services/apigateway/resource_providers/aws_apigateway_domainname_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_gatewayresponse.py +7 -7
- localstack/services/apigateway/resource_providers/aws_apigateway_gatewayresponse_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_method.py +36 -36
- localstack/services/apigateway/resource_providers/aws_apigateway_method_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_model.py +6 -6
- localstack/services/apigateway/resource_providers/aws_apigateway_model_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_requestvalidator.py +6 -6
- localstack/services/apigateway/resource_providers/aws_apigateway_requestvalidator_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_resource.py +6 -6
- localstack/services/apigateway/resource_providers/aws_apigateway_resource_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_restapi.py +26 -26
- localstack/services/apigateway/resource_providers/aws_apigateway_restapi_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_stage.py +33 -33
- localstack/services/apigateway/resource_providers/aws_apigateway_stage_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_usageplan.py +18 -18
- localstack/services/apigateway/resource_providers/aws_apigateway_usageplan_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_usageplankey.py +5 -5
- localstack/services/apigateway/resource_providers/aws_apigateway_usageplankey_plugin.py +1 -3
- localstack/services/cdk/resource_providers/cdk_metadata.py +4 -3
- localstack/services/cdk/resource_providers/cdk_metadata_plugin.py +1 -3
- localstack/services/certificatemanager/resource_providers/aws_certificatemanager_certificate.py +14 -14
- localstack/services/certificatemanager/resource_providers/aws_certificatemanager_certificate_plugin.py +1 -3
- localstack/services/cloudformation/api_utils.py +4 -8
- localstack/services/cloudformation/cfn_utils.py +2 -2
- localstack/services/cloudformation/deployment_utils.py +14 -12
- localstack/services/cloudformation/engine/changes.py +3 -3
- localstack/services/cloudformation/engine/entities.py +27 -17
- localstack/services/cloudformation/engine/parameters.py +4 -4
- localstack/services/cloudformation/engine/template_deployer.py +15 -14
- localstack/services/cloudformation/engine/template_utils.py +34 -12
- localstack/services/cloudformation/engine/transformers.py +11 -8
- localstack/services/cloudformation/engine/types.py +5 -4
- localstack/services/cloudformation/engine/v2/change_set_model.py +336 -39
- localstack/services/cloudformation/engine/v2/change_set_model_describer.py +96 -17
- localstack/services/cloudformation/engine/v2/change_set_model_executor.py +289 -136
- localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +315 -146
- localstack/services/cloudformation/engine/v2/change_set_model_transform.py +380 -105
- localstack/services/cloudformation/engine/v2/change_set_model_validator.py +183 -0
- localstack/services/cloudformation/engine/v2/change_set_model_visitor.py +6 -0
- localstack/services/cloudformation/engine/v2/resolving.py +102 -0
- localstack/services/cloudformation/engine/yaml_parser.py +9 -2
- localstack/services/cloudformation/provider.py +11 -6
- localstack/services/cloudformation/provider_utils.py +34 -4
- localstack/services/cloudformation/resource_provider.py +31 -21
- localstack/services/cloudformation/resource_providers/aws_cloudformation_macro.py +7 -7
- localstack/services/cloudformation/resource_providers/aws_cloudformation_macro_plugin.py +1 -3
- localstack/services/cloudformation/resource_providers/aws_cloudformation_stack.py +9 -9
- localstack/services/cloudformation/resource_providers/aws_cloudformation_stack_plugin.py +1 -3
- localstack/services/cloudformation/resource_providers/aws_cloudformation_waitcondition.py +6 -6
- localstack/services/cloudformation/resource_providers/aws_cloudformation_waitcondition_plugin.py +1 -3
- localstack/services/cloudformation/resource_providers/aws_cloudformation_waitconditionhandle.py +2 -2
- localstack/services/cloudformation/resource_providers/aws_cloudformation_waitconditionhandle_plugin.py +1 -3
- localstack/services/cloudformation/resources.py +24149 -0
- localstack/services/cloudformation/scaffolding/__main__.py +13 -12
- localstack/services/cloudformation/scaffolding/propgen.py +2 -2
- localstack/services/cloudformation/service_models.py +2 -2
- localstack/services/cloudformation/stores.py +33 -22
- localstack/services/cloudformation/v2/entities.py +103 -88
- localstack/services/cloudformation/v2/provider.py +872 -131
- localstack/services/cloudformation/v2/types.py +38 -0
- localstack/services/cloudformation/v2/utils.py +4 -1
- localstack/services/cloudwatch/alarm_scheduler.py +11 -8
- localstack/services/cloudwatch/cloudwatch_database_helper.py +4 -5
- localstack/services/cloudwatch/models.py +5 -7
- localstack/services/cloudwatch/provider.py +30 -25
- localstack/services/cloudwatch/provider_v2.py +27 -32
- localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm.py +40 -40
- localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm_plugin.py +1 -3
- localstack/services/cloudwatch/resource_providers/aws_cloudwatch_compositealarm.py +12 -12
- localstack/services/cloudwatch/resource_providers/aws_cloudwatch_compositealarm_plugin.py +1 -3
- localstack/services/dynamodb/packages.py +3 -3
- localstack/services/dynamodb/provider.py +159 -18
- localstack/services/dynamodb/resource_providers/aws_dynamodb_globaltable.py +63 -63
- localstack/services/dynamodb/resource_providers/aws_dynamodb_globaltable_plugin.py +1 -3
- localstack/services/dynamodb/resource_providers/aws_dynamodb_table.py +57 -57
- localstack/services/dynamodb/resource_providers/aws_dynamodb_table_plugin.py +1 -3
- localstack/services/dynamodb/server.py +2 -2
- localstack/services/dynamodb/utils.py +13 -14
- localstack/services/dynamodb/v2/provider.py +157 -18
- localstack/services/dynamodbstreams/dynamodbstreams_api.py +2 -2
- localstack/services/dynamodbstreams/models.py +1 -3
- localstack/services/ec2/patches.py +26 -5
- localstack/services/ec2/provider.py +3 -3
- localstack/services/ec2/resource_providers/aws_ec2_dhcpoptions.py +10 -10
- localstack/services/ec2/resource_providers/aws_ec2_dhcpoptions_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_instance.py +96 -96
- localstack/services/ec2/resource_providers/aws_ec2_instance_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_internetgateway.py +5 -5
- localstack/services/ec2/resource_providers/aws_ec2_internetgateway_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_keypair.py +10 -10
- localstack/services/ec2/resource_providers/aws_ec2_keypair_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_natgateway.py +13 -13
- localstack/services/ec2/resource_providers/aws_ec2_natgateway_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_networkacl.py +6 -6
- localstack/services/ec2/resource_providers/aws_ec2_networkacl_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_prefixlist.py +14 -14
- localstack/services/ec2/resource_providers/aws_ec2_prefixlist_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_route.py +15 -15
- localstack/services/ec2/resource_providers/aws_ec2_route_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_routetable.py +6 -6
- localstack/services/ec2/resource_providers/aws_ec2_routetable_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_securitygroup.py +29 -29
- localstack/services/ec2/resource_providers/aws_ec2_securitygroup_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_subnet.py +19 -19
- localstack/services/ec2/resource_providers/aws_ec2_subnet_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_subnetroutetableassociation.py +4 -4
- localstack/services/ec2/resource_providers/aws_ec2_subnetroutetableassociation_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_transitgateway.py +16 -16
- localstack/services/ec2/resource_providers/aws_ec2_transitgateway_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_transitgatewayattachment.py +9 -9
- localstack/services/ec2/resource_providers/aws_ec2_transitgatewayattachment_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_vpc.py +15 -15
- localstack/services/ec2/resource_providers/aws_ec2_vpc_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_vpcendpoint.py +29 -22
- localstack/services/ec2/resource_providers/aws_ec2_vpcendpoint_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_vpcgatewayattachment.py +5 -5
- localstack/services/ec2/resource_providers/aws_ec2_vpcgatewayattachment_plugin.py +1 -3
- localstack/services/ecr/resource_providers/aws_ecr_repository.py +22 -19
- localstack/services/ecr/resource_providers/aws_ecr_repository_plugin.py +1 -3
- localstack/services/edge.py +6 -6
- localstack/services/es/provider.py +21 -21
- localstack/services/events/archive.py +2 -2
- localstack/services/events/connection.py +5 -5
- localstack/services/events/event_bus.py +9 -9
- localstack/services/events/event_rule_engine.py +31 -13
- localstack/services/events/models.py +29 -30
- localstack/services/events/provider.py +29 -26
- localstack/services/events/replay.py +3 -3
- localstack/services/events/resource_providers/aws_events_apidestination.py +8 -8
- localstack/services/events/resource_providers/aws_events_apidestination_plugin.py +1 -3
- localstack/services/events/resource_providers/aws_events_connection.py +27 -27
- localstack/services/events/resource_providers/aws_events_connection_plugin.py +1 -3
- localstack/services/events/resource_providers/aws_events_eventbus.py +9 -9
- localstack/services/events/resource_providers/aws_events_eventbus_plugin.py +1 -3
- localstack/services/events/resource_providers/aws_events_eventbuspolicy.py +11 -11
- localstack/services/events/resource_providers/aws_events_eventbuspolicy_plugin.py +1 -3
- localstack/services/events/resource_providers/aws_events_rule.py +82 -82
- localstack/services/events/resource_providers/aws_events_rule_plugin.py +1 -3
- localstack/services/events/rule.py +15 -15
- localstack/services/events/target.py +21 -13
- localstack/services/events/utils.py +7 -7
- localstack/services/events/v1/models.py +1 -3
- localstack/services/events/v1/provider.py +15 -15
- localstack/services/firehose/models.py +1 -3
- localstack/services/firehose/provider.py +25 -16
- localstack/services/iam/iam_patches.py +5 -6
- localstack/services/iam/provider.py +14 -119
- localstack/services/iam/resource_providers/aws_iam_accesskey.py +6 -6
- localstack/services/iam/resource_providers/aws_iam_accesskey_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_group.py +9 -9
- localstack/services/iam/resource_providers/aws_iam_group_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_instanceprofile.py +5 -5
- localstack/services/iam/resource_providers/aws_iam_instanceprofile_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_managedpolicy.py +9 -9
- localstack/services/iam/resource_providers/aws_iam_managedpolicy_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_policy.py +7 -7
- localstack/services/iam/resource_providers/aws_iam_policy_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_role.py +16 -16
- localstack/services/iam/resource_providers/aws_iam_role_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_servercertificate.py +10 -10
- localstack/services/iam/resource_providers/aws_iam_servercertificate_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_servicelinkedrole.py +5 -5
- localstack/services/iam/resource_providers/aws_iam_servicelinkedrole_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_user.py +17 -17
- localstack/services/iam/resource_providers/aws_iam_user_plugin.py +1 -3
- localstack/services/iam/resources/policy_simulator.py +133 -0
- localstack/services/kinesis/kinesis_mock_server.py +7 -8
- localstack/services/kinesis/models.py +17 -5
- localstack/services/kinesis/packages.py +3 -3
- localstack/services/kinesis/provider.py +86 -3
- localstack/services/kinesis/resource_providers/aws_kinesis_stream.py +13 -13
- localstack/services/kinesis/resource_providers/aws_kinesis_stream_plugin.py +1 -3
- localstack/services/kinesis/resource_providers/aws_kinesis_streamconsumer.py +7 -7
- localstack/services/kinesis/resource_providers/aws_kinesis_streamconsumer_plugin.py +1 -3
- localstack/services/kinesisfirehose/resource_providers/aws_kinesisfirehose_deliverystream.py +191 -191
- localstack/services/kinesisfirehose/resource_providers/aws_kinesisfirehose_deliverystream_plugin.py +1 -3
- localstack/services/kms/models.py +21 -18
- localstack/services/kms/provider.py +62 -26
- localstack/services/kms/resource_providers/aws_kms_alias.py +3 -3
- localstack/services/kms/resource_providers/aws_kms_alias_plugin.py +1 -3
- localstack/services/kms/resource_providers/aws_kms_key.py +14 -14
- localstack/services/kms/resource_providers/aws_kms_key_plugin.py +1 -3
- localstack/services/kms/utils.py +4 -3
- localstack/services/lambda_/api_utils.py +19 -16
- localstack/services/lambda_/custom_endpoints.py +2 -2
- localstack/services/lambda_/event_source_mapping/esm_worker_factory.py +4 -7
- localstack/services/lambda_/event_source_mapping/pipe_utils.py +2 -2
- localstack/services/lambda_/event_source_mapping/pollers/stream_poller.py +1 -1
- localstack/services/lambda_/event_source_mapping/senders/sender_utils.py +2 -1
- localstack/services/lambda_/hooks.py +6 -1
- localstack/services/lambda_/invocation/assignment.py +1 -2
- localstack/services/lambda_/invocation/docker_runtime_executor.py +7 -11
- localstack/services/lambda_/invocation/event_manager.py +1 -1
- localstack/services/lambda_/invocation/execution_environment.py +4 -4
- localstack/services/lambda_/invocation/executor_endpoint.py +8 -11
- localstack/services/lambda_/invocation/internal_sqs_queue.py +6 -10
- localstack/services/lambda_/invocation/lambda_models.py +33 -30
- localstack/services/lambda_/invocation/lambda_service.py +12 -5
- localstack/services/lambda_/invocation/logs.py +2 -3
- localstack/services/lambda_/invocation/runtime_executor.py +3 -3
- localstack/services/lambda_/invocation/version_manager.py +31 -8
- localstack/services/lambda_/ldm.py +14 -0
- localstack/services/lambda_/packages.py +3 -4
- localstack/services/lambda_/provider.py +9 -26
- localstack/services/lambda_/provider_utils.py +1 -1
- localstack/services/lambda_/resource_providers/aws_lambda_codesigningconfig.py +8 -8
- localstack/services/lambda_/resource_providers/aws_lambda_codesigningconfig_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_eventinvokeconfig.py +11 -11
- localstack/services/lambda_/resource_providers/aws_lambda_eventinvokeconfig_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_eventsourcemapping.py +39 -39
- localstack/services/lambda_/resource_providers/aws_lambda_eventsourcemapping_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_function.py +54 -54
- localstack/services/lambda_/resource_providers/aws_lambda_function_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_layerversion.py +11 -11
- localstack/services/lambda_/resource_providers/aws_lambda_layerversion_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_layerversionpermission.py +6 -6
- localstack/services/lambda_/resource_providers/aws_lambda_layerversionpermission_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_permission.py +10 -10
- localstack/services/lambda_/resource_providers/aws_lambda_permission_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_url.py +15 -15
- localstack/services/lambda_/resource_providers/aws_lambda_url_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_version.py +8 -8
- localstack/services/lambda_/resource_providers/aws_lambda_version_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/lambda_alias.py +12 -12
- localstack/services/lambda_/resource_providers/lambda_alias_plugin.py +1 -3
- localstack/services/lambda_/runtimes.py +1 -3
- localstack/services/lambda_/urlrouter.py +14 -1
- localstack/services/logs/models.py +1 -3
- localstack/services/logs/provider.py +39 -22
- localstack/services/logs/resource_providers/aws_logs_loggroup.py +9 -9
- localstack/services/logs/resource_providers/aws_logs_loggroup_plugin.py +1 -3
- localstack/services/logs/resource_providers/aws_logs_logstream.py +4 -4
- localstack/services/logs/resource_providers/aws_logs_logstream_plugin.py +1 -3
- localstack/services/logs/resource_providers/aws_logs_subscriptionfilter.py +7 -7
- localstack/services/logs/resource_providers/aws_logs_subscriptionfilter_plugin.py +1 -3
- localstack/services/moto.py +5 -4
- localstack/services/opensearch/cluster.py +28 -20
- localstack/services/opensearch/cluster_manager.py +13 -14
- localstack/services/opensearch/models.py +1 -3
- localstack/services/opensearch/packages.py +27 -9
- localstack/services/opensearch/provider.py +15 -10
- localstack/services/opensearch/resource_providers/aws_elasticsearch_domain.py +61 -61
- localstack/services/opensearch/resource_providers/aws_elasticsearch_domain_plugin.py +1 -3
- localstack/services/opensearch/resource_providers/aws_opensearchservice_domain.py +89 -89
- localstack/services/opensearch/resource_providers/aws_opensearchservice_domain_plugin.py +1 -3
- localstack/services/opensearch/versions.py +57 -10
- localstack/services/plugins.py +37 -32
- localstack/services/providers.py +10 -2
- localstack/services/redshift/provider.py +0 -21
- localstack/services/redshift/resource_providers/aws_redshift_cluster.py +57 -57
- localstack/services/redshift/resource_providers/aws_redshift_cluster_plugin.py +1 -3
- localstack/services/resource_groups/resource_providers/aws_resourcegroups_group.py +21 -21
- localstack/services/resource_groups/resource_providers/aws_resourcegroups_group_plugin.py +1 -3
- localstack/services/route53/models.py +1 -3
- localstack/services/route53/provider.py +1 -2
- localstack/services/route53/resource_providers/aws_route53_healthcheck.py +6 -6
- localstack/services/route53/resource_providers/aws_route53_healthcheck_plugin.py +1 -3
- localstack/services/route53/resource_providers/aws_route53_recordset.py +27 -27
- localstack/services/route53/resource_providers/aws_route53_recordset_plugin.py +1 -3
- localstack/services/route53resolver/models.py +8 -10
- localstack/services/route53resolver/provider.py +12 -12
- localstack/services/s3/codec.py +2 -2
- localstack/services/s3/constants.py +5 -2
- localstack/services/s3/cors.py +8 -8
- localstack/services/s3/models.py +73 -73
- localstack/services/s3/notifications.py +74 -58
- localstack/services/s3/presigned_url.py +41 -59
- localstack/services/s3/provider.py +86 -29
- localstack/services/s3/resource_providers/aws_s3_bucket.py +180 -180
- localstack/services/s3/resource_providers/aws_s3_bucket_plugin.py +1 -3
- localstack/services/s3/resource_providers/aws_s3_bucketpolicy.py +4 -4
- localstack/services/s3/resource_providers/aws_s3_bucketpolicy_plugin.py +1 -3
- localstack/services/s3/storage/core.py +4 -3
- localstack/services/s3/storage/ephemeral.py +7 -6
- localstack/services/s3/utils.py +51 -31
- localstack/services/s3/validation.py +47 -33
- localstack/services/s3/website_hosting.py +9 -7
- localstack/services/scheduler/resource_providers/aws_scheduler_schedule.py +60 -60
- localstack/services/scheduler/resource_providers/aws_scheduler_schedule_plugin.py +1 -3
- localstack/services/scheduler/resource_providers/aws_scheduler_schedulegroup.py +9 -9
- localstack/services/scheduler/resource_providers/aws_scheduler_schedulegroup_plugin.py +1 -3
- localstack/services/secretsmanager/provider.py +10 -12
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_resourcepolicy.py +5 -5
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_resourcepolicy_plugin.py +1 -3
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_rotationschedule.py +21 -21
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_rotationschedule_plugin.py +1 -3
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secret.py +23 -23
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secret_plugin.py +1 -3
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secrettargetattachment.py +5 -5
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secrettargetattachment_plugin.py +1 -3
- localstack/services/ses/models.py +8 -1
- localstack/services/ses/provider.py +128 -55
- localstack/services/ses/resource_providers/aws_ses_emailidentity.py +21 -21
- localstack/services/ses/resource_providers/aws_ses_emailidentity_plugin.py +1 -3
- localstack/services/sns/constants.py +7 -1
- localstack/services/sns/executor.py +9 -2
- localstack/services/sns/models.py +25 -25
- localstack/services/sns/provider.py +9 -7
- localstack/services/sns/publisher.py +37 -23
- localstack/services/sns/resource_providers/aws_sns_subscription.py +13 -13
- localstack/services/sns/resource_providers/aws_sns_subscription_plugin.py +1 -3
- localstack/services/sns/resource_providers/aws_sns_topic.py +16 -16
- localstack/services/sns/resource_providers/aws_sns_topic_plugin.py +1 -3
- localstack/services/sns/resource_providers/aws_sns_topicpolicy.py +4 -4
- localstack/services/sns/resource_providers/aws_sns_topicpolicy_plugin.py +1 -3
- localstack/services/sns/v2/models.py +167 -0
- localstack/services/sns/v2/provider.py +867 -0
- localstack/services/sns/v2/utils.py +130 -0
- localstack/services/sqs/constants.py +2 -2
- localstack/services/sqs/developer_api.py +205 -0
- localstack/services/sqs/models.py +71 -36
- localstack/services/sqs/provider.py +56 -332
- localstack/services/sqs/query_api.py +8 -5
- localstack/services/sqs/resource_providers/aws_sqs_queue.py +21 -21
- localstack/services/sqs/resource_providers/aws_sqs_queue_plugin.py +1 -3
- localstack/services/sqs/resource_providers/aws_sqs_queuepolicy.py +7 -5
- localstack/services/sqs/resource_providers/aws_sqs_queuepolicy_plugin.py +1 -3
- localstack/services/sqs/utils.py +123 -4
- localstack/services/ssm/provider.py +3 -4
- localstack/services/ssm/resource_providers/aws_ssm_maintenancewindow.py +15 -15
- localstack/services/ssm/resource_providers/aws_ssm_maintenancewindow_plugin.py +1 -3
- localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtarget.py +10 -10
- localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtarget_plugin.py +1 -3
- localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtask.py +48 -48
- localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtask_plugin.py +1 -3
- localstack/services/ssm/resource_providers/aws_ssm_parameter.py +10 -10
- localstack/services/ssm/resource_providers/aws_ssm_parameter_plugin.py +1 -3
- localstack/services/ssm/resource_providers/aws_ssm_patchbaseline.py +29 -29
- localstack/services/ssm/resource_providers/aws_ssm_patchbaseline_plugin.py +1 -3
- localstack/services/stepfunctions/asl/antlt4utils/antlr4utils.py +3 -4
- localstack/services/stepfunctions/asl/component/common/assign/assign_decl.py +1 -1
- localstack/services/stepfunctions/asl/component/common/assign/assign_decl_binding.py +1 -1
- localstack/services/stepfunctions/asl/component/common/assign/assign_template_value_array.py +1 -1
- localstack/services/stepfunctions/asl/component/common/assign/assign_template_value_object.py +1 -1
- localstack/services/stepfunctions/asl/component/common/catch/catcher_decl.py +9 -9
- localstack/services/stepfunctions/asl/component/common/error_name/custom_error_name.py +2 -2
- localstack/services/stepfunctions/asl/component/common/error_name/error_name.py +4 -4
- localstack/services/stepfunctions/asl/component/common/error_name/failure_event.py +8 -8
- localstack/services/stepfunctions/asl/component/common/error_name/states_error_name_type.py +1 -1
- localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_binding.py +2 -2
- localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_value_array.py +1 -1
- localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_value_object.py +1 -1
- localstack/services/stepfunctions/asl/component/common/path/input_path.py +4 -4
- localstack/services/stepfunctions/asl/component/common/path/output_path.py +4 -4
- localstack/services/stepfunctions/asl/component/common/path/result_path.py +3 -3
- localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadarr/payload_arr.py +1 -1
- localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding.py +3 -3
- localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadtmpl/payload_tmpl.py +1 -1
- localstack/services/stepfunctions/asl/component/common/retry/retrier_decl.py +8 -8
- localstack/services/stepfunctions/asl/component/common/string/string_expression.py +3 -3
- localstack/services/stepfunctions/asl/component/common/timeouts/timeout.py +3 -3
- localstack/services/stepfunctions/asl/component/eval_component.py +2 -3
- localstack/services/stepfunctions/asl/component/intrinsic/argument/argument.py +4 -4
- localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/array/array_partition.py +1 -1
- localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/generic/string_format.py +1 -1
- localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/states_function_array.py +1 -1
- localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/states_function_format.py +1 -1
- localstack/services/stepfunctions/asl/component/intrinsic/jsonata.py +3 -3
- localstack/services/stepfunctions/asl/component/intrinsic/member.py +1 -1
- localstack/services/stepfunctions/asl/component/program/program.py +9 -9
- localstack/services/stepfunctions/asl/component/program/states.py +1 -1
- localstack/services/stepfunctions/asl/component/state/state.py +10 -11
- localstack/services/stepfunctions/asl/component/state/state_choice/choice_rule.py +11 -11
- localstack/services/stepfunctions/asl/component/state/state_choice/comparison/comparison.py +5 -11
- localstack/services/stepfunctions/asl/component/state/state_choice/comparison/operator/implementations/is_operator.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_choice/state_choice.py +3 -5
- localstack/services/stepfunctions/asl/component/state/state_execution/execute_state.py +9 -9
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/item_reader_decl.py +7 -7
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/reader_config/reader_config_decl.py +5 -5
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/resource_eval/resource_eval_s3.py +2 -1
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/resource_eval/resource_output_transformer/resource_output_transformer_csv.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/distributed_iteration_component.py +8 -8
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/inline_iteration_component.py +7 -7
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/distributed_item_processor_worker.py +4 -4
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/inline_item_processor_worker.py +5 -5
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/map_run_record.py +10 -10
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_component.py +3 -3
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_declaration.py +3 -3
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_worker.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/distributed_iterator_worker.py +3 -5
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/inline_iterator.py +1 -2
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/inline_iterator_worker.py +5 -5
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/job.py +9 -9
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/result_writer/resource_eval/resource_eval_s3.py +2 -1
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/state_map.py +12 -13
- localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/branch_worker.py +3 -3
- localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/branches_decl.py +7 -7
- localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/state_parallel.py +2 -3
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/lambda_eval_utils.py +7 -7
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/resource.py +3 -3
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service.py +10 -10
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_api_gateway.py +18 -18
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_aws_sdk.py +1 -1
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_batch.py +8 -7
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_callback.py +18 -17
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_dynamodb.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_ecs.py +5 -4
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_events.py +4 -4
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_glue.py +7 -6
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_lambda.py +4 -4
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sfn.py +9 -8
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sns.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sqs.py +4 -4
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/state_task.py +5 -5
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/state_task_lambda.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_fail/state_fail.py +3 -5
- localstack/services/stepfunctions/asl/component/state/state_pass/state_pass.py +5 -7
- localstack/services/stepfunctions/asl/component/state/state_succeed/state_succeed.py +1 -1
- localstack/services/stepfunctions/asl/component/state/state_wait/state_wait.py +1 -1
- localstack/services/stepfunctions/asl/component/state/state_wait/wait_function/timestamp.py +2 -2
- localstack/services/stepfunctions/asl/eval/callback/callback.py +18 -18
- localstack/services/stepfunctions/asl/eval/environment.py +22 -24
- localstack/services/stepfunctions/asl/eval/evaluation_details.py +3 -5
- localstack/services/stepfunctions/asl/eval/event/event_manager.py +10 -10
- localstack/services/stepfunctions/asl/eval/event/logging.py +3 -3
- localstack/services/stepfunctions/asl/eval/program_state.py +8 -8
- localstack/services/stepfunctions/asl/eval/states.py +12 -12
- localstack/services/stepfunctions/asl/eval/test_state/environment.py +3 -5
- localstack/services/stepfunctions/asl/eval/variable_store.py +6 -6
- localstack/services/stepfunctions/asl/jsonata/jsonata.py +7 -6
- localstack/services/stepfunctions/asl/parse/asl_parser.py +1 -1
- localstack/services/stepfunctions/asl/parse/intrinsic/preprocessor.py +2 -3
- localstack/services/stepfunctions/asl/parse/preprocessor.py +44 -44
- localstack/services/stepfunctions/asl/parse/typed_props.py +2 -2
- localstack/services/stepfunctions/asl/static_analyser/intrinsic/variable_names_intrinsic_static_analyser.py +1 -1
- localstack/services/stepfunctions/asl/static_analyser/variable_references_static_analyser.py +2 -2
- localstack/services/stepfunctions/asl/utils/encoding.py +2 -2
- localstack/services/stepfunctions/asl/utils/json_path.py +2 -2
- localstack/services/stepfunctions/backend/activity.py +4 -4
- localstack/services/stepfunctions/backend/alias.py +8 -8
- localstack/services/stepfunctions/backend/execution.py +29 -30
- localstack/services/stepfunctions/backend/execution_worker.py +7 -7
- localstack/services/stepfunctions/backend/state_machine.py +28 -28
- localstack/services/stepfunctions/backend/test_state/execution.py +3 -4
- localstack/services/stepfunctions/backend/test_state/execution_worker.py +1 -3
- localstack/services/stepfunctions/mocking/mock_config.py +9 -9
- localstack/services/stepfunctions/mocking/mock_config_file.py +10 -10
- localstack/services/stepfunctions/packages.py +14 -5
- localstack/services/stepfunctions/provider.py +34 -44
- localstack/services/stepfunctions/quotas.py +2 -3
- localstack/services/stepfunctions/resource_providers/aws_stepfunctions_activity.py +6 -6
- localstack/services/stepfunctions/resource_providers/aws_stepfunctions_activity_plugin.py +1 -3
- localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine.py +25 -25
- localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine_plugin.py +1 -3
- localstack/services/stepfunctions/stepfunctions_utils.py +1 -2
- localstack/services/stores.py +8 -8
- localstack/services/transcribe/packages.py +1 -3
- localstack/services/transcribe/provider.py +8 -3
- localstack/state/codecs.py +61 -0
- localstack/state/core.py +11 -5
- localstack/state/inspect.py +4 -4
- localstack/state/pickle.py +36 -23
- localstack/testing/aws/asf_utils.py +3 -2
- localstack/testing/aws/cloudformation_utils.py +1 -1
- localstack/testing/aws/lambda_utils.py +15 -14
- localstack/testing/aws/util.py +3 -2
- localstack/testing/pytest/cloudformation/fixtures.py +68 -18
- localstack/testing/pytest/container.py +5 -5
- localstack/testing/pytest/filters.py +1 -3
- localstack/testing/pytest/fixtures.py +188 -49
- localstack/testing/pytest/in_memory_localstack.py +1 -3
- localstack/testing/pytest/marking.py +42 -15
- localstack/testing/pytest/path_filter.py +1 -1
- localstack/testing/pytest/stepfunctions/fixtures.py +4 -4
- localstack/testing/pytest/stepfunctions/utils.py +11 -10
- localstack/testing/pytest/util.py +1 -1
- localstack/testing/pytest/validation_tracking.py +3 -4
- localstack/testing/scenario/provisioning.py +11 -10
- localstack/testing/snapshots/transformer_utility.py +8 -3
- localstack/testing/testselection/matching.py +2 -2
- localstack/testing/testselection/opt_out.py +1 -1
- localstack/testing/testselection/scripts/filter_by_test_selection.py +1 -1
- localstack/testing/testselection/scripts/generate_test_selection.py +1 -1
- localstack/testing/testselection/testselection.py +2 -2
- localstack/utils/analytics/cli.py +2 -3
- localstack/utils/analytics/client.py +5 -5
- localstack/utils/analytics/events.py +2 -2
- localstack/utils/analytics/metadata.py +6 -4
- localstack/utils/analytics/metrics/counter.py +11 -18
- localstack/utils/analytics/metrics/registry.py +2 -2
- localstack/utils/analytics/publisher.py +4 -5
- localstack/utils/analytics/service_providers.py +19 -0
- localstack/utils/analytics/service_request_aggregator.py +4 -4
- localstack/utils/archives.py +12 -12
- localstack/utils/asyncio.py +2 -2
- localstack/utils/aws/arns.py +26 -31
- localstack/utils/aws/aws_responses.py +21 -28
- localstack/utils/aws/aws_stack.py +7 -12
- localstack/utils/aws/dead_letter_queue.py +4 -9
- localstack/utils/aws/message_forwarding.py +8 -11
- localstack/utils/aws/request_context.py +5 -6
- localstack/utils/aws/resources.py +1 -1
- localstack/utils/aws/templating.py +4 -4
- localstack/utils/batch_policy.py +4 -4
- localstack/utils/bootstrap.py +37 -30
- localstack/utils/catalog/catalog.py +139 -0
- localstack/utils/catalog/catalog_loader.py +119 -0
- localstack/utils/catalog/common.py +58 -0
- localstack/utils/catalog/plugins.py +28 -0
- localstack/utils/cloudwatch/cloudwatch_util.py +5 -5
- localstack/utils/collections.py +33 -27
- localstack/utils/config_listener.py +2 -2
- localstack/utils/container_networking.py +5 -6
- localstack/utils/container_utils/container_client.py +156 -160
- localstack/utils/container_utils/docker_cmd_client.py +97 -81
- localstack/utils/container_utils/docker_sdk_client.py +75 -72
- localstack/utils/crypto.py +12 -13
- localstack/utils/diagnose.py +11 -12
- localstack/utils/docker_utils.py +11 -7
- localstack/utils/files.py +34 -15
- localstack/utils/functions.py +5 -4
- localstack/utils/http.py +14 -14
- localstack/utils/iputils.py +2 -1
- localstack/utils/json.py +21 -7
- localstack/utils/kinesis/kinesis_connector.py +2 -1
- localstack/utils/net.py +25 -17
- localstack/utils/no_exit_argument_parser.py +2 -2
- localstack/utils/numbers.py +9 -2
- localstack/utils/objects.py +15 -14
- localstack/utils/patch.py +14 -7
- localstack/utils/platform.py +2 -2
- localstack/utils/run.py +15 -14
- localstack/utils/scheduler.py +13 -12
- localstack/utils/server/tcp_proxy.py +2 -2
- localstack/utils/serving.py +3 -4
- localstack/utils/strings.py +15 -16
- localstack/utils/sync.py +126 -1
- localstack/utils/tagging.py +10 -8
- localstack/utils/testutil.py +17 -17
- localstack/utils/threads.py +3 -3
- localstack/utils/time.py +12 -4
- localstack/utils/urls.py +1 -3
- localstack/utils/xml.py +1 -1
- localstack/utils/xray/traceid.py +1 -1
- localstack/version.py +16 -3
- {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/METADATA +18 -13
- {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/RECORD +663 -655
- {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/entry_points.txt +8 -4
- localstack_core-4.10.1.dev12.dist-info/plux.json +1 -0
- localstack/packages/terraform.py +0 -47
- localstack/services/cloudformation/deploy.html +0 -144
- localstack/services/cloudformation/deploy_ui.py +0 -47
- localstack/services/cloudformation/plugins.py +0 -12
- localstack/services/lambda_/lambda_debug_mode/ldm.py +0 -375
- localstack/services/lambda_/lambda_debug_mode/ldm_config_file.py +0 -178
- localstack/services/lambda_/lambda_debug_mode/ldm_types.py +0 -11
- localstack/services/lambda_/lambda_debug_mode/ldm_utils.py +0 -43
- localstack_core-4.6.1.dev60.dist-info/plux.json +0 -1
- /localstack/{services/lambda_/lambda_debug_mode/__init__.py → testing/pytest/cloudformation/transformers.py} +0 -0
- {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack +0 -0
- {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack-supervisor +0 -0
- {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack.bat +0 -0
- {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/WHEEL +0 -0
- {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/licenses/LICENSE.txt +0 -0
- {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/top_level.txt +0 -0
|
@@ -1,21 +1,17 @@
|
|
|
1
|
-
import copy
|
|
2
|
-
import hashlib
|
|
3
1
|
import json
|
|
4
2
|
import logging
|
|
5
3
|
import re
|
|
6
4
|
import threading
|
|
7
5
|
import time
|
|
6
|
+
from collections.abc import Iterable
|
|
8
7
|
from concurrent.futures.thread import ThreadPoolExecutor
|
|
9
8
|
from itertools import islice
|
|
10
|
-
from typing import Dict, Iterable, List, Literal, Optional, Tuple
|
|
11
9
|
|
|
12
10
|
from botocore.utils import InvalidArnException
|
|
13
|
-
from moto.sqs.models import BINARY_TYPE_FIELD_INDEX, STRING_TYPE_FIELD_INDEX
|
|
14
|
-
from moto.sqs.models import Message as MotoMessage
|
|
15
11
|
from werkzeug import Request as WerkzeugRequest
|
|
16
12
|
|
|
17
13
|
from localstack import config
|
|
18
|
-
from localstack.aws.api import
|
|
14
|
+
from localstack.aws.api import RequestContext, ServiceException
|
|
19
15
|
from localstack.aws.api.sqs import (
|
|
20
16
|
ActionNameList,
|
|
21
17
|
AttributeNameList,
|
|
@@ -69,11 +65,8 @@ from localstack.aws.api.sqs import (
|
|
|
69
65
|
Token,
|
|
70
66
|
TooManyEntriesInBatchRequest,
|
|
71
67
|
)
|
|
72
|
-
from localstack.aws.protocol.parser import create_parser
|
|
73
|
-
from localstack.aws.protocol.serializer import aws_response_serializer
|
|
74
68
|
from localstack.aws.spec import load_service
|
|
75
69
|
from localstack.config import SQS_DISABLE_MAX_NUMBER_OF_MESSAGE_LIMIT
|
|
76
|
-
from localstack.http import Request, route
|
|
77
70
|
from localstack.services.edge import ROUTER
|
|
78
71
|
from localstack.services.plugins import ServiceLifecycleHook
|
|
79
72
|
from localstack.services.sqs import constants as sqs_constants
|
|
@@ -83,6 +76,7 @@ from localstack.services.sqs.constants import (
|
|
|
83
76
|
HEADER_LOCALSTACK_SQS_OVERRIDE_WAIT_TIME_SECONDS,
|
|
84
77
|
MAX_RESULT_LIMIT,
|
|
85
78
|
)
|
|
79
|
+
from localstack.services.sqs.developer_api import SqsDeveloperApi
|
|
86
80
|
from localstack.services.sqs.exceptions import (
|
|
87
81
|
InvalidParameterValueException,
|
|
88
82
|
MissingRequiredParameterException,
|
|
@@ -96,8 +90,10 @@ from localstack.services.sqs.models import (
|
|
|
96
90
|
SqsStore,
|
|
97
91
|
StandardQueue,
|
|
98
92
|
sqs_stores,
|
|
93
|
+
to_sqs_api_message,
|
|
99
94
|
)
|
|
100
95
|
from localstack.services.sqs.utils import (
|
|
96
|
+
create_message_attribute_hash,
|
|
101
97
|
decode_move_task_handle,
|
|
102
98
|
generate_message_id,
|
|
103
99
|
is_fifo_queue,
|
|
@@ -106,7 +102,6 @@ from localstack.services.sqs.utils import (
|
|
|
106
102
|
)
|
|
107
103
|
from localstack.services.stores import AccountRegionBundle
|
|
108
104
|
from localstack.utils.aws.arns import parse_arn
|
|
109
|
-
from localstack.utils.aws.request_context import extract_region_from_headers
|
|
110
105
|
from localstack.utils.bootstrap import is_api_enabled
|
|
111
106
|
from localstack.utils.cloudwatch.cloudwatch_util import (
|
|
112
107
|
SqsMetricBatchData,
|
|
@@ -126,13 +121,6 @@ MAX_NUMBER_OF_MESSAGES = 10
|
|
|
126
121
|
_STORE_LOCK = threading.RLock()
|
|
127
122
|
|
|
128
123
|
|
|
129
|
-
class InvalidAddress(ServiceException):
|
|
130
|
-
code = "InvalidAddress"
|
|
131
|
-
message = "The address https://queue.amazonaws.com/ is not valid for this endpoint."
|
|
132
|
-
sender_fault = True
|
|
133
|
-
status_code = 404
|
|
134
|
-
|
|
135
|
-
|
|
136
124
|
def assert_queue_name(queue_name: str, fifo: bool = False):
|
|
137
125
|
if queue_name.endswith(".fifo"):
|
|
138
126
|
if not fifo:
|
|
@@ -310,7 +298,7 @@ class CloudwatchPublishWorker:
|
|
|
310
298
|
def __init__(self) -> None:
|
|
311
299
|
super().__init__()
|
|
312
300
|
self.scheduler = Scheduler()
|
|
313
|
-
self.thread:
|
|
301
|
+
self.thread: FuncThread | None = None
|
|
314
302
|
|
|
315
303
|
def publish_approximate_cloudwatch_metrics(self):
|
|
316
304
|
"""Publishes the metrics for ApproximateNumberOfMessagesVisible, ApproximateNumberOfMessagesNotVisible
|
|
@@ -391,31 +379,39 @@ class QueueUpdateWorker:
|
|
|
391
379
|
def __init__(self) -> None:
|
|
392
380
|
super().__init__()
|
|
393
381
|
self.scheduler = Scheduler()
|
|
394
|
-
self.thread:
|
|
382
|
+
self.thread: FuncThread | None = None
|
|
395
383
|
self.mutex = threading.RLock()
|
|
396
384
|
|
|
397
385
|
def iter_queues(self) -> Iterable[SqsQueue]:
|
|
398
386
|
for account_id, region, store in sqs_stores.iter_stores():
|
|
399
|
-
|
|
400
|
-
yield queue
|
|
387
|
+
yield from store.queues.values()
|
|
401
388
|
|
|
402
389
|
def do_update_all_queues(self):
|
|
403
390
|
for queue in self.iter_queues():
|
|
404
391
|
try:
|
|
405
392
|
queue.requeue_inflight_messages()
|
|
406
393
|
except Exception:
|
|
407
|
-
LOG.
|
|
394
|
+
LOG.error(
|
|
395
|
+
"error re-queueing inflight messages",
|
|
396
|
+
exc_info=LOG.isEnabledFor(logging.DEBUG),
|
|
397
|
+
)
|
|
408
398
|
|
|
409
399
|
try:
|
|
410
400
|
queue.enqueue_delayed_messages()
|
|
411
401
|
except Exception:
|
|
412
|
-
LOG.
|
|
402
|
+
LOG.error(
|
|
403
|
+
"error enqueueing delayed messages",
|
|
404
|
+
exc_info=LOG.isEnabledFor(logging.DEBUG),
|
|
405
|
+
)
|
|
413
406
|
|
|
414
407
|
if config.SQS_ENABLE_MESSAGE_RETENTION_PERIOD:
|
|
415
408
|
try:
|
|
416
409
|
queue.remove_expired_messages()
|
|
417
410
|
except Exception:
|
|
418
|
-
LOG.
|
|
411
|
+
LOG.error(
|
|
412
|
+
"error removing expired messages",
|
|
413
|
+
exc_info=LOG.isEnabledFor(logging.DEBUG),
|
|
414
|
+
)
|
|
419
415
|
|
|
420
416
|
def start(self):
|
|
421
417
|
with self.mutex:
|
|
@@ -460,7 +456,7 @@ class MessageMoveTaskManager:
|
|
|
460
456
|
def __init__(self, stores: AccountRegionBundle[SqsStore] = None) -> None:
|
|
461
457
|
self.stores = stores or sqs_stores
|
|
462
458
|
self.mutex = threading.RLock()
|
|
463
|
-
self.move_tasks: dict[str, MessageMoveTask] =
|
|
459
|
+
self.move_tasks: dict[str, MessageMoveTask] = {}
|
|
464
460
|
self.executor = ThreadPoolExecutor(max_workers=100, thread_name_prefix="sqs-move-message")
|
|
465
461
|
|
|
466
462
|
def submit(self, move_task: MessageMoveTask):
|
|
@@ -621,177 +617,16 @@ def check_attributes(message_attributes: MessageBodyAttributeMap):
|
|
|
621
617
|
raise InvalidParameterValueException(e.args[0])
|
|
622
618
|
|
|
623
619
|
|
|
624
|
-
def check_fifo_id(fifo_id, parameter):
|
|
625
|
-
if
|
|
620
|
+
def check_fifo_id(fifo_id: str | None, parameter: str):
|
|
621
|
+
if fifo_id is None:
|
|
626
622
|
return
|
|
627
|
-
if len(fifo_id) > 128:
|
|
628
|
-
raise InvalidParameterValueException(
|
|
629
|
-
f"Value {fifo_id} for parameter {parameter} is invalid. Reason: {parameter} can only include alphanumeric and punctuation characters. 1 to 128 in length."
|
|
630
|
-
)
|
|
631
623
|
if not re.match(sqs_constants.FIFO_MSG_REGEX, fifo_id):
|
|
632
624
|
raise InvalidParameterValueException(
|
|
633
|
-
"
|
|
634
|
-
"alphanumeric characters
|
|
625
|
+
f"Value {fifo_id} for parameter {parameter} is invalid. "
|
|
626
|
+
f"Reason: {parameter} can only include alphanumeric and punctuation characters. 1 to 128 in length."
|
|
635
627
|
)
|
|
636
628
|
|
|
637
629
|
|
|
638
|
-
def get_sqs_protocol(request: Request) -> Literal["query", "json"]:
|
|
639
|
-
content_type = request.headers.get("Content-Type")
|
|
640
|
-
return "json" if content_type == "application/x-amz-json-1.0" else "query"
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
def sqs_auto_protocol_aws_response_serializer(service_name: str, operation: str):
|
|
644
|
-
def _decorate(fn):
|
|
645
|
-
def _proxy(*args, **kwargs):
|
|
646
|
-
# extract request from function invocation (decorator can be used for methods as well as for functions).
|
|
647
|
-
if len(args) > 0 and isinstance(args[0], WerkzeugRequest):
|
|
648
|
-
# function
|
|
649
|
-
request = args[0]
|
|
650
|
-
elif len(args) > 1 and isinstance(args[1], WerkzeugRequest):
|
|
651
|
-
# method (arg[0] == self)
|
|
652
|
-
request = args[1]
|
|
653
|
-
elif "request" in kwargs:
|
|
654
|
-
request = kwargs["request"]
|
|
655
|
-
else:
|
|
656
|
-
raise ValueError(f"could not find Request in signature of function {fn}")
|
|
657
|
-
|
|
658
|
-
protocol = get_sqs_protocol(request)
|
|
659
|
-
return aws_response_serializer(service_name, operation, protocol)(fn)(*args, **kwargs)
|
|
660
|
-
|
|
661
|
-
return _proxy
|
|
662
|
-
|
|
663
|
-
return _decorate
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
class SqsDeveloperEndpoints:
|
|
667
|
-
"""
|
|
668
|
-
A set of SQS developer tool endpoints:
|
|
669
|
-
|
|
670
|
-
- ``/_aws/sqs/messages``: list SQS messages without side effects, compatible with ``ReceiveMessage``.
|
|
671
|
-
"""
|
|
672
|
-
|
|
673
|
-
def __init__(self, stores=None):
|
|
674
|
-
self.stores = stores or sqs_stores
|
|
675
|
-
|
|
676
|
-
@route("/_aws/sqs/messages", methods=["GET", "POST"])
|
|
677
|
-
@sqs_auto_protocol_aws_response_serializer("sqs", "ReceiveMessage")
|
|
678
|
-
def list_messages(self, request: Request) -> ReceiveMessageResult:
|
|
679
|
-
"""
|
|
680
|
-
This endpoint expects a ``QueueUrl`` request parameter (either as query arg or form parameter), similar to
|
|
681
|
-
the ``ReceiveMessage`` operation. It will parse the Queue URL generated by one of the SQS endpoint strategies.
|
|
682
|
-
"""
|
|
683
|
-
|
|
684
|
-
if "x-amz-" in request.mimetype or "x-www-form-urlencoded" in request.mimetype:
|
|
685
|
-
# only parse the request using a parser if it comes from an AWS client
|
|
686
|
-
protocol = get_sqs_protocol(request)
|
|
687
|
-
operation, service_request = create_parser(
|
|
688
|
-
load_service("sqs", protocol=protocol)
|
|
689
|
-
).parse(request)
|
|
690
|
-
if operation.name != "ReceiveMessage":
|
|
691
|
-
raise CommonServiceException(
|
|
692
|
-
"InvalidRequest", "This endpoint only accepts ReceiveMessage calls"
|
|
693
|
-
)
|
|
694
|
-
else:
|
|
695
|
-
service_request = dict(request.values)
|
|
696
|
-
|
|
697
|
-
if not service_request.get("QueueUrl"):
|
|
698
|
-
raise QueueDoesNotExist()
|
|
699
|
-
|
|
700
|
-
try:
|
|
701
|
-
account_id, region, queue_name = parse_queue_url(service_request.get("QueueUrl"))
|
|
702
|
-
except ValueError:
|
|
703
|
-
LOG.exception(
|
|
704
|
-
"Error while parsing Queue URL from request values: %s", service_request.get
|
|
705
|
-
)
|
|
706
|
-
raise InvalidAddress()
|
|
707
|
-
|
|
708
|
-
if not region:
|
|
709
|
-
region = extract_region_from_headers(request.headers)
|
|
710
|
-
|
|
711
|
-
return self._get_and_serialize_messages(request, region, account_id, queue_name)
|
|
712
|
-
|
|
713
|
-
@route("/_aws/sqs/messages/<region>/<account_id>/<queue_name>")
|
|
714
|
-
@sqs_auto_protocol_aws_response_serializer("sqs", "ReceiveMessage")
|
|
715
|
-
def list_messages_for_queue_url(
|
|
716
|
-
self, request: Request, region: str, account_id: str, queue_name: str
|
|
717
|
-
) -> ReceiveMessageResult:
|
|
718
|
-
"""
|
|
719
|
-
This endpoint extracts the region, account_id, and queue_name directly from the URL rather than requiring the
|
|
720
|
-
QueueUrl as parameter.
|
|
721
|
-
"""
|
|
722
|
-
return self._get_and_serialize_messages(request, region, account_id, queue_name)
|
|
723
|
-
|
|
724
|
-
def _get_and_serialize_messages(
|
|
725
|
-
self,
|
|
726
|
-
request: Request,
|
|
727
|
-
region: str,
|
|
728
|
-
account_id: str,
|
|
729
|
-
queue_name: str,
|
|
730
|
-
) -> ReceiveMessageResult:
|
|
731
|
-
show_invisible = request.values.get("ShowInvisible", "").lower() in ["true", "1"]
|
|
732
|
-
show_delayed = request.values.get("ShowDelayed", "").lower() in ["true", "1"]
|
|
733
|
-
|
|
734
|
-
try:
|
|
735
|
-
store = SqsProvider.get_store(account_id, region)
|
|
736
|
-
queue = store.queues[queue_name]
|
|
737
|
-
except KeyError:
|
|
738
|
-
LOG.info(
|
|
739
|
-
"no queue named %s in region %s and account %s", queue_name, region, account_id
|
|
740
|
-
)
|
|
741
|
-
raise QueueDoesNotExist()
|
|
742
|
-
|
|
743
|
-
messages = self._collect_messages(
|
|
744
|
-
queue, show_invisible=show_invisible, show_delayed=show_delayed
|
|
745
|
-
)
|
|
746
|
-
|
|
747
|
-
return ReceiveMessageResult(Messages=messages)
|
|
748
|
-
|
|
749
|
-
def _collect_messages(
|
|
750
|
-
self, queue: SqsQueue, show_invisible: bool = False, show_delayed: bool = False
|
|
751
|
-
) -> List[Message]:
|
|
752
|
-
"""
|
|
753
|
-
Retrieves from a given SqsQueue all visible messages without causing any side effects (not setting any
|
|
754
|
-
receive timestamps, receive counts, or visibility state).
|
|
755
|
-
|
|
756
|
-
:param queue: the queue
|
|
757
|
-
:param show_invisible: show invisible messages as well
|
|
758
|
-
:param show_delayed: show delayed messages as well
|
|
759
|
-
:return: a list of messages
|
|
760
|
-
"""
|
|
761
|
-
receipt_handle = "SQS/BACKDOOR/ACCESS" # dummy receipt handle
|
|
762
|
-
|
|
763
|
-
sqs_messages: List[SqsMessage] = []
|
|
764
|
-
|
|
765
|
-
if show_invisible:
|
|
766
|
-
sqs_messages.extend(queue.inflight)
|
|
767
|
-
|
|
768
|
-
if isinstance(queue, StandardQueue):
|
|
769
|
-
sqs_messages.extend(queue.visible.queue)
|
|
770
|
-
elif isinstance(queue, FifoQueue):
|
|
771
|
-
for message_group in queue.message_groups.values():
|
|
772
|
-
for sqs_message in message_group.messages:
|
|
773
|
-
sqs_messages.append(sqs_message)
|
|
774
|
-
else:
|
|
775
|
-
raise ValueError(f"unknown queue type {type(queue)}")
|
|
776
|
-
|
|
777
|
-
if show_delayed:
|
|
778
|
-
sqs_messages.extend(queue.delayed)
|
|
779
|
-
|
|
780
|
-
messages = []
|
|
781
|
-
|
|
782
|
-
for sqs_message in sqs_messages:
|
|
783
|
-
message: Message = to_sqs_api_message(sqs_message, [QueueAttributeName.All], ["All"])
|
|
784
|
-
# these are all non-standard fields so we squelch the linter
|
|
785
|
-
if show_invisible:
|
|
786
|
-
message["Attributes"]["IsVisible"] = str(sqs_message.is_visible).lower() # noqa
|
|
787
|
-
if show_delayed:
|
|
788
|
-
message["Attributes"]["IsDelayed"] = str(sqs_message.is_delayed).lower() # noqa
|
|
789
|
-
messages.append(message)
|
|
790
|
-
message["ReceiptHandle"] = receipt_handle
|
|
791
|
-
|
|
792
|
-
return messages
|
|
793
|
-
|
|
794
|
-
|
|
795
630
|
class SqsProvider(SqsApi, ServiceLifecycleHook):
|
|
796
631
|
"""
|
|
797
632
|
LocalStack SQS Provider.
|
|
@@ -815,7 +650,7 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
|
|
|
815
650
|
- UntagQueue
|
|
816
651
|
"""
|
|
817
652
|
|
|
818
|
-
queues:
|
|
653
|
+
queues: dict[str, SqsQueue]
|
|
819
654
|
|
|
820
655
|
def __init__(self) -> None:
|
|
821
656
|
super().__init__()
|
|
@@ -828,9 +663,26 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
|
|
|
828
663
|
def get_store(account_id: str, region: str) -> SqsStore:
|
|
829
664
|
return sqs_stores[account_id][region]
|
|
830
665
|
|
|
666
|
+
def on_after_init(self):
|
|
667
|
+
# this configuration increases the processing power for Query protocol requests, which are form-encoded and by
|
|
668
|
+
# default are limited to 500kb payload size by Werkzeug. we make sure we only *increase* the limit if it's
|
|
669
|
+
# already set, and if it's already set to unlimited we leave it.
|
|
670
|
+
from rolo import Request as RoloRequest
|
|
671
|
+
|
|
672
|
+
# needed for the webserver integration (webservers create Werkzeug request objects)
|
|
673
|
+
if WerkzeugRequest.max_form_memory_size is not None:
|
|
674
|
+
WerkzeugRequest.max_form_memory_size = max(
|
|
675
|
+
WerkzeugRequest.max_form_memory_size, sqs_constants.DEFAULT_MAXIMUM_MESSAGE_SIZE * 2
|
|
676
|
+
)
|
|
677
|
+
# needed for internal/proxy requests (which create rolo request objects)
|
|
678
|
+
if RoloRequest.max_form_memory_size is not None:
|
|
679
|
+
RoloRequest.max_form_memory_size = max(
|
|
680
|
+
RoloRequest.max_form_memory_size, sqs_constants.DEFAULT_MAXIMUM_MESSAGE_SIZE * 2
|
|
681
|
+
)
|
|
682
|
+
|
|
831
683
|
def on_before_start(self):
|
|
832
684
|
query_api.register(ROUTER)
|
|
833
|
-
self._router_rules = ROUTER.add(
|
|
685
|
+
self._router_rules = ROUTER.add(SqsDeveloperApi())
|
|
834
686
|
self._queue_update_worker.start()
|
|
835
687
|
self._start_cloudwatch_metrics_reporting()
|
|
836
688
|
|
|
@@ -881,8 +733,8 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
|
|
|
881
733
|
def _resolve_queue(
|
|
882
734
|
self,
|
|
883
735
|
context: RequestContext,
|
|
884
|
-
queue_name:
|
|
885
|
-
queue_url:
|
|
736
|
+
queue_name: str | None = None,
|
|
737
|
+
queue_url: str | None = None,
|
|
886
738
|
) -> SqsQueue:
|
|
887
739
|
"""
|
|
888
740
|
Determines the name of the queue from available information (request context, queue URL) to return the respective queue,
|
|
@@ -1125,7 +977,7 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
|
|
|
1125
977
|
MD5OfMessageBody=message["MD5OfBody"],
|
|
1126
978
|
MD5OfMessageAttributes=message.get("MD5OfMessageAttributes"),
|
|
1127
979
|
SequenceNumber=queue_item.sequence_number,
|
|
1128
|
-
MD5OfMessageSystemAttributes=
|
|
980
|
+
MD5OfMessageSystemAttributes=create_message_attribute_hash(message_system_attributes),
|
|
1129
981
|
)
|
|
1130
982
|
|
|
1131
983
|
def send_message_batch(
|
|
@@ -1171,7 +1023,7 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
|
|
|
1171
1023
|
MessageId=message.get("MessageId"),
|
|
1172
1024
|
MD5OfMessageBody=message.get("MD5OfBody"),
|
|
1173
1025
|
MD5OfMessageAttributes=message.get("MD5OfMessageAttributes"),
|
|
1174
|
-
MD5OfMessageSystemAttributes=
|
|
1026
|
+
MD5OfMessageSystemAttributes=create_message_attribute_hash(
|
|
1175
1027
|
message.get("message_system_attributes")
|
|
1176
1028
|
),
|
|
1177
1029
|
SequenceNumber=queue_item.sequence_number,
|
|
@@ -1225,7 +1077,7 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
|
|
|
1225
1077
|
MD5OfBody=md5(message_body),
|
|
1226
1078
|
Body=message_body,
|
|
1227
1079
|
Attributes=self._create_message_attributes(context, message_system_attributes),
|
|
1228
|
-
MD5OfMessageAttributes=
|
|
1080
|
+
MD5OfMessageAttributes=create_message_attribute_hash(message_attributes),
|
|
1229
1081
|
MessageAttributes=message_attributes,
|
|
1230
1082
|
)
|
|
1231
1083
|
if self._cloudwatch_dispatcher:
|
|
@@ -1674,8 +1526,8 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
|
|
|
1674
1526
|
self,
|
|
1675
1527
|
context: RequestContext,
|
|
1676
1528
|
message_system_attributes: MessageBodySystemAttributeMap = None,
|
|
1677
|
-
) ->
|
|
1678
|
-
result:
|
|
1529
|
+
) -> dict[MessageSystemAttributeName, str]:
|
|
1530
|
+
result: dict[MessageSystemAttributeName, str] = {
|
|
1679
1531
|
MessageSystemAttributeName.SenderId: context.account_id, # not the account ID in AWS
|
|
1680
1532
|
MessageSystemAttributeName.SentTimestamp: str(now(millis=True)),
|
|
1681
1533
|
}
|
|
@@ -1709,7 +1561,7 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
|
|
|
1709
1561
|
|
|
1710
1562
|
def _assert_batch(
|
|
1711
1563
|
self,
|
|
1712
|
-
batch:
|
|
1564
|
+
batch: list,
|
|
1713
1565
|
*,
|
|
1714
1566
|
require_fifo_queue_params: bool = False,
|
|
1715
1567
|
require_message_deduplication_id: bool = False,
|
|
@@ -1745,7 +1597,7 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
|
|
|
1745
1597
|
else:
|
|
1746
1598
|
visited.add(entry_id)
|
|
1747
1599
|
|
|
1748
|
-
def _assert_valid_batch_size(self, batch:
|
|
1600
|
+
def _assert_valid_batch_size(self, batch: list, max_message_size: int):
|
|
1749
1601
|
batch_message_size = sum(
|
|
1750
1602
|
_message_body_size(entry.get("MessageBody"))
|
|
1751
1603
|
+ _message_attributes_size(entry.get("MessageAttributes"))
|
|
@@ -1756,7 +1608,7 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
|
|
|
1756
1608
|
error += f" You have sent {batch_message_size} bytes."
|
|
1757
1609
|
raise BatchRequestTooLong(error)
|
|
1758
1610
|
|
|
1759
|
-
def _assert_valid_message_ids(self, batch:
|
|
1611
|
+
def _assert_valid_message_ids(self, batch: list):
|
|
1760
1612
|
batch_id_regex = r"^[\w-]{1,80}$"
|
|
1761
1613
|
for message in batch:
|
|
1762
1614
|
if not re.match(batch_id_regex, message.get("Id", "")):
|
|
@@ -1785,37 +1637,9 @@ class SqsProvider(SqsApi, ServiceLifecycleHook):
|
|
|
1785
1637
|
self._cloudwatch_dispatcher.shutdown()
|
|
1786
1638
|
|
|
1787
1639
|
|
|
1788
|
-
# Method from moto's attribute_md5 of moto/sqs/models.py, separated from the Message Object
|
|
1789
|
-
def _create_message_attribute_hash(message_attributes) -> Optional[str]:
|
|
1790
|
-
# To avoid the need to check for dict conformity everytime we invoke this function
|
|
1791
|
-
if not isinstance(message_attributes, dict):
|
|
1792
|
-
return
|
|
1793
|
-
hash = hashlib.md5()
|
|
1794
|
-
|
|
1795
|
-
for attrName in sorted(message_attributes.keys()):
|
|
1796
|
-
attr_value = message_attributes[attrName]
|
|
1797
|
-
# Encode name
|
|
1798
|
-
MotoMessage.update_binary_length_and_value(hash, MotoMessage.utf8(attrName))
|
|
1799
|
-
# Encode data type
|
|
1800
|
-
MotoMessage.update_binary_length_and_value(hash, MotoMessage.utf8(attr_value["DataType"]))
|
|
1801
|
-
# Encode transport type and value
|
|
1802
|
-
if attr_value.get("StringValue"):
|
|
1803
|
-
hash.update(bytearray([STRING_TYPE_FIELD_INDEX]))
|
|
1804
|
-
MotoMessage.update_binary_length_and_value(
|
|
1805
|
-
hash, MotoMessage.utf8(attr_value.get("StringValue"))
|
|
1806
|
-
)
|
|
1807
|
-
elif attr_value.get("BinaryValue"):
|
|
1808
|
-
hash.update(bytearray([BINARY_TYPE_FIELD_INDEX]))
|
|
1809
|
-
decoded_binary_value = attr_value.get("BinaryValue")
|
|
1810
|
-
MotoMessage.update_binary_length_and_value(hash, decoded_binary_value)
|
|
1811
|
-
# string_list_value, binary_list_value type is not implemented, reserved for the future use.
|
|
1812
|
-
# See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_MessageAttributeValue.html
|
|
1813
|
-
return hash.hexdigest()
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
1640
|
def resolve_queue_location(
|
|
1817
|
-
context: RequestContext, queue_name:
|
|
1818
|
-
) ->
|
|
1641
|
+
context: RequestContext, queue_name: str | None = None, queue_url: str | None = None
|
|
1642
|
+
) -> tuple[str, str | None, str]:
|
|
1819
1643
|
"""
|
|
1820
1644
|
Resolves a queue location from the given information.
|
|
1821
1645
|
|
|
@@ -1837,106 +1661,6 @@ def resolve_queue_location(
|
|
|
1837
1661
|
return context.account_id, context.region, queue_name
|
|
1838
1662
|
|
|
1839
1663
|
|
|
1840
|
-
def to_sqs_api_message(
|
|
1841
|
-
standard_message: SqsMessage,
|
|
1842
|
-
attribute_names: AttributeNameList = None,
|
|
1843
|
-
message_attribute_names: MessageAttributeNameList = None,
|
|
1844
|
-
) -> Message:
|
|
1845
|
-
"""
|
|
1846
|
-
Utility function to convert an SQS message from LocalStack's internal representation to the AWS API
|
|
1847
|
-
concept 'Message', which is the format returned by the ``ReceiveMessage`` operation.
|
|
1848
|
-
|
|
1849
|
-
:param standard_message: A LocalStack SQS message
|
|
1850
|
-
:param attribute_names: the attribute name list to filter
|
|
1851
|
-
:param message_attribute_names: the message attribute names to filter
|
|
1852
|
-
:return: a copy of the original Message with updated message attributes and MD5 attribute hash sums
|
|
1853
|
-
"""
|
|
1854
|
-
# prepare message for receiver
|
|
1855
|
-
message = copy.deepcopy(standard_message.message)
|
|
1856
|
-
|
|
1857
|
-
# update system attributes of the message copy
|
|
1858
|
-
message["Attributes"][MessageSystemAttributeName.ApproximateFirstReceiveTimestamp] = str(
|
|
1859
|
-
int((standard_message.first_received or 0) * 1000)
|
|
1860
|
-
)
|
|
1861
|
-
|
|
1862
|
-
# filter attributes for receiver
|
|
1863
|
-
message_filter_attributes(message, attribute_names)
|
|
1864
|
-
message_filter_message_attributes(message, message_attribute_names)
|
|
1865
|
-
if message.get("MessageAttributes"):
|
|
1866
|
-
message["MD5OfMessageAttributes"] = _create_message_attribute_hash(
|
|
1867
|
-
message["MessageAttributes"]
|
|
1868
|
-
)
|
|
1869
|
-
else:
|
|
1870
|
-
# delete the value that was computed when creating the message
|
|
1871
|
-
message.pop("MD5OfMessageAttributes", None)
|
|
1872
|
-
return message
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
def message_filter_attributes(message: Message, names: Optional[AttributeNameList]):
|
|
1876
|
-
"""
|
|
1877
|
-
Utility function filter from the given message (in-place) the system attributes from the given list. It will
|
|
1878
|
-
apply all rules according to:
|
|
1879
|
-
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sqs.html#SQS.Client.receive_message.
|
|
1880
|
-
|
|
1881
|
-
:param message: The message to filter (it will be modified)
|
|
1882
|
-
:param names: the attributes names/filters
|
|
1883
|
-
"""
|
|
1884
|
-
if "Attributes" not in message:
|
|
1885
|
-
return
|
|
1886
|
-
|
|
1887
|
-
if not names:
|
|
1888
|
-
del message["Attributes"]
|
|
1889
|
-
return
|
|
1890
|
-
|
|
1891
|
-
if QueueAttributeName.All in names:
|
|
1892
|
-
return
|
|
1893
|
-
|
|
1894
|
-
for k in list(message["Attributes"].keys()):
|
|
1895
|
-
if k not in names:
|
|
1896
|
-
del message["Attributes"][k]
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
def message_filter_message_attributes(message: Message, names: Optional[MessageAttributeNameList]):
|
|
1900
|
-
"""
|
|
1901
|
-
Utility function filter from the given message (in-place) the message attributes from the given list. It will
|
|
1902
|
-
apply all rules according to:
|
|
1903
|
-
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sqs.html#SQS.Client.receive_message.
|
|
1904
|
-
|
|
1905
|
-
:param message: The message to filter (it will be modified)
|
|
1906
|
-
:param names: the attributes names/filters (can be 'All', '.*', '*' or prefix filters like 'Foo.*')
|
|
1907
|
-
"""
|
|
1908
|
-
if not message.get("MessageAttributes"):
|
|
1909
|
-
return
|
|
1910
|
-
|
|
1911
|
-
if not names:
|
|
1912
|
-
del message["MessageAttributes"]
|
|
1913
|
-
return
|
|
1914
|
-
|
|
1915
|
-
if "All" in names or ".*" in names or "*" in names:
|
|
1916
|
-
return
|
|
1917
|
-
|
|
1918
|
-
attributes = message["MessageAttributes"]
|
|
1919
|
-
matched = []
|
|
1920
|
-
|
|
1921
|
-
keys = [name for name in names if ".*" not in name]
|
|
1922
|
-
prefixes = [name.split(".*")[0] for name in names if ".*" in name]
|
|
1923
|
-
|
|
1924
|
-
# match prefix filters
|
|
1925
|
-
for k in attributes:
|
|
1926
|
-
if k in keys:
|
|
1927
|
-
matched.append(k)
|
|
1928
|
-
continue
|
|
1929
|
-
|
|
1930
|
-
for prefix in prefixes:
|
|
1931
|
-
if k.startswith(prefix):
|
|
1932
|
-
matched.append(k)
|
|
1933
|
-
break
|
|
1934
|
-
if matched:
|
|
1935
|
-
message["MessageAttributes"] = {k: attributes[k] for k in matched}
|
|
1936
|
-
else:
|
|
1937
|
-
message.pop("MessageAttributes")
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
1664
|
def extract_message_count_from_headers(context: RequestContext) -> int | None:
|
|
1941
1665
|
if override := context.request.headers.get(
|
|
1942
1666
|
HEADER_LOCALSTACK_SQS_OVERRIDE_MESSAGE_COUNT, default=None, type=int
|
|
@@ -4,7 +4,6 @@ generic implementation that creates from Query API requests the respective AWS r
|
|
|
4
4
|
to make the request."""
|
|
5
5
|
|
|
6
6
|
import logging
|
|
7
|
-
from typing import Dict, Optional, Tuple
|
|
8
7
|
from urllib.parse import urlencode
|
|
9
8
|
|
|
10
9
|
from botocore.exceptions import ClientError
|
|
@@ -36,7 +35,7 @@ LOG = logging.getLogger(__name__)
|
|
|
36
35
|
|
|
37
36
|
service = load_service("sqs-query")
|
|
38
37
|
parser = create_parser(service)
|
|
39
|
-
serializer = create_serializer(service)
|
|
38
|
+
serializer = create_serializer(service, "query")
|
|
40
39
|
|
|
41
40
|
|
|
42
41
|
@route(
|
|
@@ -167,7 +166,11 @@ def handle_request(request: Request, region: str) -> Response:
|
|
|
167
166
|
op = service.operation_model(service.operation_names[0])
|
|
168
167
|
return serializer.serialize_error_to_response(e, op, request.headers, request_id)
|
|
169
168
|
except Exception as e:
|
|
170
|
-
LOG.
|
|
169
|
+
LOG.error(
|
|
170
|
+
"Internal Server exception while executing SQS Query operation: '%s'",
|
|
171
|
+
e,
|
|
172
|
+
exc_info=LOG.isEnabledFor(logging.DEBUG),
|
|
173
|
+
)
|
|
171
174
|
op = service.operation_model(service.operation_names[0])
|
|
172
175
|
return serializer.serialize_error_to_response(
|
|
173
176
|
CommonServiceException(
|
|
@@ -179,7 +182,7 @@ def handle_request(request: Request, region: str) -> Response:
|
|
|
179
182
|
)
|
|
180
183
|
|
|
181
184
|
|
|
182
|
-
def try_call_sqs(request: Request, region: str) ->
|
|
185
|
+
def try_call_sqs(request: Request, region: str) -> tuple[dict, OperationModel]:
|
|
183
186
|
action = request.values.get("Action")
|
|
184
187
|
if not action:
|
|
185
188
|
raise UnknownOperationException()
|
|
@@ -209,7 +212,7 @@ def try_call_sqs(request: Request, region: str) -> Tuple[Dict, OperationModel]:
|
|
|
209
212
|
# Extract from auth header to allow cross-account operations
|
|
210
213
|
# TODO: permissions encoded in URL as AUTHPARAMS cannot be accounted for in this method, which is not a big
|
|
211
214
|
# problem yet since we generally don't enforce permissions.
|
|
212
|
-
account_id:
|
|
215
|
+
account_id: str | None = extract_access_key_id_from_auth_header(headers)
|
|
213
216
|
|
|
214
217
|
client = connect_to(
|
|
215
218
|
region_name=region,
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
|
|
4
4
|
import json
|
|
5
5
|
from pathlib import Path
|
|
6
|
-
from typing import
|
|
6
|
+
from typing import TypedDict
|
|
7
7
|
|
|
8
8
|
import localstack.services.cloudformation.provider_utils as util
|
|
9
9
|
from localstack.services.cloudformation.resource_provider import (
|
|
@@ -15,29 +15,29 @@ from localstack.services.cloudformation.resource_provider import (
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class SQSQueueProperties(TypedDict):
|
|
18
|
-
Arn:
|
|
19
|
-
ContentBasedDeduplication:
|
|
20
|
-
DeduplicationScope:
|
|
21
|
-
DelaySeconds:
|
|
22
|
-
FifoQueue:
|
|
23
|
-
FifoThroughputLimit:
|
|
24
|
-
KmsDataKeyReusePeriodSeconds:
|
|
25
|
-
KmsMasterKeyId:
|
|
26
|
-
MaximumMessageSize:
|
|
27
|
-
MessageRetentionPeriod:
|
|
28
|
-
QueueName:
|
|
29
|
-
QueueUrl:
|
|
30
|
-
ReceiveMessageWaitTimeSeconds:
|
|
31
|
-
RedriveAllowPolicy:
|
|
32
|
-
RedrivePolicy:
|
|
33
|
-
SqsManagedSseEnabled:
|
|
34
|
-
Tags:
|
|
35
|
-
VisibilityTimeout:
|
|
18
|
+
Arn: str | None
|
|
19
|
+
ContentBasedDeduplication: bool | None
|
|
20
|
+
DeduplicationScope: str | None
|
|
21
|
+
DelaySeconds: int | None
|
|
22
|
+
FifoQueue: bool | None
|
|
23
|
+
FifoThroughputLimit: str | None
|
|
24
|
+
KmsDataKeyReusePeriodSeconds: int | None
|
|
25
|
+
KmsMasterKeyId: str | None
|
|
26
|
+
MaximumMessageSize: int | None
|
|
27
|
+
MessageRetentionPeriod: int | None
|
|
28
|
+
QueueName: str | None
|
|
29
|
+
QueueUrl: str | None
|
|
30
|
+
ReceiveMessageWaitTimeSeconds: int | None
|
|
31
|
+
RedriveAllowPolicy: dict | str | None
|
|
32
|
+
RedrivePolicy: dict | str | None
|
|
33
|
+
SqsManagedSseEnabled: bool | None
|
|
34
|
+
Tags: list[Tag] | None
|
|
35
|
+
VisibilityTimeout: int | None
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
class Tag(TypedDict):
|
|
39
|
-
Key:
|
|
40
|
-
Value:
|
|
39
|
+
Key: str | None
|
|
40
|
+
Value: str | None
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
REPEATED_INVOCATION = "repeated_invocation"
|