localstack-core 4.6.1.dev74__py3-none-any.whl → 4.10.1.dev7__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 +1524 -64
- 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 +13 -0
- 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 +40 -31
- localstack/constants.py +4 -29
- localstack/deprecations.py +5 -5
- localstack/dev/kubernetes/__main__.py +85 -5
- 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 +286 -139
- 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 +161 -31
- 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 +8 -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 +31 -22
- localstack/services/cloudformation/v2/entities.py +65 -92
- localstack/services/cloudformation/v2/provider.py +553 -128
- 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 +49 -8
- 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 +48 -7
- 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 +17 -11
- 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 +4 -4
- 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 +4 -4
- 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 +22 -60
- 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 -55
- 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 +11 -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.dev74.dist-info → localstack_core-4.10.1.dev7.dist-info}/METADATA +18 -14
- {localstack_core-4.6.1.dev74.dist-info → localstack_core-4.10.1.dev7.dist-info}/RECORD +663 -656
- {localstack_core-4.6.1.dev74.dist-info → localstack_core-4.10.1.dev7.dist-info}/entry_points.txt +8 -4
- localstack_core-4.10.1.dev7.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.dev74.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.dev74.data → localstack_core-4.10.1.dev7.data}/scripts/localstack +0 -0
- {localstack_core-4.6.1.dev74.data → localstack_core-4.10.1.dev7.data}/scripts/localstack-supervisor +0 -0
- {localstack_core-4.6.1.dev74.data → localstack_core-4.10.1.dev7.data}/scripts/localstack.bat +0 -0
- {localstack_core-4.6.1.dev74.dist-info → localstack_core-4.10.1.dev7.dist-info}/WHEEL +0 -0
- {localstack_core-4.6.1.dev74.dist-info → localstack_core-4.10.1.dev7.dist-info}/licenses/LICENSE.txt +0 -0
- {localstack_core-4.6.1.dev74.dist-info → localstack_core-4.10.1.dev7.dist-info}/top_level.txt +0 -0
|
@@ -1,53 +1,183 @@
|
|
|
1
1
|
import re
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from botocore.exceptions import ParamValidationError
|
|
2
5
|
|
|
3
6
|
from localstack.services.cloudformation.engine.v2.change_set_model import (
|
|
4
|
-
|
|
7
|
+
NodeIntrinsicFunction,
|
|
8
|
+
NodeProperty,
|
|
5
9
|
NodeResource,
|
|
6
10
|
NodeTemplate,
|
|
11
|
+
Nothing,
|
|
7
12
|
is_nothing,
|
|
8
13
|
)
|
|
9
14
|
from localstack.services.cloudformation.engine.v2.change_set_model_preproc import (
|
|
15
|
+
_PSEUDO_PARAMETERS,
|
|
16
|
+
ChangeSetModelPreproc,
|
|
10
17
|
PreprocEntityDelta,
|
|
18
|
+
PreprocResource,
|
|
11
19
|
)
|
|
12
|
-
from localstack.services.cloudformation.engine.v2.change_set_model_visitor import (
|
|
13
|
-
ChangeSetModelVisitor,
|
|
14
|
-
)
|
|
15
|
-
from localstack.services.cloudformation.engine.validations import ValidationError
|
|
16
|
-
from localstack.services.cloudformation.v2.entities import ChangeSet
|
|
17
|
-
|
|
18
|
-
VALID_LOGICAL_RESOURCE_ID_RE = re.compile(r"^[A-Za-z0-9]+$")
|
|
19
20
|
|
|
20
21
|
|
|
21
|
-
class ChangeSetModelValidator(
|
|
22
|
-
def __init__(self, change_set: ChangeSet):
|
|
23
|
-
self._change_set = change_set
|
|
24
|
-
|
|
22
|
+
class ChangeSetModelValidator(ChangeSetModelPreproc):
|
|
25
23
|
def validate(self):
|
|
26
|
-
self.
|
|
24
|
+
self.process()
|
|
27
25
|
|
|
28
26
|
def visit_node_template(self, node_template: NodeTemplate):
|
|
29
|
-
self.visit(node_template.
|
|
27
|
+
self.visit(node_template.mappings)
|
|
30
28
|
self.visit(node_template.resources)
|
|
29
|
+
self.visit(node_template.parameters)
|
|
30
|
+
|
|
31
|
+
def visit_node_intrinsic_function_fn_get_att(
|
|
32
|
+
self, node_intrinsic_function: NodeIntrinsicFunction
|
|
33
|
+
) -> PreprocEntityDelta:
|
|
34
|
+
try:
|
|
35
|
+
return super().visit_node_intrinsic_function_fn_get_att(node_intrinsic_function)
|
|
36
|
+
except RuntimeError:
|
|
37
|
+
return self.visit(node_intrinsic_function.arguments)
|
|
31
38
|
|
|
32
|
-
def
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
def visit_node_intrinsic_function_fn_sub(
|
|
40
|
+
self, node_intrinsic_function: NodeIntrinsicFunction
|
|
41
|
+
) -> PreprocEntityDelta:
|
|
42
|
+
def _compute_sub(args: str | list[Any], select_before: bool) -> str:
|
|
43
|
+
# TODO: add further schema validation.
|
|
44
|
+
string_template: str
|
|
45
|
+
sub_parameters: dict
|
|
46
|
+
if isinstance(args, str):
|
|
47
|
+
string_template = args
|
|
48
|
+
sub_parameters = {}
|
|
49
|
+
elif (
|
|
50
|
+
isinstance(args, list)
|
|
51
|
+
and len(args) == 2
|
|
52
|
+
and isinstance(args[0], str)
|
|
53
|
+
and isinstance(args[1], dict)
|
|
39
54
|
):
|
|
40
|
-
|
|
55
|
+
string_template = args[0]
|
|
56
|
+
sub_parameters = args[1]
|
|
57
|
+
else:
|
|
58
|
+
raise RuntimeError(
|
|
59
|
+
"Invalid arguments shape for Fn::Sub, expected a String "
|
|
60
|
+
f"or a Tuple of String and Map but got '{args}'"
|
|
61
|
+
)
|
|
62
|
+
sub_string = string_template
|
|
63
|
+
template_variable_names = re.findall("\\${([^}]+)}", string_template)
|
|
64
|
+
for template_variable_name in template_variable_names:
|
|
65
|
+
template_variable_value = Nothing
|
|
66
|
+
|
|
67
|
+
# Try to resolve the variable name as pseudo parameter.
|
|
68
|
+
if template_variable_name in _PSEUDO_PARAMETERS:
|
|
69
|
+
template_variable_value = self._resolve_pseudo_parameter(
|
|
70
|
+
pseudo_parameter_name=template_variable_name
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# Try to resolve the variable name as an entry to the defined parameters.
|
|
74
|
+
elif template_variable_name in sub_parameters:
|
|
75
|
+
template_variable_value = sub_parameters[template_variable_name]
|
|
76
|
+
|
|
77
|
+
# Try to resolve the variable name as GetAtt.
|
|
78
|
+
elif "." in template_variable_name:
|
|
79
|
+
try:
|
|
80
|
+
template_variable_value = self._resolve_attribute(
|
|
81
|
+
arguments=template_variable_name, select_before=select_before
|
|
82
|
+
)
|
|
83
|
+
except RuntimeError:
|
|
84
|
+
pass
|
|
41
85
|
|
|
42
|
-
|
|
43
|
-
|
|
86
|
+
# Try to resolve the variable name as Ref.
|
|
87
|
+
else:
|
|
88
|
+
try:
|
|
89
|
+
resource_delta = self._resolve_reference(logical_id=template_variable_name)
|
|
90
|
+
template_variable_value = (
|
|
91
|
+
resource_delta.before if select_before else resource_delta.after
|
|
92
|
+
)
|
|
93
|
+
if isinstance(template_variable_value, PreprocResource):
|
|
94
|
+
template_variable_value = template_variable_value.physical_resource_id
|
|
95
|
+
except RuntimeError:
|
|
96
|
+
pass
|
|
44
97
|
|
|
45
|
-
|
|
46
|
-
|
|
98
|
+
if is_nothing(template_variable_value):
|
|
99
|
+
# override the base method just for this line to prevent accessing the
|
|
100
|
+
# resource properties since we are not deploying any resources
|
|
101
|
+
template_variable_value = ""
|
|
102
|
+
|
|
103
|
+
if not isinstance(template_variable_value, str):
|
|
104
|
+
template_variable_value = str(template_variable_value)
|
|
105
|
+
|
|
106
|
+
sub_string = sub_string.replace(
|
|
107
|
+
f"${{{template_variable_name}}}", template_variable_value
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
# FIXME: the following type reduction is ported from v1; however it appears as though such
|
|
111
|
+
# reduction is not performed by the engine, and certainly not at this depth given the
|
|
112
|
+
# lack of context. This section should be removed with Fn::Sub always retuning a string
|
|
113
|
+
# and the resource providers reviewed.
|
|
114
|
+
account_id = self._change_set.account_id
|
|
115
|
+
is_another_account_id = sub_string.isdigit() and len(sub_string) == len(account_id)
|
|
116
|
+
if sub_string == account_id or is_another_account_id:
|
|
117
|
+
result = sub_string
|
|
118
|
+
elif sub_string.isdigit():
|
|
119
|
+
result = int(sub_string)
|
|
120
|
+
else:
|
|
121
|
+
try:
|
|
122
|
+
result = float(sub_string)
|
|
123
|
+
except ValueError:
|
|
124
|
+
result = sub_string
|
|
125
|
+
return result
|
|
126
|
+
|
|
127
|
+
arguments_delta = self.visit(node_intrinsic_function.arguments)
|
|
128
|
+
arguments_before = arguments_delta.before
|
|
129
|
+
arguments_after = arguments_delta.after
|
|
130
|
+
before = self._before_cache.get(node_intrinsic_function.scope, Nothing)
|
|
131
|
+
if is_nothing(before) and not is_nothing(arguments_before):
|
|
132
|
+
before = _compute_sub(args=arguments_before, select_before=True)
|
|
133
|
+
after = self._after_cache.get(node_intrinsic_function.scope, Nothing)
|
|
134
|
+
if is_nothing(after) and not is_nothing(arguments_after):
|
|
135
|
+
after = _compute_sub(args=arguments_after, select_before=False)
|
|
136
|
+
return PreprocEntityDelta(before=before, after=after)
|
|
137
|
+
|
|
138
|
+
def visit_node_intrinsic_function_fn_transform(
|
|
139
|
+
self, node_intrinsic_function: NodeIntrinsicFunction
|
|
140
|
+
):
|
|
141
|
+
# TODO Research this issue:
|
|
142
|
+
# Function is already resolved in the template reaching this point
|
|
143
|
+
# But transformation is still present in update model
|
|
144
|
+
return self.visit(node_intrinsic_function.arguments)
|
|
145
|
+
|
|
146
|
+
def visit_node_intrinsic_function_fn_split(
|
|
147
|
+
self, node_intrinsic_function: NodeIntrinsicFunction
|
|
148
|
+
) -> PreprocEntityDelta:
|
|
149
|
+
try:
|
|
150
|
+
# If an argument is a Parameter it should be resolved, any other case, ignore it
|
|
151
|
+
return super().visit_node_intrinsic_function_fn_split(node_intrinsic_function)
|
|
152
|
+
except RuntimeError:
|
|
153
|
+
return self.visit(node_intrinsic_function.arguments)
|
|
154
|
+
|
|
155
|
+
def visit_node_intrinsic_function_fn_select(
|
|
156
|
+
self, node_intrinsic_function: NodeIntrinsicFunction
|
|
157
|
+
) -> PreprocEntityDelta:
|
|
158
|
+
try:
|
|
159
|
+
# If an argument is a Parameter it should be resolved, any other case, ignore it
|
|
160
|
+
return super().visit_node_intrinsic_function_fn_select(node_intrinsic_function)
|
|
161
|
+
except RuntimeError:
|
|
162
|
+
return self.visit(node_intrinsic_function.arguments)
|
|
47
163
|
|
|
48
164
|
def visit_node_resource(self, node_resource: NodeResource) -> PreprocEntityDelta:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
)
|
|
53
|
-
|
|
165
|
+
try:
|
|
166
|
+
if delta := super().visit_node_resource(node_resource):
|
|
167
|
+
return delta
|
|
168
|
+
return super().visit_node_properties(node_resource.properties)
|
|
169
|
+
except RuntimeError:
|
|
170
|
+
return super().visit_node_properties(node_resource.properties)
|
|
171
|
+
|
|
172
|
+
def visit_node_property(self, node_property: NodeProperty) -> PreprocEntityDelta:
|
|
173
|
+
try:
|
|
174
|
+
return super().visit_node_property(node_property)
|
|
175
|
+
except ParamValidationError:
|
|
176
|
+
return self.visit(node_property.value)
|
|
177
|
+
|
|
178
|
+
# ignore errors from dynamic replacements
|
|
179
|
+
def _maybe_perform_dynamic_replacements(self, delta: PreprocEntityDelta) -> PreprocEntityDelta:
|
|
180
|
+
try:
|
|
181
|
+
return super()._maybe_perform_dynamic_replacements(delta)
|
|
182
|
+
except Exception:
|
|
183
|
+
return delta
|
|
@@ -54,6 +54,7 @@ class ChangeSetModelVisitor(abc.ABC):
|
|
|
54
54
|
# entities (parameters, mappings, conditions, etc.). Then compute the output fields; computing
|
|
55
55
|
# only the output fields would only result in the deployment logic of the referenced outputs
|
|
56
56
|
# being evaluated, hence enforce the visiting of all the resources first.
|
|
57
|
+
self.visit(node_template.conditions)
|
|
57
58
|
self.visit(node_template.resources)
|
|
58
59
|
self.visit(node_template.outputs)
|
|
59
60
|
|
|
@@ -177,6 +178,11 @@ class ChangeSetModelVisitor(abc.ABC):
|
|
|
177
178
|
):
|
|
178
179
|
self.visit_children(node_intrinsic_function)
|
|
179
180
|
|
|
181
|
+
def visit_node_intrinsic_function_fn_import_value(
|
|
182
|
+
self, node_intrinsic_function: NodeIntrinsicFunction
|
|
183
|
+
):
|
|
184
|
+
self.visit_children(node_intrinsic_function)
|
|
185
|
+
|
|
180
186
|
def visit_node_divergence(self, node_divergence: NodeDivergence):
|
|
181
187
|
self.visit_children(node_divergence)
|
|
182
188
|
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
import re
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from botocore.exceptions import ClientError
|
|
8
|
+
|
|
9
|
+
from localstack.aws.connect import connect_to
|
|
10
|
+
|
|
11
|
+
LOG = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
# CloudFormation allows using dynamic references in `Fn::Sub` expressions, so we must make sure
|
|
14
|
+
# we don't capture the parameter usage by excluding ${} characters
|
|
15
|
+
REGEX_DYNAMIC_REF = re.compile(r"{{resolve:([^:]+):([^${}]+)}}")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class DynamicReference:
|
|
20
|
+
service_name: str
|
|
21
|
+
reference_key: str
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def extract_dynamic_reference(value: Any) -> DynamicReference | None:
|
|
25
|
+
if isinstance(value, str):
|
|
26
|
+
if dynamic_ref_match := REGEX_DYNAMIC_REF.search(value):
|
|
27
|
+
return DynamicReference(dynamic_ref_match[1], dynamic_ref_match[2])
|
|
28
|
+
return None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def perform_dynamic_reference_lookup(
|
|
32
|
+
reference: DynamicReference, account_id: str, region_name: str
|
|
33
|
+
) -> str | None:
|
|
34
|
+
# basic dynamic reference support
|
|
35
|
+
# see: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html
|
|
36
|
+
# technically there are more restrictions for each of these services but checking each of these
|
|
37
|
+
# isn't really necessary for the current level of emulation
|
|
38
|
+
|
|
39
|
+
# only these 3 services are supported for dynamic references right now
|
|
40
|
+
if reference.service_name == "ssm":
|
|
41
|
+
ssm_client = connect_to(aws_access_key_id=account_id, region_name=region_name).ssm
|
|
42
|
+
try:
|
|
43
|
+
return ssm_client.get_parameter(Name=reference.reference_key)["Parameter"]["Value"]
|
|
44
|
+
except ClientError as e:
|
|
45
|
+
LOG.error("client error accessing SSM parameter '%s': %s", reference.reference_key, e)
|
|
46
|
+
raise
|
|
47
|
+
elif reference.service_name == "ssm-secure":
|
|
48
|
+
ssm_client = connect_to(aws_access_key_id=account_id, region_name=region_name).ssm
|
|
49
|
+
try:
|
|
50
|
+
return ssm_client.get_parameter(Name=reference.reference_key, WithDecryption=True)[
|
|
51
|
+
"Parameter"
|
|
52
|
+
]["Value"]
|
|
53
|
+
except ClientError as e:
|
|
54
|
+
LOG.error("client error accessing SSM parameter '%s': %s", reference.reference_key, e)
|
|
55
|
+
raise
|
|
56
|
+
elif reference.service_name == "secretsmanager":
|
|
57
|
+
# reference key needs to be parsed further
|
|
58
|
+
# because {{resolve:secretsmanager:secret-id:secret-string:json-key:version-stage:version-id}}
|
|
59
|
+
# we match for "secret-id:secret-string:json-key:version-stage:version-id"
|
|
60
|
+
# where
|
|
61
|
+
# secret-id can either be the secret name or the full ARN of the secret
|
|
62
|
+
# secret-string *must* be SecretString
|
|
63
|
+
# all other values are optional
|
|
64
|
+
secret_id = reference.reference_key
|
|
65
|
+
[json_key, version_stage, version_id] = [None, None, None]
|
|
66
|
+
if "SecretString" in reference.reference_key:
|
|
67
|
+
parts = reference.reference_key.split(":SecretString:")
|
|
68
|
+
secret_id = parts[0]
|
|
69
|
+
# json-key, version-stage and version-id are optional.
|
|
70
|
+
[json_key, version_stage, version_id] = f"{parts[1]}::".split(":")[:3]
|
|
71
|
+
|
|
72
|
+
kwargs = {} # optional args for get_secret_value
|
|
73
|
+
if version_id:
|
|
74
|
+
kwargs["VersionId"] = version_id
|
|
75
|
+
if version_stage:
|
|
76
|
+
kwargs["VersionStage"] = version_stage
|
|
77
|
+
|
|
78
|
+
secretsmanager_client = connect_to(
|
|
79
|
+
aws_access_key_id=account_id, region_name=region_name
|
|
80
|
+
).secretsmanager
|
|
81
|
+
try:
|
|
82
|
+
secret_value = secretsmanager_client.get_secret_value(SecretId=secret_id, **kwargs)[
|
|
83
|
+
"SecretString"
|
|
84
|
+
]
|
|
85
|
+
except ClientError:
|
|
86
|
+
LOG.error("client error while trying to access key '%s': %s", secret_id)
|
|
87
|
+
raise
|
|
88
|
+
|
|
89
|
+
if json_key:
|
|
90
|
+
json_secret = json.loads(secret_value)
|
|
91
|
+
if json_key not in json_secret:
|
|
92
|
+
raise RuntimeError(
|
|
93
|
+
f"JSON value for {reference.service_name}.{reference.reference_key} not present"
|
|
94
|
+
)
|
|
95
|
+
return str(json_secret[json_key])
|
|
96
|
+
else:
|
|
97
|
+
return str(secret_value)
|
|
98
|
+
|
|
99
|
+
LOG.warning(
|
|
100
|
+
"Unsupported service for dynamic parameter: service_name=%s", reference.service_name
|
|
101
|
+
)
|
|
102
|
+
return None
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import yaml
|
|
2
2
|
|
|
3
|
+
from localstack.services.cloudformation.engine.validations import ValidationError
|
|
4
|
+
|
|
3
5
|
|
|
4
6
|
def construct_raw(_, node):
|
|
5
7
|
return node.value
|
|
@@ -60,5 +62,10 @@ customloader = NoDatesSafeLoader
|
|
|
60
62
|
yaml.add_multi_constructor("!", shorthand_constructor, customloader)
|
|
61
63
|
|
|
62
64
|
|
|
63
|
-
def parse_yaml(input_data: str):
|
|
64
|
-
|
|
65
|
+
def parse_yaml(input_data: str) -> dict:
|
|
66
|
+
parsed = yaml.load(input_data, Loader=customloader)
|
|
67
|
+
|
|
68
|
+
if not isinstance(parsed, dict):
|
|
69
|
+
raise ValidationError("Template format error: unsupported structure.")
|
|
70
|
+
|
|
71
|
+
return parsed
|
|
@@ -159,7 +159,7 @@ def find_stack_instance(stack_set: StackSet, account: str, region: str):
|
|
|
159
159
|
|
|
160
160
|
def stack_not_found_error(stack_name: str):
|
|
161
161
|
# FIXME
|
|
162
|
-
raise ValidationError("Stack with id
|
|
162
|
+
raise ValidationError(f"Stack with id {stack_name} does not exist")
|
|
163
163
|
|
|
164
164
|
|
|
165
165
|
def not_found_error(message: str):
|
|
@@ -305,8 +305,8 @@ class CloudformationProvider(CloudformationApi):
|
|
|
305
305
|
deployer.deploy_stack()
|
|
306
306
|
except Exception as e:
|
|
307
307
|
stack.set_stack_status("CREATE_FAILED")
|
|
308
|
-
msg = 'Unable to create stack "
|
|
309
|
-
LOG.
|
|
308
|
+
msg = f'Unable to create stack "{stack.stack_name}": {e}'
|
|
309
|
+
LOG.error("%s", exc_info=LOG.isEnabledFor(logging.DEBUG))
|
|
310
310
|
raise ValidationError(msg) from e
|
|
311
311
|
|
|
312
312
|
return CreateStackOutput(StackId=stack.stack_id)
|
|
@@ -423,7 +423,7 @@ class CloudformationProvider(CloudformationApi):
|
|
|
423
423
|
except Exception as e:
|
|
424
424
|
stack.set_stack_status("UPDATE_FAILED")
|
|
425
425
|
msg = f'Unable to update stack "{stack_name}": {e}'
|
|
426
|
-
LOG.
|
|
426
|
+
LOG.error("%s", msg, exc_info=LOG.isEnabledFor(logging.DEBUG))
|
|
427
427
|
raise ValidationError(msg) from e
|
|
428
428
|
|
|
429
429
|
return UpdateStackOutput(StackId=stack.stack_id)
|
|
@@ -605,6 +605,8 @@ class CloudformationProvider(CloudformationApi):
|
|
|
605
605
|
req_params = request
|
|
606
606
|
change_set_type = req_params.get("ChangeSetType", "UPDATE")
|
|
607
607
|
stack_name = req_params.get("StackName")
|
|
608
|
+
if not stack_name:
|
|
609
|
+
raise ValidationError("Member must have length greater than or equal to 1")
|
|
608
610
|
change_set_name = req_params.get("ChangeSetName")
|
|
609
611
|
template_body = req_params.get("TemplateBody")
|
|
610
612
|
# s3 or secretsmanager url
|
|
@@ -927,7 +929,7 @@ class CloudformationProvider(CloudformationApi):
|
|
|
927
929
|
self, context: RequestContext, next_token: NextToken = None, **kwargs
|
|
928
930
|
) -> ListExportsOutput:
|
|
929
931
|
state = get_cloudformation_store(context.account_id, context.region)
|
|
930
|
-
return ListExportsOutput(Exports=state.exports)
|
|
932
|
+
return ListExportsOutput(Exports=state.exports.values())
|
|
931
933
|
|
|
932
934
|
@handler("ListImports")
|
|
933
935
|
def list_imports(
|
|
@@ -1052,7 +1054,7 @@ class CloudformationProvider(CloudformationApi):
|
|
|
1052
1054
|
Description=valid_template.get("Description"), Parameters=parameters
|
|
1053
1055
|
)
|
|
1054
1056
|
except Exception as e:
|
|
1055
|
-
LOG.
|
|
1057
|
+
LOG.error("Error validating template", exc_info=LOG.isEnabledFor(logging.DEBUG))
|
|
1056
1058
|
raise ValidationError("Template Validation Error") from e
|
|
1057
1059
|
|
|
1058
1060
|
# =======================================
|
|
@@ -9,9 +9,9 @@ import builtins
|
|
|
9
9
|
import json
|
|
10
10
|
import re
|
|
11
11
|
import uuid
|
|
12
|
+
from collections.abc import Callable
|
|
12
13
|
from copy import deepcopy
|
|
13
14
|
from pathlib import Path
|
|
14
|
-
from typing import Callable, List, Optional
|
|
15
15
|
|
|
16
16
|
from botocore.model import Shape, StructureShape
|
|
17
17
|
|
|
@@ -73,9 +73,12 @@ def recurse_properties(properties: dict, fn: Callable) -> dict:
|
|
|
73
73
|
return _recurse_properties(deepcopy(properties), fn)
|
|
74
74
|
|
|
75
75
|
|
|
76
|
-
def keys_pascalcase_to_lower_camelcase(model: dict) -> dict:
|
|
76
|
+
def keys_pascalcase_to_lower_camelcase(model: dict, skip_keys: set = None) -> dict:
|
|
77
77
|
"""Recursively change any dicts keys to lower camelcase"""
|
|
78
78
|
|
|
79
|
+
if skip_keys:
|
|
80
|
+
return _pascal_to_camel_keys_preserve_values(model, skip_keys)
|
|
81
|
+
|
|
79
82
|
def _keys_pascalcase_to_lower_camelcase(obj):
|
|
80
83
|
if isinstance(obj, dict):
|
|
81
84
|
return {convert_pascalcase_to_lower_camelcase(k): v for k, v in obj.items()}
|
|
@@ -85,6 +88,33 @@ def keys_pascalcase_to_lower_camelcase(model: dict) -> dict:
|
|
|
85
88
|
return _recurse_properties(model, _keys_pascalcase_to_lower_camelcase)
|
|
86
89
|
|
|
87
90
|
|
|
91
|
+
def _pascal_to_camel_keys_preserve_values(model: dict, skip_keys: set = None) -> dict:
|
|
92
|
+
"""
|
|
93
|
+
Variant of keys_pascalcase_to_lower_camelcase
|
|
94
|
+
All VALUES of provided keys are skipped and not transformed to lower camelcase.
|
|
95
|
+
The keys themselves will be transformed.
|
|
96
|
+
The function simply stops recursion if a key matches, so make sure no lower level values are ignored.
|
|
97
|
+
"""
|
|
98
|
+
skip_keys = skip_keys or set()
|
|
99
|
+
|
|
100
|
+
def _transform(obj):
|
|
101
|
+
if isinstance(obj, dict):
|
|
102
|
+
new_dict = {}
|
|
103
|
+
for k, v in obj.items():
|
|
104
|
+
new_key = convert_pascalcase_to_lower_camelcase(k)
|
|
105
|
+
if k in skip_keys:
|
|
106
|
+
new_dict[new_key] = v
|
|
107
|
+
else:
|
|
108
|
+
new_dict[new_key] = _transform(v)
|
|
109
|
+
return new_dict
|
|
110
|
+
elif isinstance(obj, list):
|
|
111
|
+
return [_transform(i) for i in obj]
|
|
112
|
+
else:
|
|
113
|
+
return obj
|
|
114
|
+
|
|
115
|
+
return _transform(model)
|
|
116
|
+
|
|
117
|
+
|
|
88
118
|
def keys_lower_camelcase_to_pascalcase(model: dict) -> dict:
|
|
89
119
|
"""Recursively change any dicts keys to PascalCase"""
|
|
90
120
|
|
|
@@ -152,7 +182,7 @@ def fix_boto_parameters_based_on_report(original_params: dict, report: str) -> d
|
|
|
152
182
|
cast_class = getattr(builtins, valid_class)
|
|
153
183
|
old_value = get_nested(params, param_name)
|
|
154
184
|
|
|
155
|
-
if cast_class
|
|
185
|
+
if isinstance(cast_class, bool) and str(old_value).lower() in ["true", "false"]:
|
|
156
186
|
new_value = str(old_value).lower() == "true"
|
|
157
187
|
else:
|
|
158
188
|
new_value = cast_class(old_value)
|
|
@@ -213,7 +243,7 @@ def convert_request_kwargs(parameters: dict, input_shape: StructureShape) -> dic
|
|
|
213
243
|
return transformed_dict
|
|
214
244
|
|
|
215
245
|
|
|
216
|
-
def convert_values_to_numbers(input_dict: dict, keys_to_skip:
|
|
246
|
+
def convert_values_to_numbers(input_dict: dict, keys_to_skip: list[str] | None = None):
|
|
217
247
|
"""
|
|
218
248
|
Recursively converts all string values that represent valid integers
|
|
219
249
|
in a dictionary (including nested dictionaries and lists) to integers.
|
|
@@ -5,11 +5,12 @@ import logging
|
|
|
5
5
|
import re
|
|
6
6
|
import time
|
|
7
7
|
import uuid
|
|
8
|
+
from collections.abc import Callable
|
|
8
9
|
from dataclasses import dataclass, field
|
|
9
10
|
from enum import Enum, auto
|
|
10
11
|
from logging import Logger
|
|
11
12
|
from math import ceil
|
|
12
|
-
from typing import TYPE_CHECKING, Any,
|
|
13
|
+
from typing import TYPE_CHECKING, Any, Generic, TypedDict, TypeVar
|
|
13
14
|
|
|
14
15
|
import botocore
|
|
15
16
|
from botocore.client import BaseClient
|
|
@@ -51,7 +52,7 @@ LOG = logging.getLogger(__name__)
|
|
|
51
52
|
|
|
52
53
|
Properties = TypeVar("Properties")
|
|
53
54
|
|
|
54
|
-
PUBLIC_REGISTRY: dict[str,
|
|
55
|
+
PUBLIC_REGISTRY: dict[str, type[ResourceProvider]] = {}
|
|
55
56
|
|
|
56
57
|
PROVIDER_DEFAULTS = {} # TODO: remove this after removing patching in -ext
|
|
57
58
|
|
|
@@ -66,12 +67,12 @@ class OperationStatus(Enum):
|
|
|
66
67
|
@dataclass
|
|
67
68
|
class ProgressEvent(Generic[Properties]):
|
|
68
69
|
status: OperationStatus
|
|
69
|
-
resource_model:
|
|
70
|
-
resource_models:
|
|
70
|
+
resource_model: Properties | None = None
|
|
71
|
+
resource_models: list[Properties] | None = None
|
|
71
72
|
|
|
72
73
|
message: str = ""
|
|
73
|
-
result:
|
|
74
|
-
error_code:
|
|
74
|
+
result: str | None = None
|
|
75
|
+
error_code: str | None = None # TODO: enum
|
|
75
76
|
custom_context: dict = field(default_factory=dict)
|
|
76
77
|
|
|
77
78
|
|
|
@@ -84,7 +85,7 @@ class Credentials(TypedDict):
|
|
|
84
85
|
class ResourceProviderPayloadRequestData(TypedDict):
|
|
85
86
|
logicalResourceId: str
|
|
86
87
|
resourceProperties: Properties
|
|
87
|
-
previousResourceProperties:
|
|
88
|
+
previousResourceProperties: Properties | None
|
|
88
89
|
callerCredentials: Credentials
|
|
89
90
|
providerCredentials: Credentials
|
|
90
91
|
systemTags: dict[str, str]
|
|
@@ -184,8 +185,8 @@ class ResourceRequest(Generic[Properties]):
|
|
|
184
185
|
|
|
185
186
|
custom_context: dict = field(default_factory=dict)
|
|
186
187
|
|
|
187
|
-
previous_state:
|
|
188
|
-
previous_tags:
|
|
188
|
+
previous_state: Properties | None = None
|
|
189
|
+
previous_tags: dict[str, str] | None = None
|
|
189
190
|
tags: dict[str, str] = field(default_factory=dict)
|
|
190
191
|
|
|
191
192
|
|
|
@@ -235,7 +236,7 @@ def get_resource_type(resource: dict) -> str:
|
|
|
235
236
|
LOG.warning(
|
|
236
237
|
"Failed to retrieve resource type %s",
|
|
237
238
|
resource.get("Type"),
|
|
238
|
-
exc_info=LOG.isEnabledFor(logging.DEBUG),
|
|
239
|
+
exc_info=LOG.isEnabledFor(logging.DEBUG) and config.CFN_VERBOSE_ERRORS,
|
|
239
240
|
)
|
|
240
241
|
|
|
241
242
|
|
|
@@ -465,15 +466,18 @@ class ResourceProviderExecutor:
|
|
|
465
466
|
"A ResourceProvider should always have a SCHEMA property defined."
|
|
466
467
|
)
|
|
467
468
|
resource_type_schema = resource_provider.SCHEMA
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
469
|
+
if raw_payload["action"] != "Remove":
|
|
470
|
+
physical_resource_id = (
|
|
471
|
+
self.extract_physical_resource_id_from_model_with_schema(
|
|
472
|
+
event.resource_model,
|
|
473
|
+
raw_payload["resourceType"],
|
|
474
|
+
resource_type_schema,
|
|
475
|
+
)
|
|
476
|
+
)
|
|
473
477
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
478
|
+
resource["PhysicalResourceId"] = physical_resource_id
|
|
479
|
+
resource["Properties"] = event.resource_model
|
|
480
|
+
resource["_last_deployed_state"] = copy.deepcopy(event.resource_model)
|
|
477
481
|
return event
|
|
478
482
|
case OperationStatus.IN_PROGRESS:
|
|
479
483
|
# update the shared state
|
|
@@ -514,10 +518,14 @@ class ResourceProviderExecutor:
|
|
|
514
518
|
try:
|
|
515
519
|
return resource_provider.update(request)
|
|
516
520
|
except NotImplementedError:
|
|
521
|
+
feature_request_url = "https://github.com/localstack/localstack/issues/new?template=feature-request.yml"
|
|
517
522
|
LOG.warning(
|
|
518
|
-
'Unable to update resource type "%s", id "%s"'
|
|
523
|
+
'Unable to update resource type "%s", id "%s", '
|
|
524
|
+
"the update operation is not implemented for this resource. "
|
|
525
|
+
"Please consider submitting a feature request at this URL: %s",
|
|
519
526
|
request.resource_type,
|
|
520
527
|
request.logical_resource_id,
|
|
528
|
+
feature_request_url,
|
|
521
529
|
)
|
|
522
530
|
if request.previous_state is None:
|
|
523
531
|
# this is an issue with our update detection. We should never be in this state.
|
|
@@ -559,6 +567,8 @@ class ResourceProviderExecutor:
|
|
|
559
567
|
@staticmethod
|
|
560
568
|
def try_load_resource_provider(resource_type: str) -> ResourceProvider | None:
|
|
561
569
|
# TODO: unify namespace of plugins
|
|
570
|
+
if resource_type and resource_type.startswith("Custom"):
|
|
571
|
+
resource_type = "AWS::CloudFormation::CustomResource"
|
|
562
572
|
|
|
563
573
|
# 1. try to load pro resource provider
|
|
564
574
|
# prioritise pro resource providers
|
|
@@ -573,7 +583,7 @@ class ResourceProviderExecutor:
|
|
|
573
583
|
LOG.warning(
|
|
574
584
|
"Failed to load PRO resource type %s as a ResourceProvider.",
|
|
575
585
|
resource_type,
|
|
576
|
-
exc_info=LOG.isEnabledFor(logging.DEBUG),
|
|
586
|
+
exc_info=LOG.isEnabledFor(logging.DEBUG) and config.CFN_VERBOSE_ERRORS,
|
|
577
587
|
)
|
|
578
588
|
|
|
579
589
|
# 2. try to load community resource provider
|
|
@@ -588,7 +598,7 @@ class ResourceProviderExecutor:
|
|
|
588
598
|
LOG.warning(
|
|
589
599
|
"Failed to load community resource type %s as a ResourceProvider.",
|
|
590
600
|
resource_type,
|
|
591
|
-
exc_info=LOG.isEnabledFor(logging.DEBUG),
|
|
601
|
+
exc_info=LOG.isEnabledFor(logging.DEBUG) and config.CFN_VERBOSE_ERRORS,
|
|
592
602
|
)
|
|
593
603
|
|
|
594
604
|
# we could not find the resource provider
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import TypedDict
|
|
6
6
|
|
|
7
7
|
import localstack.services.cloudformation.provider_utils as util
|
|
8
8
|
from localstack.services.cloudformation.resource_provider import (
|
|
@@ -15,12 +15,12 @@ from localstack.services.cloudformation.stores import get_cloudformation_store
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class CloudFormationMacroProperties(TypedDict):
|
|
18
|
-
FunctionName:
|
|
19
|
-
Name:
|
|
20
|
-
Description:
|
|
21
|
-
Id:
|
|
22
|
-
LogGroupName:
|
|
23
|
-
LogRoleARN:
|
|
18
|
+
FunctionName: str | None
|
|
19
|
+
Name: str | None
|
|
20
|
+
Description: str | None
|
|
21
|
+
Id: str | None
|
|
22
|
+
LogGroupName: str | None
|
|
23
|
+
LogRoleARN: str | None
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
REPEATED_INVOCATION = "repeated_invocation"
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Optional, Type
|
|
2
|
-
|
|
3
1
|
from localstack.services.cloudformation.resource_provider import (
|
|
4
2
|
CloudFormationResourceProviderPlugin,
|
|
5
3
|
ResourceProvider,
|
|
@@ -10,7 +8,7 @@ class CloudFormationMacroProviderPlugin(CloudFormationResourceProviderPlugin):
|
|
|
10
8
|
name = "AWS::CloudFormation::Macro"
|
|
11
9
|
|
|
12
10
|
def __init__(self):
|
|
13
|
-
self.factory:
|
|
11
|
+
self.factory: type[ResourceProvider] | None = None
|
|
14
12
|
|
|
15
13
|
def load(self):
|
|
16
14
|
from localstack.services.cloudformation.resource_providers.aws_cloudformation_macro import (
|