Skip to content

Commit cc53cbb

Browse files
committed
Bug fix for Provisioned Concurrency
1 parent 4a0b79d commit cc53cbb

File tree

3 files changed

+53
-20
lines changed

3 files changed

+53
-20
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-07-24T18:19:28Z"
2+
build_date: "2023-08-02T20:25:36Z"
33
build_hash: e9b68590da73ce9143ba1e4361cebdc1d876c81e
44
go_version: go1.19
55
version: v0.26.1-7-ge9b6859

pkg/resource/alias/hooks.go

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ func (rm *resourceManager) syncEventInvokeConfig(
7171
return r, nil
7272
}
7373

74+
// updateProvisionedConcurrency calls `PutProvisionedConcurrencyConfig` to update the fields
75+
// or `DeleteProvisionedConcurrencyConfig` if users removes the fields
7476
func (rm *resourceManager) updateProvisionedConcurrency(
7577
ctx context.Context,
7678
desired *resource,
@@ -80,20 +82,26 @@ func (rm *resourceManager) updateProvisionedConcurrency(
8082
exit := rlog.Trace("rm.updateProvisionedConcurrency")
8183
defer exit(err)
8284

83-
dspec := desired.ko.Spec
84-
input := &svcsdk.PutProvisionedConcurrencyConfigInput{
85-
FunctionName: aws.String(*dspec.FunctionName),
86-
Qualifier: aws.String(*dspec.Name),
85+
// Check if the user deleted the 'ProvisionedConcurrency' configuration
86+
// If yes, delete ProvisionedConcurrencyConfig
87+
if desired.ko.Spec.ProvisionedConcurrencyConfig == nil || desired.ko.Spec.ProvisionedConcurrencyConfig.ProvisionedConcurrentExecutions == nil {
88+
input_delete := &svcsdk.DeleteProvisionedConcurrencyConfigInput{
89+
FunctionName: aws.String(*desired.ko.Spec.FunctionName),
90+
Qualifier: aws.String(*desired.ko.Spec.Name),
91+
}
92+
_, err = rm.sdkapi.DeleteProvisionedConcurrencyConfigWithContext(ctx, input_delete)
93+
rm.metrics.RecordAPICall("DELETE", "DeleteProvisionedConcurrency", err)
94+
if err != nil {
95+
return err
96+
}
97+
return nil
8798
}
8899

89-
if desired.ko.Spec.ProvisionedConcurrencyConfig != nil {
90-
if desired.ko.Spec.ProvisionedConcurrencyConfig.ProvisionedConcurrentExecutions != nil {
91-
input.ProvisionedConcurrentExecutions = aws.Int64(*desired.ko.Spec.ProvisionedConcurrencyConfig.ProvisionedConcurrentExecutions)
92-
} else {
93-
input.ProvisionedConcurrentExecutions = aws.Int64(0)
94-
}
95-
} else {
96-
input.ProvisionedConcurrentExecutions = aws.Int64(0)
100+
dspec := desired.ko.Spec
101+
input := &svcsdk.PutProvisionedConcurrencyConfigInput{
102+
FunctionName: aws.String(*dspec.FunctionName),
103+
Qualifier: aws.String(*dspec.Name),
104+
ProvisionedConcurrentExecutions: aws.Int64(*dspec.ProvisionedConcurrencyConfig.ProvisionedConcurrentExecutions),
97105
}
98106

99107
_, err = rm.sdkapi.PutProvisionedConcurrencyConfigWithContext(ctx, input)
@@ -104,10 +112,15 @@ func (rm *resourceManager) updateProvisionedConcurrency(
104112
return nil
105113
}
106114

107-
func (rm *resourceManager) getProvisionedConcurrencyConfig(
115+
// setProvisionedConcurrencyConfig sets the Provisioned Concurrency
116+
// for the Function's Alias
117+
func (rm *resourceManager) setProvisionedConcurrencyConfig(
108118
ctx context.Context,
109119
ko *svcapitypes.Alias,
110120
) (err error) {
121+
rlog := ackrtlog.FromContext(ctx)
122+
exit := rlog.Trace("rm.setProvisionedConcurrencyConfig")
123+
defer exit(err)
111124

112125
var getProvisionedConcurrencyConfigOutput *svcsdk.GetProvisionedConcurrencyConfigOutput
113126
getProvisionedConcurrencyConfigOutput, err = rm.sdkapi.GetProvisionedConcurrencyConfigWithContext(
@@ -126,12 +139,17 @@ func (rm *resourceManager) getProvisionedConcurrencyConfig(
126139
return err
127140
}
128141
} else {
129-
ko.Spec.ProvisionedConcurrencyConfig.ProvisionedConcurrentExecutions = getProvisionedConcurrencyConfigOutput.RequestedProvisionedConcurrentExecutions
142+
// creating ProvisionedConcurrency object to store the values returned from `Get` call
143+
cloudProvisionedConcurrency := &svcapitypes.PutProvisionedConcurrencyConfigInput{}
144+
cloudProvisionedConcurrency.ProvisionedConcurrentExecutions = getProvisionedConcurrencyConfigOutput.RequestedProvisionedConcurrentExecutions
145+
ko.Spec.ProvisionedConcurrencyConfig = cloudProvisionedConcurrency
130146
}
131147

132148
return nil
133149
}
134150

151+
// getFunctionEventInvokeConfig will describe the fields that are
152+
// custom to the Alias resource
135153
func (rm *resourceManager) getFunctionEventInvokeConfig(
136154
ctx context.Context,
137155
ko *svcapitypes.Alias,
@@ -183,6 +201,8 @@ func (rm *resourceManager) getFunctionEventInvokeConfig(
183201
return nil
184202
}
185203

204+
// setResourceAdditionalFields will describe the fields that are not return by the
205+
// getFunctionConfiguration API call
186206
func (rm *resourceManager) setResourceAdditionalFields(
187207
ctx context.Context,
188208
ko *svcapitypes.Alias,
@@ -191,14 +211,16 @@ func (rm *resourceManager) setResourceAdditionalFields(
191211
exit := rlog.Trace("rm.setResourceAdditionalFields")
192212
defer exit(err)
193213

214+
// To set Asynchronous Invocations for the function's alias
194215
eic_err := rm.getFunctionEventInvokeConfig(ctx, ko)
195216
if eic_err != nil {
196217
return eic_err
197218
}
198219

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

204226
return nil

test/e2e/tests/test_alias.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,17 +245,28 @@ def test_provisioned_concurrency_config(self, lambda_client, lambda_function):
245245
# Check alias exists
246246
assert lambda_validator.alias_exists(resource_name, lambda_function_name)
247247

248-
# Update cr
248+
# Update provisioned_concurrency
249249
cr["spec"]["provisionedConcurrencyConfig"]["provisionedConcurrentExecutions"] = 2
250250

251251
# Patch k8s resource
252252
k8s.patch_custom_resource(ref, cr)
253253
time.sleep(UPDATE_WAIT_AFTER_SECONDS)
254254

255-
#Check function_event_invoke_config update fields
255+
#Check provisioned_concurrency_config update fields
256256
provisioned_concurrency_config = lambda_validator.get_provisioned_concurrency_config(lambda_function_name,resource_name)
257257
assert provisioned_concurrency_config["RequestedProvisionedConcurrentExecutions"] == 2
258258

259+
# Delete provisioned_concurrency from alias
260+
cr = k8s.wait_resource_consumed_by_controller(ref)
261+
cr["spec"]["provisionedConcurrencyConfig"] = None
262+
263+
# Patch k8s resource
264+
k8s.patch_custom_resource(ref, cr)
265+
time.sleep(UPDATE_WAIT_AFTER_SECONDS)
266+
267+
#Check provisioned_concurrency_config is deleted
268+
assert not lambda_validator.get_provisioned_concurrency_config(lambda_function_name, resource_name)
269+
259270
# Delete k8s resource
260271
_, deleted = k8s.delete_custom_resource(ref)
261272
assert deleted

0 commit comments

Comments
 (0)