@@ -15,14 +15,38 @@ package function
15
15
16
16
import (
17
17
"context"
18
+ "errors"
19
+ "time"
18
20
19
21
svcapitypes "github.com/aws-controllers-k8s/lambda-controller/apis/v1alpha1"
20
22
ackcompare "github.com/aws-controllers-k8s/runtime/pkg/compare"
23
+ ackrequeue "github.com/aws-controllers-k8s/runtime/pkg/requeue"
21
24
ackrtlog "github.com/aws-controllers-k8s/runtime/pkg/runtime/log"
22
25
"github.com/aws/aws-sdk-go/aws"
23
26
svcsdk "github.com/aws/aws-sdk-go/service/lambda"
24
27
)
25
28
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
+
26
50
// customUpdateFunction patches each of the resource properties in the backend AWS
27
51
// service API and returns a new resource with updated fields.
28
52
func (rm * resourceManager ) customUpdateFunction (
@@ -36,8 +60,12 @@ func (rm *resourceManager) customUpdateFunction(
36
60
exit := rlog .Trace ("rm.customUpdateFunction" )
37
61
defer exit (err )
38
62
63
+ if isFunctionPending (desired ) {
64
+ return nil , requeueWaitWhilePending
65
+ }
66
+
39
67
if delta .DifferentAt ("Spec.Code" ) {
40
- err = rm .updateFunctionCode (ctx , desired )
68
+ err = rm .updateFunctionCode (ctx , desired , delta )
41
69
if err != nil {
42
70
return nil , err
43
71
}
@@ -70,6 +98,12 @@ func (rm *resourceManager) customUpdateFunction(
70
98
return nil , err
71
99
}
72
100
}
101
+ if delta .DifferentAt ("Spec.CodeSigningConfigARN" ) {
102
+ err = rm .updateFunctionCodeSigningConfig (ctx , desired )
103
+ if err != nil {
104
+ return nil , err
105
+ }
106
+ }
73
107
74
108
readOneLatest , err := rm .ReadOne (ctx , desired )
75
109
if err != nil {
@@ -247,12 +281,22 @@ func (rm *resourceManager) updateFunctionTags(
247
281
func (rm * resourceManager ) updateFunctionCode (
248
282
ctx context.Context ,
249
283
desired * resource ,
284
+ delta * ackcompare.Delta ,
250
285
) error {
251
286
var err error
252
287
rlog := ackrtlog .FromContext (ctx )
253
288
exit := rlog .Trace ("rm.updateFunctionCode" )
254
289
defer exit (err )
255
290
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
+
256
300
dspec := desired .ko .Spec
257
301
input := & svcsdk.UpdateFunctionCodeInput {
258
302
FunctionName : aws .String (* dspec .Name ),
@@ -265,10 +309,6 @@ func (rm *resourceManager) updateFunctionCode(
265
309
case dspec .Code .S3Bucket != nil ,
266
310
dspec .Code .S3Key != nil ,
267
311
dspec .Code .S3ObjectVersion != nil :
268
-
269
- log := ackrtlog .FromContext (ctx )
270
- log .Debug ("updating code.s3Bucket field is not currently supported." )
271
-
272
312
input .S3Bucket = dspec .Code .S3Bucket
273
313
input .S3Key = dspec .Code .S3Key
274
314
input .S3ObjectVersion = dspec .Code .S3ObjectVersion
@@ -384,6 +424,59 @@ func (rm *resourceManager) updateFunctionConcurrency(
384
424
return nil
385
425
}
386
426
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
+
387
480
// setResourceAdditionalFields will describe the fields that are not return by
388
481
// GetFunctionConcurrency calls
389
482
func (rm * resourceManager ) setResourceAdditionalFields (
@@ -406,5 +499,18 @@ func (rm *resourceManager) setResourceAdditionalFields(
406
499
return err
407
500
}
408
501
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
409
515
return nil
410
516
}
0 commit comments