Skip to content

Commit

Permalink
Update to ACK runtime v0.25.0, code-generator v0.25.0 (#87)
Browse files Browse the repository at this point in the history
----------

* 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.
  • Loading branch information
ack-bot authored and Vandita2020 committed Apr 4, 2023
1 parent 39f35a1 commit 217a0db
Show file tree
Hide file tree
Showing 17 changed files with 181 additions and 39 deletions.
10 changes: 5 additions & 5 deletions apis/v1alpha1/ack-generate-metadata.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
ack_generate_info:
build_date: "2023-03-22T22:14:24Z"
build_hash: fa24753ea8b657d8815ae3eac7accd0958f5f9fb
build_date: "2023-04-04T19:55:45Z"
build_hash: a6ae2078e57187b2daf47978bc07bd67072d2cba
go_version: go1.19
version: v0.25.0
api_directory_checksum: a9fcef68210dd72b4b2e37052f2c1a9e971326c6
version: v0.20.1-70-ga6ae207
api_directory_checksum: 09a0bda876eac49a802be254317710529b6c9f3b
api_version: v1alpha1
aws_sdk_go_version: v1.44.181
generator_config_info:
file_checksum: 095af1082df5c34cdc12296dc085bc6b2b7eadb9
file_checksum: e495db568ae64db031fcfa40b8a53f9866f22302
original_file_name: generator.yaml
last_modification:
reason: API generation
3 changes: 2 additions & 1 deletion apis/v1alpha1/function.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions apis/v1alpha1/generator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ resources:
- path: Status.State
in: [ "Active" ]
fields:
CodeS3SHA256:
type: String
compare:
is_ignored: true
Code.S3Bucket:
references:
resource: Bucket
Expand Down
5 changes: 5 additions & 0 deletions apis/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion config/controller/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ kind: Kustomization
images:
- name: controller
newName: public.ecr.aws/aws-controllers-k8s/lambda-controller
newTag: v0.1.7
newTag: v0.1.5
2 changes: 2 additions & 0 deletions config/crd/bases/lambda.services.k8s.aws_functions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ spec:
format: byte
type: string
type: object
codeS3SHA256:
type: string
codeSigningConfigARN:
description: To enable code signing for this function, specify the
ARN of a code-signing configuration. A code-signing configuration
Expand Down
4 changes: 4 additions & 0 deletions generator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ resources:
- path: Status.State
in: [ "Active" ]
fields:
CodeS3SHA256:
type: String
compare:
is_ignored: true
Code.S3Bucket:
references:
resource: Bucket
Expand Down
4 changes: 2 additions & 2 deletions helm/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
apiVersion: v1
name: lambda-chart
description: A Helm chart for the ACK service controller for AWS Lambda (Lambda)
version: v0.1.7
appVersion: v0.1.7
version: v0.1.5
appVersion: v0.1.5
home: https://github.com/aws-controllers-k8s/lambda-controller
icon: https://raw.githubusercontent.com/aws/eks-charts/master/docs/logo/aws.png
sources:
Expand Down
2 changes: 2 additions & 0 deletions helm/crds/lambda.services.k8s.aws_functions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ spec:
format: byte
type: string
type: object
codeS3SHA256:
type: string
codeSigningConfigARN:
description: To enable code signing for this function, specify the
ARN of a code-signing configuration. A code-signing configuration
Expand Down
5 changes: 1 addition & 4 deletions helm/crds/services.k8s.aws_adoptedresources.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,7 @@ spec:
blockOwnerDeletion:
description: If true, AND if the owner has the "foregroundDeletion"
finalizer, then the owner cannot be deleted from the
key-value store until this reference is removed. See
https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion
for how the garbage collector interacts with this
field and enforces the foreground deletion. Defaults
key-value store until this reference is removed. Defaults
to false. To set this field, a user needs "delete"
permission of the owner, otherwise 422 (Unprocessable
Entity) will be returned.
Expand Down
2 changes: 1 addition & 1 deletion helm/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{ .Chart.Name }} has been installed.
This chart deploys "public.ecr.aws/aws-controllers-k8s/lambda-controller:v0.1.7".
This chart deploys "public.ecr.aws/aws-controllers-k8s/lambda-controller:v0.1.5".

Check its status by running:
kubectl --namespace {{ .Release.Namespace }} get pods -l "app.kubernetes.io/instance={{ .Release.Name }}"
Expand Down
2 changes: 1 addition & 1 deletion helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

image:
repository: public.ecr.aws/aws-controllers-k8s/lambda-controller
tag: v0.1.7
tag: v0.1.5
pullPolicy: IfNotPresent
pullSecrets: []

Expand Down
56 changes: 33 additions & 23 deletions pkg/resource/function/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ package function

import (
"context"
"encoding/json"
"errors"
"fmt"
"time"

ackcompare "github.com/aws-controllers-k8s/runtime/pkg/compare"
Expand Down Expand Up @@ -96,20 +98,21 @@ func (rm *resourceManager) customUpdateFunction(
// UpdateFunctionCode because both of them can put the function in a
// Pending state.
switch {
case delta.DifferentAt("Spec.Code"):
err = rm.updateFunctionCode(ctx, desired, delta)
if err != nil {
return nil, err
}
case delta.DifferentExcept(
"Spec.Code",
"Spec.Tags",
"Spec.ReservedConcurrentExecutions",
"Spec.CodeSigningConfigARN"):
"Spec.CodeSigningConfigARN",
"Spec.CodeS3SHA256"):
err = rm.updateFunctionConfiguration(ctx, desired, delta)
if err != nil {
return nil, err
}
case delta.DifferentAt("Spec.Code") || delta.DifferentAt("Spec.CodeS3SHA256"):
err = rm.updateFunctionCode(ctx, desired, delta)
if err != nil {
return nil, err
}
}

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

if delta.DifferentAt("Spec.Code.S3Key") &&
!delta.DifferentAt("Spec.Code.S3Bucket") &&
!delta.DifferentAt("Spec.Code.S3ObjectVersion") &&
!delta.DifferentAt("Spec.Code.ImageURI") {
log := ackrtlog.FromContext(ctx)
log.Info("updating code.s3Key field is not currently supported.")
return nil
}

dspec := desired.ko.Spec
input := &svcsdk.UpdateFunctionCodeInput{
FunctionName: aws.String(*dspec.Name),
}

if dspec.Code != nil {
switch {
case dspec.Code.ImageURI != nil:
if delta.DifferentAt("Spec.Code.ImageURI") {
input.ImageUri = dspec.Code.ImageURI
case dspec.Code.S3Bucket != nil,
dspec.Code.S3Key != nil,
dspec.Code.S3ObjectVersion != nil:
input.S3Bucket = dspec.Code.S3Bucket
input.S3Key = dspec.Code.S3Key
input.S3ObjectVersion = dspec.Code.S3ObjectVersion
} else if delta.DifferentAt("Spec.CodeS3SHA256") {
if dspec.Code.S3Key != nil {
input.S3Key = aws.String(*dspec.Code.S3Key)
}
if dspec.Code.S3Bucket != nil {
input.S3Bucket = aws.String(*dspec.Code.S3Bucket)
}
if dspec.Code.S3ObjectVersion != nil {
input.S3ObjectVersion = aws.String(*dspec.Code.S3ObjectVersion)
}
}
}

Expand Down Expand Up @@ -416,6 +413,19 @@ func customPreCompare(
delta.Add("Spec.Code.ImageURI", a.ko.Spec.Code.ImageURI, b.ko.Spec.Code.ImageURI)
}
}
expected, _ := json.Marshal(a.ko.Spec.CodeS3SHA256)
fmt.Println("expected:", string(expected))

actual, _ := json.Marshal(b.ko.Status.CodeSHA256)
fmt.Println("actual:", string(actual))

if ackcompare.HasNilDifference(a.ko.Spec.CodeS3SHA256, b.ko.Status.CodeSHA256) {
delta.Add("Spec.CodeS3SHA256", a.ko.Spec.CodeS3SHA256, b.ko.Status.CodeSHA256)
} else if a.ko.Spec.CodeS3SHA256 != nil && b.ko.Status.CodeSHA256 != nil {
if *a.ko.Spec.CodeS3SHA256 != *b.ko.Status.CodeSHA256 {
delta.Add("Spec.CodeS3SHA256", a.ko.Spec.CodeS3SHA256, b.ko.Status.CodeSHA256)
}
}
//TODO(hialylmh) handle Spec.Code.S3bucket changes
// if ackcompare.HasNilDifference(a.ko.Spec.Code.S3Bucket, b.ko.Spec.Code.S3Bucket) {
// delta.Add("Spec.Code.S3Bucket", a.ko.Spec.Code.S3Bucket, b.ko.Spec.Code.S3Bucket)
Expand Down
18 changes: 18 additions & 0 deletions test/e2e/resources/function_code_s3.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: lambda.services.k8s.aws/v1alpha1
kind: Function
metadata:
name: $FUNCTION_NAME
annotations:
services.k8s.aws/region: $AWS_REGION
spec:
name: $FUNCTION_NAME
code:
s3Bucket: $BUCKET_NAME
s3Key: $LAMBDA_FILE_NAME
role: $LAMBDA_ROLE
codeS3SHA256: $HASH
runtime: python3.9
handler: main
description: function created by ACK lambda-controller e2e tests
reservedConcurrentExecutions: $RESERVED_CONCURRENT_EXECUTIONS
codeSigningConfigARN: "$CODE_SIGNING_CONFIG_ARN"
2 changes: 2 additions & 0 deletions test/e2e/resources/lambda_function/updated_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
if __name__ == "__main__":
print("Updated Hello ACK!")
11 changes: 11 additions & 0 deletions test/e2e/service_bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
LAMBDA_FUNCTION_FILE_PATH = f"./resources/lambda_function/{LAMBDA_FUNCTION_FILE}"
LAMBDA_FUNCTION_FILE_PATH_ZIP = f"./resources/lambda_function/{LAMBDA_FUNCTION_FILE_ZIP}"

LAMBDA_FUNCTION_UPDATED_FILE = "updated_main.py"
LAMBDA_FUNCTION_UPDATED_FILE_ZIP = "updated_main.zip"
LAMBDA_FUNCTION_UPDATED_FILE_PATH = f"./resources/lambda_function/{LAMBDA_FUNCTION_UPDATED_FILE}"
LAMBDA_FUNCTION_UPDATED_FILE_PATH_ZIP = f"./resources/lambda_function/{LAMBDA_FUNCTION_UPDATED_FILE_ZIP}"

AWS_SIGNING_PLATFORM_ID = "AWSLambda-SHA384-ECDSA"

def zip_function_file(src: str, dst: str):
Expand Down Expand Up @@ -127,6 +132,12 @@ def service_bootstrap() -> Resources:
LAMBDA_FUNCTION_FILE_PATH_ZIP,
resources.FunctionsBucket.name,
)

zip_function_file(LAMBDA_FUNCTION_UPDATED_FILE_PATH, LAMBDA_FUNCTION_UPDATED_FILE_PATH_ZIP)
upload_function_to_bucket(
LAMBDA_FUNCTION_UPDATED_FILE_PATH_ZIP,
resources.FunctionsBucket.name,
)
except BootstrapFailureException as ex:
exit(254)
return resources
Expand Down
88 changes: 87 additions & 1 deletion test/e2e/tests/test_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
import pytest
import time
import logging
import zipfile
import hashlib
import base64

from acktest import tags
from acktest.resources import random_suffix_name
Expand All @@ -26,7 +29,8 @@
from e2e import service_marker, CRD_GROUP, CRD_VERSION, load_lambda_resource
from e2e.replacement_values import REPLACEMENT_VALUES
from e2e.bootstrap_resources import get_bootstrap_resources
from e2e.service_bootstrap import LAMBDA_FUNCTION_FILE_ZIP
from e2e.service_bootstrap import LAMBDA_FUNCTION_FILE_ZIP, LAMBDA_FUNCTION_UPDATED_FILE_PATH_ZIP
from e2e.service_bootstrap import LAMBDA_FUNCTION_UPDATED_FILE_ZIP, LAMBDA_FUNCTION_FILE_PATH_ZIP
from e2e.tests.helper import LambdaValidator

RESOURCE_PLURAL = "functions"
Expand Down Expand Up @@ -536,5 +540,87 @@ def test_function_snapstart(self, lambda_client):

time.sleep(DELETE_WAIT_AFTER_SECONDS)

# Check Lambda function doesn't exist
assert not lambda_validator.function_exists(resource_name)

def test_function_code_s3(self, lambda_client):
resource_name = random_suffix_name("functioncodes3", 24)

resources = get_bootstrap_resources()
logging.debug(resources)

archive_1 = zipfile.ZipFile(LAMBDA_FUNCTION_FILE_PATH_ZIP, 'r')
readFile_1 = archive_1.read()
hash_1 = hashlib.sha256(readFile_1.encode())
binary_hash_1 = hash_1.hexdigest()
base64_hash_1 = base64.b64encode(binary_hash_1).decode('utf-8')

archive_2 = zipfile.ZipFile(LAMBDA_FUNCTION_UPDATED_FILE_PATH_ZIP, 'r')
readFile_2 = archive_2.read()
hash_2 = hashlib.sha256(readFile_2.encode())
binary_hash_2 = hash_2.hexdigest()
base64_hash_2 = base64.b64encode(binary_hash_2).decode('utf-8')

replacements = REPLACEMENT_VALUES.copy()
replacements["FUNCTION_NAME"] = resource_name
replacements["BUCKET_NAME"] = resources.FunctionsBucket.name
replacements["LAMBDA_ROLE"] = resources.BasicRole.arn
replacements["LAMBDA_FILE_NAME"] = LAMBDA_FUNCTION_FILE_ZIP
replacements["RESERVED_CONCURRENT_EXECUTIONS"] = "0"
replacements["CODE_SIGNING_CONFIG_ARN"] = ""
replacements["AWS_REGION"] = get_region()
replacements["HASH"] = base64_hash_1

# Load Lambda CR
resource_data = load_lambda_resource(
"function_code_s3",
additional_replacements=replacements,
)
logging.debug(resource_data)

# Create k8s resource
ref = k8s.CustomResourceReference(
CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL,
resource_name, namespace="default",
)
k8s.create_custom_resource(ref, resource_data)
cr = k8s.wait_resource_consumed_by_controller(ref)

assert cr is not None
assert k8s.get_resource_exists(ref)

time.sleep(CREATE_WAIT_AFTER_SECONDS)

cr = k8s.wait_resource_consumed_by_controller(ref)

lambda_validator = LambdaValidator(lambda_client)

# Assert that the original code.s3Bucket and code.s3Key is still part of
# the function's CR
assert cr["spec"]["code"]["s3Bucket"] == resources.FunctionsBucket.name
assert cr["spec"]["code"]["s3Key"] == LAMBDA_FUNCTION_FILE_ZIP

# Check Lambda function exists
assert lambda_validator.function_exists(resource_name)

# Update cr
cr["spec"]["codeS3SHA256"] = base64_hash_2
cr["spec"]["code"]["s3Key"] = LAMBDA_FUNCTION_UPDATED_FILE_ZIP

# Patch k8s resource
k8s.patch_custom_resource(ref, cr)
time.sleep(UPDATE_WAIT_AFTER_SECONDS)

# Check function updated fields
function = lambda_validator.get_function(resource_name)
assert function is not None
assert function["Configuration"]["CodeSha256"] == base64_hash_2

# Delete k8s resource
_, deleted = k8s.delete_custom_resource(ref)
assert deleted is True

time.sleep(DELETE_WAIT_AFTER_SECONDS)

# Check Lambda function doesn't exist
assert not lambda_validator.function_exists(resource_name)

0 comments on commit 217a0db

Please sign in to comment.