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 74a6bde
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 25 deletions.
2 changes: 1 addition & 1 deletion apis/v1alpha1/ack-generate-metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ api_directory_checksum: a9fcef68210dd72b4b2e37052f2c1a9e971326c6
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: 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
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
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
86 changes: 86 additions & 0 deletions 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 hashlib
import base64
import zipfile

from acktest import tags
from acktest.resources import random_suffix_name
Expand All @@ -27,6 +30,7 @@
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_UPDATED_FILE_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_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_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 74a6bde

Please sign in to comment.