8000 Fix layer version handling for external Lambda layers (#9286) · codeperl/localstack@0aea7e2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0aea7e2

Browse files
authored
Fix layer version handling for external Lambda layers (localstack#9286)
1 parent f990594 commit 0aea7e2

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
@@ -618,25 +618,31 @@ def _validate_layers(self, new_layers: list[str], region: str, account_id: int):
618618

619619
visited_layers = dict()
620620
for layer_version_arn in new_layers:
621-
layer_region, layer_account_id, layer_name, layer_version = api_utils.parse_layer_arn(
622-
layer_version_arn
623-
)
624-
if layer_version is None:
621+
(
622+
layer_region,
623+
layer_account_id,
624+
layer_name,
625+
layer_version_str,
626+
) = api_utils.parse_layer_arn(layer_version_arn)
627+
if layer_version_str is None:
625628
raise ValidationException(
626629
f"1 validation error detected: Value '[{layer_version_arn}]'"
627630
+ 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]",
628631
)
629632

630633
state = lambda_stores[layer_account_id][layer_region]
631634
layer = state.layers.get(layer_name)
635+
layer_version = None
636+
if layer is not None:
637+
layer_version = layer.layer_versions.get(layer_version_str)
632638
if layer_account_id == get_aws_account_id():
633639
if region and layer_region != region:
634640
raise InvalidParameterValueException(
635641
f"Layers are not in the same region as the function. "
636642
f"Layers are expected to be in region {region}.",
637643
Type="User",
638644
)
639-
if layer is None or layer.layer_versions.get(layer_version) is None:
645+
if layer is None or layer.layer_versions.get(layer_version_str) is None:
640646
raise InvalidParameterValueException(
641647
f"Layer version {layer_version_arn} does not exist.", Type="User"
642648
)
@@ -648,7 +654,7 @@ def _validate_layers(self, new_layers: list[str], region: str, account_id: int):
648654
raise AccessDeniedException(
649655
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"
650656
)
651-
if layer is None:
657+
if layer is None or layer_version is None:
652658
# Limitation: cannot fetch external layers when using the same account id as the target layer
653659
# because we do not want to trigger the layer fetcher for every non-existing layer.
654660
if self.layer_fetcher is None:
@@ -663,7 +669,16 @@ def _validate_layers(self, new_layers: list[str], region: str, account_id: int):
663669
raise AccessDeniedException(
664670
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"
665671
)
666-
state.layers[layer_name] = layer
672+
673+
# Distinguish between new layer and new layer version
674+
if layer_version is None:
675+
# Create whole layer from scratch
676+
state.layers[layer_name] = layer
677+
else:
678+
# Create layer version if another version of the same layer already exists
679+
state.layers[layer_name].layer_versions[
680+
layer_version_str
681+
] = layer.layer_versions.get(layer_version_str)
667682

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

0 commit comments

Comments
 (0)
0