Skip to content

Commit cda221d

Browse files
committed
Prevent the controller from calling GetFunctionCodeSigningConfig when a functions packageType is Image
Functions code signing config should only be called when a function is created using an s3bucket and a key. Functions created using a container image cannot get a code signing configuration.
1 parent 33fd9c7 commit cda221d

File tree

10 files changed

+200
-18
lines changed

10 files changed

+200
-18
lines changed
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
ack_generate_info:
2-
build_date: "2022-04-27T16:40:07Z"
2+
build_date: "2022-05-06T16:31:27Z"
33
build_hash: 141cb9db73f881228ea20e572de3ba9df19d5b6f
44
go_version: go1.18.1
55
version: v0.18.4-4-g141cb9d-dirty
6-
api_directory_checksum: 7c4e0f8971a8ab06389e98b21c00eddad87366f3
6+
api_directory_checksum: a704674d4df0400198d5a11035a2099240bccf80
77
api_version: v1alpha1
88
aws_sdk_go_version: v1.42.0
99
generator_config_info:
10-
file_checksum: c48a2acfc8da0b28ee9b81745b9af773d10c7f71
10+
file_checksum: 64116ddc3a8abec393a5e08aaff75b6a7d848ad0
1111
original_file_name: generator.yaml
1212
last_modification:
1313
reason: API generation

apis/v1alpha1/generator.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ ignore:
66
# EventSourceMapping
77
resources:
88
Function:
9+
exceptions:
10+
terminal_codes:
11+
- InvalidParameterValueException
912
fields:
1013
Name:
1114
is_primary_key: true

generator.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ ignore:
66
# EventSourceMapping
77
resources:
88
Function:
9+
exceptions:
10+
terminal_codes:
11+
- InvalidParameterValueException
912
fields:
1013
Name:
1114
is_primary_key: true

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ require (
1313
sigs.k8s.io/controller-runtime v0.11.0
1414
)
1515

16+
replace github.com/aws-controllers-k8s/runtime => ../runtime
17+
1618
require (
1719
github.com/beorn7/perks v1.0.1 // indirect
1820
github.com/cenkalti/backoff/v4 v4.1.2 // indirect

pkg/resource/function/hooks.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@ import (
1818
"errors"
1919
"time"
2020

21-
svcapitypes "github.com/aws-controllers-k8s/lambda-controller/apis/v1alpha1"
2221
ackcompare "github.com/aws-controllers-k8s/runtime/pkg/compare"
22+
ackrtcondition "github.com/aws-controllers-k8s/runtime/pkg/condition"
2323
ackrequeue "github.com/aws-controllers-k8s/runtime/pkg/requeue"
2424
ackrtlog "github.com/aws-controllers-k8s/runtime/pkg/runtime/log"
2525
"github.com/aws/aws-sdk-go/aws"
2626
svcsdk "github.com/aws/aws-sdk-go/service/lambda"
27+
corev1 "k8s.io/api/core/v1"
28+
29+
svcapitypes "github.com/aws-controllers-k8s/lambda-controller/apis/v1alpha1"
2730
)
2831

2932
var (
@@ -500,17 +503,27 @@ func (rm *resourceManager) setResourceAdditionalFields(
500503
}
501504
ko.Spec.ReservedConcurrentExecutions = getFunctionConcurrencyOutput.ReservedConcurrentExecutions
502505

503-
var getFunctionCodeSigningConfigOutput *svcsdk.GetFunctionCodeSigningConfigOutput
504-
getFunctionCodeSigningConfigOutput, err = rm.sdkapi.GetFunctionCodeSigningConfigWithContext(
505-
ctx,
506-
&svcsdk.GetFunctionCodeSigningConfigInput{
507-
FunctionName: ko.Spec.Name,
508-
},
509-
)
510-
rm.metrics.RecordAPICall("GET", "GetFunctionCodeSigningConfig", err)
511-
if err != nil {
512-
return err
506+
if ko.Spec.PackageType != nil && *ko.Spec.PackageType == "Zip" {
507+
var getFunctionCodeSigningConfigOutput *svcsdk.GetFunctionCodeSigningConfigOutput
508+
getFunctionCodeSigningConfigOutput, err = rm.sdkapi.GetFunctionCodeSigningConfigWithContext(
509+
ctx,
510+
&svcsdk.GetFunctionCodeSigningConfigInput{
511+
FunctionName: ko.Spec.Name,
512+
},
513+
)
514+
rm.metrics.RecordAPICall("GET", "GetFunctionCodeSigningConfig", err)
515+
if err != nil {
516+
return err
517+
}
518+
ko.Spec.CodeSigningConfigARN = getFunctionCodeSigningConfigOutput.CodeSigningConfigArn
519+
}
520+
if ko.Spec.PackageType != nil && *ko.Spec.PackageType == "Image" && ko.Spec.CodeSigningConfigARN != nil {
521+
ackrtcondition.SetTerminal(
522+
&resource{ko},
523+
corev1.ConditionTrue,
524+
aws.String("Cannot set function code signing config when package type is Image"),
525+
nil,
526+
)
513527
}
514-
ko.Spec.CodeSigningConfigARN = getFunctionCodeSigningConfigOutput.CodeSigningConfigArn
515528
return nil
516529
}

pkg/resource/function/sdk.go

Lines changed: 13 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: lambda.services.k8s.aws/v1alpha1
2+
kind: Function
3+
metadata:
4+
name: $FUNCTION_NAME
5+
annotations:
6+
services.k8s.aws/region: $AWS_REGION
7+
spec:
8+
name: $FUNCTION_NAME
9+
code:
10+
imageURI: $IMAGE_URL
11+
role: $LAMBDA_ROLE
12+
description: function created by ACK lambda-controller e2e tests
13+
packageType: Image
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
FROM public.ecr.aws/lambda/python:3.8
2+
3+
COPY main.py main.py
4+
5+
CMD [ "main.handler" ]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
AWS_REGION ?= "us-west-2"
2+
ECR_REPOSITORY ?= ack-e2e-testing-lambda-controller
3+
IMAGE_TAG ?= v1
4+
5+
AWS_ACCOUNT_ID ?= $(shell aws sts get-caller-identity --query "Account" --output text)
6+
IMAGE_URL ?= $(AWS_ACCOUNT_ID).dkr.ecr.us-west-2.amazonaws.com/$(ECR_REPOSITORY):$(IMAGE_TAG)
7+
8+
build-image:
9+
docker build -t $(IMAGE_URL) .
10+
11+
publish-image:
12+
docker push $(IMAGE_URL)
13+
14+
create-ecr-repository:
15+
aws ecr create-repository --region $(AWS_REGION) --repository-name $(ECR_REPOSITORY) >/dev/null
16+
17+
all: build-image publish-image

test/e2e/tests/test_function.py

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from typing import Dict, Tuple
2222

2323
from acktest.resources import random_suffix_name
24-
from acktest.aws.identity import get_region
24+
from acktest.aws.identity import get_region, get_account_id
2525
from acktest.k8s import resource as k8s
2626
from e2e import service_marker, CRD_GROUP, CRD_VERSION, load_lambda_resource
2727
from e2e.replacement_values import REPLACEMENT_VALUES
@@ -33,6 +33,12 @@
3333
UPDATE_WAIT_AFTER_SECONDS = 25
3434
DELETE_WAIT_AFTER_SECONDS = 25
3535

36+
37+
def get_testing_image_url():
38+
aws_region = get_region()
39+
account_id = get_account_id()
40+
return f"{account_id}.dkr.ecr.{aws_region}.amazonaws.com/ack-e2e-testing-lambda-controller:v1"
41+
3642
@pytest.fixture(scope="module")
3743
def lambda_client():
3844
return boto3.client("lambda")
@@ -313,3 +319,112 @@ def test_function_code_signing_config(self, lambda_client, code_signing_config):
313319
# Check Lambda function doesn't exist
314320
exists = self.function_exists(lambda_client, resource_name)
315321
assert not exists
322+
323+
def test_function_package_type_image(self, lambda_client, code_signing_config):
324+
resource_name = random_suffix_name("lambda-function", 24)
325+
326+
resources = get_bootstrap_resources()
327+
328+
replacements = REPLACEMENT_VALUES.copy()
329+
replacements["FUNCTION_NAME"] = resource_name
330+
replacements["LAMBDA_ROLE"] = resources.LambdaBasicRoleARN
331+
replacements["AWS_REGION"] = get_region()
332+
replacements["IMAGE_URL"] = get_testing_image_url()
333+
334+
# Load Lambda CR
335+
resource_data = load_lambda_resource(
336+
"function_package_type_image",
337+
additional_replacements=replacements,
338+
)
339+
logging.debug(resource_data)
340+
341+
# Create k8s resource
342+
ref = k8s.CustomResourceReference(
343+
CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL,
344+
resource_name, namespace="default",
345+
)
346+
k8s.create_custom_resource(ref, resource_data)
347+
cr = k8s.wait_resource_consumed_by_controller(ref)
348+
349+
assert cr is not None
350+
assert k8s.get_resource_exists(ref)
351+
352+
time.sleep(CREATE_WAIT_AFTER_SECONDS)
353+
354+
cr = k8s.wait_resource_consumed_by_controller(ref)
355+
356+
# Check Lambda function exists
357+
exists = self.function_exists(lambda_client, resource_name)
358+
assert exists
359+
360+
# Delete k8s resource
361+
_, deleted = k8s.delete_custom_resource(ref)
362+
assert deleted is True
363+
364+
time.sleep(DELETE_WAIT_AFTER_SECONDS)
365+
366+
# Check Lambda function doesn't exist
367+
exists = self.function_exists(lambda_client, resource_name)
368+
assert not exists
369+
370+
def test_function_package_type_image_with_signing_config(self, lambda_client, code_signing_config):
371+
resource_name = random_suffix_name("lambda-function", 24)
372+
373+
resources = get_bootstrap_resources()
374+
375+
replacements = REPLACEMENT_VALUES.copy()
376+
replacements["FUNCTION_NAME"] = resource_name
377+
replacements["LAMBDA_ROLE"] = resources.LambdaBasicRoleARN
378+
replacements["AWS_REGION"] = get_region()
379+
replacements["IMAGE_URL"] = get_testing_image_url()
380+
381+
# Load Lambda CR
382+
resource_data = load_lambda_resource(
383+
"function_package_type_image",
384+
additional_replacements=replacements,
385+
)
386+
logging.debug(resource_data)
387+
388+
# Create k8s resource
389+
ref = k8s.CustomResourceReference(
390+
CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL,
391+
resource_name, namespace="default",
392+
)
393+
k8s.create_custom_resource(ref, resource_data)
394+
cr = k8s.wait_resource_consumed_by_controller(ref)
395+
396+
assert cr is not None
397+
assert k8s.get_resource_exists(ref)
398+
399+
time.sleep(CREATE_WAIT_AFTER_SECONDS)
400+
401+
cr = k8s.wait_resource_consumed_by_controller(ref)
402+
403+
# Check Lambda function exists
404+
exists = self.function_exists(lambda_client, resource_name)
405+
assert exists
406+
407+
# Add signing configuration
408+
cr["spec"]["codeSigningConfigARN"] = "random-csc"
409+
k8s.patch_custom_resource(ref, cr)
410+
411+
time.sleep(UPDATE_WAIT_AFTER_SECONDS)
412+
413+
cr = k8s.wait_resource_consumed_by_controller(ref)
414+
# assert condition
415+
assert k8s.assert_condition_state_message(
416+
ref,
417+
"ACK.Terminal",
418+
"True",
419+
"Cannot set function code signing config when package type is Image",
420+
)
421+
422+
# Delete k8s resource
423+
_, deleted = k8s.delete_custom_resource(ref)
424+
assert deleted is True
425+
426+
time.sleep(DELETE_WAIT_AFTER_SECONDS)
427+
428+
# Check Lambda function doesn't exist
429+
exists = self.function_exists(lambda_client, resource_name)
430+
assert not exists

0 commit comments

Comments
 (0)