Skip to content

Commit 07b712d

Browse files
committed
Bug fix for EventInvokeConfig in Alias
1 parent d0a1dd3 commit 07b712d

File tree

3 files changed

+122
-115
lines changed

3 files changed

+122
-115
lines changed

pkg/resource/alias/hooks.go

Lines changed: 64 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import (
2424
svcapitypes "github.com/aws-controllers-k8s/lambda-controller/apis/v1alpha1"
2525
)
2626

27+
// syncEventInvokeConfig calls `PutFunctionEventInvokeConfig` to update the fields
28+
// or `DeleteFunctionEventInvokeConfig` if users removes the fields
2729
func (rm *resourceManager) syncEventInvokeConfig(
2830
ctx context.Context,
2931
r *resource,
@@ -32,42 +34,55 @@ func (rm *resourceManager) syncEventInvokeConfig(
3234
exit := rlog.Trace("rm.syncEventInvokeConfig")
3335
defer exit(err)
3436

37+
// Check if the user deleted the 'FunctionEventInvokeConfig' configuration
38+
// If yes, delete FunctionEventInvokeConfig
39+
if r.ko.Spec.FunctionEventInvokeConfig == nil {
40+
input_delete := &svcsdk.DeleteFunctionEventInvokeConfigInput{
41+
FunctionName: aws.String(*r.ko.Spec.FunctionName),
42+
Qualifier: aws.String(*r.ko.Spec.Name),
43+
}
44+
_, err = rm.sdkapi.DeleteFunctionEventInvokeConfigWithContext(ctx, input_delete)
45+
rm.metrics.RecordAPICall("DELETE", "DeleteFunctionEventInvokeConfig", err)
46+
if err != nil {
47+
return nil, err
48+
}
49+
return r, nil
50+
}
51+
3552
dspec := r.ko.Spec
3653
input := &svcsdk.PutFunctionEventInvokeConfigInput{
3754
FunctionName: aws.String(*dspec.FunctionName),
3855
Qualifier: aws.String(*dspec.Name),
3956
}
4057

41-
if r.ko.Spec.FunctionEventInvokeConfig != nil {
42-
if r.ko.Spec.FunctionEventInvokeConfig.DestinationConfig != nil {
43-
destinations := &svcsdk.DestinationConfig{}
44-
if r.ko.Spec.FunctionEventInvokeConfig.DestinationConfig.OnFailure != nil {
45-
destinations.OnFailure = &svcsdk.OnFailure{}
46-
if r.ko.Spec.FunctionEventInvokeConfig.DestinationConfig.OnFailure.Destination != nil {
47-
destinations.OnFailure.Destination = aws.String(*r.ko.Spec.FunctionEventInvokeConfig.DestinationConfig.OnFailure.Destination)
48-
}
49-
}
50-
if r.ko.Spec.FunctionEventInvokeConfig.DestinationConfig.OnSuccess != nil {
51-
destinations.OnSuccess = &svcsdk.OnSuccess{}
52-
if r.ko.Spec.FunctionEventInvokeConfig.DestinationConfig.OnSuccess.Destination != nil {
53-
destinations.OnSuccess.Destination = aws.String(*r.ko.Spec.FunctionEventInvokeConfig.DestinationConfig.OnSuccess.Destination)
54-
}
58+
if dspec.FunctionEventInvokeConfig.DestinationConfig != nil {
59+
destinations := &svcsdk.DestinationConfig{}
60+
if dspec.FunctionEventInvokeConfig.DestinationConfig.OnFailure != nil {
61+
destinations.OnFailure = &svcsdk.OnFailure{}
62+
if dspec.FunctionEventInvokeConfig.DestinationConfig.OnFailure.Destination != nil {
63+
destinations.OnFailure.Destination = aws.String(*dspec.FunctionEventInvokeConfig.DestinationConfig.OnFailure.Destination)
5564
}
56-
input.DestinationConfig = destinations
5765
}
58-
if r.ko.Spec.FunctionEventInvokeConfig.MaximumEventAgeInSeconds != nil {
59-
input.MaximumEventAgeInSeconds = aws.Int64(*r.ko.Spec.FunctionEventInvokeConfig.MaximumEventAgeInSeconds)
60-
}
61-
if r.ko.Spec.FunctionEventInvokeConfig.MaximumRetryAttempts != nil {
62-
input.MaximumRetryAttempts = aws.Int64(*r.ko.Spec.FunctionEventInvokeConfig.MaximumRetryAttempts)
66+
if dspec.FunctionEventInvokeConfig.DestinationConfig.OnSuccess != nil {
67+
destinations.OnSuccess = &svcsdk.OnSuccess{}
68+
if dspec.FunctionEventInvokeConfig.DestinationConfig.OnSuccess.Destination != nil {
69+
destinations.OnSuccess.Destination = aws.String(*dspec.FunctionEventInvokeConfig.DestinationConfig.OnSuccess.Destination)
70+
}
6371
}
72+
input.DestinationConfig = destinations
6473
}
74+
if dspec.FunctionEventInvokeConfig.MaximumEventAgeInSeconds != nil {
75+
input.MaximumEventAgeInSeconds = aws.Int64(*dspec.FunctionEventInvokeConfig.MaximumEventAgeInSeconds)
76+
}
77+
if dspec.FunctionEventInvokeConfig.MaximumRetryAttempts != nil {
78+
input.MaximumRetryAttempts = aws.Int64(*dspec.FunctionEventInvokeConfig.MaximumRetryAttempts)
79+
}
80+
6581
_, err = rm.sdkapi.PutFunctionEventInvokeConfigWithContext(ctx, input)
6682
rm.metrics.RecordAPICall("UPDATE", "SyncEventInvokeConfig", err)
6783
if err != nil {
6884
return nil, err
6985
}
70-
7186
return r, nil
7287
}
7388

@@ -148,12 +163,33 @@ func (rm *resourceManager) setProvisionedConcurrencyConfig(
148163
return nil
149164
}
150165

151-
// getFunctionEventInvokeConfig will describe the fields that are
152-
// custom to the Alias resource
153-
func (rm *resourceManager) getFunctionEventInvokeConfig(
166+
func (rm *resourceManager) setFunctionEventInvokeConfigFromResponse(
167+
ko *svcapitypes.Alias,
168+
getFunctionEventInvokeConfigOutput *svcsdk.GetFunctionEventInvokeConfigOutput,
169+
) {
170+
// creating FunctionEventInvokeConfig object to store the values returned from `Get` call
171+
cloudFunctionEventInvokeConfig := &svcapitypes.PutFunctionEventInvokeConfigInput{}
172+
cloudFunctionEventInvokeConfig.DestinationConfig = &svcapitypes.DestinationConfig{}
173+
cloudFunctionEventInvokeConfig.DestinationConfig.OnFailure = &svcapitypes.OnFailure{}
174+
cloudFunctionEventInvokeConfig.DestinationConfig.OnSuccess = &svcapitypes.OnSuccess{}
175+
cloudFunctionEventInvokeConfig.DestinationConfig.OnFailure.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnFailure.Destination
176+
cloudFunctionEventInvokeConfig.DestinationConfig.OnSuccess.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnSuccess.Destination
177+
cloudFunctionEventInvokeConfig.MaximumEventAgeInSeconds = getFunctionEventInvokeConfigOutput.MaximumEventAgeInSeconds
178+
cloudFunctionEventInvokeConfig.MaximumRetryAttempts = getFunctionEventInvokeConfigOutput.MaximumRetryAttempts
179+
ko.Spec.FunctionEventInvokeConfig = cloudFunctionEventInvokeConfig
180+
181+
}
182+
183+
// setFunctionEventInvokeConfig sets the fields to set asynchronous invocation
184+
// for Function's Alias
185+
func (rm *resourceManager) setFunctionEventInvokeConfig(
154186
ctx context.Context,
155187
ko *svcapitypes.Alias,
156188
) (err error) {
189+
rlog := ackrtlog.FromContext(ctx)
190+
exit := rlog.Trace("rm.setFunctionEventInvokeConfig")
191+
defer exit(err)
192+
157193
var getFunctionEventInvokeConfigOutput *svcsdk.GetFunctionEventInvokeConfigOutput
158194
getFunctionEventInvokeConfigOutput, err = rm.sdkapi.GetFunctionEventInvokeConfigWithContext(
159195
ctx,
@@ -162,7 +198,6 @@ func (rm *resourceManager) getFunctionEventInvokeConfig(
162198
Qualifier: ko.Spec.Name,
163199
},
164200
)
165-
166201
rm.metrics.RecordAPICall("GET", "GetFunctionEventInvokeConfig", err)
167202

168203
if err != nil {
@@ -172,30 +207,7 @@ func (rm *resourceManager) getFunctionEventInvokeConfig(
172207
return err
173208
}
174209
} else {
175-
if getFunctionEventInvokeConfigOutput.DestinationConfig != nil {
176-
if getFunctionEventInvokeConfigOutput.DestinationConfig.OnFailure != nil {
177-
if getFunctionEventInvokeConfigOutput.DestinationConfig.OnFailure.Destination != nil {
178-
ko.Spec.FunctionEventInvokeConfig.DestinationConfig.OnFailure.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnFailure.Destination
179-
}
180-
}
181-
if getFunctionEventInvokeConfigOutput.DestinationConfig.OnSuccess != nil {
182-
if getFunctionEventInvokeConfigOutput.DestinationConfig.OnSuccess.Destination != nil {
183-
ko.Spec.FunctionEventInvokeConfig.DestinationConfig.OnSuccess.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnSuccess.Destination
184-
}
185-
}
186-
} else {
187-
ko.Spec.FunctionEventInvokeConfig.DestinationConfig = nil
188-
}
189-
if getFunctionEventInvokeConfigOutput.MaximumEventAgeInSeconds != nil {
190-
ko.Spec.FunctionEventInvokeConfig.MaximumEventAgeInSeconds = getFunctionEventInvokeConfigOutput.MaximumEventAgeInSeconds
191-
} else {
192-
ko.Spec.FunctionEventInvokeConfig.MaximumEventAgeInSeconds = nil
193-
}
194-
if getFunctionEventInvokeConfigOutput.DestinationConfig != nil {
195-
ko.Spec.FunctionEventInvokeConfig.MaximumRetryAttempts = getFunctionEventInvokeConfigOutput.MaximumRetryAttempts
196-
} else {
197-
ko.Spec.FunctionEventInvokeConfig.MaximumRetryAttempts = nil
198-
}
210+
rm.setFunctionEventInvokeConfigFromResponse(ko, getFunctionEventInvokeConfigOutput)
199211
}
200212

201213
return nil
@@ -212,9 +224,9 @@ func (rm *resourceManager) setResourceAdditionalFields(
212224
defer exit(err)
213225

214226
// To set Asynchronous Invocations for the function's alias
215-
eic_err := rm.getFunctionEventInvokeConfig(ctx, ko)
216-
if eic_err != nil {
217-
return eic_err
227+
err = rm.setFunctionEventInvokeConfig(ctx, ko)
228+
if err != nil {
229+
return err
218230
}
219231

220232
// To set Provisioned Concurrency for the function's alias

pkg/resource/function/hooks.go

Lines changed: 47 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func (rm *resourceManager) customUpdateFunction(
8686
}
8787
}
8888
if delta.DifferentAt("Spec.FunctionEventInvokeConfig") {
89-
err = rm.updateFunctionEventInvokeConfig(ctx, desired)
89+
err = rm.syncFunctionEventInvokeConfig(ctx, desired)
9090
if err != nil {
9191
return nil, err
9292
}
@@ -491,7 +491,9 @@ func (rm *resourceManager) updateFunctionConcurrency(
491491
return nil
492492
}
493493

494-
func (rm *resourceManager) updateFunctionEventInvokeConfig(
494+
// syncFunctionEventInvokeConfig calls `PutFunctionEventInvokeConfig` to update the fields
495+
// or `DeleteFunctionEventInvokeConfig` is users removes the fields
496+
func (rm *resourceManager) syncFunctionEventInvokeConfig(
495497
ctx context.Context,
496498
desired *resource,
497499
) error {
@@ -551,7 +553,7 @@ func (rm *resourceManager) updateFunctionEventInvokeConfig(
551553
}
552554

553555
// updateFunctionCodeSigningConfig calls PutFunctionCodeSigningConfig to update
554-
// it code signing configuration
556+
// the code signing configuration
555557
func (rm *resourceManager) updateFunctionCodeSigningConfig(
556558
ctx context.Context,
557559
desired *resource,
@@ -580,7 +582,7 @@ func (rm *resourceManager) updateFunctionCodeSigningConfig(
580582
}
581583

582584
// deleteFunctionCodeSigningConfig calls deleteFunctionCodeSigningConfig to update
583-
// it code signing configuration
585+
// the code signing configuration
584586
func (rm *resourceManager) deleteFunctionCodeSigningConfig(
585587
ctx context.Context,
586588
desired *resource,
@@ -603,11 +605,16 @@ func (rm *resourceManager) deleteFunctionCodeSigningConfig(
603605
return nil
604606
}
605607

606-
// getFunctionConcurrency will describe the fields that are not return by GetFunctionConcurrency calls
607-
func (rm *resourceManager) getFunctionConcurrency(
608+
// setFunctionConcurrency sets the concurrency fields
609+
// for the Function resource
610+
func (rm *resourceManager) setFunctionConcurrency(
608611
ctx context.Context,
609612
ko *svcapitypes.Function,
610613
) (err error) {
614+
rlog := ackrtlog.FromContext(ctx)
615+
exit := rlog.Trace("rm.setFunctionConcurrency")
616+
defer exit(err)
617+
611618
var getFunctionConcurrencyOutput *svcsdk.GetFunctionConcurrencyOutput
612619
getFunctionConcurrencyOutput, err = rm.sdkapi.GetFunctionConcurrencyWithContext(
613620
ctx,
@@ -624,12 +631,16 @@ func (rm *resourceManager) getFunctionConcurrency(
624631
return nil
625632
}
626633

627-
// getFunctionCodeSigningConfig will describe the code signing
634+
// setFunctionCodeSigningConfig sets the code signing
628635
// fields for the Function resource
629-
func (rm *resourceManager) getFunctionCodeSigningConfig(
636+
func (rm *resourceManager) setFunctionCodeSigningConfig(
630637
ctx context.Context,
631638
ko *svcapitypes.Function,
632639
) (err error) {
640+
rlog := ackrtlog.FromContext(ctx)
641+
exit := rlog.Trace("rm.setFunctionCodeSigningConfig")
642+
defer exit(err)
643+
633644
var getFunctionCodeSigningConfigOutput *svcsdk.GetFunctionCodeSigningConfigOutput
634645
getFunctionCodeSigningConfigOutput, err = rm.sdkapi.GetFunctionCodeSigningConfigWithContext(
635646
ctx,
@@ -649,62 +660,30 @@ func (rm *resourceManager) getFunctionCodeSigningConfig(
649660
func (rm *resourceManager) setFunctionEventInvokeConfigFromResponse(
650661
ko *svcapitypes.Function,
651662
getFunctionEventInvokeConfigOutput *svcsdk.GetFunctionEventInvokeConfigOutput,
652-
apiError error,
653-
) (err error) {
663+
) {
664+
// creating FunctionEventInvokeConfig object to store the values returned from `Get` call
665+
cloudFunctionEventInvokeConfig := &svcapitypes.PutFunctionEventInvokeConfigInput{}
666+
cloudFunctionEventInvokeConfig.DestinationConfig = &svcapitypes.DestinationConfig{}
667+
cloudFunctionEventInvokeConfig.DestinationConfig.OnFailure = &svcapitypes.OnFailure{}
668+
cloudFunctionEventInvokeConfig.DestinationConfig.OnSuccess = &svcapitypes.OnSuccess{}
669+
cloudFunctionEventInvokeConfig.DestinationConfig.OnFailure.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnFailure.Destination
670+
cloudFunctionEventInvokeConfig.DestinationConfig.OnSuccess.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnSuccess.Destination
671+
cloudFunctionEventInvokeConfig.MaximumEventAgeInSeconds = getFunctionEventInvokeConfigOutput.MaximumEventAgeInSeconds
672+
cloudFunctionEventInvokeConfig.MaximumRetryAttempts = getFunctionEventInvokeConfigOutput.MaximumRetryAttempts
673+
ko.Spec.FunctionEventInvokeConfig = cloudFunctionEventInvokeConfig
654674

655-
if apiError != nil {
656-
if awserr, ok := ackerr.AWSError(apiError); ok && (awserr.Code() == "EventInvokeConfigNotFoundException" || awserr.Code() == "ResourceNotFoundException") {
657-
ko.Spec.FunctionEventInvokeConfig = nil
658-
} else {
659-
return apiError
660-
}
661-
} else {
662-
if ko.Spec.FunctionEventInvokeConfig != nil {
663-
if getFunctionEventInvokeConfigOutput.DestinationConfig != nil {
664-
if getFunctionEventInvokeConfigOutput.DestinationConfig.OnFailure != nil {
665-
if getFunctionEventInvokeConfigOutput.DestinationConfig.OnFailure.Destination != nil {
666-
ko.Spec.FunctionEventInvokeConfig.DestinationConfig.OnFailure.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnFailure.Destination
667-
}
668-
}
669-
if getFunctionEventInvokeConfigOutput.DestinationConfig.OnSuccess != nil {
670-
if getFunctionEventInvokeConfigOutput.DestinationConfig.OnSuccess.Destination != nil {
671-
ko.Spec.FunctionEventInvokeConfig.DestinationConfig.OnSuccess.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnSuccess.Destination
672-
}
673-
}
674-
} else {
675-
ko.Spec.FunctionEventInvokeConfig.DestinationConfig = nil
676-
}
677-
if getFunctionEventInvokeConfigOutput.MaximumEventAgeInSeconds != nil {
678-
ko.Spec.FunctionEventInvokeConfig.MaximumEventAgeInSeconds = getFunctionEventInvokeConfigOutput.MaximumEventAgeInSeconds
679-
} else {
680-
ko.Spec.FunctionEventInvokeConfig.MaximumEventAgeInSeconds = nil
681-
}
682-
if getFunctionEventInvokeConfigOutput.DestinationConfig != nil {
683-
ko.Spec.FunctionEventInvokeConfig.MaximumRetryAttempts = getFunctionEventInvokeConfigOutput.MaximumRetryAttempts
684-
} else {
685-
ko.Spec.FunctionEventInvokeConfig.MaximumRetryAttempts = nil
686-
}
687-
} else {
688-
cloudFunctionEventInvokeConfig := &svcapitypes.PutFunctionEventInvokeConfigInput{}
689-
cloudFunctionEventInvokeConfig.DestinationConfig = &svcapitypes.DestinationConfig{}
690-
cloudFunctionEventInvokeConfig.DestinationConfig.OnFailure = &svcapitypes.OnFailure{}
691-
cloudFunctionEventInvokeConfig.DestinationConfig.OnSuccess = &svcapitypes.OnSuccess{}
692-
cloudFunctionEventInvokeConfig.DestinationConfig.OnFailure.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnFailure.Destination
693-
cloudFunctionEventInvokeConfig.DestinationConfig.OnSuccess.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnSuccess.Destination
694-
cloudFunctionEventInvokeConfig.MaximumEventAgeInSeconds = getFunctionEventInvokeConfigOutput.MaximumEventAgeInSeconds
695-
cloudFunctionEventInvokeConfig.MaximumRetryAttempts = getFunctionEventInvokeConfigOutput.MaximumRetryAttempts
696-
ko.Spec.FunctionEventInvokeConfig = cloudFunctionEventInvokeConfig
697-
}
698-
}
699-
return nil
700675
}
701676

702-
// getFunctionEventInvokeConfig will describe the fields that are
703-
// custom to the Function resource
704-
func (rm *resourceManager) getFunctionEventInvokeConfig(
677+
// setFunctionEventInvokeConfig sets the fields to set asynchronous invocation
678+
// for Function resource
679+
func (rm *resourceManager) setFunctionEventInvokeConfig(
705680
ctx context.Context,
706681
ko *svcapitypes.Function,
707682
) (err error) {
683+
rlog := ackrtlog.FromContext(ctx)
684+
exit := rlog.Trace("rm.setFunctionEventInvokeConfig")
685+
defer exit(err)
686+
708687
var getFunctionEventInvokeConfigOutput *svcsdk.GetFunctionEventInvokeConfigOutput
709688
getFunctionEventInvokeConfigOutput, err = rm.sdkapi.GetFunctionEventInvokeConfigWithContext(
710689
ctx,
@@ -714,9 +693,14 @@ func (rm *resourceManager) getFunctionEventInvokeConfig(
714693
)
715694
rm.metrics.RecordAPICall("GET", "GetFunctionEventInvokeConfig", err)
716695

717-
err = rm.setFunctionEventInvokeConfigFromResponse(ko, getFunctionEventInvokeConfigOutput, err)
718696
if err != nil {
719-
return err
697+
if awserr, ok := ackerr.AWSError(err); ok && (awserr.Code() == "EventInvokeConfigNotFoundException" || awserr.Code() == "ResourceNotFoundException") {
698+
ko.Spec.FunctionEventInvokeConfig = nil
699+
} else {
700+
return err
701+
}
702+
} else {
703+
rm.setFunctionEventInvokeConfigFromResponse(ko, getFunctionEventInvokeConfigOutput)
720704
}
721705

722706
return nil
@@ -733,20 +717,20 @@ func (rm *resourceManager) setResourceAdditionalFields(
733717
defer exit(err)
734718

735719
// To set Function Concurrency for the function
736-
err = rm.getFunctionConcurrency(ctx, ko)
720+
err = rm.setFunctionConcurrency(ctx, ko)
737721
if err != nil {
738722
return err
739723
}
740724

741725
// To set Asynchronous Invocations for the function
742-
err = rm.getFunctionEventInvokeConfig(ctx, ko)
726+
err = rm.setFunctionEventInvokeConfig(ctx, ko)
743727
if err != nil {
744728
return err
745729
}
746730

747731
// To set Code Signing Config based on the PackageType for the function
748732
if ko.Spec.PackageType != nil && *ko.Spec.PackageType == "Zip" {
749-
err = rm.getFunctionCodeSigningConfig(ctx, ko)
733+
err = rm.setFunctionCodeSigningConfig(ctx, ko)
750734
if err != nil {
751735
return err
752736
}

test/e2e/tests/test_alias.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,17 @@ def test_function_event_invoke_config(self, lambda_client, lambda_function):
335335
assert function_event_invoke_config["MaximumEventAgeInSeconds"] == 200
336336
assert function_event_invoke_config["MaximumRetryAttempts"] == 2
337337

338+
# Delete FunctionEventInvokeConfig
339+
cr = k8s.wait_resource_consumed_by_controller(ref)
340+
cr["spec"]["functionEventInvokeConfig"] = None
341+
342+
# Patch k8s resource
343+
k8s.patch_custom_resource(ref, cr)
344+
time.sleep(UPDATE_WAIT_AFTER_SECONDS)
345+
346+
# Check if FunctionEventInvokeConfig is deleted
347+
assert not lambda_validator.get_function_event_invoke_config_alias(lambda_function_name,resource_name)
348+
338349
# Delete k8s resource
339350
_, deleted = k8s.delete_custom_resource(ref)
340351
assert deleted

0 commit comments

Comments
 (0)