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
localstack/services/s3/cors.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import re
|
|
3
|
-
from typing import
|
|
3
|
+
from typing import Protocol
|
|
4
4
|
|
|
5
5
|
from werkzeug.datastructures import Headers
|
|
6
6
|
|
|
@@ -21,13 +21,13 @@ from localstack.aws.protocol.op_router import RestServiceOperationRouter
|
|
|
21
21
|
from localstack.aws.spec import get_service_catalog
|
|
22
22
|
from localstack.config import S3_VIRTUAL_HOSTNAME
|
|
23
23
|
from localstack.http import Request, Response
|
|
24
|
+
from localstack.services.s3.constants import S3_HOST_ID
|
|
24
25
|
from localstack.services.s3.utils import S3_VIRTUAL_HOSTNAME_REGEX
|
|
25
26
|
|
|
26
27
|
# TODO: add more logging statements
|
|
27
28
|
LOG = logging.getLogger(__name__)
|
|
28
29
|
|
|
29
30
|
_s3_virtual_host_regex = re.compile(S3_VIRTUAL_HOSTNAME_REGEX)
|
|
30
|
-
FAKE_HOST_ID = "9Gjjt1m+cjU4OPvX9O9/8RuvnG41MRb/18Oux2o5H5MY7ISNTlXN+Dz9IG62/ILVxhAGI0qyPfg="
|
|
31
31
|
|
|
32
32
|
# TODO: refactor those to expose the needed methods maybe in another way that both can import
|
|
33
33
|
add_default_headers = CorsResponseEnricher.add_cors_headers
|
|
@@ -58,7 +58,7 @@ class S3CorsHandler(Handler):
|
|
|
58
58
|
def __call__(self, chain: HandlerChain, context: RequestContext, response: Response):
|
|
59
59
|
self.handle_cors(chain, context, response)
|
|
60
60
|
|
|
61
|
-
def pre_parse_s3_request(self, request: Request) ->
|
|
61
|
+
def pre_parse_s3_request(self, request: Request) -> tuple[bool, str | None]:
|
|
62
62
|
"""
|
|
63
63
|
Parse the request to try to determine if it's directed towards S3. It tries to match on host, then check
|
|
64
64
|
if the targeted bucket exists. If we could not determine it was a s3 request from the host, but the first
|
|
@@ -135,7 +135,7 @@ class S3CorsHandler(Handler):
|
|
|
135
135
|
if is_options_request:
|
|
136
136
|
context.operation = self._get_op_from_request(request)
|
|
137
137
|
raise BadRequest(
|
|
138
|
-
"Insufficient information. Origin request header needed.", HostId=
|
|
138
|
+
"Insufficient information. Origin request header needed.", HostId=S3_HOST_ID
|
|
139
139
|
)
|
|
140
140
|
else:
|
|
141
141
|
# If the header is missing, Amazon S3 doesn't treat the request as a cross-origin request,
|
|
@@ -167,7 +167,7 @@ class S3CorsHandler(Handler):
|
|
|
167
167
|
context.operation = self._get_op_from_request(request)
|
|
168
168
|
raise AccessForbidden(
|
|
169
169
|
message,
|
|
170
|
-
HostId=
|
|
170
|
+
HostId=S3_HOST_ID,
|
|
171
171
|
Method=request.headers.get("Access-Control-Request-Method", "OPTIONS"),
|
|
172
172
|
ResourceType="BUCKET",
|
|
173
173
|
)
|
|
@@ -182,7 +182,7 @@ class S3CorsHandler(Handler):
|
|
|
182
182
|
context.operation = self._get_op_from_request(request)
|
|
183
183
|
raise AccessForbidden(
|
|
184
184
|
"CORSResponse: This CORS request is not allowed. This is usually because the evalution of Origin, request method / Access-Control-Request-Method or Access-Control-Request-Headers are not whitelisted by the resource's CORS spec.",
|
|
185
|
-
HostId=
|
|
185
|
+
HostId=S3_HOST_ID,
|
|
186
186
|
Method=request.headers.get("Access-Control-Request-Method"),
|
|
187
187
|
ResourceType="OBJECT",
|
|
188
188
|
)
|
|
@@ -224,7 +224,7 @@ class S3CorsHandler(Handler):
|
|
|
224
224
|
def invalidate_cache(self):
|
|
225
225
|
self.bucket_cors_index.invalidate()
|
|
226
226
|
|
|
227
|
-
def match_rules(self, request: Request, rules: CORSRules) ->
|
|
227
|
+
def match_rules(self, request: Request, rules: CORSRules) -> CORSRule | None:
|
|
228
228
|
"""
|
|
229
229
|
Try to match the request to the bucket rules. How to match rules:
|
|
230
230
|
- The request's Origin header must match AllowedOrigin elements.
|
|
@@ -243,7 +243,7 @@ class S3CorsHandler(Handler):
|
|
|
243
243
|
return matched_rule
|
|
244
244
|
|
|
245
245
|
@staticmethod
|
|
246
|
-
def _match_rule(rule: CORSRule, method: str, headers: Headers) ->
|
|
246
|
+
def _match_rule(rule: CORSRule, method: str, headers: Headers) -> CORSRule | None:
|
|
247
247
|
"""
|
|
248
248
|
Check if the request method and headers matches the given CORS rule.
|
|
249
249
|
:param rule: CORSRule: a CORS Rule from the bucket
|
localstack/services/s3/models.py
CHANGED
|
@@ -4,7 +4,7 @@ import logging
|
|
|
4
4
|
from collections import defaultdict
|
|
5
5
|
from datetime import datetime
|
|
6
6
|
from secrets import token_urlsafe
|
|
7
|
-
from typing import Literal, NamedTuple,
|
|
7
|
+
from typing import Literal, NamedTuple, Union
|
|
8
8
|
from zoneinfo import ZoneInfo
|
|
9
9
|
|
|
10
10
|
from localstack.aws.api import CommonServiceException
|
|
@@ -105,25 +105,25 @@ class S3Bucket:
|
|
|
105
105
|
multiparts: dict[MultipartUploadId, "S3Multipart"]
|
|
106
106
|
objects: Union["KeyStore", "VersionedKeyStore"]
|
|
107
107
|
versioning_status: BucketVersioningStatus | None
|
|
108
|
-
lifecycle_rules:
|
|
109
|
-
transition_default_minimum_object_size:
|
|
110
|
-
policy:
|
|
111
|
-
website_configuration:
|
|
108
|
+
lifecycle_rules: LifecycleRules | None
|
|
109
|
+
transition_default_minimum_object_size: TransitionDefaultMinimumObjectSize | None
|
|
110
|
+
policy: Policy | None
|
|
111
|
+
website_configuration: WebsiteConfiguration | None
|
|
112
112
|
acl: AccessControlPolicy
|
|
113
|
-
cors_rules:
|
|
113
|
+
cors_rules: CORSConfiguration | None
|
|
114
114
|
logging: LoggingEnabled
|
|
115
115
|
notification_configuration: NotificationConfiguration
|
|
116
116
|
payer: Payer
|
|
117
|
-
encryption_rule:
|
|
118
|
-
public_access_block:
|
|
119
|
-
accelerate_status:
|
|
117
|
+
encryption_rule: ServerSideEncryptionRule | None
|
|
118
|
+
public_access_block: PublicAccessBlockConfiguration | None
|
|
119
|
+
accelerate_status: BucketAccelerateStatus | None
|
|
120
120
|
object_lock_enabled: bool
|
|
121
121
|
object_ownership: ObjectOwnership
|
|
122
122
|
intelligent_tiering_configurations: dict[IntelligentTieringId, IntelligentTieringConfiguration]
|
|
123
123
|
analytics_configurations: dict[AnalyticsId, AnalyticsConfiguration]
|
|
124
124
|
inventory_configurations: dict[InventoryId, InventoryConfiguration]
|
|
125
125
|
metric_configurations: dict[MetricsId, MetricsConfiguration]
|
|
126
|
-
object_lock_default_retention:
|
|
126
|
+
object_lock_default_retention: DefaultRetention | None
|
|
127
127
|
replication: ReplicationConfiguration
|
|
128
128
|
owner: Owner
|
|
129
129
|
|
|
@@ -256,58 +256,58 @@ class S3Bucket:
|
|
|
256
256
|
|
|
257
257
|
class S3Object:
|
|
258
258
|
key: ObjectKey
|
|
259
|
-
version_id:
|
|
259
|
+
version_id: ObjectVersionId | None
|
|
260
260
|
bucket: BucketName
|
|
261
|
-
owner:
|
|
262
|
-
size:
|
|
263
|
-
etag:
|
|
261
|
+
owner: Owner | None
|
|
262
|
+
size: Size | None
|
|
263
|
+
etag: ETag | None
|
|
264
264
|
user_metadata: Metadata
|
|
265
265
|
system_metadata: Metadata
|
|
266
266
|
last_modified: datetime
|
|
267
|
-
expires:
|
|
268
|
-
expiration:
|
|
267
|
+
expires: datetime | None
|
|
268
|
+
expiration: Expiration | None # right now, this is stored in the provider cache
|
|
269
269
|
storage_class: StorageClass | ObjectStorageClass
|
|
270
|
-
encryption:
|
|
271
|
-
kms_key_id:
|
|
272
|
-
bucket_key_enabled:
|
|
273
|
-
sse_key_hash:
|
|
270
|
+
encryption: ServerSideEncryption | None # inherit bucket
|
|
271
|
+
kms_key_id: SSEKMSKeyId | None # inherit bucket
|
|
272
|
+
bucket_key_enabled: bool | None # inherit bucket
|
|
273
|
+
sse_key_hash: SSECustomerKeyMD5 | None
|
|
274
274
|
checksum_algorithm: ChecksumAlgorithm
|
|
275
275
|
checksum_value: str
|
|
276
276
|
checksum_type: ChecksumType
|
|
277
|
-
lock_mode:
|
|
278
|
-
lock_legal_status:
|
|
279
|
-
lock_until:
|
|
280
|
-
website_redirect_location:
|
|
281
|
-
acl:
|
|
277
|
+
lock_mode: ObjectLockMode | ObjectLockRetentionMode | None
|
|
278
|
+
lock_legal_status: ObjectLockLegalHoldStatus | None
|
|
279
|
+
lock_until: datetime | None
|
|
280
|
+
website_redirect_location: WebsiteRedirectLocation | None
|
|
281
|
+
acl: AccessControlPolicy | None
|
|
282
282
|
is_current: bool
|
|
283
|
-
parts:
|
|
284
|
-
restore:
|
|
283
|
+
parts: dict[int, InternalObjectPart] | None
|
|
284
|
+
restore: Restore | None
|
|
285
285
|
internal_last_modified: int
|
|
286
286
|
|
|
287
287
|
def __init__(
|
|
288
288
|
self,
|
|
289
289
|
key: ObjectKey,
|
|
290
|
-
etag:
|
|
291
|
-
size:
|
|
292
|
-
version_id:
|
|
293
|
-
user_metadata:
|
|
294
|
-
system_metadata:
|
|
290
|
+
etag: ETag | None = None,
|
|
291
|
+
size: int | None = None,
|
|
292
|
+
version_id: ObjectVersionId | None = None,
|
|
293
|
+
user_metadata: Metadata | None = None,
|
|
294
|
+
system_metadata: Metadata | None = None,
|
|
295
295
|
storage_class: StorageClass = StorageClass.STANDARD,
|
|
296
|
-
expires:
|
|
297
|
-
expiration:
|
|
298
|
-
checksum_algorithm:
|
|
299
|
-
checksum_value:
|
|
300
|
-
checksum_type:
|
|
301
|
-
encryption:
|
|
302
|
-
kms_key_id:
|
|
303
|
-
sse_key_hash:
|
|
296
|
+
expires: datetime | None = None,
|
|
297
|
+
expiration: Expiration | None = None,
|
|
298
|
+
checksum_algorithm: ChecksumAlgorithm | None = None,
|
|
299
|
+
checksum_value: str | None = None,
|
|
300
|
+
checksum_type: ChecksumType | None = ChecksumType.FULL_OBJECT,
|
|
301
|
+
encryption: ServerSideEncryption | None = None,
|
|
302
|
+
kms_key_id: SSEKMSKeyId | None = None,
|
|
303
|
+
sse_key_hash: SSECustomerKeyMD5 | None = None,
|
|
304
304
|
bucket_key_enabled: bool = False,
|
|
305
|
-
lock_mode:
|
|
306
|
-
lock_legal_status:
|
|
307
|
-
lock_until:
|
|
308
|
-
website_redirect_location:
|
|
309
|
-
acl:
|
|
310
|
-
owner:
|
|
305
|
+
lock_mode: ObjectLockMode | ObjectLockRetentionMode | None = None,
|
|
306
|
+
lock_legal_status: ObjectLockLegalHoldStatus | None = None,
|
|
307
|
+
lock_until: datetime | None = None,
|
|
308
|
+
website_redirect_location: WebsiteRedirectLocation | None = None,
|
|
309
|
+
acl: AccessControlPolicy | None = None, # TODO
|
|
310
|
+
owner: Owner | None = None,
|
|
311
311
|
):
|
|
312
312
|
self.key = key
|
|
313
313
|
self.user_metadata = (
|
|
@@ -406,19 +406,19 @@ class S3DeleteMarker:
|
|
|
406
406
|
# TODO: could use dataclass, validate after models are set
|
|
407
407
|
class S3Part:
|
|
408
408
|
part_number: PartNumber
|
|
409
|
-
etag:
|
|
409
|
+
etag: ETag | None
|
|
410
410
|
last_modified: datetime
|
|
411
|
-
size:
|
|
412
|
-
checksum_algorithm:
|
|
413
|
-
checksum_value:
|
|
411
|
+
size: int | None
|
|
412
|
+
checksum_algorithm: ChecksumAlgorithm | None
|
|
413
|
+
checksum_value: str | None
|
|
414
414
|
|
|
415
415
|
def __init__(
|
|
416
416
|
self,
|
|
417
417
|
part_number: PartNumber,
|
|
418
418
|
size: int = None,
|
|
419
419
|
etag: ETag = None,
|
|
420
|
-
checksum_algorithm:
|
|
421
|
-
checksum_value:
|
|
420
|
+
checksum_algorithm: ChecksumAlgorithm | None = None,
|
|
421
|
+
checksum_value: str | None = None,
|
|
422
422
|
):
|
|
423
423
|
self.last_modified = datetime.now(tz=_gmt_zone_info)
|
|
424
424
|
self.part_number = part_number
|
|
@@ -436,8 +436,8 @@ class S3Multipart:
|
|
|
436
436
|
parts: dict[PartNumber, S3Part]
|
|
437
437
|
object: S3Object
|
|
438
438
|
upload_id: MultipartUploadId
|
|
439
|
-
checksum_value:
|
|
440
|
-
checksum_type:
|
|
439
|
+
checksum_value: str | None
|
|
440
|
+
checksum_type: ChecksumType | None
|
|
441
441
|
checksum_algorithm: ChecksumAlgorithm
|
|
442
442
|
initiated: datetime
|
|
443
443
|
precondition: bool
|
|
@@ -446,25 +446,25 @@ class S3Multipart:
|
|
|
446
446
|
self,
|
|
447
447
|
key: ObjectKey,
|
|
448
448
|
storage_class: StorageClass | ObjectStorageClass = StorageClass.STANDARD,
|
|
449
|
-
expires:
|
|
450
|
-
expiration:
|
|
451
|
-
checksum_algorithm:
|
|
452
|
-
checksum_type:
|
|
453
|
-
encryption:
|
|
454
|
-
kms_key_id:
|
|
449
|
+
expires: datetime | None = None,
|
|
450
|
+
expiration: datetime | None = None, # come from lifecycle
|
|
451
|
+
checksum_algorithm: ChecksumAlgorithm | None = None,
|
|
452
|
+
checksum_type: ChecksumType | None = None,
|
|
453
|
+
encryption: ServerSideEncryption | None = None, # inherit bucket
|
|
454
|
+
kms_key_id: SSEKMSKeyId | None = None, # inherit bucket
|
|
455
455
|
bucket_key_enabled: bool = False, # inherit bucket
|
|
456
|
-
sse_key_hash:
|
|
457
|
-
lock_mode:
|
|
458
|
-
lock_legal_status:
|
|
459
|
-
lock_until:
|
|
460
|
-
website_redirect_location:
|
|
461
|
-
acl:
|
|
462
|
-
user_metadata:
|
|
463
|
-
system_metadata:
|
|
464
|
-
initiator:
|
|
465
|
-
tagging:
|
|
466
|
-
owner:
|
|
467
|
-
precondition:
|
|
456
|
+
sse_key_hash: SSECustomerKeyMD5 | None = None,
|
|
457
|
+
lock_mode: ObjectLockMode | None = None,
|
|
458
|
+
lock_legal_status: ObjectLockLegalHoldStatus | None = None,
|
|
459
|
+
lock_until: datetime | None = None,
|
|
460
|
+
website_redirect_location: WebsiteRedirectLocation | None = None,
|
|
461
|
+
acl: AccessControlPolicy | None = None, # TODO
|
|
462
|
+
user_metadata: Metadata | None = None,
|
|
463
|
+
system_metadata: Metadata | None = None,
|
|
464
|
+
initiator: Owner | None = None,
|
|
465
|
+
tagging: dict[str, str] | None = None,
|
|
466
|
+
owner: Owner | None = None,
|
|
467
|
+
precondition: bool | None = None,
|
|
468
468
|
):
|
|
469
469
|
self.id = token_urlsafe(96) # MultipartUploadId is 128 characters long
|
|
470
470
|
self.initiated = datetime.now(tz=_gmt_zone_info)
|
|
@@ -638,7 +638,7 @@ class KeyStore:
|
|
|
638
638
|
|
|
639
639
|
def values(self, *_, **__) -> list[S3Object | S3DeleteMarker]:
|
|
640
640
|
# we create a shallow copy with dict to avoid size changed during iteration
|
|
641
|
-
return
|
|
641
|
+
return list(dict(self._store).values())
|
|
642
642
|
|
|
643
643
|
def is_empty(self) -> bool:
|
|
644
644
|
return not self._store
|
|
@@ -6,7 +6,7 @@ import logging
|
|
|
6
6
|
import re
|
|
7
7
|
from concurrent.futures import ThreadPoolExecutor
|
|
8
8
|
from dataclasses import dataclass
|
|
9
|
-
from typing import
|
|
9
|
+
from typing import TypedDict
|
|
10
10
|
from urllib.parse import quote
|
|
11
11
|
|
|
12
12
|
from botocore.exceptions import ClientError
|
|
@@ -21,6 +21,7 @@ from localstack.aws.api.s3 import (
|
|
|
21
21
|
Event,
|
|
22
22
|
EventBridgeConfiguration,
|
|
23
23
|
EventList,
|
|
24
|
+
InvalidArgument,
|
|
24
25
|
LambdaFunctionArn,
|
|
25
26
|
LambdaFunctionConfiguration,
|
|
26
27
|
NotificationConfiguration,
|
|
@@ -34,8 +35,8 @@ from localstack.aws.api.s3 import (
|
|
|
34
35
|
TopicConfiguration,
|
|
35
36
|
)
|
|
36
37
|
from localstack.aws.connect import connect_to
|
|
38
|
+
from localstack.services.s3.exceptions import MalformedXML
|
|
37
39
|
from localstack.services.s3.models import S3Bucket, S3DeleteMarker, S3Object
|
|
38
|
-
from localstack.services.s3.utils import _create_invalid_argument_exc
|
|
39
40
|
from localstack.utils.aws import arns
|
|
40
41
|
from localstack.utils.aws.arns import ARN_PARTITION_REGEX, get_partition, parse_arn, s3_bucket_arn
|
|
41
42
|
from localstack.utils.aws.client_types import ServicePrincipal
|
|
@@ -64,8 +65,8 @@ HEADER_AMZN_XRAY = "X-Amzn-Trace-Id"
|
|
|
64
65
|
class S3NotificationContent(TypedDict):
|
|
65
66
|
s3SchemaVersion: str
|
|
66
67
|
configurationId: NotificationId
|
|
67
|
-
bucket:
|
|
68
|
-
object:
|
|
68
|
+
bucket: dict[str, str] # todo
|
|
69
|
+
object: dict[str, str | int] # todo
|
|
69
70
|
|
|
70
71
|
|
|
71
72
|
class EventRecord(TypedDict):
|
|
@@ -74,14 +75,14 @@ class EventRecord(TypedDict):
|
|
|
74
75
|
awsRegion: str
|
|
75
76
|
eventTime: str
|
|
76
77
|
eventName: str
|
|
77
|
-
userIdentity:
|
|
78
|
-
requestParameters:
|
|
79
|
-
responseElements:
|
|
78
|
+
userIdentity: dict[str, str]
|
|
79
|
+
requestParameters: dict[str, str]
|
|
80
|
+
responseElements: dict[str, str]
|
|
80
81
|
s3: S3NotificationContent
|
|
81
82
|
|
|
82
83
|
|
|
83
84
|
class Notification(TypedDict):
|
|
84
|
-
Records:
|
|
85
|
+
Records: list[EventRecord]
|
|
85
86
|
|
|
86
87
|
|
|
87
88
|
@dataclass
|
|
@@ -101,15 +102,15 @@ class S3EventNotificationContext:
|
|
|
101
102
|
key_etag: str
|
|
102
103
|
key_version_id: str
|
|
103
104
|
key_expiry: datetime.datetime
|
|
104
|
-
key_storage_class:
|
|
105
|
+
key_storage_class: StorageClass | None
|
|
105
106
|
|
|
106
107
|
@classmethod
|
|
107
|
-
def
|
|
108
|
+
def from_request_context(
|
|
108
109
|
cls,
|
|
109
110
|
request_context: RequestContext,
|
|
110
111
|
s3_bucket: S3Bucket,
|
|
111
112
|
s3_object: S3Object | S3DeleteMarker,
|
|
112
|
-
) ->
|
|
113
|
+
) -> S3EventNotificationContext:
|
|
113
114
|
"""
|
|
114
115
|
Create an S3EventNotificationContext from a RequestContext.
|
|
115
116
|
The key is not always present in the request context depending on the event type. In that case, we can use
|
|
@@ -165,7 +166,7 @@ class BucketVerificationContext:
|
|
|
165
166
|
request_id: str
|
|
166
167
|
bucket_name: str
|
|
167
168
|
region: str
|
|
168
|
-
configuration:
|
|
169
|
+
configuration: dict
|
|
169
170
|
skip_destination_validation: bool
|
|
170
171
|
|
|
171
172
|
|
|
@@ -185,7 +186,7 @@ def _matching_event(events: EventList, event_name: str) -> bool:
|
|
|
185
186
|
|
|
186
187
|
|
|
187
188
|
def _matching_filter(
|
|
188
|
-
notification_filter:
|
|
189
|
+
notification_filter: NotificationConfigurationFilter | None, key_name: str
|
|
189
190
|
) -> bool:
|
|
190
191
|
"""
|
|
191
192
|
See: https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-filtering.html
|
|
@@ -213,11 +214,11 @@ def _matching_filter(
|
|
|
213
214
|
class BaseNotifier:
|
|
214
215
|
service_name: str
|
|
215
216
|
|
|
216
|
-
def notify(self, ctx: S3EventNotificationContext, config:
|
|
217
|
+
def notify(self, ctx: S3EventNotificationContext, config: dict):
|
|
217
218
|
raise NotImplementedError
|
|
218
219
|
|
|
219
220
|
@staticmethod
|
|
220
|
-
def should_notify(ctx: S3EventNotificationContext, config:
|
|
221
|
+
def should_notify(ctx: S3EventNotificationContext, config: dict) -> bool:
|
|
221
222
|
"""
|
|
222
223
|
Helper method checking if the event should be notified to the configured notifiers from the configuration
|
|
223
224
|
:param ctx: S3EventNotificationContext
|
|
@@ -229,12 +230,12 @@ class BaseNotifier:
|
|
|
229
230
|
)
|
|
230
231
|
|
|
231
232
|
@staticmethod
|
|
232
|
-
def _get_arn_value_and_name(notifier_configuration:
|
|
233
|
+
def _get_arn_value_and_name(notifier_configuration: dict) -> tuple[str, str]:
|
|
233
234
|
raise NotImplementedError
|
|
234
235
|
|
|
235
236
|
def validate_configuration_for_notifier(
|
|
236
237
|
self,
|
|
237
|
-
configurations:
|
|
238
|
+
configurations: list[dict],
|
|
238
239
|
skip_destination_validation: bool,
|
|
239
240
|
context: RequestContext,
|
|
240
241
|
bucket_name: str,
|
|
@@ -272,26 +273,29 @@ class BaseNotifier:
|
|
|
272
273
|
arn, argument_name = self._get_arn_value_and_name(configuration)
|
|
273
274
|
|
|
274
275
|
if not re.match(f"{ARN_PARTITION_REGEX}:{self.service_name}:", arn):
|
|
275
|
-
raise
|
|
276
|
-
"The ARN could not be parsed",
|
|
276
|
+
raise InvalidArgument(
|
|
277
|
+
"The ARN could not be parsed",
|
|
278
|
+
ArgumentName=argument_name,
|
|
279
|
+
ArgumentValue=arn,
|
|
277
280
|
)
|
|
281
|
+
|
|
278
282
|
if not verification_ctx.skip_destination_validation:
|
|
279
283
|
self._verify_target(arn, verification_ctx)
|
|
280
284
|
|
|
281
285
|
if filter_rules := configuration.get("Filter", {}).get("Key", {}).get("FilterRules"):
|
|
282
286
|
for rule in filter_rules:
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
287
|
+
if "Name" not in rule or "Value" not in rule:
|
|
288
|
+
raise MalformedXML()
|
|
289
|
+
|
|
290
|
+
if rule["Name"].lower() not in ["suffix", "prefix"]:
|
|
291
|
+
raise InvalidArgument(
|
|
286
292
|
"filter rule name must be either prefix or suffix",
|
|
287
|
-
|
|
288
|
-
rule["
|
|
289
|
-
)
|
|
290
|
-
if not rule["Value"]:
|
|
291
|
-
raise _create_invalid_argument_exc(
|
|
292
|
-
"filter value cannot be empty", rule["Name"], rule["Value"]
|
|
293
|
+
ArgumentName="FilterRule.Name",
|
|
294
|
+
ArgumentValue=rule["Name"],
|
|
293
295
|
)
|
|
294
296
|
|
|
297
|
+
rule["Name"] = rule["Name"].capitalize()
|
|
298
|
+
|
|
295
299
|
@staticmethod
|
|
296
300
|
def _get_test_payload(verification_ctx: BucketVerificationContext):
|
|
297
301
|
return {
|
|
@@ -381,8 +385,8 @@ class SqsNotifier(BaseNotifier):
|
|
|
381
385
|
service_name = "sqs"
|
|
382
386
|
|
|
383
387
|
@staticmethod
|
|
384
|
-
def _get_arn_value_and_name(queue_configuration: QueueConfiguration) ->
|
|
385
|
-
return queue_configuration.get("QueueArn", ""), "
|
|
388
|
+
def _get_arn_value_and_name(queue_configuration: QueueConfiguration) -> tuple[QueueArn, str]:
|
|
389
|
+
return queue_configuration.get("QueueArn", ""), "Queue"
|
|
386
390
|
|
|
387
391
|
def _verify_target(self, target_arn: str, verification_ctx: BucketVerificationContext) -> None:
|
|
388
392
|
if not is_api_enabled("sqs"):
|
|
@@ -402,13 +406,20 @@ class SqsNotifier(BaseNotifier):
|
|
|
402
406
|
queue_url = sqs_client.get_queue_url(
|
|
403
407
|
QueueName=arn_data["resource"], QueueOwnerAWSAccountId=arn_data["account"]
|
|
404
408
|
)["QueueUrl"]
|
|
405
|
-
except ClientError:
|
|
406
|
-
|
|
407
|
-
|
|
409
|
+
except ClientError as e:
|
|
410
|
+
code = e.response["Error"]["Code"]
|
|
411
|
+
LOG.error(
|
|
412
|
+
"Could not validate the notification destination %s: %s",
|
|
413
|
+
target_arn,
|
|
414
|
+
code,
|
|
415
|
+
exc_info=LOG.isEnabledFor(logging.DEBUG),
|
|
416
|
+
)
|
|
417
|
+
raise InvalidArgument(
|
|
408
418
|
"Unable to validate the following destination configurations",
|
|
409
|
-
|
|
410
|
-
|
|
419
|
+
ArgumentName=target_arn,
|
|
420
|
+
ArgumentValue="The destination queue does not exist",
|
|
411
421
|
)
|
|
422
|
+
|
|
412
423
|
# send test event with the request metadata for permissions
|
|
413
424
|
# https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-event-types-and-destinations.html#supported-notification-event-types
|
|
414
425
|
sqs_client = connect_to(region_name=arn_data["region"]).sqs.request_metadata(
|
|
@@ -424,10 +435,10 @@ class SqsNotifier(BaseNotifier):
|
|
|
424
435
|
verification_ctx.bucket_name,
|
|
425
436
|
target_arn,
|
|
426
437
|
)
|
|
427
|
-
raise
|
|
438
|
+
raise InvalidArgument(
|
|
428
439
|
"Unable to validate the following destination configurations",
|
|
429
|
-
|
|
430
|
-
|
|
440
|
+
ArgumentName=target_arn,
|
|
441
|
+
ArgumentValue="Permissions on the destination queue do not allow S3 to publish notifications from this bucket",
|
|
431
442
|
) from e
|
|
432
443
|
|
|
433
444
|
def notify(self, ctx: S3EventNotificationContext, config: QueueConfiguration):
|
|
@@ -454,10 +465,11 @@ class SqsNotifier(BaseNotifier):
|
|
|
454
465
|
MessageSystemAttributes=system_attributes,
|
|
455
466
|
)
|
|
456
467
|
except Exception:
|
|
457
|
-
LOG.
|
|
468
|
+
LOG.error(
|
|
458
469
|
'Unable to send notification for S3 bucket "%s" to SQS queue "%s"',
|
|
459
470
|
ctx.bucket_name,
|
|
460
471
|
parsed_arn["resource"],
|
|
472
|
+
exc_info=LOG.isEnabledFor(logging.DEBUG),
|
|
461
473
|
)
|
|
462
474
|
|
|
463
475
|
|
|
@@ -483,10 +495,10 @@ class SnsNotifier(BaseNotifier):
|
|
|
483
495
|
try:
|
|
484
496
|
sns_client.get_topic_attributes(TopicArn=target_arn)
|
|
485
497
|
except ClientError:
|
|
486
|
-
raise
|
|
498
|
+
raise InvalidArgument(
|
|
487
499
|
"Unable to validate the following destination configurations",
|
|
488
|
-
|
|
489
|
-
|
|
500
|
+
ArgumentName=target_arn,
|
|
501
|
+
ArgumentValue="The destination topic does not exist",
|
|
490
502
|
)
|
|
491
503
|
|
|
492
504
|
sns_client = connect_to(region_name=arn_data["region"]).sns.request_metadata(
|
|
@@ -506,10 +518,10 @@ class SnsNotifier(BaseNotifier):
|
|
|
506
518
|
verification_ctx.bucket_name,
|
|
507
519
|
target_arn,
|
|
508
520
|
)
|
|
509
|
-
raise
|
|
521
|
+
raise InvalidArgument(
|
|
510
522
|
"Unable to validate the following destination configurations",
|
|
511
|
-
|
|
512
|
-
|
|
523
|
+
ArgumentName=target_arn,
|
|
524
|
+
ArgumentValue="Permissions on the destination topic do not allow S3 to publish notifications from this bucket",
|
|
513
525
|
) from e
|
|
514
526
|
|
|
515
527
|
def notify(self, ctx: S3EventNotificationContext, config: TopicConfiguration):
|
|
@@ -536,10 +548,11 @@ class SnsNotifier(BaseNotifier):
|
|
|
536
548
|
Subject="Amazon S3 Notification",
|
|
537
549
|
)
|
|
538
550
|
except Exception:
|
|
539
|
-
LOG.
|
|
551
|
+
LOG.error(
|
|
540
552
|
'Unable to send notification for S3 bucket "%s" to SNS topic "%s"',
|
|
541
553
|
ctx.bucket_name,
|
|
542
554
|
topic_arn,
|
|
555
|
+
exc_info=LOG.isEnabledFor(logging.DEBUG),
|
|
543
556
|
)
|
|
544
557
|
|
|
545
558
|
|
|
@@ -549,7 +562,7 @@ class LambdaNotifier(BaseNotifier):
|
|
|
549
562
|
@staticmethod
|
|
550
563
|
def _get_arn_value_and_name(
|
|
551
564
|
lambda_configuration: LambdaFunctionConfiguration,
|
|
552
|
-
) ->
|
|
565
|
+
) -> tuple[LambdaFunctionArn, str]:
|
|
553
566
|
return lambda_configuration.get("LambdaFunctionArn", ""), "LambdaFunctionArn"
|
|
554
567
|
|
|
555
568
|
def _verify_target(self, target_arn: str, verification_ctx: BucketVerificationContext) -> None:
|
|
@@ -567,10 +580,10 @@ class LambdaNotifier(BaseNotifier):
|
|
|
567
580
|
try:
|
|
568
581
|
lambda_client.get_function(FunctionName=target_arn)
|
|
569
582
|
except ClientError:
|
|
570
|
-
raise
|
|
583
|
+
raise InvalidArgument(
|
|
571
584
|
"Unable to validate the following destination configurations",
|
|
572
|
-
|
|
573
|
-
|
|
585
|
+
ArgumentName=target_arn,
|
|
586
|
+
ArgumentValue="The destination Lambda does not exist",
|
|
574
587
|
)
|
|
575
588
|
lambda_client = connect_to(region_name=arn_data["region"]).lambda_.request_metadata(
|
|
576
589
|
source_arn=s3_bucket_arn(verification_ctx.bucket_name, region=verification_ctx.region),
|
|
@@ -579,10 +592,10 @@ class LambdaNotifier(BaseNotifier):
|
|
|
579
592
|
try:
|
|
580
593
|
lambda_client.invoke(FunctionName=target_arn, InvocationType=InvocationType.DryRun)
|
|
581
594
|
except ClientError as e:
|
|
582
|
-
raise
|
|
595
|
+
raise InvalidArgument(
|
|
583
596
|
"Unable to validate the following destination configurations",
|
|
584
|
-
|
|
585
|
-
|
|
597
|
+
ArgumentName=f"{target_arn}, null",
|
|
598
|
+
ArgumentValue=f"Not authorized to invoke function [{target_arn}]",
|
|
586
599
|
) from e
|
|
587
600
|
|
|
588
601
|
def notify(self, ctx: S3EventNotificationContext, config: LambdaFunctionConfiguration):
|
|
@@ -604,10 +617,11 @@ class LambdaNotifier(BaseNotifier):
|
|
|
604
617
|
Payload=payload,
|
|
605
618
|
)
|
|
606
619
|
except Exception:
|
|
607
|
-
LOG.
|
|
620
|
+
LOG.error(
|
|
608
621
|
'Unable to send notification for S3 bucket "%s" to Lambda function "%s".',
|
|
609
622
|
ctx.bucket_name,
|
|
610
623
|
lambda_arn,
|
|
624
|
+
exc_info=LOG.isEnabledFor(logging.DEBUG),
|
|
611
625
|
)
|
|
612
626
|
|
|
613
627
|
|
|
@@ -698,14 +712,14 @@ class EventBridgeNotifier(BaseNotifier):
|
|
|
698
712
|
return entry
|
|
699
713
|
|
|
700
714
|
@staticmethod
|
|
701
|
-
def should_notify(ctx: S3EventNotificationContext, config:
|
|
715
|
+
def should_notify(ctx: S3EventNotificationContext, config: dict) -> bool:
|
|
702
716
|
# Events are always passed to EventBridge, you can route the event in EventBridge
|
|
703
717
|
# See https://docs.aws.amazon.com/AmazonS3/latest/userguide/EventBridge.html
|
|
704
718
|
return True
|
|
705
719
|
|
|
706
720
|
def validate_configuration_for_notifier(
|
|
707
721
|
self,
|
|
708
|
-
configurations:
|
|
722
|
+
configurations: list[dict],
|
|
709
723
|
skip_destination_validation: bool,
|
|
710
724
|
context: RequestContext,
|
|
711
725
|
bucket_name: str,
|
|
@@ -729,8 +743,10 @@ class EventBridgeNotifier(BaseNotifier):
|
|
|
729
743
|
try:
|
|
730
744
|
events_client.put_events(Entries=[entry])
|
|
731
745
|
except Exception:
|
|
732
|
-
LOG.
|
|
733
|
-
'Unable to send notification for S3 bucket "%s" to EventBridge',
|
|
746
|
+
LOG.error(
|
|
747
|
+
'Unable to send notification for S3 bucket "%s" to EventBridge',
|
|
748
|
+
ctx.bucket_name,
|
|
749
|
+
exc_info=LOG.isEnabledFor(logging.DEBUG),
|
|
734
750
|
)
|
|
735
751
|
|
|
736
752
|
|