Skip to content

Commit 84d5125

Browse files
ack-botVandita2020
authored andcommitted
Update to ACK runtime v0.25.0, code-generator v0.25.0 (#87)
---------- * ACK code-generator `v0.25.0` [release notes](https://github.com/aws-controllers-k8s/code-generator/releases/tag/v0.25.0) * ACK runtime `v0.25.0` [release notes](https://github.com/aws-controllers-k8s/runtime/releases/tag/v0.25.0) ---------- NOTE: This PR increments the release version of service controller from `v0.1.6` to `v0.1.7` Once this PR is merged, release `v0.1.7` will be automatically created for `lambda-controller` **Please close this PR, if you do not want the new patch release for `lambda-controller`** ---------- ``` building ack-generate ... ok. ==== building lambda-controller ==== Copying common custom resource definitions into lambda Building Kubernetes API objects for lambda Generating deepcopy code for lambda Generating custom resource definitions for lambda Building service controller for lambda Generating RBAC manifests for lambda Running gofmt against generated code for lambda Updating additional GitHub repository maintenance files ==== building lambda-controller release artifacts ==== Building release artifacts for lambda-v0.1.7 Generating common custom resource definitions Generating custom resource definitions for lambda Generating RBAC manifests for lambda ``` ---------- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 39f35a1 commit 84d5125

12 files changed

+170
-26
lines changed

apis/v1alpha1/ack-generate-metadata.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ api_directory_checksum: a9fcef68210dd72b4b2e37052f2c1a9e971326c6
77
api_version: v1alpha1
88
aws_sdk_go_version: v1.44.181
99
generator_config_info:
10-
file_checksum: 095af1082df5c34cdc12296dc085bc6b2b7eadb9
10+
file_checksum: e495db568ae64db031fcfa40b8a53f9866f22302
1111
original_file_name: generator.yaml
1212
last_modification:
1313
reason: API generation

apis/v1alpha1/function.go

+2-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apis/v1alpha1/generator.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ resources:
1919
- path: Status.State
2020
in: [ "Active" ]
2121
fields:
22+
CodeS3SHA256:
23+
type: String
24+
compare:
25+
is_ignored: true
2226
Code.S3Bucket:
2327
references:
2428
resource: Bucket

apis/v1alpha1/zz_generated.deepcopy.go

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/lambda.services.k8s.aws_functions.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ spec:
6969
format: byte
7070
type: string
7171
type: object
72+
codeS3SHA256:
73+
type: string
7274
codeSigningConfigARN:
7375
description: To enable code signing for this function, specify the
7476
ARN of a code-signing configuration. A code-signing configuration

generator.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ resources:
1919
- path: Status.State
2020
in: [ "Active" ]
2121
fields:
22+
CodeS3SHA256:
23+
type: String
24+
compare:
25+
is_ignored: true
2226
Code.S3Bucket:
2327
references:
2428
resource: Bucket

helm/crds/lambda.services.k8s.aws_functions.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ spec:
6969
format: byte
7070
type: string
7171
type: object
72+
codeS3SHA256:
73+
type: string
7274
codeSigningConfigARN:
7375
description: To enable code signing for this function, specify the
7476
ARN of a code-signing configuration. A code-signing configuration

pkg/resource/function/hooks.go

+33-23
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ package function
1515

1616
import (
1717
"context"
18+
"encoding/json"
1819
"errors"
20+
"fmt"
1921
"time"
2022

2123
ackcompare "github.com/aws-controllers-k8s/runtime/pkg/compare"
@@ -96,20 +98,21 @@ func (rm *resourceManager) customUpdateFunction(
9698
// UpdateFunctionCode because both of them can put the function in a
9799
// Pending state.
98100
switch {
99-
case delta.DifferentAt("Spec.Code"):
100-
err = rm.updateFunctionCode(ctx, desired, delta)
101-
if err != nil {
102-
return nil, err
103-
}
104101
case delta.DifferentExcept(
105102
"Spec.Code",
106103
"Spec.Tags",
107104
"Spec.ReservedConcurrentExecutions",
108-
"Spec.CodeSigningConfigARN"):
105+
"Spec.CodeSigningConfigARN",
106+
"Spec.CodeS3SHA256"):
109107
err = rm.updateFunctionConfiguration(ctx, desired, delta)
110108
if err != nil {
111109
return nil, err
112110
}
111+
case delta.DifferentAt("Spec.Code") || delta.DifferentAt("Spec.CodeS3SHA256"):
112+
err = rm.updateFunctionCode(ctx, desired, delta)
113+
if err != nil {
114+
return nil, err
115+
}
113116
}
114117

115118
readOneLatest, err := rm.ReadOne(ctx, desired)
@@ -335,30 +338,24 @@ func (rm *resourceManager) updateFunctionCode(
335338
exit := rlog.Trace("rm.updateFunctionCode")
336339
defer exit(err)
337340

338-
if delta.DifferentAt("Spec.Code.S3Key") &&
339-
!delta.DifferentAt("Spec.Code.S3Bucket") &&
340-
!delta.DifferentAt("Spec.Code.S3ObjectVersion") &&
341-
!delta.DifferentAt("Spec.Code.ImageURI") {
342-
log := ackrtlog.FromContext(ctx)
343-
log.Info("updating code.s3Key field is not currently supported.")
344-
return nil
345-
}
346-
347341
dspec := desired.ko.Spec
348342
input := &svcsdk.UpdateFunctionCodeInput{
349343
FunctionName: aws.String(*dspec.Name),
350344
}
351345

352346
if dspec.Code != nil {
353-
switch {
354-
case dspec.Code.ImageURI != nil:
347+
if delta.DifferentAt("Spec.Code.ImageURI") {
355348
input.ImageUri = dspec.Code.ImageURI
356-
case dspec.Code.S3Bucket != nil,
357-
dspec.Code.S3Key != nil,
358-
dspec.Code.S3ObjectVersion != nil:
359-
input.S3Bucket = dspec.Code.S3Bucket
360-
input.S3Key = dspec.Code.S3Key
361-
input.S3ObjectVersion = dspec.Code.S3ObjectVersion
349+
} else if delta.DifferentAt("Spec.CodeS3SHA256") {
350+
if dspec.Code.S3Key != nil {
351+
input.S3Key = aws.String(*dspec.Code.S3Key)
352+
}
353+
if dspec.Code.S3Bucket != nil {
354+
input.S3Bucket = aws.String(*dspec.Code.S3Bucket)
355+
}
356+
if dspec.Code.S3ObjectVersion != nil {
357+
input.S3ObjectVersion = aws.String(*dspec.Code.S3ObjectVersion)
358+
}
362359
}
363360
}
364361

@@ -416,6 +413,19 @@ func customPreCompare(
416413
delta.Add("Spec.Code.ImageURI", a.ko.Spec.Code.ImageURI, b.ko.Spec.Code.ImageURI)
417414
}
418415
}
416+
expected, _ := json.Marshal(a.ko.Spec.CodeS3SHA256)
417+
fmt.Println("expected:", string(expected))
418+
419+
actual, _ := json.Marshal(b.ko.Status.CodeSHA256)
420+
fmt.Println("actual:", string(actual))
421+
422+
if ackcompare.HasNilDifference(a.ko.Spec.CodeS3SHA256, b.ko.Status.CodeSHA256) {
423+
delta.Add("Spec.CodeS3SHA256", a.ko.Spec.CodeS3SHA256, b.ko.Status.CodeSHA256)
424+
} else if a.ko.Spec.CodeS3SHA256 != nil && b.ko.Status.CodeSHA256 != nil {
425+
if *a.ko.Spec.CodeS3SHA256 != *b.ko.Status.CodeSHA256 {
426+
delta.Add("Spec.CodeS3SHA256", a.ko.Spec.CodeS3SHA256, b.ko.Status.CodeSHA256)
427+
}
428+
}
419429
//TODO(hialylmh) handle Spec.Code.S3bucket changes
420430
// if ackcompare.HasNilDifference(a.ko.Spec.Code.S3Bucket, b.ko.Spec.Code.S3Bucket) {
421431
// delta.Add("Spec.Code.S3Bucket", a.ko.Spec.Code.S3Bucket, b.ko.Spec.Code.S3Bucket)
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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+
s3Bucket: $BUCKET_NAME
11+
s3Key: $LAMBDA_FILE_NAME
12+
role: $LAMBDA_ROLE
13+
codeS3SHA256: $HASH
14+
runtime: python3.9
15+
handler: main
16+
description: function created by ACK lambda-controller e2e tests
17+
reservedConcurrentExecutions: $RESERVED_CONCURRENT_EXECUTIONS
18+
codeSigningConfigARN: "$CODE_SIGNING_CONFIG_ARN"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
if __name__ == "__main__":
2+
print("Updated Hello ACK!")

test/e2e/service_bootstrap.py

+11
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
LAMBDA_FUNCTION_FILE_PATH = f"./resources/lambda_function/{LAMBDA_FUNCTION_FILE}"
4444
LAMBDA_FUNCTION_FILE_PATH_ZIP = f"./resources/lambda_function/{LAMBDA_FUNCTION_FILE_ZIP}"
4545

46+
LAMBDA_FUNCTION_UPDATED_FILE = "updated_main.py"
47+
LAMBDA_FUNCTION_UPDATED_FILE_ZIP = "updated_main.zip"
48+
LAMBDA_FUNCTION_UPDATED_FILE_PATH = f"./resources/lambda_function/{LAMBDA_FUNCTION_UPDATED_FILE}"
49+
LAMBDA_FUNCTION_UPDATED_FILE_PATH_ZIP = f"./resources/lambda_function/{LAMBDA_FUNCTION_UPDATED_FILE_ZIP}"
50+
4651
AWS_SIGNING_PLATFORM_ID = "AWSLambda-SHA384-ECDSA"
4752

4853
def zip_function_file(src: str, dst: str):
@@ -127,6 +132,12 @@ def service_bootstrap() -> Resources:
127132
LAMBDA_FUNCTION_FILE_PATH_ZIP,
128133
resources.FunctionsBucket.name,
129134
)
135+
136+
zip_function_file(LAMBDA_FUNCTION_UPDATED_FILE_PATH, LAMBDA_FUNCTION_UPDATED_FILE_PATH_ZIP)
137+
upload_function_to_bucket(
138+
LAMBDA_FUNCTION_UPDATED_FILE_PATH_ZIP,
139+
resources.FunctionsBucket.name,
140+
)
130141
except BootstrapFailureException as ex:
131142
exit(254)
132143
return resources

test/e2e/tests/test_function.py

+86-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import pytest
1818
import time
1919
import logging
20+
import hashlib
21+
import base64
2022

2123
from acktest import tags
2224
from acktest.resources import random_suffix_name
@@ -26,7 +28,8 @@
2628
from e2e import service_marker, CRD_GROUP, CRD_VERSION, load_lambda_resource
2729
from e2e.replacement_values import REPLACEMENT_VALUES
2830
from e2e.bootstrap_resources import get_bootstrap_resources
29-
from e2e.service_bootstrap import LAMBDA_FUNCTION_FILE_ZIP
31+
from e2e.service_bootstrap import LAMBDA_FUNCTION_FILE_ZIP, LAMBDA_FUNCTION_UPDATED_FILE_PATH_ZIP
32+
from e2e.service_bootstrap import LAMBDA_FUNCTION_UPDATED_FILE_ZIP, LAMBDA_FUNCTION_FILE_PATH_ZIP
3033
from e2e.tests.helper import LambdaValidator
3134

3235
RESOURCE_PLURAL = "functions"
@@ -536,5 +539,87 @@ def test_function_snapstart(self, lambda_client):
536539

537540
time.sleep(DELETE_WAIT_AFTER_SECONDS)
538541

542+
# Check Lambda function doesn't exist
543+
assert not lambda_validator.function_exists(resource_name)
544+
545+
def test_function_code_s3(self, lambda_client):
546+
resource_name = random_suffix_name("functioncodes3", 24)
547+
548+
resources = get_bootstrap_resources()
549+
logging.debug(resources)
550+
551+
archive_1 = open(LAMBDA_FUNCTION_FILE_PATH_ZIP, 'rb')
552+
readFile_1 = archive_1.read()
553+
hash_1 = hashlib.sha256(readFile_1)
554+
binary_hash_1 = hash_1.digest()
555+
base64_hash_1 = base64.b64encode(binary_hash_1)
556+
557+
archive_2 = open(LAMBDA_FUNCTION_UPDATED_FILE_PATH_ZIP, 'rb')
558+
readFile_2 = archive_2.read()
559+
hash_2 = hashlib.sha256(readFile_2)
560+
binary_hash_2 = hash_2.digest()
561+
base64_hash_2 = base64.b64encode(binary_hash_2)
562+
563+
replacements = REPLACEMENT_VALUES.copy()
564+
replacements["FUNCTION_NAME"] = resource_name
565+
replacements["BUCKET_NAME"] = resources.FunctionsBucket.name
566+
replacements["LAMBDA_ROLE"] = resources.BasicRole.arn
567+
replacements["LAMBDA_FILE_NAME"] = LAMBDA_FUNCTION_FILE_ZIP
568+
replacements["RESERVED_CONCURRENT_EXECUTIONS"] = "0"
569+
replacements["CODE_SIGNING_CONFIG_ARN"] = ""
570+
replacements["AWS_REGION"] = get_region()
571+
replacements["HASH"] = base64_hash_1
572+
573+
# Load Lambda CR
574+
resource_data = load_lambda_resource(
575+
"function_code_s3",
576+
additional_replacements=replacements,
577+
)
578+
logging.debug(resource_data)
579+
580+
# Create k8s resource
581+
ref = k8s.CustomResourceReference(
582+
CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL,
583+
resource_name, namespace="default",
584+
)
585+
k8s.create_custom_resource(ref, resource_data)
586+
cr = k8s.wait_resource_consumed_by_controller(ref)
587+
588+
assert cr is not None
589+
assert k8s.get_resource_exists(ref)
590+
591+
time.sleep(CREATE_WAIT_AFTER_SECONDS)
592+
593+
cr = k8s.wait_resource_consumed_by_controller(ref)
594+
595+
lambda_validator = LambdaValidator(lambda_client)
596+
597+
# Assert that the original code.s3Bucket and code.s3Key is still part of
598+
# the function's CR
599+
assert cr["spec"]["code"]["s3Bucket"] == resources.FunctionsBucket.name
600+
assert cr["spec"]["code"]["s3Key"] == LAMBDA_FUNCTION_FILE_ZIP
601+
602+
# Check Lambda function exists
603+
assert lambda_validator.function_exists(resource_name)
604+
605+
# Update cr
606+
cr["spec"]["codeS3SHA256"] = base64_hash_2
607+
cr["spec"]["code"]["s3Key"] = LAMBDA_FUNCTION_UPDATED_FILE_ZIP
608+
609+
# Patch k8s resource
610+
k8s.patch_custom_resource(ref, cr)
611+
time.sleep(UPDATE_WAIT_AFTER_SECONDS)
612+
613+
# Check function updated fields
614+
function = lambda_validator.get_function(resource_name)
615+
assert function is not None
616+
assert function["Configuration"]["CodeSha256"] == base64_hash_2
617+
618+
# Delete k8s resource
619+
_, deleted = k8s.delete_custom_resource(ref)
620+
assert deleted is True
621+
622+
time.sleep(DELETE_WAIT_AFTER_SECONDS)
623+
539624
# Check Lambda function doesn't exist
540625
assert not lambda_validator.function_exists(resource_name)

0 commit comments

Comments
 (0)