@@ -15,14 +15,38 @@ package function
1515
1616import (
1717 "context"
18+ "errors"
19+ "time"
1820
1921 svcapitypes "github.com/aws-controllers-k8s/lambda-controller/apis/v1alpha1"
2022 ackcompare "github.com/aws-controllers-k8s/runtime/pkg/compare"
23+ ackrequeue "github.com/aws-controllers-k8s/runtime/pkg/requeue"
2124 ackrtlog "github.com/aws-controllers-k8s/runtime/pkg/runtime/log"
2225 "github.com/aws/aws-sdk-go/aws"
2326 svcsdk "github.com/aws/aws-sdk-go/service/lambda"
2427)
2528
29+ var (
30+ ErrFunctionPending = errors .New ("Function in 'Pending' state, cannot be modified or deleted" )
31+ )
32+
33+ var (
34+ requeueWaitWhilePending = ackrequeue .NeededAfter (
35+ ErrFunctionPending ,
36+ 5 * time .Second ,
37+ )
38+ )
39+
40+ // isFunctionPending returns true if the supplied Lambda Function is in a pending
41+ // state
42+ func isFunctionPending (r * resource ) bool {
43+ if r .ko .Status .State == nil {
44+ return false
45+ }
46+ state := * r .ko .Status .State
47+ return state == string (svcapitypes .State_Pending )
48+ }
49+
2650// customUpdateFunction patches each of the resource properties in the backend AWS
2751// service API and returns a new resource with updated fields.
2852func (rm * resourceManager ) customUpdateFunction (
@@ -36,8 +60,12 @@ func (rm *resourceManager) customUpdateFunction(
3660 exit := rlog .Trace ("rm.customUpdateFunction" )
3761 defer exit (err )
3862
63+ if isFunctionPending (desired ) {
64+ return nil , requeueWaitWhilePending
65+ }
66+
3967 if delta .DifferentAt ("Spec.Code" ) {
40- err = rm .updateFunctionCode (ctx , desired )
68+ err = rm .updateFunctionCode (ctx , desired , delta )
4169 if err != nil {
4270 return nil , err
4371 }
@@ -70,6 +98,12 @@ func (rm *resourceManager) customUpdateFunction(
7098 return nil , err
7199 }
72100 }
101+ if delta .DifferentAt ("Spec.CodeSigningConfigARN" ) {
102+ err = rm .updateFunctionCodeSigningConfig (ctx , desired )
103+ if err != nil {
104+ return nil , err
105+ }
106+ }
73107
74108 readOneLatest , err := rm .ReadOne (ctx , desired )
75109 if err != nil {
@@ -247,12 +281,22 @@ func (rm *resourceManager) updateFunctionTags(
247281func (rm * resourceManager ) updateFunctionCode (
248282 ctx context.Context ,
249283 desired * resource ,
284+ delta * ackcompare.Delta ,
250285) error {
251286 var err error
252287 rlog := ackrtlog .FromContext (ctx )
253288 exit := rlog .Trace ("rm.updateFunctionCode" )
254289 defer exit (err )
255290
291+ if delta .DifferentAt ("Spec.Code.S3Key" ) &&
292+ ! delta .DifferentAt ("Spec.Code.S3Bucket" ) &&
293+ ! delta .DifferentAt ("Spec.Code.S3ObjectVersion" ) &&
294+ ! delta .DifferentAt ("Spec.Code.ImageURI" ) {
295+ log := ackrtlog .FromContext (ctx )
296+ log .Info ("updating code.s3Key field is not currently supported." )
297+ return nil
298+ }
299+
256300 dspec := desired .ko .Spec
257301 input := & svcsdk.UpdateFunctionCodeInput {
258302 FunctionName : aws .String (* dspec .Name ),
@@ -265,10 +309,6 @@ func (rm *resourceManager) updateFunctionCode(
265309 case dspec .Code .S3Bucket != nil ,
266310 dspec .Code .S3Key != nil ,
267311 dspec .Code .S3ObjectVersion != nil :
268-
269- log := ackrtlog .FromContext (ctx )
270- log .Debug ("updating code.s3Bucket field is not currently supported." )
271-
272312 input .S3Bucket = dspec .Code .S3Bucket
273313 input .S3Key = dspec .Code .S3Key
274314 input .S3ObjectVersion = dspec .Code .S3ObjectVersion
@@ -384,6 +424,59 @@ func (rm *resourceManager) updateFunctionConcurrency(
384424 return nil
385425}
386426
427+ // updateFunctionCodeSigningConfig calls PutFunctionCodeSigningConfig to update
428+ // it code signing configuration
429+ func (rm * resourceManager ) updateFunctionCodeSigningConfig (
430+ ctx context.Context ,
431+ desired * resource ,
432+ ) error {
433+ var err error
434+ rlog := ackrtlog .FromContext (ctx )
435+ exit := rlog .Trace ("rm.updateFunctionCodeSigningConfig" )
436+ defer exit (err )
437+
438+ if desired .ko .Spec .CodeSigningConfigARN == nil || * desired .ko .Spec .CodeSigningConfigARN == "" {
439+ return rm .deleteFunctionCodeSigningConfig (ctx , desired )
440+ }
441+
442+ dspec := desired .ko .Spec
443+ input := & svcsdk.PutFunctionCodeSigningConfigInput {
444+ FunctionName : aws .String (* dspec .Name ),
445+ CodeSigningConfigArn : aws .String (* dspec .CodeSigningConfigARN ),
446+ }
447+
448+ _ , err = rm .sdkapi .PutFunctionCodeSigningConfigWithContext (ctx , input )
449+ rm .metrics .RecordAPICall ("UPDATE" , "PutFunctionCodeSigningConfig" , err )
450+ if err != nil {
451+ return err
452+ }
453+ return nil
454+ }
455+
456+ // deleteFunctionCodeSigningConfig calls deleteFunctionCodeSigningConfig to update
457+ // it code signing configuration
458+ func (rm * resourceManager ) deleteFunctionCodeSigningConfig (
459+ ctx context.Context ,
460+ desired * resource ,
461+ ) error {
462+ var err error
463+ rlog := ackrtlog .FromContext (ctx )
464+ exit := rlog .Trace ("rm.deleteFunctionCodeSigningConfig" )
465+ defer exit (err )
466+
467+ dspec := desired .ko .Spec
468+ input := & svcsdk.DeleteFunctionCodeSigningConfigInput {
469+ FunctionName : aws .String (* dspec .Name ),
470+ }
471+
472+ _ , err = rm .sdkapi .DeleteFunctionCodeSigningConfigWithContext (ctx , input )
473+ rm .metrics .RecordAPICall ("UPDATE" , "DeleteFunctionCodeSigningConfig" , err )
474+ if err != nil {
475+ return err
476+ }
477+ return nil
478+ }
479+
387480// setResourceAdditionalFields will describe the fields that are not return by
388481// GetFunctionConcurrency calls
389482func (rm * resourceManager ) setResourceAdditionalFields (
@@ -406,5 +499,18 @@ func (rm *resourceManager) setResourceAdditionalFields(
406499 return err
407500 }
408501 ko .Spec .ReservedConcurrentExecutions = getFunctionConcurrencyOutput .ReservedConcurrentExecutions
502+
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
513+ }
514+ ko .Spec .CodeSigningConfigARN = getFunctionCodeSigningConfigOutput .CodeSigningConfigArn
409515 return nil
410516}
0 commit comments