Skip to content

Commit 26dab5a

Browse files
committed
Bug fix for EventInvokeConfig in Alias
1 parent 807eecc commit 26dab5a

File tree

4 files changed

+131
-111
lines changed

4 files changed

+131
-111
lines changed

apis/v1alpha1/ack-generate-metadata.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
ack_generate_info:
2-
build_date: "2023-08-02T22:43:32Z"
2+
build_date: "2023-08-17T20:19:22Z"
33
build_hash: e9b68590da73ce9143ba1e4361cebdc1d876c81e
44
go_version: go1.19
55
version: v0.26.1-7-ge9b6859

pkg/resource/alias/hooks.go

Lines changed: 80 additions & 60 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+
// syncFunctionEventInvokeConfig 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
57-
}
58-
if r.ko.Spec.FunctionEventInvokeConfig.MaximumEventAgeInSeconds != nil {
59-
input.MaximumEventAgeInSeconds = aws.Int64(*r.ko.Spec.FunctionEventInvokeConfig.MaximumEventAgeInSeconds)
6065
}
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
73+
}
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)
6479
}
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

@@ -108,7 +123,6 @@ func (rm *resourceManager) getProvisionedConcurrencyConfig(
108123
ctx context.Context,
109124
ko *svcapitypes.Alias,
110125
) (err error) {
111-
112126
var getProvisionedConcurrencyConfigOutput *svcsdk.GetProvisionedConcurrencyConfigOutput
113127
getProvisionedConcurrencyConfigOutput, err = rm.sdkapi.GetProvisionedConcurrencyConfigWithContext(
114128
ctx,
@@ -132,10 +146,43 @@ func (rm *resourceManager) getProvisionedConcurrencyConfig(
132146
return nil
133147
}
134148

135-
func (rm *resourceManager) getFunctionEventInvokeConfig(
149+
func (rm *resourceManager) setFunctionEventInvokeConfigFromResponse(
150+
ko *svcapitypes.Alias,
151+
getFunctionEventInvokeConfigOutput *svcsdk.GetFunctionEventInvokeConfigOutput,
152+
apiError error,
153+
) (err error) {
154+
155+
if apiError != nil {
156+
if awserr, ok := ackerr.AWSError(apiError); ok && (awserr.Code() == "EventInvokeConfigNotFoundException" || awserr.Code() == "ResourceNotFoundException") {
157+
ko.Spec.FunctionEventInvokeConfig = nil
158+
} else {
159+
return apiError
160+
}
161+
} else {
162+
// creating FunctionEventInvokeConfig object to store the values returned from `Get` call
163+
cloudFunctionEventInvokeConfig := &svcapitypes.PutFunctionEventInvokeConfigInput{}
164+
cloudFunctionEventInvokeConfig.DestinationConfig = &svcapitypes.DestinationConfig{}
165+
cloudFunctionEventInvokeConfig.DestinationConfig.OnFailure = &svcapitypes.OnFailure{}
166+
cloudFunctionEventInvokeConfig.DestinationConfig.OnSuccess = &svcapitypes.OnSuccess{}
167+
cloudFunctionEventInvokeConfig.DestinationConfig.OnFailure.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnFailure.Destination
168+
cloudFunctionEventInvokeConfig.DestinationConfig.OnSuccess.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnSuccess.Destination
169+
cloudFunctionEventInvokeConfig.MaximumEventAgeInSeconds = getFunctionEventInvokeConfigOutput.MaximumEventAgeInSeconds
170+
cloudFunctionEventInvokeConfig.MaximumRetryAttempts = getFunctionEventInvokeConfigOutput.MaximumRetryAttempts
171+
ko.Spec.FunctionEventInvokeConfig = cloudFunctionEventInvokeConfig
172+
}
173+
return nil
174+
}
175+
176+
// setFunctionEventInvokeConfig sets the fields to set asynchronous invocation
177+
// for Function's Alias
178+
func (rm *resourceManager) setFunctionEventInvokeConfig(
136179
ctx context.Context,
137180
ko *svcapitypes.Alias,
138181
) (err error) {
182+
rlog := ackrtlog.FromContext(ctx)
183+
exit := rlog.Trace("rm.setFunctionEventInvokeConfig")
184+
defer exit(err)
185+
139186
var getFunctionEventInvokeConfigOutput *svcsdk.GetFunctionEventInvokeConfigOutput
140187
getFunctionEventInvokeConfigOutput, err = rm.sdkapi.GetFunctionEventInvokeConfigWithContext(
141188
ctx,
@@ -144,40 +191,11 @@ func (rm *resourceManager) getFunctionEventInvokeConfig(
144191
Qualifier: ko.Spec.Name,
145192
},
146193
)
147-
148194
rm.metrics.RecordAPICall("GET", "GetFunctionEventInvokeConfig", err)
149195

196+
err = rm.setFunctionEventInvokeConfigFromResponse(ko, getFunctionEventInvokeConfigOutput, err)
150197
if err != nil {
151-
if awserr, ok := ackerr.AWSError(err); ok && (awserr.Code() == "EventInvokeConfigNotFoundException" || awserr.Code() == "ResourceNotFoundException") {
152-
ko.Spec.FunctionEventInvokeConfig = nil
153-
} else {
154-
return err
155-
}
156-
} else {
157-
if getFunctionEventInvokeConfigOutput.DestinationConfig != nil {
158-
if getFunctionEventInvokeConfigOutput.DestinationConfig.OnFailure != nil {
159-
if getFunctionEventInvokeConfigOutput.DestinationConfig.OnFailure.Destination != nil {
160-
ko.Spec.FunctionEventInvokeConfig.DestinationConfig.OnFailure.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnFailure.Destination
161-
}
162-
}
163-
if getFunctionEventInvokeConfigOutput.DestinationConfig.OnSuccess != nil {
164-
if getFunctionEventInvokeConfigOutput.DestinationConfig.OnSuccess.Destination != nil {
165-
ko.Spec.FunctionEventInvokeConfig.DestinationConfig.OnSuccess.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnSuccess.Destination
166-
}
167-
}
168-
} else {
169-
ko.Spec.FunctionEventInvokeConfig.DestinationConfig = nil
170-
}
171-
if getFunctionEventInvokeConfigOutput.MaximumEventAgeInSeconds != nil {
172-
ko.Spec.FunctionEventInvokeConfig.MaximumEventAgeInSeconds = getFunctionEventInvokeConfigOutput.MaximumEventAgeInSeconds
173-
} else {
174-
ko.Spec.FunctionEventInvokeConfig.MaximumEventAgeInSeconds = nil
175-
}
176-
if getFunctionEventInvokeConfigOutput.DestinationConfig != nil {
177-
ko.Spec.FunctionEventInvokeConfig.MaximumRetryAttempts = getFunctionEventInvokeConfigOutput.MaximumRetryAttempts
178-
} else {
179-
ko.Spec.FunctionEventInvokeConfig.MaximumRetryAttempts = nil
180-
}
198+
return err
181199
}
182200

183201
return nil
@@ -191,14 +209,16 @@ func (rm *resourceManager) setResourceAdditionalFields(
191209
exit := rlog.Trace("rm.setResourceAdditionalFields")
192210
defer exit(err)
193211

194-
eic_err := rm.getFunctionEventInvokeConfig(ctx, ko)
195-
if eic_err != nil {
196-
return eic_err
212+
// To set Asynchronous Invocations for the function's alias
213+
err = rm.setFunctionEventInvokeConfig(ctx, ko)
214+
if err != nil {
215+
return err
197216
}
198217

199-
pc_err := rm.getProvisionedConcurrencyConfig(ctx, ko)
200-
if pc_err != nil {
201-
return pc_err
218+
// To set Provisioned Concurrency for the function's alias
219+
err = rm.getProvisionedConcurrencyConfig(ctx, ko)
220+
if err != nil {
221+
return err
202222
}
203223

204224
return nil

pkg/resource/function/hooks.go

Lines changed: 39 additions & 50 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,
@@ -659,52 +670,30 @@ func (rm *resourceManager) setFunctionEventInvokeConfigFromResponse(
659670
return apiError
660671
}
661672
} 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-
}
673+
// creating FunctionEventInvokeConfig object to store the values returned from `Get` call
674+
cloudFunctionEventInvokeConfig := &svcapitypes.PutFunctionEventInvokeConfigInput{}
675+
cloudFunctionEventInvokeConfig.DestinationConfig = &svcapitypes.DestinationConfig{}
676+
cloudFunctionEventInvokeConfig.DestinationConfig.OnFailure = &svcapitypes.OnFailure{}
677+
cloudFunctionEventInvokeConfig.DestinationConfig.OnSuccess = &svcapitypes.OnSuccess{}
678+
cloudFunctionEventInvokeConfig.DestinationConfig.OnFailure.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnFailure.Destination
679+
cloudFunctionEventInvokeConfig.DestinationConfig.OnSuccess.Destination = getFunctionEventInvokeConfigOutput.DestinationConfig.OnSuccess.Destination
680+
cloudFunctionEventInvokeConfig.MaximumEventAgeInSeconds = getFunctionEventInvokeConfigOutput.MaximumEventAgeInSeconds
681+
cloudFunctionEventInvokeConfig.MaximumRetryAttempts = getFunctionEventInvokeConfigOutput.MaximumRetryAttempts
682+
ko.Spec.FunctionEventInvokeConfig = cloudFunctionEventInvokeConfig
698683
}
699684
return nil
700685
}
701686

702-
// getFunctionEventInvokeConfig will describe the fields that are
703-
// custom to the Function resource
704-
func (rm *resourceManager) getFunctionEventInvokeConfig(
687+
// setFunctionEventInvokeConfig sets the fields to set asynchronous invocation
688+
// for Function resource
689+
func (rm *resourceManager) setFunctionEventInvokeConfig(
705690
ctx context.Context,
706691
ko *svcapitypes.Function,
707692
) (err error) {
693+
rlog := ackrtlog.FromContext(ctx)
694+
exit := rlog.Trace("rm.setFunctionEventInvokeConfig")
695+
defer exit(err)
696+
708697
var getFunctionEventInvokeConfigOutput *svcsdk.GetFunctionEventInvokeConfigOutput
709698
getFunctionEventInvokeConfigOutput, err = rm.sdkapi.GetFunctionEventInvokeConfigWithContext(
710699
ctx,
@@ -733,20 +722,20 @@ func (rm *resourceManager) setResourceAdditionalFields(
733722
defer exit(err)
734723

735724
// To set Function Concurrency for the function
736-
err = rm.getFunctionConcurrency(ctx, ko)
725+
err = rm.setFunctionConcurrency(ctx, ko)
737726
if err != nil {
738727
return err
739728
}
740729

741730
// To set Asynchronous Invocations for the function
742-
err = rm.getFunctionEventInvokeConfig(ctx, ko)
731+
err = rm.setFunctionEventInvokeConfig(ctx, ko)
743732
if err != nil {
744733
return err
745734
}
746735

747736
// To set Code Signing Config based on the PackageType for the function
748737
if ko.Spec.PackageType != nil && *ko.Spec.PackageType == "Zip" {
749-
err = rm.getFunctionCodeSigningConfig(ctx, ko)
738+
err = rm.setFunctionCodeSigningConfig(ctx, ko)
750739
if err != nil {
751740
return err
752741
}

test/e2e/tests/test_alias.py

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

327+
# Delete FunctionEventInvokeConfig
328+
cr = k8s.wait_resource_consumed_by_controller(ref)
329+
cr["spec"]["functionEventInvokeConfig"] = None
330+
331+
# Patch k8s resource
332+
k8s.patch_custom_resource(ref, cr)
333+
time.sleep(UPDATE_WAIT_AFTER_SECONDS)
334+
335+
# Check if FunctionEventInvokeConfig is deleted
336+
assert not lambda_validator.get_function_event_invoke_config_alias(lambda_function_name,resource_name)
337+
327338
# Delete k8s resource
328339
_, deleted = k8s.delete_custom_resource(ref)
329340
assert deleted

0 commit comments

Comments
 (0)