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
|
@@ -2,12 +2,19 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import abc
|
|
4
4
|
import enum
|
|
5
|
+
from collections.abc import Generator
|
|
5
6
|
from itertools import zip_longest
|
|
6
|
-
from typing import Any, Final,
|
|
7
|
+
from typing import Any, Final, TypedDict, cast
|
|
7
8
|
|
|
8
9
|
from typing_extensions import TypeVar
|
|
9
10
|
|
|
10
11
|
from localstack.aws.api.cloudformation import ChangeAction
|
|
12
|
+
from localstack.services.cloudformation.resource_provider import ResourceProviderExecutor
|
|
13
|
+
from localstack.services.cloudformation.v2.types import (
|
|
14
|
+
EngineParameter,
|
|
15
|
+
engine_parameter_value,
|
|
16
|
+
)
|
|
17
|
+
from localstack.utils.json import extract_jsonpath
|
|
11
18
|
from localstack.utils.strings import camel_to_snake_case
|
|
12
19
|
|
|
13
20
|
T = TypeVar("T")
|
|
@@ -43,7 +50,7 @@ class NothingType:
|
|
|
43
50
|
return False
|
|
44
51
|
|
|
45
52
|
|
|
46
|
-
Maybe =
|
|
53
|
+
Maybe = T | NothingType
|
|
47
54
|
Nothing = NothingType()
|
|
48
55
|
|
|
49
56
|
|
|
@@ -63,6 +70,9 @@ def parent_change_type_of(children: list[Maybe[ChangeSetEntity]]):
|
|
|
63
70
|
change_types = [c.change_type for c in children if not is_nothing(c)]
|
|
64
71
|
if not change_types:
|
|
65
72
|
return ChangeType.UNCHANGED
|
|
73
|
+
# TODO: rework this logic. Currently if any values are different then we consider it
|
|
74
|
+
# modified, but e.g. if everything is unchanged or created, the result should probably be
|
|
75
|
+
# "created"
|
|
66
76
|
first_type = change_types[0]
|
|
67
77
|
if all(ct == first_type for ct in change_types):
|
|
68
78
|
return first_type
|
|
@@ -85,7 +95,7 @@ class NormalisedGlobalTransformDefinition(TypedDict):
|
|
|
85
95
|
|
|
86
96
|
|
|
87
97
|
class Scope(str):
|
|
88
|
-
_ROOT_SCOPE: Final[str] =
|
|
98
|
+
_ROOT_SCOPE: Final[str] = ""
|
|
89
99
|
_SEPARATOR: Final[str] = "/"
|
|
90
100
|
|
|
91
101
|
def __new__(cls, scope: str = _ROOT_SCOPE) -> Scope:
|
|
@@ -100,6 +110,30 @@ class Scope(str):
|
|
|
100
110
|
def unwrap(self) -> list[str]:
|
|
101
111
|
return self.split(self._SEPARATOR)
|
|
102
112
|
|
|
113
|
+
@property
|
|
114
|
+
def parent(self) -> Scope:
|
|
115
|
+
return Scope(self._SEPARATOR.join(self.split(self._SEPARATOR)[:-1]))
|
|
116
|
+
|
|
117
|
+
@property
|
|
118
|
+
def jsonpath(self) -> str:
|
|
119
|
+
parts = self.split("/")
|
|
120
|
+
json_parts = []
|
|
121
|
+
|
|
122
|
+
for part in parts:
|
|
123
|
+
if not part: # Skip empty strings from leading/trailing slashes
|
|
124
|
+
continue
|
|
125
|
+
|
|
126
|
+
if part == "divergence":
|
|
127
|
+
continue
|
|
128
|
+
|
|
129
|
+
# Wrap keys with special characters (e.g., colon) in quotes
|
|
130
|
+
if ":" in part:
|
|
131
|
+
json_parts.append(f'"{part}"')
|
|
132
|
+
else:
|
|
133
|
+
json_parts.append(part)
|
|
134
|
+
|
|
135
|
+
return f"$.{'.'.join(json_parts)}"
|
|
136
|
+
|
|
103
137
|
|
|
104
138
|
class ChangeType(enum.Enum):
|
|
105
139
|
UNCHANGED = "Unchanged"
|
|
@@ -121,7 +155,7 @@ class ChangeType(enum.Enum):
|
|
|
121
155
|
|
|
122
156
|
class ChangeSetEntity(abc.ABC):
|
|
123
157
|
scope: Final[Scope]
|
|
124
|
-
change_type:
|
|
158
|
+
change_type: ChangeType
|
|
125
159
|
|
|
126
160
|
def __init__(self, scope: Scope, change_type: ChangeType):
|
|
127
161
|
self.scope = scope
|
|
@@ -168,8 +202,8 @@ class UpdateModel:
|
|
|
168
202
|
node_template: NodeTemplate,
|
|
169
203
|
):
|
|
170
204
|
self.node_template = node_template
|
|
171
|
-
self.before_runtime_cache =
|
|
172
|
-
self.after_runtime_cache =
|
|
205
|
+
self.before_runtime_cache = {}
|
|
206
|
+
self.after_runtime_cache = {}
|
|
173
207
|
|
|
174
208
|
|
|
175
209
|
class NodeTemplate(ChangeSetNode):
|
|
@@ -337,11 +371,21 @@ class NodeTransform(ChangeSetNode):
|
|
|
337
371
|
|
|
338
372
|
class NodeResources(ChangeSetNode):
|
|
339
373
|
resources: Final[list[NodeResource]]
|
|
374
|
+
fn_transform: Final[Maybe[NodeIntrinsicFunctionFnTransform]]
|
|
375
|
+
fn_foreaches: Final[list[NodeForEach]]
|
|
340
376
|
|
|
341
|
-
def __init__(
|
|
342
|
-
|
|
377
|
+
def __init__(
|
|
378
|
+
self,
|
|
379
|
+
scope: Scope,
|
|
380
|
+
resources: list[NodeResource],
|
|
381
|
+
fn_transform: Maybe[NodeIntrinsicFunctionFnTransform],
|
|
382
|
+
fn_foreaches: list[NodeForEach],
|
|
383
|
+
):
|
|
384
|
+
change_type = parent_change_type_of(resources + [fn_transform] + fn_foreaches)
|
|
343
385
|
super().__init__(scope=scope, change_type=change_type)
|
|
344
386
|
self.resources = resources
|
|
387
|
+
self.fn_transform = fn_transform
|
|
388
|
+
self.fn_foreaches = fn_foreaches
|
|
345
389
|
|
|
346
390
|
|
|
347
391
|
class NodeResource(ChangeSetNode):
|
|
@@ -350,6 +394,10 @@ class NodeResource(ChangeSetNode):
|
|
|
350
394
|
properties: Final[NodeProperties]
|
|
351
395
|
condition_reference: Final[Maybe[TerminalValue]]
|
|
352
396
|
depends_on: Final[Maybe[NodeDependsOn]]
|
|
397
|
+
requires_replacement: Final[bool]
|
|
398
|
+
deletion_policy: Final[Maybe[ChangeSetTerminal]]
|
|
399
|
+
update_replace_policy: Final[Maybe[ChangeSetTerminal]]
|
|
400
|
+
fn_transform: Final[Maybe[NodeIntrinsicFunctionFnTransform]]
|
|
353
401
|
|
|
354
402
|
def __init__(
|
|
355
403
|
self,
|
|
@@ -360,6 +408,10 @@ class NodeResource(ChangeSetNode):
|
|
|
360
408
|
properties: NodeProperties,
|
|
361
409
|
condition_reference: Maybe[TerminalValue],
|
|
362
410
|
depends_on: Maybe[NodeDependsOn],
|
|
411
|
+
requires_replacement: bool,
|
|
412
|
+
deletion_policy: Maybe[ChangeSetTerminal],
|
|
413
|
+
update_replace_policy: Maybe[ChangeSetTerminal],
|
|
414
|
+
fn_transform: Maybe[NodeIntrinsicFunctionFnTransform],
|
|
363
415
|
):
|
|
364
416
|
super().__init__(scope=scope, change_type=change_type)
|
|
365
417
|
self.name = name
|
|
@@ -367,15 +419,26 @@ class NodeResource(ChangeSetNode):
|
|
|
367
419
|
self.properties = properties
|
|
368
420
|
self.condition_reference = condition_reference
|
|
369
421
|
self.depends_on = depends_on
|
|
422
|
+
self.requires_replacement = requires_replacement
|
|
423
|
+
self.deletion_policy = deletion_policy
|
|
424
|
+
self.update_replace_policy = update_replace_policy
|
|
425
|
+
self.fn_transform = fn_transform
|
|
370
426
|
|
|
371
427
|
|
|
372
428
|
class NodeProperties(ChangeSetNode):
|
|
373
429
|
properties: Final[list[NodeProperty]]
|
|
430
|
+
fn_transform: Final[Maybe[NodeIntrinsicFunctionFnTransform]]
|
|
374
431
|
|
|
375
|
-
def __init__(
|
|
432
|
+
def __init__(
|
|
433
|
+
self,
|
|
434
|
+
scope: Scope,
|
|
435
|
+
properties: list[NodeProperty],
|
|
436
|
+
fn_transform: Maybe[NodeIntrinsicFunctionFnTransform],
|
|
437
|
+
):
|
|
376
438
|
change_type = parent_change_type_of(properties)
|
|
377
439
|
super().__init__(scope=scope, change_type=change_type)
|
|
378
440
|
self.properties = properties
|
|
441
|
+
self.fn_transform = fn_transform
|
|
379
442
|
|
|
380
443
|
|
|
381
444
|
class NodeDependsOn(ChangeSetNode):
|
|
@@ -412,6 +475,40 @@ class NodeIntrinsicFunction(ChangeSetNode):
|
|
|
412
475
|
self.arguments = arguments
|
|
413
476
|
|
|
414
477
|
|
|
478
|
+
class NodeIntrinsicFunctionFnTransform(NodeIntrinsicFunction):
|
|
479
|
+
def __init__(
|
|
480
|
+
self,
|
|
481
|
+
scope: Scope,
|
|
482
|
+
change_type: ChangeType,
|
|
483
|
+
intrinsic_function: str,
|
|
484
|
+
arguments: ChangeSetEntity,
|
|
485
|
+
before_siblings: list[Any],
|
|
486
|
+
after_siblings: list[Any],
|
|
487
|
+
):
|
|
488
|
+
super().__init__(
|
|
489
|
+
scope=scope,
|
|
490
|
+
change_type=change_type,
|
|
491
|
+
intrinsic_function=intrinsic_function,
|
|
492
|
+
arguments=arguments,
|
|
493
|
+
)
|
|
494
|
+
self.before_siblings = before_siblings
|
|
495
|
+
self.after_siblings = after_siblings
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
class NodeForEach(ChangeSetNode):
|
|
499
|
+
def __init__(
|
|
500
|
+
self,
|
|
501
|
+
scope: Scope,
|
|
502
|
+
change_type: Final[ChangeType],
|
|
503
|
+
arguments: Final[ChangeSetEntity],
|
|
504
|
+
):
|
|
505
|
+
super().__init__(
|
|
506
|
+
scope=scope,
|
|
507
|
+
change_type=change_type,
|
|
508
|
+
)
|
|
509
|
+
self.arguments = arguments
|
|
510
|
+
|
|
511
|
+
|
|
415
512
|
class NodeObject(ChangeSetNode):
|
|
416
513
|
bindings: Final[dict[str, ChangeSetEntity]]
|
|
417
514
|
|
|
@@ -473,6 +570,8 @@ ValueKey: Final[str] = "Value"
|
|
|
473
570
|
ExportKey: Final[str] = "Export"
|
|
474
571
|
OutputsKey: Final[str] = "Outputs"
|
|
475
572
|
DependsOnKey: Final[str] = "DependsOn"
|
|
573
|
+
DeletionPolicyKey: Final[str] = "DeletionPolicy"
|
|
574
|
+
UpdateReplacePolicyKey: Final[str] = "UpdateReplacePolicy"
|
|
476
575
|
# TODO: expand intrinsic functions set.
|
|
477
576
|
RefKey: Final[str] = "Ref"
|
|
478
577
|
RefConditionKey: Final[str] = "Condition"
|
|
@@ -490,6 +589,7 @@ FnSelect: Final[str] = "Fn::Select"
|
|
|
490
589
|
FnSplit: Final[str] = "Fn::Split"
|
|
491
590
|
FnGetAZs: Final[str] = "Fn::GetAZs"
|
|
492
591
|
FnBase64: Final[str] = "Fn::Base64"
|
|
592
|
+
FnImportValue: Final[str] = "Fn::ImportValue"
|
|
493
593
|
INTRINSIC_FUNCTIONS: Final[set[str]] = {
|
|
494
594
|
RefKey,
|
|
495
595
|
RefConditionKey,
|
|
@@ -507,6 +607,7 @@ INTRINSIC_FUNCTIONS: Final[set[str]] = {
|
|
|
507
607
|
FnSplit,
|
|
508
608
|
FnGetAZs,
|
|
509
609
|
FnBase64,
|
|
610
|
+
FnImportValue,
|
|
510
611
|
}
|
|
511
612
|
|
|
512
613
|
|
|
@@ -527,16 +628,17 @@ class ChangeSetModel:
|
|
|
527
628
|
|
|
528
629
|
def __init__(
|
|
529
630
|
self,
|
|
530
|
-
before_template:
|
|
531
|
-
after_template:
|
|
532
|
-
before_parameters:
|
|
533
|
-
after_parameters:
|
|
631
|
+
before_template: dict | None,
|
|
632
|
+
after_template: dict | None,
|
|
633
|
+
before_parameters: dict | None,
|
|
634
|
+
after_parameters: dict[str, EngineParameter] | None,
|
|
534
635
|
):
|
|
535
636
|
self._before_template = before_template or Nothing
|
|
536
637
|
self._after_template = after_template or Nothing
|
|
537
638
|
self._before_parameters = before_parameters or Nothing
|
|
538
639
|
self._after_parameters = after_parameters or Nothing
|
|
539
|
-
self._visited_scopes =
|
|
640
|
+
self._visited_scopes = {}
|
|
641
|
+
# TODO: move this modeling process to the `get_update_model` method as constructors shouldn't do work
|
|
540
642
|
self._node_template = self._model(
|
|
541
643
|
before_template=self._before_template, after_template=self._after_template
|
|
542
644
|
)
|
|
@@ -578,6 +680,7 @@ class ChangeSetModel:
|
|
|
578
680
|
arguments = self._visit_value(
|
|
579
681
|
scope=arguments_scope, before_value=before_arguments, after_value=after_arguments
|
|
580
682
|
)
|
|
683
|
+
|
|
581
684
|
if is_created(before=before_arguments, after=after_arguments):
|
|
582
685
|
change_type = ChangeType.CREATED
|
|
583
686
|
elif is_removed(before=before_arguments, after=after_arguments):
|
|
@@ -591,15 +694,47 @@ class ChangeSetModel:
|
|
|
591
694
|
change_type = resolve_function(arguments)
|
|
592
695
|
else:
|
|
593
696
|
change_type = arguments.change_type
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
697
|
+
|
|
698
|
+
if intrinsic_function == FnTransform:
|
|
699
|
+
if scope.count(FnTransform) > 1:
|
|
700
|
+
raise RuntimeError(
|
|
701
|
+
"Invalid: Fn::Transforms cannot be nested inside another Fn::Transform"
|
|
702
|
+
)
|
|
703
|
+
|
|
704
|
+
path = scope.parent.jsonpath
|
|
705
|
+
before_siblings = extract_jsonpath(self._before_template, path)
|
|
706
|
+
after_siblings = extract_jsonpath(self._after_template, path)
|
|
707
|
+
|
|
708
|
+
node_intrinsic_function = NodeIntrinsicFunctionFnTransform(
|
|
709
|
+
scope=scope,
|
|
710
|
+
change_type=change_type,
|
|
711
|
+
arguments=arguments,
|
|
712
|
+
intrinsic_function=intrinsic_function,
|
|
713
|
+
before_siblings=before_siblings,
|
|
714
|
+
after_siblings=after_siblings,
|
|
715
|
+
)
|
|
716
|
+
else:
|
|
717
|
+
node_intrinsic_function = NodeIntrinsicFunction(
|
|
718
|
+
scope=scope,
|
|
719
|
+
change_type=change_type,
|
|
720
|
+
intrinsic_function=intrinsic_function,
|
|
721
|
+
arguments=arguments,
|
|
722
|
+
)
|
|
600
723
|
self._visited_scopes[scope] = node_intrinsic_function
|
|
601
724
|
return node_intrinsic_function
|
|
602
725
|
|
|
726
|
+
def _visit_foreach(
|
|
727
|
+
self, scope: Scope, before_arguments: Maybe[list], after_arguments: Maybe[list]
|
|
728
|
+
) -> NodeForEach:
|
|
729
|
+
node_foreach = self._visited_scopes.get(scope)
|
|
730
|
+
if isinstance(node_foreach, NodeForEach):
|
|
731
|
+
return node_foreach
|
|
732
|
+
arguments_scope = scope.open_scope("args")
|
|
733
|
+
arguments = self._visit_array(
|
|
734
|
+
arguments_scope, before_array=before_arguments, after_array=after_arguments
|
|
735
|
+
)
|
|
736
|
+
return NodeForEach(scope=scope, change_type=arguments.change_type, arguments=arguments)
|
|
737
|
+
|
|
603
738
|
def _resolve_intrinsic_function_fn_sub(self, arguments: ChangeSetEntity) -> ChangeType:
|
|
604
739
|
# TODO: This routine should instead export the implicit Ref and GetAtt calls within the first
|
|
605
740
|
# string template parameter and compute the respective change set types. Currently,
|
|
@@ -647,6 +782,9 @@ class ChangeSetModel:
|
|
|
647
782
|
|
|
648
783
|
logical_id = arguments.value
|
|
649
784
|
|
|
785
|
+
if isinstance(logical_id, str) and logical_id.startswith("AWS::"):
|
|
786
|
+
return arguments.change_type
|
|
787
|
+
|
|
650
788
|
node_condition = self._retrieve_condition_if_exists(condition_name=logical_id)
|
|
651
789
|
if isinstance(node_condition, NodeCondition):
|
|
652
790
|
return node_condition.change_type
|
|
@@ -717,13 +855,38 @@ class ChangeSetModel:
|
|
|
717
855
|
)
|
|
718
856
|
if not isinstance(node_condition, NodeCondition):
|
|
719
857
|
raise RuntimeError()
|
|
720
|
-
change_type = parent_change_type_of([node_condition, *arguments[1:]])
|
|
858
|
+
change_type = parent_change_type_of([node_condition, *arguments.array[1:]])
|
|
721
859
|
return change_type
|
|
722
860
|
|
|
861
|
+
def _resolve_requires_replacement(
|
|
862
|
+
self, node_properties: NodeProperties, resource_type: TerminalValue
|
|
863
|
+
) -> bool:
|
|
864
|
+
# a bit hacky but we have to load the resource provider executor _and_ resource provider to get the schema
|
|
865
|
+
# Note: we don't log the attempt to load the resource provider, we need to make sure this is only done once and we already do this in the executor
|
|
866
|
+
|
|
867
|
+
resource_provider = ResourceProviderExecutor.try_load_resource_provider(resource_type.value)
|
|
868
|
+
if not resource_provider:
|
|
869
|
+
# if we don't support a resource, assume an in-place update for simplicity
|
|
870
|
+
return False
|
|
871
|
+
|
|
872
|
+
create_only_properties: list[str] = resource_provider.SCHEMA.get("createOnlyProperties", [])
|
|
873
|
+
# TODO: also hacky: strip the leading `/properties/` string from the definition
|
|
874
|
+
# ideally we should use a jsonpath or similar
|
|
875
|
+
create_only_properties = [
|
|
876
|
+
property.replace("/properties/", "", 1) for property in create_only_properties
|
|
877
|
+
]
|
|
878
|
+
for node_property in node_properties.properties:
|
|
879
|
+
if (
|
|
880
|
+
node_property.change_type == ChangeType.MODIFIED
|
|
881
|
+
and node_property.name in create_only_properties
|
|
882
|
+
):
|
|
883
|
+
return True
|
|
884
|
+
return False
|
|
885
|
+
|
|
723
886
|
def _visit_array(
|
|
724
887
|
self, scope: Scope, before_array: Maybe[list], after_array: Maybe[list]
|
|
725
888
|
) -> NodeArray:
|
|
726
|
-
array: list[ChangeSetEntity] =
|
|
889
|
+
array: list[ChangeSetEntity] = []
|
|
727
890
|
for index, (before_value, after_value) in enumerate(
|
|
728
891
|
zip_longest(before_array, after_array, fillvalue=Nothing)
|
|
729
892
|
):
|
|
@@ -742,7 +905,7 @@ class ChangeSetModel:
|
|
|
742
905
|
if isinstance(node_object, NodeObject):
|
|
743
906
|
return node_object
|
|
744
907
|
binding_names = self._safe_keys_of(before_object, after_object)
|
|
745
|
-
bindings: dict[str, ChangeSetEntity] =
|
|
908
|
+
bindings: dict[str, ChangeSetEntity] = {}
|
|
746
909
|
for binding_name in binding_names:
|
|
747
910
|
binding_scope, (before_value, after_value) = self._safe_access_in(
|
|
748
911
|
scope, binding_name, before_object, after_object
|
|
@@ -844,11 +1007,19 @@ class ChangeSetModel:
|
|
|
844
1007
|
if isinstance(node_properties, NodeProperties):
|
|
845
1008
|
return node_properties
|
|
846
1009
|
property_names: list[str] = self._safe_keys_of(before_properties, after_properties)
|
|
847
|
-
properties: list[NodeProperty] =
|
|
1010
|
+
properties: list[NodeProperty] = []
|
|
1011
|
+
fn_transform = Nothing
|
|
1012
|
+
|
|
848
1013
|
for property_name in property_names:
|
|
849
1014
|
property_scope, (before_property, after_property) = self._safe_access_in(
|
|
850
1015
|
scope, property_name, before_properties, after_properties
|
|
851
1016
|
)
|
|
1017
|
+
if property_name == FnTransform:
|
|
1018
|
+
fn_transform = self._visit_intrinsic_function(
|
|
1019
|
+
property_scope, FnTransform, before_property, after_property
|
|
1020
|
+
)
|
|
1021
|
+
continue
|
|
1022
|
+
|
|
852
1023
|
property_ = self._visit_property(
|
|
853
1024
|
scope=property_scope,
|
|
854
1025
|
property_name=property_name,
|
|
@@ -856,7 +1027,10 @@ class ChangeSetModel:
|
|
|
856
1027
|
after_property=after_property,
|
|
857
1028
|
)
|
|
858
1029
|
properties.append(property_)
|
|
859
|
-
|
|
1030
|
+
|
|
1031
|
+
node_properties = NodeProperties(
|
|
1032
|
+
scope=scope, properties=properties, fn_transform=fn_transform
|
|
1033
|
+
)
|
|
860
1034
|
self._visited_scopes[scope] = node_properties
|
|
861
1035
|
return node_properties
|
|
862
1036
|
|
|
@@ -867,6 +1041,30 @@ class ChangeSetModel:
|
|
|
867
1041
|
raise RuntimeError()
|
|
868
1042
|
return value
|
|
869
1043
|
|
|
1044
|
+
def _visit_deletion_policy(
|
|
1045
|
+
self, scope: Scope, before_deletion_policy: Any, after_deletion_policy: Any
|
|
1046
|
+
) -> TerminalValue:
|
|
1047
|
+
value = self._visit_value(
|
|
1048
|
+
scope=scope, before_value=before_deletion_policy, after_value=after_deletion_policy
|
|
1049
|
+
)
|
|
1050
|
+
if not isinstance(value, TerminalValue):
|
|
1051
|
+
# TODO: decide where template schema validation should occur.
|
|
1052
|
+
raise RuntimeError()
|
|
1053
|
+
return value
|
|
1054
|
+
|
|
1055
|
+
def _visit_update_replace_policy(
|
|
1056
|
+
self, scope: Scope, before_update_replace_policy: Any, after_deletion_policy: Any
|
|
1057
|
+
) -> TerminalValue:
|
|
1058
|
+
value = self._visit_value(
|
|
1059
|
+
scope=scope,
|
|
1060
|
+
before_value=before_update_replace_policy,
|
|
1061
|
+
after_value=after_deletion_policy,
|
|
1062
|
+
)
|
|
1063
|
+
if not isinstance(value, TerminalValue):
|
|
1064
|
+
# TODO: decide where template schema validation should occur.
|
|
1065
|
+
raise RuntimeError()
|
|
1066
|
+
return value
|
|
1067
|
+
|
|
870
1068
|
def _visit_resource(
|
|
871
1069
|
self,
|
|
872
1070
|
scope: Scope,
|
|
@@ -912,8 +1110,67 @@ class ChangeSetModel:
|
|
|
912
1110
|
after_properties=after_properties,
|
|
913
1111
|
)
|
|
914
1112
|
|
|
1113
|
+
deletion_policy = Nothing
|
|
1114
|
+
scope_deletion_policy, (before_deletion_policy, after_deletion_policy) = (
|
|
1115
|
+
self._safe_access_in(scope, DeletionPolicyKey, before_resource, after_resource)
|
|
1116
|
+
)
|
|
1117
|
+
if before_deletion_policy or after_deletion_policy:
|
|
1118
|
+
deletion_policy = self._visit_deletion_policy(
|
|
1119
|
+
scope_deletion_policy, before_deletion_policy, after_deletion_policy
|
|
1120
|
+
)
|
|
1121
|
+
|
|
1122
|
+
update_replace_policy = Nothing
|
|
1123
|
+
scope_update_replace_policy, (before_update_replace_policy, after_update_replace_policy) = (
|
|
1124
|
+
self._safe_access_in(scope, UpdateReplacePolicyKey, before_resource, after_resource)
|
|
1125
|
+
)
|
|
1126
|
+
if before_update_replace_policy or after_update_replace_policy:
|
|
1127
|
+
update_replace_policy = self._visit_update_replace_policy(
|
|
1128
|
+
scope_update_replace_policy,
|
|
1129
|
+
before_update_replace_policy,
|
|
1130
|
+
after_update_replace_policy,
|
|
1131
|
+
)
|
|
1132
|
+
|
|
1133
|
+
fn_transform = Nothing
|
|
1134
|
+
scope_fn_transform, (before_fn_transform_args, after_fn_transform_args) = (
|
|
1135
|
+
self._safe_access_in(scope, FnTransform, before_resource, after_resource)
|
|
1136
|
+
)
|
|
1137
|
+
if not is_nothing(before_fn_transform_args) or not is_nothing(after_fn_transform_args):
|
|
1138
|
+
if scope_fn_transform.count(FnTransform) > 1:
|
|
1139
|
+
raise RuntimeError(
|
|
1140
|
+
"Invalid: Fn::Transforms cannot be nested inside another Fn::Transform"
|
|
1141
|
+
)
|
|
1142
|
+
path = "$" + ".".join(scope_fn_transform.split("/")[:-1])
|
|
1143
|
+
before_siblings = extract_jsonpath(self._before_template, path)
|
|
1144
|
+
after_siblings = extract_jsonpath(self._after_template, path)
|
|
1145
|
+
arguments_scope = scope.open_scope("args")
|
|
1146
|
+
arguments = self._visit_value(
|
|
1147
|
+
scope=arguments_scope,
|
|
1148
|
+
before_value=before_fn_transform_args,
|
|
1149
|
+
after_value=after_fn_transform_args,
|
|
1150
|
+
)
|
|
1151
|
+
fn_transform = NodeIntrinsicFunctionFnTransform(
|
|
1152
|
+
scope=scope_fn_transform,
|
|
1153
|
+
change_type=ChangeType.MODIFIED, # TODO
|
|
1154
|
+
arguments=arguments, # TODO
|
|
1155
|
+
intrinsic_function=FnTransform,
|
|
1156
|
+
before_siblings=before_siblings,
|
|
1157
|
+
after_siblings=after_siblings,
|
|
1158
|
+
)
|
|
1159
|
+
|
|
915
1160
|
change_type = change_type_of(
|
|
916
|
-
before_resource,
|
|
1161
|
+
before_resource,
|
|
1162
|
+
after_resource,
|
|
1163
|
+
[
|
|
1164
|
+
properties,
|
|
1165
|
+
condition_reference,
|
|
1166
|
+
depends_on,
|
|
1167
|
+
deletion_policy,
|
|
1168
|
+
update_replace_policy,
|
|
1169
|
+
fn_transform,
|
|
1170
|
+
],
|
|
1171
|
+
)
|
|
1172
|
+
requires_replacement = self._resolve_requires_replacement(
|
|
1173
|
+
node_properties=properties, resource_type=terminal_value_type
|
|
917
1174
|
)
|
|
918
1175
|
node_resource = NodeResource(
|
|
919
1176
|
scope=scope,
|
|
@@ -923,6 +1180,10 @@ class ChangeSetModel:
|
|
|
923
1180
|
properties=properties,
|
|
924
1181
|
condition_reference=condition_reference,
|
|
925
1182
|
depends_on=depends_on,
|
|
1183
|
+
requires_replacement=requires_replacement,
|
|
1184
|
+
deletion_policy=deletion_policy,
|
|
1185
|
+
update_replace_policy=update_replace_policy,
|
|
1186
|
+
fn_transform=fn_transform,
|
|
926
1187
|
)
|
|
927
1188
|
self._visited_scopes[scope] = node_resource
|
|
928
1189
|
return node_resource
|
|
@@ -931,12 +1192,30 @@ class ChangeSetModel:
|
|
|
931
1192
|
self, scope: Scope, before_resources: Maybe[dict], after_resources: Maybe[dict]
|
|
932
1193
|
) -> NodeResources:
|
|
933
1194
|
# TODO: investigate type changes behavior.
|
|
934
|
-
resources: list[NodeResource] =
|
|
1195
|
+
resources: list[NodeResource] = []
|
|
935
1196
|
resource_names = self._safe_keys_of(before_resources, after_resources)
|
|
1197
|
+
fn_transform = Nothing
|
|
1198
|
+
fn_foreaches = []
|
|
936
1199
|
for resource_name in resource_names:
|
|
937
1200
|
resource_scope, (before_resource, after_resource) = self._safe_access_in(
|
|
938
1201
|
scope, resource_name, before_resources, after_resources
|
|
939
1202
|
)
|
|
1203
|
+
if resource_name == FnTransform:
|
|
1204
|
+
fn_transform = self._visit_intrinsic_function(
|
|
1205
|
+
scope=resource_scope,
|
|
1206
|
+
intrinsic_function=resource_name,
|
|
1207
|
+
before_arguments=before_resource,
|
|
1208
|
+
after_arguments=after_resource,
|
|
1209
|
+
)
|
|
1210
|
+
continue
|
|
1211
|
+
elif resource_name.startswith("Fn::ForEach"):
|
|
1212
|
+
fn_for_each = self._visit_foreach(
|
|
1213
|
+
scope=resource_scope,
|
|
1214
|
+
before_arguments=before_resource,
|
|
1215
|
+
after_arguments=after_resource,
|
|
1216
|
+
)
|
|
1217
|
+
fn_foreaches.append(fn_for_each)
|
|
1218
|
+
continue
|
|
940
1219
|
resource = self._visit_resource(
|
|
941
1220
|
scope=resource_scope,
|
|
942
1221
|
resource_name=resource_name,
|
|
@@ -944,7 +1223,12 @@ class ChangeSetModel:
|
|
|
944
1223
|
after_resource=after_resource,
|
|
945
1224
|
)
|
|
946
1225
|
resources.append(resource)
|
|
947
|
-
return NodeResources(
|
|
1226
|
+
return NodeResources(
|
|
1227
|
+
scope=scope,
|
|
1228
|
+
resources=resources,
|
|
1229
|
+
fn_transform=fn_transform,
|
|
1230
|
+
fn_foreaches=fn_foreaches,
|
|
1231
|
+
)
|
|
948
1232
|
|
|
949
1233
|
def _visit_mapping(
|
|
950
1234
|
self, scope: Scope, name: str, before_mapping: Maybe[dict], after_mapping: Maybe[dict]
|
|
@@ -957,7 +1241,7 @@ class ChangeSetModel:
|
|
|
957
1241
|
def _visit_mappings(
|
|
958
1242
|
self, scope: Scope, before_mappings: Maybe[dict], after_mappings: Maybe[dict]
|
|
959
1243
|
) -> NodeMappings:
|
|
960
|
-
mappings: list[NodeMapping] =
|
|
1244
|
+
mappings: list[NodeMapping] = []
|
|
961
1245
|
mapping_names = self._safe_keys_of(before_mappings, after_mappings)
|
|
962
1246
|
for mapping_name in mapping_names:
|
|
963
1247
|
scope_mapping, (before_mapping, after_mapping) = self._safe_access_in(
|
|
@@ -974,9 +1258,22 @@ class ChangeSetModel:
|
|
|
974
1258
|
|
|
975
1259
|
def _visit_dynamic_parameter(self, parameter_name: str) -> ChangeSetEntity:
|
|
976
1260
|
scope = Scope("Dynamic").open_scope("Parameters")
|
|
977
|
-
scope_parameter, (
|
|
1261
|
+
scope_parameter, (before_parameter_dct, after_parameter_dct) = self._safe_access_in(
|
|
978
1262
|
scope, parameter_name, self._before_parameters, self._after_parameters
|
|
979
1263
|
)
|
|
1264
|
+
|
|
1265
|
+
before_parameter = Nothing
|
|
1266
|
+
if not is_nothing(before_parameter_dct):
|
|
1267
|
+
before_parameter = before_parameter_dct.get("resolved_value") or engine_parameter_value(
|
|
1268
|
+
before_parameter_dct
|
|
1269
|
+
)
|
|
1270
|
+
|
|
1271
|
+
after_parameter = Nothing
|
|
1272
|
+
if not is_nothing(after_parameter_dct):
|
|
1273
|
+
after_parameter = after_parameter_dct.get("resolved_value") or engine_parameter_value(
|
|
1274
|
+
after_parameter_dct
|
|
1275
|
+
)
|
|
1276
|
+
|
|
980
1277
|
parameter = self._visit_value(
|
|
981
1278
|
scope=scope_parameter, before_value=before_parameter, after_value=after_parameter
|
|
982
1279
|
)
|
|
@@ -1022,7 +1319,7 @@ class ChangeSetModel:
|
|
|
1022
1319
|
if isinstance(node_parameters, NodeParameters):
|
|
1023
1320
|
return node_parameters
|
|
1024
1321
|
parameter_names: list[str] = self._safe_keys_of(before_parameters, after_parameters)
|
|
1025
|
-
parameters: list[NodeParameter] =
|
|
1322
|
+
parameters: list[NodeParameter] = []
|
|
1026
1323
|
for parameter_name in parameter_names:
|
|
1027
1324
|
parameter_scope, (before_parameter, after_parameter) = self._safe_access_in(
|
|
1028
1325
|
scope, parameter_name, before_parameters, after_parameters
|
|
@@ -1092,7 +1389,7 @@ class ChangeSetModel:
|
|
|
1092
1389
|
if isinstance(node_conditions, NodeConditions):
|
|
1093
1390
|
return node_conditions
|
|
1094
1391
|
condition_names: list[str] = self._safe_keys_of(before_conditions, after_conditions)
|
|
1095
|
-
conditions: list[NodeCondition] =
|
|
1392
|
+
conditions: list[NodeCondition] = []
|
|
1096
1393
|
for condition_name in condition_names:
|
|
1097
1394
|
condition_scope, (before_condition, after_condition) = self._safe_access_in(
|
|
1098
1395
|
scope, condition_name, before_conditions, after_conditions
|
|
@@ -1144,7 +1441,7 @@ class ChangeSetModel:
|
|
|
1144
1441
|
def _visit_outputs(
|
|
1145
1442
|
self, scope: Scope, before_outputs: Maybe[dict], after_outputs: Maybe[dict]
|
|
1146
1443
|
) -> NodeOutputs:
|
|
1147
|
-
outputs: list[NodeOutput] =
|
|
1444
|
+
outputs: list[NodeOutput] = []
|
|
1148
1445
|
output_names: list[str] = self._safe_keys_of(before_outputs, after_outputs)
|
|
1149
1446
|
for output_name in output_names:
|
|
1150
1447
|
scope_output, (before_output, after_output) = self._safe_access_in(
|
|
@@ -1191,7 +1488,7 @@ class ChangeSetModel:
|
|
|
1191
1488
|
elif isinstance(value, str):
|
|
1192
1489
|
value = [NormalisedGlobalTransformDefinition(Name=value, Parameters=Nothing)]
|
|
1193
1490
|
elif isinstance(value, list):
|
|
1194
|
-
tmp_value =
|
|
1491
|
+
tmp_value = []
|
|
1195
1492
|
for item in value:
|
|
1196
1493
|
if isinstance(item, str):
|
|
1197
1494
|
tmp_value.append(
|
|
@@ -1215,7 +1512,7 @@ class ChangeSetModel:
|
|
|
1215
1512
|
) -> NodeTransform:
|
|
1216
1513
|
before_transform_normalised = self._normalise_transformer_value(before_transform)
|
|
1217
1514
|
after_transform_normalised = self._normalise_transformer_value(after_transform)
|
|
1218
|
-
global_transforms =
|
|
1515
|
+
global_transforms = []
|
|
1219
1516
|
for index, (before_global_transform, after_global_transform) in enumerate(
|
|
1220
1517
|
zip_longest(before_transform_normalised, after_transform_normalised, fillvalue=Nothing)
|
|
1221
1518
|
):
|
|
@@ -1296,8 +1593,8 @@ class ChangeSetModel:
|
|
|
1296
1593
|
conditions_scope, (before_conditions, after_conditions) = self._safe_access_in(
|
|
1297
1594
|
Scope(), ConditionsKey, self._before_template, self._after_template
|
|
1298
1595
|
)
|
|
1299
|
-
before_conditions = before_conditions or
|
|
1300
|
-
after_conditions = after_conditions or
|
|
1596
|
+
before_conditions = before_conditions or {}
|
|
1597
|
+
after_conditions = after_conditions or {}
|
|
1301
1598
|
if condition_name in before_conditions or condition_name in after_conditions:
|
|
1302
1599
|
condition_scope, (before_condition, after_condition) = self._safe_access_in(
|
|
1303
1600
|
conditions_scope, condition_name, before_conditions, after_conditions
|
|
@@ -1367,7 +1664,7 @@ class ChangeSetModel:
|
|
|
1367
1664
|
|
|
1368
1665
|
@staticmethod
|
|
1369
1666
|
def _safe_access_in(scope: Scope, key: str, *objects: Maybe[dict]) -> tuple[Scope, Maybe[Any]]:
|
|
1370
|
-
results =
|
|
1667
|
+
results = []
|
|
1371
1668
|
for obj in objects:
|
|
1372
1669
|
if not isinstance(obj, (dict, NothingType)):
|
|
1373
1670
|
raise RuntimeError(f"Invalid definition type at '{obj}'")
|
|
@@ -1391,7 +1688,7 @@ class ChangeSetModel:
|
|
|
1391
1688
|
return keys
|
|
1392
1689
|
|
|
1393
1690
|
@staticmethod
|
|
1394
|
-
def _name_if_intrinsic_function(value: Maybe[Any]) ->
|
|
1691
|
+
def _name_if_intrinsic_function(value: Maybe[Any]) -> str | None:
|
|
1395
1692
|
if isinstance(value, dict):
|
|
1396
1693
|
keys = ChangeSetModel._safe_keys_of(value)
|
|
1397
1694
|
if len(keys) == 1:
|