localstack-core 4.7.1.dev139__py3-none-any.whl → 4.10.1.dev42__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.
Potentially problematic release.
This version of localstack-core might be problematic. Click here for more details.
- localstack/aws/api/acm/__init__.py +122 -122
- localstack/aws/api/apigateway/__init__.py +560 -559
- localstack/aws/api/cloudcontrol/__init__.py +63 -63
- localstack/aws/api/cloudformation/__init__.py +1041 -969
- localstack/aws/api/cloudwatch/__init__.py +408 -368
- localstack/aws/api/config/__init__.py +788 -786
- localstack/aws/api/core.py +4 -0
- localstack/aws/api/dynamodb/__init__.py +753 -759
- localstack/aws/api/dynamodbstreams/__init__.py +74 -74
- localstack/aws/api/ec2/__init__.py +9713 -8573
- localstack/aws/api/es/__init__.py +453 -453
- localstack/aws/api/events/__init__.py +552 -552
- localstack/aws/api/firehose/__init__.py +541 -543
- localstack/aws/api/iam/__init__.py +646 -572
- localstack/aws/api/kinesis/__init__.py +251 -144
- localstack/aws/api/kms/__init__.py +343 -333
- localstack/aws/api/lambda_/__init__.py +585 -571
- localstack/aws/api/logs/__init__.py +682 -666
- localstack/aws/api/opensearch/__init__.py +814 -785
- localstack/aws/api/pipes/__init__.py +336 -336
- localstack/aws/api/redshift/__init__.py +1192 -1164
- localstack/aws/api/resource_groups/__init__.py +175 -175
- localstack/aws/api/resourcegroupstaggingapi/__init__.py +67 -67
- localstack/aws/api/route53/__init__.py +256 -254
- localstack/aws/api/route53resolver/__init__.py +396 -396
- localstack/aws/api/s3/__init__.py +1358 -1345
- localstack/aws/api/s3control/__init__.py +616 -584
- localstack/aws/api/scheduler/__init__.py +118 -118
- localstack/aws/api/secretsmanager/__init__.py +193 -193
- localstack/aws/api/ses/__init__.py +227 -227
- localstack/aws/api/sns/__init__.py +115 -115
- localstack/aws/api/sqs/__init__.py +100 -100
- localstack/aws/api/ssm/__init__.py +1978 -1970
- localstack/aws/api/stepfunctions/__init__.py +323 -323
- localstack/aws/api/sts/__init__.py +90 -66
- localstack/aws/api/support/__init__.py +112 -112
- localstack/aws/api/swf/__init__.py +378 -386
- localstack/aws/api/transcribe/__init__.py +425 -425
- localstack/aws/client.py +7 -2
- localstack/aws/forwarder.py +52 -5
- localstack/aws/handlers/analytics.py +1 -1
- localstack/aws/handlers/logging.py +12 -2
- localstack/aws/handlers/metric_handler.py +41 -1
- localstack/aws/handlers/service.py +43 -10
- localstack/aws/protocol/parser.py +440 -21
- localstack/aws/protocol/serializer.py +684 -64
- localstack/aws/protocol/service_router.py +120 -20
- localstack/aws/scaffold.py +15 -17
- localstack/aws/skeleton.py +4 -2
- localstack/aws/spec-patches.json +58 -0
- localstack/aws/spec.py +33 -13
- localstack/cli/exceptions.py +1 -1
- localstack/cli/localstack.py +10 -5
- localstack/cli/lpm.py +3 -4
- localstack/cli/profiles.py +1 -2
- localstack/config.py +18 -12
- localstack/constants.py +4 -29
- localstack/dev/kubernetes/__main__.py +39 -4
- localstack/dev/run/paths.py +1 -1
- localstack/dns/plugins.py +5 -1
- localstack/dns/server.py +12 -3
- localstack/packages/api.py +9 -8
- localstack/packages/core.py +2 -2
- localstack/packages/plugins.py +0 -8
- localstack/runtime/init.py +1 -1
- localstack/services/apigateway/helpers.py +5 -9
- localstack/services/apigateway/legacy/provider.py +85 -12
- localstack/services/apigateway/next_gen/execute_api/integrations/aws.py +3 -0
- localstack/services/apigateway/next_gen/execute_api/integrations/http.py +3 -3
- localstack/services/apigateway/next_gen/execute_api/test_invoke.py +50 -6
- localstack/services/apigateway/next_gen/provider.py +5 -0
- localstack/services/apigateway/patches.py +0 -9
- localstack/services/cloudformation/engine/entities.py +12 -1
- localstack/services/cloudformation/engine/v2/change_set_model.py +0 -3
- localstack/services/cloudformation/engine/v2/change_set_model_describer.py +14 -0
- localstack/services/cloudformation/engine/v2/change_set_model_executor.py +13 -15
- localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +118 -24
- localstack/services/cloudformation/engine/v2/change_set_model_transform.py +4 -1
- localstack/services/cloudformation/engine/v2/change_set_model_validator.py +5 -14
- localstack/services/cloudformation/engine/v2/change_set_model_visitor.py +1 -0
- localstack/services/cloudformation/engine/v2/resolving.py +6 -4
- localstack/services/cloudformation/engine/yaml_parser.py +9 -2
- localstack/services/cloudformation/provider.py +2 -2
- localstack/services/cloudformation/resource_provider.py +5 -1
- localstack/services/cloudformation/resources.py +24149 -0
- localstack/services/cloudformation/v2/entities.py +6 -3
- localstack/services/cloudformation/v2/provider.py +178 -33
- localstack/services/cloudformation/v2/types.py +8 -4
- localstack/services/cloudwatch/provider_v2.py +25 -28
- localstack/services/dynamodb/packages.py +2 -1
- localstack/services/dynamodb/provider.py +42 -0
- localstack/services/dynamodb/v2/provider.py +42 -0
- localstack/services/ecr/resource_providers/aws_ecr_repository.py +5 -2
- localstack/services/es/provider.py +2 -2
- localstack/services/events/event_rule_engine.py +31 -13
- localstack/services/events/models.py +4 -5
- localstack/services/events/target.py +17 -9
- localstack/services/iam/provider.py +11 -116
- localstack/services/iam/resources/policy_simulator.py +133 -0
- localstack/services/kinesis/models.py +15 -2
- localstack/services/kinesis/packages.py +1 -1
- localstack/services/kinesis/provider.py +77 -0
- localstack/services/kms/models.py +34 -4
- localstack/services/kms/provider.py +107 -21
- localstack/services/lambda_/api_utils.py +3 -1
- localstack/services/lambda_/invocation/internal_sqs_queue.py +5 -9
- localstack/services/lambda_/packages.py +1 -1
- localstack/services/lambda_/provider.py +1 -1
- localstack/services/lambda_/runtimes.py +8 -3
- localstack/services/logs/provider.py +36 -19
- localstack/services/moto.py +2 -1
- localstack/services/opensearch/cluster.py +15 -7
- localstack/services/opensearch/packages.py +26 -7
- localstack/services/opensearch/provider.py +6 -1
- localstack/services/opensearch/versions.py +56 -7
- localstack/services/s3/constants.py +5 -2
- localstack/services/s3/cors.py +4 -4
- localstack/services/s3/notifications.py +1 -1
- localstack/services/s3/presigned_url.py +27 -43
- localstack/services/s3/provider.py +68 -12
- localstack/services/s3/utils.py +42 -11
- localstack/services/ses/provider.py +16 -7
- localstack/services/sns/constants.py +7 -1
- localstack/services/sns/v2/models.py +190 -0
- localstack/services/sns/v2/provider.py +992 -2
- localstack/services/sns/v2/utils.py +138 -0
- localstack/services/sqs/developer_api.py +205 -0
- localstack/services/sqs/models.py +79 -13
- localstack/services/sqs/provider.py +8 -309
- localstack/services/sqs/query_api.py +1 -1
- localstack/services/sqs/utils.py +121 -2
- localstack/services/stepfunctions/asl/jsonata/jsonata.py +1 -1
- localstack/testing/aws/cloudformation_utils.py +1 -1
- localstack/testing/pytest/cloudformation/fixtures.py +3 -3
- localstack/testing/pytest/container.py +4 -5
- localstack/testing/pytest/fixtures.py +20 -19
- localstack/testing/pytest/in_memory_localstack.py +0 -4
- localstack/testing/pytest/marking.py +13 -4
- localstack/testing/pytest/stepfunctions/utils.py +4 -3
- localstack/testing/pytest/util.py +1 -1
- localstack/testing/pytest/validation_tracking.py +1 -2
- localstack/testing/snapshots/transformer_utility.py +7 -0
- localstack/testing/testselection/matching.py +0 -1
- localstack/utils/analytics/events.py +2 -2
- localstack/utils/analytics/metadata.py +1 -2
- localstack/utils/analytics/metrics/counter.py +6 -8
- localstack/utils/analytics/publisher.py +1 -2
- localstack/utils/analytics/service_request_aggregator.py +2 -2
- localstack/utils/archives.py +11 -11
- localstack/utils/aws/arns.py +17 -9
- localstack/utils/aws/aws_responses.py +7 -7
- localstack/utils/aws/aws_stack.py +2 -3
- localstack/utils/aws/client_types.py +0 -8
- localstack/utils/aws/message_forwarding.py +1 -2
- localstack/utils/aws/request_context.py +4 -5
- localstack/utils/batch_policy.py +3 -3
- localstack/utils/bootstrap.py +7 -7
- 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 +7 -8
- localstack/utils/config_listener.py +1 -1
- localstack/utils/container_networking.py +2 -3
- localstack/utils/container_utils/container_client.py +115 -131
- localstack/utils/container_utils/docker_cmd_client.py +42 -42
- localstack/utils/container_utils/docker_sdk_client.py +63 -62
- localstack/utils/crypto.py +109 -0
- localstack/utils/diagnose.py +2 -3
- localstack/utils/docker_utils.py +3 -4
- localstack/utils/files.py +31 -7
- localstack/utils/functions.py +3 -2
- localstack/utils/http.py +4 -5
- localstack/utils/json.py +19 -5
- localstack/utils/kinesis/kinesis_connector.py +2 -1
- localstack/utils/net.py +6 -6
- localstack/utils/no_exit_argument_parser.py +2 -2
- localstack/utils/numbers.py +9 -2
- localstack/utils/objects.py +6 -5
- localstack/utils/patch.py +2 -1
- localstack/utils/run.py +10 -9
- localstack/utils/scheduler.py +11 -11
- localstack/utils/server/tcp_proxy.py +2 -2
- localstack/utils/serving.py +2 -3
- localstack/utils/strings.py +10 -11
- localstack/utils/sync.py +126 -1
- localstack/utils/tagging.py +1 -4
- localstack/utils/testutil.py +5 -4
- localstack/utils/threads.py +2 -2
- localstack/utils/time.py +11 -3
- localstack/utils/urls.py +1 -3
- localstack/version.py +2 -2
- {localstack_core-4.7.1.dev139.dist-info → localstack_core-4.10.1.dev42.dist-info}/METADATA +19 -13
- {localstack_core-4.7.1.dev139.dist-info → localstack_core-4.10.1.dev42.dist-info}/RECORD +203 -199
- {localstack_core-4.7.1.dev139.dist-info → localstack_core-4.10.1.dev42.dist-info}/entry_points.txt +4 -2
- localstack_core-4.10.1.dev42.dist-info/plux.json +1 -0
- localstack/packages/terraform.py +0 -46
- localstack/services/cloudformation/deploy.html +0 -144
- localstack/services/cloudformation/deploy_ui.py +0 -47
- localstack/services/cloudformation/plugins.py +0 -12
- localstack_core-4.7.1.dev139.dist-info/plux.json +0 -1
- {localstack_core-4.7.1.dev139.data → localstack_core-4.10.1.dev42.data}/scripts/localstack +0 -0
- {localstack_core-4.7.1.dev139.data → localstack_core-4.10.1.dev42.data}/scripts/localstack-supervisor +0 -0
- {localstack_core-4.7.1.dev139.data → localstack_core-4.10.1.dev42.data}/scripts/localstack.bat +0 -0
- {localstack_core-4.7.1.dev139.dist-info → localstack_core-4.10.1.dev42.dist-info}/WHEEL +0 -0
- {localstack_core-4.7.1.dev139.dist-info → localstack_core-4.10.1.dev42.dist-info}/licenses/LICENSE.txt +0 -0
- {localstack_core-4.7.1.dev139.dist-info → localstack_core-4.10.1.dev42.dist-info}/top_level.txt +0 -0
|
@@ -3728,7 +3728,7 @@ class LambdaProvider(LambdaApi, ServiceLifecycleHook):
|
|
|
3728
3728
|
if not layer_version:
|
|
3729
3729
|
raise ValidationException(
|
|
3730
3730
|
f"1 validation error detected: Value '{arn}' at 'arn' failed to satisfy constraint: Member must satisfy regular expression pattern: "
|
|
3731
|
-
+ "(arn:(aws[a-zA-Z-]*)?:lambda:[a-z]{2}((-gov)|(-iso([a-z]?)))?-[a-z]+-\\d{1}:\\d{12}:layer:[a-zA-Z0-9-_]+:[0-9]+)|(arn:[a-zA-Z0-9-]+:lambda:::awslayer:[a-zA-Z0-9-_]+)"
|
|
3731
|
+
+ "(arn:(aws[a-zA-Z-]*)?:lambda:(eusc-)?[a-z]{2}((-gov)|(-iso([a-z]?)))?-[a-z]+-\\d{1}:\\d{12}:layer:[a-zA-Z0-9-_]+:[0-9]+)|(arn:[a-zA-Z0-9-]+:lambda:::awslayer:[a-zA-Z0-9-_]+)"
|
|
3732
3732
|
)
|
|
3733
3733
|
|
|
3734
3734
|
store = lambda_stores[account_id][region_name]
|
|
@@ -23,7 +23,7 @@ from localstack.aws.api.lambda_ import Runtime
|
|
|
23
23
|
# 5. Run the unit test to check the runtime setup:
|
|
24
24
|
# tests.unit.services.lambda_.test_api_utils.TestApiUtils.test_check_runtime
|
|
25
25
|
# 6. Review special tests including:
|
|
26
|
-
# a) [
|
|
26
|
+
# a) [pro] tests.aws.services.lambda_.test_lambda_endpoint_injection
|
|
27
27
|
# 7. Before merging, run the ext integration tests to cover transparent endpoint injection testing.
|
|
28
28
|
# 8. Add the new runtime to the K8 image build: https://github.com/localstack/lambda-images
|
|
29
29
|
# 9. Inform the web team to update the resource browser (consider offering an endpoint in the future)
|
|
@@ -40,6 +40,7 @@ IMAGE_MAPPING: dict[Runtime, str] = {
|
|
|
40
40
|
Runtime.nodejs16_x: "nodejs:16",
|
|
41
41
|
Runtime.nodejs14_x: "nodejs:14", # deprecated Dec 4, 2023 => Jan 9, 2024 => Feb 8, 2024
|
|
42
42
|
Runtime.nodejs12_x: "nodejs:12", # deprecated Mar 31, 2023 => Mar 31, 2023 => Apr 30, 2023
|
|
43
|
+
Runtime.python3_14: "python:3.14",
|
|
43
44
|
Runtime.python3_13: "python:3.13",
|
|
44
45
|
Runtime.python3_12: "python:3.12",
|
|
45
46
|
Runtime.python3_11: "python:3.11",
|
|
@@ -47,6 +48,7 @@ IMAGE_MAPPING: dict[Runtime, str] = {
|
|
|
47
48
|
Runtime.python3_9: "python:3.9",
|
|
48
49
|
Runtime.python3_8: "python:3.8",
|
|
49
50
|
Runtime.python3_7: "python:3.7", # deprecated Dec 4, 2023 => Jan 9, 2024 => Feb 8, 2024
|
|
51
|
+
Runtime.java25: "java:25",
|
|
50
52
|
Runtime.java21: "java:21",
|
|
51
53
|
Runtime.java17: "java:17",
|
|
52
54
|
Runtime.java11: "java:11",
|
|
@@ -116,6 +118,7 @@ RUNTIMES_AGGREGATED = {
|
|
|
116
118
|
Runtime.nodejs16_x,
|
|
117
119
|
],
|
|
118
120
|
"python": [
|
|
121
|
+
Runtime.python3_14,
|
|
119
122
|
Runtime.python3_13,
|
|
120
123
|
Runtime.python3_12,
|
|
121
124
|
Runtime.python3_11,
|
|
@@ -124,6 +127,7 @@ RUNTIMES_AGGREGATED = {
|
|
|
124
127
|
Runtime.python3_8,
|
|
125
128
|
],
|
|
126
129
|
"java": [
|
|
130
|
+
Runtime.java25,
|
|
127
131
|
Runtime.java21,
|
|
128
132
|
Runtime.java17,
|
|
129
133
|
Runtime.java11,
|
|
@@ -155,12 +159,13 @@ SNAP_START_SUPPORTED_RUNTIMES = [
|
|
|
155
159
|
Runtime.java11,
|
|
156
160
|
Runtime.java17,
|
|
157
161
|
Runtime.java21,
|
|
162
|
+
Runtime.java25,
|
|
158
163
|
Runtime.python3_12,
|
|
159
164
|
Runtime.python3_13,
|
|
160
165
|
Runtime.dotnet8,
|
|
161
166
|
]
|
|
162
167
|
|
|
163
168
|
# An ordered list of all Lambda runtimes considered valid by AWS. Matching snapshots in test_create_lambda_exceptions
|
|
164
|
-
VALID_RUNTIMES: str = "[nodejs20.x, provided.al2023, python3.12, python3.13, nodejs22.x, java17, nodejs16.x, dotnet8, python3.10, java11, python3.11, dotnet6, java21, nodejs18.x, provided.al2, ruby3.3, ruby3.4, java8.al2, ruby3.2, python3.8, python3.9]"
|
|
169
|
+
VALID_RUNTIMES: str = "[nodejs20.x, python3.14, provided.al2023, python3.12, python3.13, nodejs22.x, java17, nodejs16.x, java25, dotnet8, python3.10, java11, python3.11, dotnet6, java21, nodejs18.x, provided.al2, ruby3.3, ruby3.4, java8.al2, ruby3.2, python3.8, python3.9]"
|
|
165
170
|
# An ordered list of all Lambda runtimes for layers considered valid by AWS. Matching snapshots in test_layer_exceptions
|
|
166
|
-
VALID_LAYER_RUNTIMES: str = "[ruby2.6, dotnetcore1.0, python3.7, nodejs8.10, nasa, ruby2.7, python2.7-greengrass, dotnetcore2.0, python3.8, java21, dotnet6, dotnetcore2.1, python3.9, java11, nodejs6.10, provided, dotnetcore3.1, dotnet8, java25, java17, nodejs, nodejs4.3, java8.al2, go1.x, dotnet10, nodejs20.x, go1.9, byol, nodejs10.x, provided.al2023, nodejs22.x, python3.10, java8, nodejs12.x, python3.11, nodejs24.x, nodejs8.x, python3.12, nodejs14.x, nodejs8.9, python3.13, python3.14, nodejs16.x, provided.al2, nodejs4.3-edge, nodejs18.x, ruby3.2, python3.4, ruby3.3, ruby3.4, ruby2.5, python3.6, python2.7]"
|
|
171
|
+
VALID_LAYER_RUNTIMES: str = "[ruby3.5, ruby2.6, dotnetcore1.0, python3.7, nodejs8.10, nasa, ruby2.7, python2.7-greengrass, dotnetcore2.0, python3.8, java21, dotnet6, dotnetcore2.1, python3.9, java11, nodejs6.10, provided, dotnetcore3.1, dotnet8, java25, java17, nodejs, nodejs4.3, java8.al2, go1.x, dotnet10, nodejs20.x, go1.9, byol, nodejs10.x, provided.al2023, nodejs22.x, python3.10, java8, nodejs12.x, python3.11, nodejs24.x, nodejs8.x, python3.12, nodejs14.x, nodejs8.9, nodejs26.x, python3.13, python3.14, nodejs16.x, python3.15, provided.al2, nodejs4.3-edge, nodejs18.x, ruby3.2, python3.4, ruby3.3, ruby3.4, ruby2.5, python3.6, python2.7]"
|
|
@@ -22,10 +22,13 @@ from localstack.aws.api.logs import (
|
|
|
22
22
|
InputLogEvents,
|
|
23
23
|
InvalidParameterException,
|
|
24
24
|
KmsKeyId,
|
|
25
|
+
ListLogGroupsRequest,
|
|
26
|
+
ListLogGroupsResponse,
|
|
25
27
|
ListTagsForResourceResponse,
|
|
26
28
|
ListTagsLogGroupResponse,
|
|
27
29
|
LogGroupClass,
|
|
28
30
|
LogGroupName,
|
|
31
|
+
LogGroupSummary,
|
|
29
32
|
LogsApi,
|
|
30
33
|
LogStreamName,
|
|
31
34
|
PutLogEventsResponse,
|
|
@@ -43,7 +46,7 @@ from localstack.services.plugins import ServiceLifecycleHook
|
|
|
43
46
|
from localstack.utils.aws import arns
|
|
44
47
|
from localstack.utils.aws.client_types import ServicePrincipal
|
|
45
48
|
from localstack.utils.bootstrap import is_api_enabled
|
|
46
|
-
from localstack.utils.
|
|
49
|
+
from localstack.utils.numbers import is_number
|
|
47
50
|
from localstack.utils.patch import patch
|
|
48
51
|
|
|
49
52
|
LOG = logging.getLogger(__name__)
|
|
@@ -60,8 +63,8 @@ class LogsProvider(LogsApi, ServiceLifecycleHook):
|
|
|
60
63
|
log_group_name: LogGroupName,
|
|
61
64
|
log_stream_name: LogStreamName,
|
|
62
65
|
log_events: InputLogEvents,
|
|
63
|
-
sequence_token: SequenceToken = None,
|
|
64
|
-
entity: Entity = None,
|
|
66
|
+
sequence_token: SequenceToken | None = None,
|
|
67
|
+
entity: Entity | None = None,
|
|
65
68
|
**kwargs,
|
|
66
69
|
) -> PutLogEventsResponse:
|
|
67
70
|
logs_backend = get_moto_logs_backend(context.account_id, context.region)
|
|
@@ -97,33 +100,32 @@ class LogsProvider(LogsApi, ServiceLifecycleHook):
|
|
|
97
100
|
) -> DescribeLogGroupsResponse:
|
|
98
101
|
region_backend = get_moto_logs_backend(context.account_id, context.region)
|
|
99
102
|
|
|
100
|
-
prefix: str = request.get("logGroupNamePrefix", "")
|
|
101
|
-
pattern: str = request.get("logGroupNamePattern", "")
|
|
103
|
+
prefix: str | None = request.get("logGroupNamePrefix", "")
|
|
104
|
+
pattern: str | None = request.get("logGroupNamePattern", "")
|
|
102
105
|
|
|
103
106
|
if pattern and prefix:
|
|
104
107
|
raise InvalidParameterException(
|
|
105
108
|
"LogGroup name prefix and LogGroup name pattern are mutually exclusive parameters."
|
|
106
109
|
)
|
|
107
110
|
|
|
108
|
-
|
|
111
|
+
moto_groups = copy.deepcopy(dict(region_backend.groups)).values()
|
|
109
112
|
|
|
110
113
|
groups = [
|
|
111
|
-
group.to_describe_dict()
|
|
112
|
-
for
|
|
114
|
+
{"logGroupClass": LogGroupClass.STANDARD} | group.to_describe_dict()
|
|
115
|
+
for group in sorted(moto_groups, key=lambda g: g.name)
|
|
113
116
|
if not (prefix or pattern)
|
|
114
|
-
or (prefix and name.startswith(prefix))
|
|
115
|
-
or (pattern and pattern in name)
|
|
117
|
+
or (prefix and group.name.startswith(prefix))
|
|
118
|
+
or (pattern and pattern in group.name)
|
|
116
119
|
]
|
|
117
120
|
|
|
118
|
-
groups = sorted(groups, key=lambda x: x["logGroupName"])
|
|
119
121
|
return DescribeLogGroupsResponse(logGroups=groups)
|
|
120
122
|
|
|
121
123
|
@handler("DescribeLogStreams", expand=False)
|
|
122
124
|
def describe_log_streams(
|
|
123
125
|
self, context: RequestContext, request: DescribeLogStreamsRequest
|
|
124
126
|
) -> DescribeLogStreamsResponse:
|
|
125
|
-
log_group_name: str = request.get("logGroupName")
|
|
126
|
-
log_group_identifier: str = request.get("logGroupIdentifier")
|
|
127
|
+
log_group_name: str | None = request.get("logGroupName")
|
|
128
|
+
log_group_identifier: str | None = request.get("logGroupIdentifier")
|
|
127
129
|
|
|
128
130
|
if log_group_identifier and log_group_name:
|
|
129
131
|
raise CommonServiceException(
|
|
@@ -138,13 +140,29 @@ class LogsProvider(LogsApi, ServiceLifecycleHook):
|
|
|
138
140
|
|
|
139
141
|
return moto.call_moto_with_request(context, request_copy)
|
|
140
142
|
|
|
143
|
+
@handler("ListLogGroups", expand=False)
|
|
144
|
+
def list_log_groups(
|
|
145
|
+
self, context: RequestContext, request: ListLogGroupsRequest
|
|
146
|
+
) -> ListLogGroupsResponse:
|
|
147
|
+
pattern: str | None = request.get("logGroupNamePattern")
|
|
148
|
+
region_backend: LogsBackend = get_moto_logs_backend(context.account_id, context.region)
|
|
149
|
+
moto_groups = copy.deepcopy(region_backend.groups).values()
|
|
150
|
+
groups = [
|
|
151
|
+
LogGroupSummary(
|
|
152
|
+
logGroupName=group.name, logGroupArn=group.arn, logGroupClass=LogGroupClass.STANDARD
|
|
153
|
+
)
|
|
154
|
+
for group in sorted(moto_groups, key=lambda g: g.name)
|
|
155
|
+
if not pattern or pattern in group.name
|
|
156
|
+
]
|
|
157
|
+
return ListLogGroupsResponse(logGroups=groups)
|
|
158
|
+
|
|
141
159
|
def create_log_group(
|
|
142
160
|
self,
|
|
143
161
|
context: RequestContext,
|
|
144
162
|
log_group_name: LogGroupName,
|
|
145
|
-
kms_key_id: KmsKeyId = None,
|
|
146
|
-
tags: Tags = None,
|
|
147
|
-
log_group_class: LogGroupClass = None,
|
|
163
|
+
kms_key_id: KmsKeyId | None = None,
|
|
164
|
+
tags: Tags | None = None,
|
|
165
|
+
log_group_class: LogGroupClass | None = None,
|
|
148
166
|
**kwargs,
|
|
149
167
|
) -> None:
|
|
150
168
|
call_moto(context)
|
|
@@ -442,10 +460,9 @@ def moto_to_describe_dict(target, self):
|
|
|
442
460
|
# reported race condition in https://github.com/localstack/localstack/issues/8011
|
|
443
461
|
# making copy of "streams" dict here to avoid issues while summing up storedBytes
|
|
444
462
|
copy_streams = copy.deepcopy(self.streams)
|
|
445
|
-
# parity tests shows that the arn ends with ":*"
|
|
446
|
-
arn = self.arn if self.arn.endswith(":*") else f"{self.arn}:*"
|
|
447
463
|
log_group = {
|
|
448
|
-
"arn": arn,
|
|
464
|
+
"arn": f"{self.arn}:*",
|
|
465
|
+
"logGroupArn": self.arn,
|
|
449
466
|
"creationTime": self.creation_time,
|
|
450
467
|
"logGroupName": self.name,
|
|
451
468
|
"metricFilterCount": 0,
|
localstack/services/moto.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
This module provides tools to call
|
|
2
|
+
This module provides tools to call Moto service implementations.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import copy
|
|
@@ -65,6 +65,7 @@ def call_moto_with_request(
|
|
|
65
65
|
action=context.operation.name,
|
|
66
66
|
parameters=service_request,
|
|
67
67
|
region=context.region,
|
|
68
|
+
protocol=context.protocol,
|
|
68
69
|
)
|
|
69
70
|
# we keep the headers from the original request, but override them with the ones created from the `service_request`
|
|
70
71
|
headers = copy.deepcopy(context.request.headers)
|
|
@@ -18,7 +18,12 @@ from localstack.http.client import SimpleRequestsClient
|
|
|
18
18
|
from localstack.http.proxy import ProxyHandler
|
|
19
19
|
from localstack.services.edge import ROUTER
|
|
20
20
|
from localstack.services.opensearch import versions
|
|
21
|
-
from localstack.services.opensearch.packages import
|
|
21
|
+
from localstack.services.opensearch.packages import (
|
|
22
|
+
ELASTICSEARCH_DEFAULT_VERSION,
|
|
23
|
+
OPENSEARCH_DEFAULT_VERSION,
|
|
24
|
+
elasticsearch_package,
|
|
25
|
+
opensearch_package,
|
|
26
|
+
)
|
|
22
27
|
from localstack.utils.aws.arns import parse_arn
|
|
23
28
|
from localstack.utils.common import (
|
|
24
29
|
ShellCommandThread,
|
|
@@ -37,6 +42,9 @@ LOG = logging.getLogger(__name__)
|
|
|
37
42
|
INTERNAL_USER_AUTH = ("localstack-internal", "localstack-internal")
|
|
38
43
|
DEFAULT_BACKEND_HOST = "127.0.0.1"
|
|
39
44
|
|
|
45
|
+
# user that starts the opensearch process if the current user is root
|
|
46
|
+
OS_USER_OPENSEARCH = "localstack"
|
|
47
|
+
|
|
40
48
|
CommandSettings = dict[str, str]
|
|
41
49
|
|
|
42
50
|
|
|
@@ -314,7 +322,7 @@ class OpensearchCluster(Server):
|
|
|
314
322
|
|
|
315
323
|
@property
|
|
316
324
|
def default_version(self) -> str:
|
|
317
|
-
return
|
|
325
|
+
return OPENSEARCH_DEFAULT_VERSION
|
|
318
326
|
|
|
319
327
|
@property
|
|
320
328
|
def version(self) -> str:
|
|
@@ -336,7 +344,7 @@ class OpensearchCluster(Server):
|
|
|
336
344
|
|
|
337
345
|
@property
|
|
338
346
|
def os_user(self):
|
|
339
|
-
return
|
|
347
|
+
return OS_USER_OPENSEARCH
|
|
340
348
|
|
|
341
349
|
def health(self) -> str | None:
|
|
342
350
|
return get_cluster_health_status(self.url, auth=self.auth)
|
|
@@ -580,7 +588,7 @@ class EdgeProxiedOpensearchCluster(Server):
|
|
|
580
588
|
|
|
581
589
|
@property
|
|
582
590
|
def default_version(self):
|
|
583
|
-
return
|
|
591
|
+
return OPENSEARCH_DEFAULT_VERSION
|
|
584
592
|
|
|
585
593
|
@property
|
|
586
594
|
def url(self) -> str:
|
|
@@ -658,7 +666,7 @@ class ElasticsearchCluster(OpensearchCluster):
|
|
|
658
666
|
|
|
659
667
|
@property
|
|
660
668
|
def default_version(self) -> str:
|
|
661
|
-
return
|
|
669
|
+
return ELASTICSEARCH_DEFAULT_VERSION
|
|
662
670
|
|
|
663
671
|
@property
|
|
664
672
|
def bin_name(self) -> str:
|
|
@@ -666,7 +674,7 @@ class ElasticsearchCluster(OpensearchCluster):
|
|
|
666
674
|
|
|
667
675
|
@property
|
|
668
676
|
def os_user(self):
|
|
669
|
-
return
|
|
677
|
+
return OS_USER_OPENSEARCH
|
|
670
678
|
|
|
671
679
|
def _ensure_installed(self):
|
|
672
680
|
elasticsearch_package.install(self.version)
|
|
@@ -710,7 +718,7 @@ class ElasticsearchCluster(OpensearchCluster):
|
|
|
710
718
|
class EdgeProxiedElasticsearchCluster(EdgeProxiedOpensearchCluster):
|
|
711
719
|
@property
|
|
712
720
|
def default_version(self):
|
|
713
|
-
return
|
|
721
|
+
return ELASTICSEARCH_DEFAULT_VERSION
|
|
714
722
|
|
|
715
723
|
def _backend_cluster(self) -> OpensearchCluster:
|
|
716
724
|
return ElasticsearchCluster(
|
|
@@ -9,13 +9,6 @@ import threading
|
|
|
9
9
|
import semver
|
|
10
10
|
|
|
11
11
|
from localstack import config
|
|
12
|
-
from localstack.constants import (
|
|
13
|
-
ELASTICSEARCH_DEFAULT_VERSION,
|
|
14
|
-
ELASTICSEARCH_DELETE_MODULES,
|
|
15
|
-
ELASTICSEARCH_PLUGIN_LIST,
|
|
16
|
-
OPENSEARCH_DEFAULT_VERSION,
|
|
17
|
-
OPENSEARCH_PLUGIN_LIST,
|
|
18
|
-
)
|
|
19
12
|
from localstack.packages import InstallTarget, Package, PackageInstaller
|
|
20
13
|
from localstack.packages.java import java_package
|
|
21
14
|
from localstack.services.opensearch import versions
|
|
@@ -32,6 +25,32 @@ from localstack.utils.sync import SynchronizedDefaultDict, retry
|
|
|
32
25
|
|
|
33
26
|
LOG = logging.getLogger(__name__)
|
|
34
27
|
|
|
28
|
+
# the version of opensearch which is used by default
|
|
29
|
+
OPENSEARCH_DEFAULT_VERSION = "OpenSearch_3.1"
|
|
30
|
+
|
|
31
|
+
# See https://docs.aws.amazon.com/opensearch-service/latest/developerguide/supported-plugins.html
|
|
32
|
+
OPENSEARCH_PLUGIN_LIST = [
|
|
33
|
+
"ingest-attachment",
|
|
34
|
+
"analysis-kuromoji",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
# the version of elasticsearch that is pre-seeded into the base image (sync with Dockerfile.base)
|
|
38
|
+
ELASTICSEARCH_DEFAULT_VERSION = "Elasticsearch_7.10"
|
|
39
|
+
|
|
40
|
+
# See https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/aes-supported-plugins.html
|
|
41
|
+
ELASTICSEARCH_PLUGIN_LIST = [
|
|
42
|
+
"analysis-icu",
|
|
43
|
+
"ingest-attachment",
|
|
44
|
+
"analysis-kuromoji",
|
|
45
|
+
"mapper-murmur3",
|
|
46
|
+
"mapper-size",
|
|
47
|
+
"analysis-phonetic",
|
|
48
|
+
"analysis-smartcn",
|
|
49
|
+
"analysis-stempel",
|
|
50
|
+
"analysis-ukrainian",
|
|
51
|
+
]
|
|
52
|
+
# Default ES modules to exclude (save apprx 66MB in the final image)
|
|
53
|
+
ELASTICSEARCH_DELETE_MODULES = ["ingest-geoip"]
|
|
35
54
|
|
|
36
55
|
_OPENSEARCH_INSTALL_LOCKS = SynchronizedDefaultDict(threading.RLock)
|
|
37
56
|
|
|
@@ -26,6 +26,7 @@ from localstack.aws.api.opensearch import (
|
|
|
26
26
|
CognitoOptions,
|
|
27
27
|
CognitoOptionsStatus,
|
|
28
28
|
ColdStorageOptions,
|
|
29
|
+
CompatibleVersionsMap,
|
|
29
30
|
CreateDomainRequest,
|
|
30
31
|
CreateDomainResponse,
|
|
31
32
|
DeleteDomainResponse,
|
|
@@ -75,7 +76,6 @@ from localstack.aws.api.opensearch import (
|
|
|
75
76
|
VolumeType,
|
|
76
77
|
VPCDerivedInfoStatus,
|
|
77
78
|
)
|
|
78
|
-
from localstack.constants import OPENSEARCH_DEFAULT_VERSION
|
|
79
79
|
from localstack.services.opensearch import versions
|
|
80
80
|
from localstack.services.opensearch.cluster import SecurityOptions
|
|
81
81
|
from localstack.services.opensearch.cluster_manager import (
|
|
@@ -84,6 +84,7 @@ from localstack.services.opensearch.cluster_manager import (
|
|
|
84
84
|
create_cluster_manager,
|
|
85
85
|
)
|
|
86
86
|
from localstack.services.opensearch.models import OpenSearchStore, opensearch_stores
|
|
87
|
+
from localstack.services.opensearch.packages import OPENSEARCH_DEFAULT_VERSION
|
|
87
88
|
from localstack.services.plugins import ServiceLifecycleHook
|
|
88
89
|
from localstack.state import AssetDirectory, StateVisitor
|
|
89
90
|
from localstack.utils.aws.arns import parse_arn
|
|
@@ -650,6 +651,10 @@ class OpensearchProvider(OpensearchApi, ServiceLifecycleHook):
|
|
|
650
651
|
for comp in versions.compatible_versions
|
|
651
652
|
if comp["SourceVersion"] == version_filter
|
|
652
653
|
]
|
|
654
|
+
if not compatible_versions:
|
|
655
|
+
compatible_versions = [
|
|
656
|
+
CompatibleVersionsMap(SourceVersion=version_filter, TargetVersions=[])
|
|
657
|
+
]
|
|
653
658
|
return GetCompatibleVersionsResponse(CompatibleVersions=compatible_versions)
|
|
654
659
|
|
|
655
660
|
def describe_domain_config(
|
|
@@ -13,20 +13,24 @@ from localstack.utils.common import get_arch
|
|
|
13
13
|
|
|
14
14
|
# Internal representation of the OpenSearch versions (without the "OpenSearch_" prefix)
|
|
15
15
|
_opensearch_install_versions = {
|
|
16
|
+
"3.1": "3.1.0",
|
|
17
|
+
"2.19": "2.19.3",
|
|
18
|
+
"2.17": "2.17.1",
|
|
19
|
+
"2.15": "2.15.0",
|
|
16
20
|
"2.13": "2.13.0",
|
|
17
21
|
"2.11": "2.11.1",
|
|
18
22
|
"2.9": "2.9.0",
|
|
19
23
|
"2.7": "2.7.0",
|
|
20
24
|
"2.5": "2.5.0",
|
|
21
25
|
"2.3": "2.3.0",
|
|
22
|
-
"1.3": "1.3.
|
|
26
|
+
"1.3": "1.3.20",
|
|
23
27
|
"1.2": "1.2.4",
|
|
24
28
|
"1.1": "1.1.0",
|
|
25
29
|
"1.0": "1.0.0",
|
|
26
30
|
}
|
|
27
31
|
# Internal representation of the Elasticsearch versions (without the "Elasticsearch_" prefix)
|
|
28
32
|
_elasticsearch_install_versions = {
|
|
29
|
-
"7.10": "7.10.
|
|
33
|
+
"7.10": "7.10.2",
|
|
30
34
|
"7.9": "7.9.3",
|
|
31
35
|
"7.8": "7.8.1",
|
|
32
36
|
"7.7": "7.7.1",
|
|
@@ -221,6 +225,9 @@ compatible_versions = [
|
|
|
221
225
|
"OpenSearch_2.9",
|
|
222
226
|
"OpenSearch_2.11",
|
|
223
227
|
"OpenSearch_2.13",
|
|
228
|
+
"OpenSearch_2.15",
|
|
229
|
+
"OpenSearch_2.17",
|
|
230
|
+
"OpenSearch_2.19",
|
|
224
231
|
],
|
|
225
232
|
),
|
|
226
233
|
CompatibleVersionsMap(
|
|
@@ -231,28 +238,68 @@ compatible_versions = [
|
|
|
231
238
|
"OpenSearch_2.9",
|
|
232
239
|
"OpenSearch_2.11",
|
|
233
240
|
"OpenSearch_2.13",
|
|
241
|
+
"OpenSearch_2.15",
|
|
242
|
+
"OpenSearch_2.17",
|
|
243
|
+
"OpenSearch_2.19",
|
|
234
244
|
],
|
|
235
245
|
),
|
|
236
246
|
CompatibleVersionsMap(
|
|
237
247
|
SourceVersion="OpenSearch_2.5",
|
|
238
|
-
TargetVersions=[
|
|
248
|
+
TargetVersions=[
|
|
249
|
+
"OpenSearch_2.7",
|
|
250
|
+
"OpenSearch_2.9",
|
|
251
|
+
"OpenSearch_2.11",
|
|
252
|
+
"OpenSearch_2.13",
|
|
253
|
+
"OpenSearch_2.15",
|
|
254
|
+
"OpenSearch_2.17",
|
|
255
|
+
"OpenSearch_2.19",
|
|
256
|
+
],
|
|
239
257
|
),
|
|
240
258
|
CompatibleVersionsMap(
|
|
241
259
|
SourceVersion="OpenSearch_2.7",
|
|
242
|
-
TargetVersions=[
|
|
260
|
+
TargetVersions=[
|
|
261
|
+
"OpenSearch_2.9",
|
|
262
|
+
"OpenSearch_2.11",
|
|
263
|
+
"OpenSearch_2.13",
|
|
264
|
+
"OpenSearch_2.15",
|
|
265
|
+
"OpenSearch_2.17",
|
|
266
|
+
"OpenSearch_2.19",
|
|
267
|
+
],
|
|
243
268
|
),
|
|
244
269
|
CompatibleVersionsMap(
|
|
245
270
|
SourceVersion="OpenSearch_2.9",
|
|
246
|
-
TargetVersions=[
|
|
271
|
+
TargetVersions=[
|
|
272
|
+
"OpenSearch_2.11",
|
|
273
|
+
"OpenSearch_2.13",
|
|
274
|
+
"OpenSearch_2.15",
|
|
275
|
+
"OpenSearch_2.17",
|
|
276
|
+
"OpenSearch_2.19",
|
|
277
|
+
],
|
|
247
278
|
),
|
|
248
279
|
CompatibleVersionsMap(
|
|
249
280
|
SourceVersion="OpenSearch_2.11",
|
|
250
|
-
TargetVersions=["OpenSearch_2.13"],
|
|
281
|
+
TargetVersions=["OpenSearch_2.13", "OpenSearch_2.15", "OpenSearch_2.17", "OpenSearch_2.19"],
|
|
282
|
+
),
|
|
283
|
+
CompatibleVersionsMap(
|
|
284
|
+
SourceVersion="OpenSearch_2.13",
|
|
285
|
+
TargetVersions=["OpenSearch_2.15", "OpenSearch_2.17", "OpenSearch_2.19"],
|
|
286
|
+
),
|
|
287
|
+
CompatibleVersionsMap(
|
|
288
|
+
SourceVersion="OpenSearch_2.15",
|
|
289
|
+
TargetVersions=["OpenSearch_2.17", "OpenSearch_2.19"],
|
|
290
|
+
),
|
|
291
|
+
CompatibleVersionsMap(
|
|
292
|
+
SourceVersion="OpenSearch_2.17",
|
|
293
|
+
TargetVersions=["OpenSearch_2.19"],
|
|
294
|
+
),
|
|
295
|
+
CompatibleVersionsMap(
|
|
296
|
+
SourceVersion="OpenSearch_2.19",
|
|
297
|
+
TargetVersions=["OpenSearch_3.1"],
|
|
251
298
|
),
|
|
252
299
|
]
|
|
253
300
|
|
|
254
301
|
|
|
255
|
-
def get_install_type_and_version(version: str) ->
|
|
302
|
+
def get_install_type_and_version(version: str) -> tuple[EngineType, str]:
|
|
256
303
|
engine_type = EngineType(version.split("_")[0])
|
|
257
304
|
|
|
258
305
|
if version not in install_versions:
|
|
@@ -297,6 +344,8 @@ def get_download_url(install_version: str, engine_type: EngineType) -> str:
|
|
|
297
344
|
return _opensearch_url(install_version)
|
|
298
345
|
elif engine_type == EngineType.Elasticsearch:
|
|
299
346
|
return _es_url(install_version)
|
|
347
|
+
else:
|
|
348
|
+
raise ValueError(f"Unknown OpenSearch engine type: {engine_type}")
|
|
300
349
|
|
|
301
350
|
|
|
302
351
|
def fetch_latest_versions() -> dict[str, str]: # pragma: no cover
|
|
@@ -10,8 +10,6 @@ from localstack.aws.api.s3 import (
|
|
|
10
10
|
)
|
|
11
11
|
from localstack.aws.api.s3 import Type as GranteeType
|
|
12
12
|
|
|
13
|
-
S3_VIRTUAL_HOST_FORWARDED_HEADER = "x-s3-vhost-forwarded-for"
|
|
14
|
-
|
|
15
13
|
S3_UPLOAD_PART_MIN_SIZE = 5242880
|
|
16
14
|
"""
|
|
17
15
|
This is minimum size allowed by S3 when uploading more than one part for a Multipart Upload, except for the last part
|
|
@@ -21,6 +19,11 @@ This is minimum size allowed by S3 when uploading more than one part for a Multi
|
|
|
21
19
|
DEFAULT_PRE_SIGNED_ACCESS_KEY_ID = "test"
|
|
22
20
|
DEFAULT_PRE_SIGNED_SECRET_ACCESS_KEY = "test"
|
|
23
21
|
|
|
22
|
+
S3_HOST_ID = "9Gjjt1m+cjU4OPvX9O9/8RuvnG41MRb/18Oux2o5H5MY7ISNTlXN+Dz9IG62/ILVxhAGI0qyPfg="
|
|
23
|
+
"""
|
|
24
|
+
S3 is returning a Host Id as part of its exceptions
|
|
25
|
+
"""
|
|
26
|
+
|
|
24
27
|
AUTHENTICATED_USERS_ACL_GROUP = "http://acs.amazonaws.com/groups/global/AuthenticatedUsers"
|
|
25
28
|
ALL_USERS_ACL_GROUP = "http://acs.amazonaws.com/groups/global/AllUsers"
|
|
26
29
|
LOG_DELIVERY_ACL_GROUP = "http://acs.amazonaws.com/groups/s3/LogDelivery"
|
localstack/services/s3/cors.py
CHANGED
|
@@ -21,13 +21,13 @@ from localstack.aws.protocol.op_router import RestServiceOperationRouter
|
|
|
21
21
|
from localstack.aws.spec import get_service_catalog
|
|
22
22
|
from localstack.config import S3_VIRTUAL_HOSTNAME
|
|
23
23
|
from localstack.http import Request, Response
|
|
24
|
+
from localstack.services.s3.constants import S3_HOST_ID
|
|
24
25
|
from localstack.services.s3.utils import S3_VIRTUAL_HOSTNAME_REGEX
|
|
25
26
|
|
|
26
27
|
# TODO: add more logging statements
|
|
27
28
|
LOG = logging.getLogger(__name__)
|
|
28
29
|
|
|
29
30
|
_s3_virtual_host_regex = re.compile(S3_VIRTUAL_HOSTNAME_REGEX)
|
|
30
|
-
FAKE_HOST_ID = "9Gjjt1m+cjU4OPvX9O9/8RuvnG41MRb/18Oux2o5H5MY7ISNTlXN+Dz9IG62/ILVxhAGI0qyPfg="
|
|
31
31
|
|
|
32
32
|
# TODO: refactor those to expose the needed methods maybe in another way that both can import
|
|
33
33
|
add_default_headers = CorsResponseEnricher.add_cors_headers
|
|
@@ -135,7 +135,7 @@ class S3CorsHandler(Handler):
|
|
|
135
135
|
if is_options_request:
|
|
136
136
|
context.operation = self._get_op_from_request(request)
|
|
137
137
|
raise BadRequest(
|
|
138
|
-
"Insufficient information. Origin request header needed.", HostId=
|
|
138
|
+
"Insufficient information. Origin request header needed.", HostId=S3_HOST_ID
|
|
139
139
|
)
|
|
140
140
|
else:
|
|
141
141
|
# If the header is missing, Amazon S3 doesn't treat the request as a cross-origin request,
|
|
@@ -167,7 +167,7 @@ class S3CorsHandler(Handler):
|
|
|
167
167
|
context.operation = self._get_op_from_request(request)
|
|
168
168
|
raise AccessForbidden(
|
|
169
169
|
message,
|
|
170
|
-
HostId=
|
|
170
|
+
HostId=S3_HOST_ID,
|
|
171
171
|
Method=request.headers.get("Access-Control-Request-Method", "OPTIONS"),
|
|
172
172
|
ResourceType="BUCKET",
|
|
173
173
|
)
|
|
@@ -182,7 +182,7 @@ class S3CorsHandler(Handler):
|
|
|
182
182
|
context.operation = self._get_op_from_request(request)
|
|
183
183
|
raise AccessForbidden(
|
|
184
184
|
"CORSResponse: This CORS request is not allowed. This is usually because the evalution of Origin, request method / Access-Control-Request-Method or Access-Control-Request-Headers are not whitelisted by the resource's CORS spec.",
|
|
185
|
-
HostId=
|
|
185
|
+
HostId=S3_HOST_ID,
|
|
186
186
|
Method=request.headers.get("Access-Control-Request-Method"),
|
|
187
187
|
ResourceType="OBJECT",
|
|
188
188
|
)
|