@@ -102,25 +102,15 @@ func (rm *resourceManager) customUpdateFunction(
102102 }
103103 }
104104 }
105- if delta .DifferentAt ("Spec.Architectures" ) {
106- err = rm .updateFunctionArchitectures (ctx , desired , latest )
107- if err != nil {
108- return nil , err
109- }
110- }
111105
112106 // Only try to update Spec.Code or Spec.Configuration at once. It is
113107 // not correct to sequentially call UpdateFunctionConfiguration and
114108 // UpdateFunctionCode because both of them can put the function in a
115109 // Pending state.
116110 switch {
117- case delta .DifferentAt ("Spec.Code" ):
118- err = rm .updateFunctionCode (ctx , desired , delta )
111+ case delta .DifferentAt ("Spec.Code.ImageURI" ) || delta . DifferentAt ( "Spec.Code.SHA256" ) || delta . DifferentAt ( "Spec.Architectures " ):
112+ err = rm .updateFunctionCode (ctx , desired , delta , latest )
119113 if err != nil {
120- // If the source image is not available, we get an error like this:
121- // "InvalidParameterValueException: Source image 1234567890.dkr.ecr.us-east-2.amazonaws.com/my-lambda:my-tag does not exist. Provide a valid source image."
122- // Because this may be recoverable (i.e. the image may be pushed once a build completes),
123- // we requeue the function for reconciliation after one minute.
124114 if strings .Contains (err .Error (), "Provide a valid source image." ) {
125115 return nil , requeueWaitWhileSourceImageDoesNotExist
126116 } else {
@@ -131,6 +121,7 @@ func (rm *resourceManager) customUpdateFunction(
131121 "Spec.Code" ,
132122 "Spec.Tags" ,
133123 "Spec.ReservedConcurrentExecutions" ,
124+ "Spec.FunctionEventInvokeConfig" ,
134125 "Spec.CodeSigningConfigARN" ):
135126 err = rm .updateFunctionConfiguration (ctx , desired , delta )
136127 if err != nil {
@@ -377,16 +368,17 @@ func (rm *resourceManager) updateFunctionTags(
377368 return nil
378369}
379370
380- // updateFunctionArchitectures calls UpdateFunctionCode to update architecture for lambda
371+ // updateFunctionsCode calls UpdateFunctionCode to update a specific lambda
381372// function code.
382- func (rm * resourceManager ) updateFunctionArchitectures (
373+ func (rm * resourceManager ) updateFunctionCode (
383374 ctx context.Context ,
384375 desired * resource ,
376+ delta * ackcompare.Delta ,
385377 latest * resource ,
386378) error {
387379 var err error
388380 rlog := ackrtlog .FromContext (ctx )
389- exit := rlog .Trace ("rm.updateFunctionArchitectures " )
381+ exit := rlog .Trace ("rm.updateFunctionCode " )
390382 defer exit (err )
391383
392384 dspec := desired .ko .Spec
@@ -400,60 +392,30 @@ func (rm *resourceManager) updateFunctionArchitectures(
400392 input .Architectures = nil
401393 }
402394
403- if latest .ko .Spec .Code != nil {
404- if latest .ko .Spec .PackageType != nil && * latest .ko .Spec .PackageType == "Image" {
405- input .ImageUri = latest .ko .Spec .Code .ImageURI
406- } else if latest .ko .Spec .PackageType != nil && * latest .ko .Spec .PackageType == "Zip" {
407- input .S3Bucket = latest .ko .Spec .Code .S3Bucket
408- input .S3Key = latest .ko .Spec .Code .S3Key
409- }
410- }
411-
412- _ , err = rm .sdkapi .UpdateFunctionCodeWithContext (ctx , input )
413- rm .metrics .RecordAPICall ("UPDATE" , "UpdateFunctionArchitectures" , err )
414- if err != nil {
415- return err
416- }
417-
418- return nil
419- }
420-
421- // updateFunctionsCode calls UpdateFunctionCode to update a specific lambda
422- // function code.
423- func (rm * resourceManager ) updateFunctionCode (
424- ctx context.Context ,
425- desired * resource ,
426- delta * ackcompare.Delta ,
427- ) error {
428- var err error
429- rlog := ackrtlog .FromContext (ctx )
430- exit := rlog .Trace ("rm.updateFunctionCode" )
431- defer exit (err )
432-
433- if delta .DifferentAt ("Spec.Code.S3Key" ) &&
434- ! delta .DifferentAt ("Spec.Code.S3Bucket" ) &&
435- ! delta .DifferentAt ("Spec.Code.S3ObjectVersion" ) &&
436- ! delta .DifferentAt ("Spec.Code.ImageURI" ) {
437- log := ackrtlog .FromContext (ctx )
438- log .Info ("updating code.s3Key field is not currently supported." )
439- return nil
440- }
441-
442- dspec := desired .ko .Spec
443- input := & svcsdk.UpdateFunctionCodeInput {
444- FunctionName : aws .String (* dspec .Name ),
445- }
446-
447395 if dspec .Code != nil {
448- switch {
449- case dspec .Code .ImageURI != nil :
450- input .ImageUri = dspec .Code .ImageURI
451- case dspec .Code .S3Bucket != nil ,
452- dspec .Code .S3Key != nil ,
453- dspec .Code .S3ObjectVersion != nil :
454- input .S3Bucket = dspec .Code .S3Bucket
455- input .S3Key = dspec .Code .S3Key
456- input .S3ObjectVersion = dspec .Code .S3ObjectVersion
396+ if delta .DifferentAt ("Spec.Code.SHA256" ) && dspec .Code .SHA256 != nil {
397+ if dspec .Code .S3Key != nil {
398+ input .S3Key = aws .String (* dspec .Code .S3Key )
399+ }
400+ if dspec .Code .S3Bucket != nil {
401+ input .S3Bucket = aws .String (* dspec .Code .S3Bucket )
402+ }
403+ if dspec .Code .S3ObjectVersion != nil {
404+ input .S3ObjectVersion = aws .String (* dspec .Code .S3ObjectVersion )
405+ }
406+ } else if delta .DifferentAt ("Spec.Code.ImageURI" ) && dspec .Code .ImageURI != nil {
407+ if dspec .Code .ImageURI != nil {
408+ input .ImageUri = aws .String (* dspec .Code .ImageURI )
409+ }
410+
411+ } else { // We need to pass the latest code to Update API call,
412+ //if there is change in architecture and no change in Code
413+ if latest .ko .Spec .PackageType != nil && * latest .ko .Spec .PackageType == "Image" {
414+ input .ImageUri = latest .ko .Spec .Code .ImageURI
415+ } else if latest .ko .Spec .PackageType != nil && * latest .ko .Spec .PackageType == "Zip" {
416+ input .S3Bucket = latest .ko .Spec .Code .S3Bucket
417+ input .S3Key = latest .ko .Spec .Code .S3Key
418+ }
457419 }
458420 }
459421
@@ -501,36 +463,27 @@ func customPreCompare(
501463 a * resource ,
502464 b * resource ,
503465) {
466+ // No need to compare difference in S3 Key/Bucket/ObjectVersion. As in sdkFind() there is a copy 'ko := r.ko.DeepCopy()'
467+ // of S3 Key/Bucket/ObjectVersion passed. This 'ko' then stores the values of latest S3 fields which API returns
468+ // and compares it with desired field values. Since the API doesn't return values of S3 fields, it doesn't
469+ // notice any changes between desired and latest, hence fails to recognize the update in the values.
470+
471+ // To solve this we created a new field 'Code.SHA256' to store the hash value of deployment package. Any change
472+ // in hash value refers to change in S3 Key/Bucket/ObjectVersion and controller can recognize the change in
473+ // desired and latest value of 'Code.SHA256' and hence calls the update function.
474+
504475 if ackcompare .HasNilDifference (a .ko .Spec .Code , b .ko .Spec .Code ) {
505476 delta .Add ("Spec.Code" , a .ko .Spec .Code , b .ko .Spec .Code )
506477 } else if a .ko .Spec .Code != nil && b .ko .Spec .Code != nil {
507- if ackcompare .HasNilDifference (a .ko .Spec .Code .ImageURI , b .ko .Spec .Code .ImageURI ) {
508- delta .Add ("Spec.Code.ImageURI" , a .ko .Spec .Code .ImageURI , b .ko .Spec .Code .ImageURI )
509- } else if a .ko .Spec .Code .ImageURI != nil && b .ko .Spec .Code .ImageURI != nil {
510- if * a .ko .Spec .Code .ImageURI != * b .ko .Spec .Code .ImageURI {
511- delta .Add ("Spec.Code.ImageURI" , a .ko .Spec .Code .ImageURI , b .ko .Spec .Code .ImageURI )
512- }
513- }
514- //TODO(hialylmh) handle Spec.Code.S3bucket changes
515- // if ackcompare.HasNilDifference(a.ko.Spec.Code.S3Bucket, b.ko.Spec.Code.S3Bucket) {
516- // delta.Add("Spec.Code.S3Bucket", a.ko.Spec.Code.S3Bucket, b.ko.Spec.Code.S3Bucket)
517- // } else if a.ko.Spec.Code.S3Bucket != nil && b.ko.Spec.Code.S3Bucket != nil {
518- // if *a.ko.Spec.Code.S3Bucket != *b.ko.Spec.Code.S3Bucket {
519- // delta.Add("Spec.Code.S3Bucket", a.ko.Spec.Code.S3Bucket, b.ko.Spec.Code.S3Bucket)
520- // }
521- // }
522- if ackcompare .HasNilDifference (a .ko .Spec .Code .S3Key , b .ko .Spec .Code .S3Key ) {
523- delta .Add ("Spec.Code.S3Key" , a .ko .Spec .Code .S3Key , b .ko .Spec .Code .S3Key )
524- } else if a .ko .Spec .Code .S3Key != nil && b .ko .Spec .Code .S3Key != nil {
525- if * a .ko .Spec .Code .S3Key != * b .ko .Spec .Code .S3Key {
526- delta .Add ("Spec.Code.S3Key" , a .ko .Spec .Code .S3Key , b .ko .Spec .Code .S3Key )
527- }
528- }
529- if ackcompare .HasNilDifference (a .ko .Spec .Code .S3ObjectVersion , b .ko .Spec .Code .S3ObjectVersion ) {
530- delta .Add ("Spec.Code.S3ObjectVersion" , a .ko .Spec .Code .S3ObjectVersion , b .ko .Spec .Code .S3ObjectVersion )
531- } else if a .ko .Spec .Code .S3ObjectVersion != nil && b .ko .Spec .Code .S3ObjectVersion != nil {
532- if * a .ko .Spec .Code .S3ObjectVersion != * b .ko .Spec .Code .S3ObjectVersion {
533- delta .Add ("Spec.Code.S3ObjectVersion" , a .ko .Spec .Code .S3ObjectVersion , b .ko .Spec .Code .S3ObjectVersion )
478+ if a .ko .Spec .PackageType != nil && * a .ko .Spec .PackageType == "Zip" {
479+ if a .ko .Spec .Code .SHA256 != nil {
480+ if ackcompare .HasNilDifference (a .ko .Spec .Code .SHA256 , b .ko .Status .CodeSHA256 ) {
481+ delta .Add ("Spec.Code.SHA256" , a .ko .Spec .Code .SHA256 , b .ko .Status .CodeSHA256 )
482+ } else if a .ko .Spec .Code .SHA256 != nil && b .ko .Status .CodeSHA256 != nil {
483+ if * a .ko .Spec .Code .SHA256 != * b .ko .Status .CodeSHA256 {
484+ delta .Add ("Spec.Code.SHA256" , a .ko .Spec .Code .SHA256 , b .ko .Status .CodeSHA256 )
485+ }
486+ }
534487 }
535488 }
536489 }
0 commit comments