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
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from botocore.exceptions import ParamValidationError
|
|
5
|
+
|
|
6
|
+
from localstack.services.cloudformation.engine.v2.change_set_model import (
|
|
7
|
+
NodeIntrinsicFunction,
|
|
8
|
+
NodeProperty,
|
|
9
|
+
NodeResource,
|
|
10
|
+
NodeTemplate,
|
|
11
|
+
Nothing,
|
|
12
|
+
is_nothing,
|
|
13
|
+
)
|
|
14
|
+
from localstack.services.cloudformation.engine.v2.change_set_model_preproc import (
|
|
15
|
+
_PSEUDO_PARAMETERS,
|
|
16
|
+
ChangeSetModelPreproc,
|
|
17
|
+
PreprocEntityDelta,
|
|
18
|
+
PreprocResource,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ChangeSetModelValidator(ChangeSetModelPreproc):
|
|
23
|
+
def validate(self):
|
|
24
|
+
self.process()
|
|
25
|
+
|
|
26
|
+
def visit_node_template(self, node_template: NodeTemplate):
|
|
27
|
+
self.visit(node_template.mappings)
|
|
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)
|
|
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)
|
|
54
|
+
):
|
|
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
|
|
85
|
+
|
|
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
|
|
97
|
+
|
|
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)
|
|
163
|
+
|
|
164
|
+
def visit_node_resource(self, node_resource: NodeResource) -> PreprocEntityDelta:
|
|
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
|
|
@@ -137,6 +137,9 @@ ARN_CHANGESET_REGEX = re.compile(
|
|
|
137
137
|
ARN_STACK_REGEX = re.compile(
|
|
138
138
|
r"arn:(aws|aws-us-gov|aws-cn):cloudformation:[-a-zA-Z0-9]+:\d{12}:stack/[a-zA-Z][-a-zA-Z0-9]*/[-a-zA-Z0-9:/._+]+"
|
|
139
139
|
)
|
|
140
|
+
ARN_STACK_SET_REGEX = re.compile(
|
|
141
|
+
r"arn:(aws|aws-us-gov|aws-cn):cloudformation:[-a-zA-Z0-9]+:\d{12}:stack-set/[a-zA-Z][-a-zA-Z0-9]*/[-a-zA-Z0-9:/._+]+"
|
|
142
|
+
)
|
|
140
143
|
|
|
141
144
|
|
|
142
145
|
def clone_stack_params(stack_params):
|
|
@@ -156,7 +159,7 @@ def find_stack_instance(stack_set: StackSet, account: str, region: str):
|
|
|
156
159
|
|
|
157
160
|
def stack_not_found_error(stack_name: str):
|
|
158
161
|
# FIXME
|
|
159
|
-
raise ValidationError("Stack with id
|
|
162
|
+
raise ValidationError(f"Stack with id {stack_name} does not exist")
|
|
160
163
|
|
|
161
164
|
|
|
162
165
|
def not_found_error(message: str):
|
|
@@ -302,8 +305,8 @@ class CloudformationProvider(CloudformationApi):
|
|
|
302
305
|
deployer.deploy_stack()
|
|
303
306
|
except Exception as e:
|
|
304
307
|
stack.set_stack_status("CREATE_FAILED")
|
|
305
|
-
msg = 'Unable to create stack "
|
|
306
|
-
LOG.
|
|
308
|
+
msg = f'Unable to create stack "{stack.stack_name}": {e}'
|
|
309
|
+
LOG.error("%s", exc_info=LOG.isEnabledFor(logging.DEBUG))
|
|
307
310
|
raise ValidationError(msg) from e
|
|
308
311
|
|
|
309
312
|
return CreateStackOutput(StackId=stack.stack_id)
|
|
@@ -420,7 +423,7 @@ class CloudformationProvider(CloudformationApi):
|
|
|
420
423
|
except Exception as e:
|
|
421
424
|
stack.set_stack_status("UPDATE_FAILED")
|
|
422
425
|
msg = f'Unable to update stack "{stack_name}": {e}'
|
|
423
|
-
LOG.
|
|
426
|
+
LOG.error("%s", msg, exc_info=LOG.isEnabledFor(logging.DEBUG))
|
|
424
427
|
raise ValidationError(msg) from e
|
|
425
428
|
|
|
426
429
|
return UpdateStackOutput(StackId=stack.stack_id)
|
|
@@ -602,6 +605,8 @@ class CloudformationProvider(CloudformationApi):
|
|
|
602
605
|
req_params = request
|
|
603
606
|
change_set_type = req_params.get("ChangeSetType", "UPDATE")
|
|
604
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")
|
|
605
610
|
change_set_name = req_params.get("ChangeSetName")
|
|
606
611
|
template_body = req_params.get("TemplateBody")
|
|
607
612
|
# s3 or secretsmanager url
|
|
@@ -924,7 +929,7 @@ class CloudformationProvider(CloudformationApi):
|
|
|
924
929
|
self, context: RequestContext, next_token: NextToken = None, **kwargs
|
|
925
930
|
) -> ListExportsOutput:
|
|
926
931
|
state = get_cloudformation_store(context.account_id, context.region)
|
|
927
|
-
return ListExportsOutput(Exports=state.exports)
|
|
932
|
+
return ListExportsOutput(Exports=state.exports.values())
|
|
928
933
|
|
|
929
934
|
@handler("ListImports")
|
|
930
935
|
def list_imports(
|
|
@@ -1049,7 +1054,7 @@ class CloudformationProvider(CloudformationApi):
|
|
|
1049
1054
|
Description=valid_template.get("Description"), Parameters=parameters
|
|
1050
1055
|
)
|
|
1051
1056
|
except Exception as e:
|
|
1052
|
-
LOG.
|
|
1057
|
+
LOG.error("Error validating template", exc_info=LOG.isEnabledFor(logging.DEBUG))
|
|
1053
1058
|
raise ValidationError("Template Validation Error") from e
|
|
1054
1059
|
|
|
1055
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 (
|