From f99dac599fd2e7cc2b301cd6ad19f256c5449797 Mon Sep 17 00:00:00 2001 From: Mallikarjunadevops Date: Mon, 1 Jun 2026 22:50:37 -0400 Subject: [PATCH] fix(lambda): remove empty DestinationConfig from EventSourceMapping Fixes aws-controllers-k8s/community#2865 When creating an EventSourceMapping without specifying a DestinationConfig, the AWS Lambda API returns a DestinationConfig containing empty OnFailure or OnSuccess structs. The controller's ReadOne logic previously copied this empty structure into the resource's Spec, causing the Kubernetes API Server to persist the invalid empty config as a default value. During subsequent reconciliations, the controller would then attempt to update the resource by sending this empty config back to AWS, resulting in an InvalidParameterValueException. This fix injects hooks into the Create, ReadOne, and Update paths to detect and nil-out empty DestinationConfig blocks, preventing them from being saved to Kubernetes or sent to AWS. --- generator.yaml | 8 ++++ pkg/resource/event_source_mapping/sdk.go | 44 +++++++++++++++++++ .../clean_destination_config.go.tpl | 11 +++++ .../sdk_update_pre_build_request.go.tpl | 11 +++++ 4 files changed, 74 insertions(+) create mode 100644 templates/hooks/eventsourcemapping/clean_destination_config.go.tpl create mode 100644 templates/hooks/eventsourcemapping/sdk_update_pre_build_request.go.tpl diff --git a/generator.yaml b/generator.yaml index b44d8dc7..7f1e5fe0 100644 --- a/generator.yaml +++ b/generator.yaml @@ -245,8 +245,16 @@ resources: hooks: delta_pre_compare: code: customPreCompare(delta, a, b) + sdk_read_one_post_set_output: + template_path: hooks/eventsourcemapping/clean_destination_config.go.tpl + sdk_create_post_set_output: + template_path: hooks/eventsourcemapping/clean_destination_config.go.tpl + sdk_update_post_set_output: + template_path: hooks/eventsourcemapping/clean_destination_config.go.tpl sdk_update_post_build_request: template_path: hooks/eventsourcemapping/sdk_update_post_build_request.go.tpl + sdk_update_pre_build_request: + template_path: hooks/eventsourcemapping/sdk_update_pre_build_request.go.tpl tags: ignore: true FunctionUrlConfig: diff --git a/pkg/resource/event_source_mapping/sdk.go b/pkg/resource/event_source_mapping/sdk.go index 247fffe4..4cb99035 100644 --- a/pkg/resource/event_source_mapping/sdk.go +++ b/pkg/resource/event_source_mapping/sdk.go @@ -371,6 +371,17 @@ func (rm *resourceManager) sdkFind( } rm.setStatusDefaults(ko) + if ko.Spec.DestinationConfig != nil { + if ko.Spec.DestinationConfig.OnFailure != nil && ko.Spec.DestinationConfig.OnFailure.Destination == nil { + ko.Spec.DestinationConfig.OnFailure = nil + } + if ko.Spec.DestinationConfig.OnSuccess != nil && ko.Spec.DestinationConfig.OnSuccess.Destination == nil { + ko.Spec.DestinationConfig.OnSuccess = nil + } + if ko.Spec.DestinationConfig.OnFailure == nil && ko.Spec.DestinationConfig.OnSuccess == nil { + ko.Spec.DestinationConfig = nil + } + } return &resource{ko}, nil } @@ -706,6 +717,17 @@ func (rm *resourceManager) sdkCreate( } rm.setStatusDefaults(ko) + if ko.Spec.DestinationConfig != nil { + if ko.Spec.DestinationConfig.OnFailure != nil && ko.Spec.DestinationConfig.OnFailure.Destination == nil { + ko.Spec.DestinationConfig.OnFailure = nil + } + if ko.Spec.DestinationConfig.OnSuccess != nil && ko.Spec.DestinationConfig.OnSuccess.Destination == nil { + ko.Spec.DestinationConfig.OnSuccess = nil + } + if ko.Spec.DestinationConfig.OnFailure == nil && ko.Spec.DestinationConfig.OnSuccess == nil { + ko.Spec.DestinationConfig = nil + } + } return &resource{ko}, nil } @@ -969,6 +991,17 @@ func (rm *resourceManager) sdkUpdate( defer func() { exit(err) }() + if desired.ko.Spec.DestinationConfig != nil { + if desired.ko.Spec.DestinationConfig.OnFailure != nil && desired.ko.Spec.DestinationConfig.OnFailure.Destination == nil { + desired.ko.Spec.DestinationConfig.OnFailure = nil + } + if desired.ko.Spec.DestinationConfig.OnSuccess != nil && desired.ko.Spec.DestinationConfig.OnSuccess.Destination == nil { + desired.ko.Spec.DestinationConfig.OnSuccess = nil + } + if desired.ko.Spec.DestinationConfig.OnFailure == nil && desired.ko.Spec.DestinationConfig.OnSuccess == nil { + desired.ko.Spec.DestinationConfig = nil + } + } input, err := rm.newUpdateRequestPayload(ctx, desired, delta) if err != nil { return nil, err @@ -1274,6 +1307,17 @@ func (rm *resourceManager) sdkUpdate( } rm.setStatusDefaults(ko) + if ko.Spec.DestinationConfig != nil { + if ko.Spec.DestinationConfig.OnFailure != nil && ko.Spec.DestinationConfig.OnFailure.Destination == nil { + ko.Spec.DestinationConfig.OnFailure = nil + } + if ko.Spec.DestinationConfig.OnSuccess != nil && ko.Spec.DestinationConfig.OnSuccess.Destination == nil { + ko.Spec.DestinationConfig.OnSuccess = nil + } + if ko.Spec.DestinationConfig.OnFailure == nil && ko.Spec.DestinationConfig.OnSuccess == nil { + ko.Spec.DestinationConfig = nil + } + } return &resource{ko}, nil } diff --git a/templates/hooks/eventsourcemapping/clean_destination_config.go.tpl b/templates/hooks/eventsourcemapping/clean_destination_config.go.tpl new file mode 100644 index 00000000..cad282b8 --- /dev/null +++ b/templates/hooks/eventsourcemapping/clean_destination_config.go.tpl @@ -0,0 +1,11 @@ + if ko.Spec.DestinationConfig != nil { + if ko.Spec.DestinationConfig.OnFailure != nil && ko.Spec.DestinationConfig.OnFailure.Destination == nil { + ko.Spec.DestinationConfig.OnFailure = nil + } + if ko.Spec.DestinationConfig.OnSuccess != nil && ko.Spec.DestinationConfig.OnSuccess.Destination == nil { + ko.Spec.DestinationConfig.OnSuccess = nil + } + if ko.Spec.DestinationConfig.OnFailure == nil && ko.Spec.DestinationConfig.OnSuccess == nil { + ko.Spec.DestinationConfig = nil + } + } diff --git a/templates/hooks/eventsourcemapping/sdk_update_pre_build_request.go.tpl b/templates/hooks/eventsourcemapping/sdk_update_pre_build_request.go.tpl new file mode 100644 index 00000000..c6bda277 --- /dev/null +++ b/templates/hooks/eventsourcemapping/sdk_update_pre_build_request.go.tpl @@ -0,0 +1,11 @@ + if desired.ko.Spec.DestinationConfig != nil { + if desired.ko.Spec.DestinationConfig.OnFailure != nil && desired.ko.Spec.DestinationConfig.OnFailure.Destination == nil { + desired.ko.Spec.DestinationConfig.OnFailure = nil + } + if desired.ko.Spec.DestinationConfig.OnSuccess != nil && desired.ko.Spec.DestinationConfig.OnSuccess.Destination == nil { + desired.ko.Spec.DestinationConfig.OnSuccess = nil + } + if desired.ko.Spec.DestinationConfig.OnFailure == nil && desired.ko.Spec.DestinationConfig.OnSuccess == nil { + desired.ko.Spec.DestinationConfig = nil + } + }