@@ -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