8000 Fix layer version handling for external Lambda layers · localstack/localstack@7908925 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7908925

Browse files
committed
Fix layer version handling for external Lambda layers
1 parent f5be27b commit 7908925

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

localstack/services/lambda_/provider.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -588,25 +588,31 @@ def _validate_layers(self, new_layers: list[str], region: str, account_id: int):
588588

589589
visited_layers = dict()
590590
for layer_version_arn in new_layers:
591-
layer_region, layer_account_id, layer_name, layer_version = api_utils.parse_layer_arn(
592-
layer_version_arn
593-
)
594-
if layer_version is None:
591+
(
592+
layer_region,
593+
layer_account_id,
594+
layer_name,
595+
layer_version_str,
596+
) = api_utils.parse_layer_arn(layer_version_arn)
597+
if layer_version_str is None:
595598
raise ValidationException(
596599
f"1 validation error detected: Value '[{layer_version_arn}]'"
597600
+ r" at 'layers' failed to satisfy constraint: Member must satisfy constraint: [Member must have length less than or equal to 140, Member must have length greater than or equal to 1, Member must satisfy regular expression pattern: (arn:[a-zA-Z0-9-]+:lambda:[a-zA-Z0-9-]+:\d{12}:layer:[a-zA-Z0-9-_]+:[0-9]+)|(arn:[a-zA-Z0-9-]+:lambda:::awslayer:[a-zA-Z0-9-_]+), Member must not be null]",
598601
)
599602

600603
state = lambda_stores[layer_account_id][layer_region]
601604
layer = state.layers.get(layer_name)
605+
layer_version = None
606+
if layer is not None:
607+
layer_version = layer.layer_versions.get(layer_version_str)
602608
if layer_account_id == get_aws_account_id():
603609
if region and layer_region != region:
604610
raise InvalidParameterValueException(
605611
f"Layers are not in the same region as the function. "
606612
f"Layers are expected to be in region {region}.",
607613
Type="User",
608614
)
609-
if layer is None or layer.layer_versions.get(layer_version) is None:
615+
if layer is None or layer.layer_versions.get(layer_version_str) is None:
610616
raise InvalidParameterValueException(
611617
f"Layer version {layer_version_arn} does not exist.", Type="User"
612618
)
@@ -618,7 +624,7 @@ def _validate_layers(self, new_layers: list[str], region: str, account_id: int):
618624
raise AccessDeniedException(
619625
f"User: arn:aws:iam::{account_id}:{user} is not authorized to perform: lambda:GetLayerVersion on resource: {layer_version_arn} because no resource-based policy allows the lambda:GetLayerVersion action"
620626
)
621-
if layer is None:
627+
if layer is None or layer_version is None:
622628
# Limitation: cannot fetch external layers when using the same account id as the target layer
623629
# because we do not want to trigger the layer fetcher for every non-existing layer.
624630
if self.layer_fetcher is None:
@@ -633,7 +639,16 @@ def _validate_layers(self, new_layers: list[str], region: str, account_id: int):
633639
raise AccessDeniedException(
634640
f"User: arn:aws:iam::{account_id}:{user} is not authorized to perform: lambda:GetLayerVersion on resource: {layer_version_arn} because no resource-based policy allows the lambda:GetLayerVersion action"
635641
)
636-
state.layers[layer_name] = layer
642+
643+
# Distinguish between new layer and new layer version
644+
if layer_version is None:
645+
# Create whole layer from scratch
646+
state.layers[layer_name] = layer
647+
else:
648+
# Create layer version if another version of the same layer already exists
649+
state.layers[layer_name].layer_versions[
650+
layer_version_str
651+
] = layer.layer_versions.get(layer_version_str)
637652

638653
# only the first two matches in the array are considered for the error message
639654
layer_arn = ":".join(layer_version_arn.split(":")[:-1])

0 commit comments

Comments
 (0)
0