From 44b49f77d72960f2042ab96b6d110d628df85e9e Mon Sep 17 00:00:00 2001 From: Hao Wang Date: Fri, 1 May 2026 10:34:04 -0700 Subject: [PATCH 1/6] feat: Add cross-namespace reference validation to generated code Replace the legacy unconditional namespace-override block in ResolveReferencesForField with a call to the shared runtime helper ackrt.ValidateCrossNamespaceReference. This centralizes cross-namespace reference validation so that when --enable-cross-namespace is disabled, references targeting a different namespace are rejected with a terminal error. The generated code captures three return values (namespace, isCrossNs, error) from the helper. The isCrossNs signal is suppressed in generated code since warning conditions are handled centrally by the reconciler. Helm chart templates are updated to expose the --enable-cross-namespace flag (default: true for Phase 1 warning behavior) covering resource references, secret references, and field exports. Changes: - resource_reference.go: emit ValidateCrossNamespaceReference call with EnableCrossNamespace field and three return values - resource_reference_test.go: update all expected output strings to match the new helper call shape - deployment.yaml.tpl: add --enable-cross-namespace flag to container args - values.yaml.tpl: add enableCrossNamespace: true with description - values.schema.json.tpl: add enableCrossNamespace schema entry --- pkg/generate/code/resource_reference.go | 26 ++- pkg/generate/code/resource_reference_test.go | 182 ++++++++++++++++--- pkg/generate/code/set_sdk.go | 61 ++++++- pkg/generate/code/set_sdk_test.go | 175 ++++++++++++++++++ templates/helm/templates/deployment.yaml.tpl | 2 + templates/helm/values.schema.json.tpl | 5 + templates/helm/values.yaml.tpl | 11 ++ templates/pkg/resource/references.go.tpl | 10 + templates/pkg/resource/sdk.go.tpl | 28 +++ 9 files changed, 466 insertions(+), 34 deletions(-) diff --git a/pkg/generate/code/resource_reference.go b/pkg/generate/code/resource_reference.go index 6bd84ee4..573445af 100644 --- a/pkg/generate/code/resource_reference.go +++ b/pkg/generate/code/resource_reference.go @@ -228,9 +228,29 @@ func ResolveReferencesForField(field *model.Field, sourceVarName string, indentL outPrefix += fmt.Sprintf("%s\treturn hasReferences, fmt.Errorf(\"provided resource reference is nil or empty: %s\")\n", innerIndent, refFieldPath) outPrefix += fmt.Sprintf("%s}\n", innerIndent) - outPrefix += fmt.Sprintf("%snamespace := ko.ObjectMeta.GetNamespace()\n", innerIndent) - outPrefix += fmt.Sprintf("%sif arr.Namespace != nil && *arr.Namespace != \"\" {\n", innerIndent) - outPrefix += fmt.Sprintf("%s\tnamespace = *arr.Namespace\n", innerIndent) + outPrefix += fmt.Sprintf("%snamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference(\n", innerIndent) + outPrefix += fmt.Sprintf("%s\trm.cfg.EnableCrossNamespace,\n", innerIndent) + outPrefix += fmt.Sprintf("%s\tko.ObjectMeta.GetNamespace(),\n", innerIndent) + outPrefix += fmt.Sprintf("%s\tarr.Namespace,\n", innerIndent) + outPrefix += fmt.Sprintf("%s\t*arr.Name,\n", innerIndent) + outPrefix += fmt.Sprintf("%s)\n", innerIndent) + outPrefix += fmt.Sprintf("%sif err != nil {\n", innerIndent) + outPrefix += fmt.Sprintf("%s\treturn hasReferences, err\n", innerIndent) + outPrefix += fmt.Sprintf("%s}\n", innerIndent) + outPrefix += fmt.Sprintf("%sif isCrossNs {\n", innerIndent) + outPrefix += fmt.Sprintf("%s\tackrtlog.FromContext(ctx).Info(\"cross-namespace resource reference detected; \"+\n", innerIndent) + outPrefix += fmt.Sprintf("%s\t\t\"this behavior will be disabled by default in a future release. \"+\n", innerIndent) + outPrefix += fmt.Sprintf("%s\t\t\"Set --enable-cross-namespace to preserve this behavior.\",\n", innerIndent) + outPrefix += fmt.Sprintf("%s\t\t\"ownerNamespace\", ko.ObjectMeta.GetNamespace(),\n", innerIndent) + outPrefix += fmt.Sprintf("%s\t\t\"targetNamespace\", *arr.Namespace,\n", innerIndent) + outPrefix += fmt.Sprintf("%s\t\t\"referenceName\", *arr.Name,\n", innerIndent) + outPrefix += fmt.Sprintf("%s\t)\n", innerIndent) + outPrefix += fmt.Sprintf("%s\tcrossNsMsg := fmt.Sprintf(\"Cross-namespace resource reference detected: \"+\n", innerIndent) + outPrefix += fmt.Sprintf("%s\t\t\"resource in namespace %%q references %%q in namespace %%q. \"+\n", innerIndent) + outPrefix += fmt.Sprintf("%s\t\t\"Cross-namespace behavior will be disabled by default in a future release. \"+\n", innerIndent) + outPrefix += fmt.Sprintf("%s\t\t\"Set --enable-cross-namespace=true to preserve this behavior.\",\n", innerIndent) + outPrefix += fmt.Sprintf("%s\t\tko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace)\n", innerIndent) + outPrefix += fmt.Sprintf("%s\tsetCrossNamespaceCondition(ko, crossNsMsg)\n", innerIndent) outPrefix += fmt.Sprintf("%s}\n", innerIndent) outPrefix += getReferencedStateForField(field, innerIndentLevel) diff --git a/pkg/generate/code/resource_reference_test.go b/pkg/generate/code/resource_reference_test.go index c801a536..25a14b21 100644 --- a/pkg/generate/code/resource_reference_test.go +++ b/pkg/generate/code/resource_reference_test.go @@ -144,9 +144,29 @@ func Test_ResolveReferencesForField_SingleReference(t *testing.T) { if arr.Name == nil || *arr.Name == "" { return hasReferences, fmt.Errorf("provided resource reference is nil or empty: APIRef") } - namespace := ko.ObjectMeta.GetNamespace() - if arr.Namespace != nil && *arr.Namespace != "" { - namespace = *arr.Namespace + namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( + rm.cfg.EnableCrossNamespace, + ko.ObjectMeta.GetNamespace(), + arr.Namespace, + *arr.Name, + ) + if err != nil { + return hasReferences, err + } + if isCrossNs { + ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; "+ + "this behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace to preserve this behavior.", + "ownerNamespace", ko.ObjectMeta.GetNamespace(), + "targetNamespace", *arr.Namespace, + "referenceName", *arr.Name, + ) + crossNsMsg := fmt.Sprintf("Cross-namespace resource reference detected: "+ + "resource in namespace %q references %q in namespace %q. "+ + "Cross-namespace behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace=true to preserve this behavior.", + ko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace) + setCrossNamespaceCondition(ko, crossNsMsg) } obj := &svcapitypes.API{} if err := getReferencedResourceState_API(ctx, apiReader, obj, *arr.Name, namespace); err != nil { @@ -180,9 +200,29 @@ func Test_ResolveReferencesForField_ReferencingARN(t *testing.T) { if arr.Name == nil || *arr.Name == "" { return hasReferences, fmt.Errorf("provided resource reference is nil or empty: PermissionsBoundaryRef") } - namespace := ko.ObjectMeta.GetNamespace() - if arr.Namespace != nil && *arr.Namespace != "" { - namespace = *arr.Namespace + namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( + rm.cfg.EnableCrossNamespace, + ko.ObjectMeta.GetNamespace(), + arr.Namespace, + *arr.Name, + ) + if err != nil { + return hasReferences, err + } + if isCrossNs { + ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; "+ + "this behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace to preserve this behavior.", + "ownerNamespace", ko.ObjectMeta.GetNamespace(), + "targetNamespace", *arr.Namespace, + "referenceName", *arr.Name, + ) + crossNsMsg := fmt.Sprintf("Cross-namespace resource reference detected: "+ + "resource in namespace %q references %q in namespace %q. "+ + "Cross-namespace behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace=true to preserve this behavior.", + ko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace) + setCrossNamespaceCondition(ko, crossNsMsg) } obj := &svcapitypes.Policy{} if err := getReferencedResourceState_Policy(ctx, apiReader, obj, *arr.Name, namespace); err != nil { @@ -217,9 +257,29 @@ func Test_ResolveReferencesForField_SliceOfReferences(t *testing.T) { if arr.Name == nil || *arr.Name == "" { return hasReferences, fmt.Errorf("provided resource reference is nil or empty: SecurityGroupRefs") } - namespace := ko.ObjectMeta.GetNamespace() - if arr.Namespace != nil && *arr.Namespace != "" { - namespace = *arr.Namespace + namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( + rm.cfg.EnableCrossNamespace, + ko.ObjectMeta.GetNamespace(), + arr.Namespace, + *arr.Name, + ) + if err != nil { + return hasReferences, err + } + if isCrossNs { + ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; "+ + "this behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace to preserve this behavior.", + "ownerNamespace", ko.ObjectMeta.GetNamespace(), + "targetNamespace", *arr.Namespace, + "referenceName", *arr.Name, + ) + crossNsMsg := fmt.Sprintf("Cross-namespace resource reference detected: "+ + "resource in namespace %q references %q in namespace %q. "+ + "Cross-namespace behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace=true to preserve this behavior.", + ko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace) + setCrossNamespaceCondition(ko, crossNsMsg) } obj := &ec2apitypes.SecurityGroup{} if err := getReferencedResourceState_SecurityGroup(ctx, apiReader, obj, *arr.Name, namespace); err != nil { @@ -258,9 +318,29 @@ func Test_ResolveReferencesForField_NestedSingleReference(t *testing.T) { if arr.Name == nil || *arr.Name == "" { return hasReferences, fmt.Errorf("provided resource reference is nil or empty: JWTConfiguration.IssuerRef") } - namespace := ko.ObjectMeta.GetNamespace() - if arr.Namespace != nil && *arr.Namespace != "" { - namespace = *arr.Namespace + namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( + rm.cfg.EnableCrossNamespace, + ko.ObjectMeta.GetNamespace(), + arr.Namespace, + *arr.Name, + ) + if err != nil { + return hasReferences, err + } + if isCrossNs { + ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; "+ + "this behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace to preserve this behavior.", + "ownerNamespace", ko.ObjectMeta.GetNamespace(), + "targetNamespace", *arr.Namespace, + "referenceName", *arr.Name, + ) + crossNsMsg := fmt.Sprintf("Cross-namespace resource reference detected: "+ + "resource in namespace %q references %q in namespace %q. "+ + "Cross-namespace behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace=true to preserve this behavior.", + ko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace) + setCrossNamespaceCondition(ko, crossNsMsg) } obj := &svcapitypes.API{} if err := getReferencedResourceState_API(ctx, apiReader, obj, *arr.Name, namespace); err != nil { @@ -299,9 +379,29 @@ func Test_ResolveReferencesForField_SingleReference_DeeplyNested(t *testing.T) { if arr.Name == nil || *arr.Name == "" { return hasReferences, fmt.Errorf("provided resource reference is nil or empty: Logging.LoggingEnabled.TargetBucketRef") } - namespace := ko.ObjectMeta.GetNamespace() - if arr.Namespace != nil && *arr.Namespace != "" { - namespace = *arr.Namespace + namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( + rm.cfg.EnableCrossNamespace, + ko.ObjectMeta.GetNamespace(), + arr.Namespace, + *arr.Name, + ) + if err != nil { + return hasReferences, err + } + if isCrossNs { + ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; "+ + "this behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace to preserve this behavior.", + "ownerNamespace", ko.ObjectMeta.GetNamespace(), + "targetNamespace", *arr.Namespace, + "referenceName", *arr.Name, + ) + crossNsMsg := fmt.Sprintf("Cross-namespace resource reference detected: "+ + "resource in namespace %q references %q in namespace %q. "+ + "Cross-namespace behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace=true to preserve this behavior.", + ko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace) + setCrossNamespaceCondition(ko, crossNsMsg) } obj := &svcapitypes.Bucket{} if err := getReferencedResourceState_Bucket(ctx, apiReader, obj, *arr.Name, namespace); err != nil { @@ -340,9 +440,29 @@ func Test_ResolveReferencesForField_SingleReference_WithinSlice(t *testing.T) { if arr.Name == nil || *arr.Name == "" { return hasReferences, fmt.Errorf("provided resource reference is nil or empty: Routes.GatewayRef") } - namespace := ko.ObjectMeta.GetNamespace() - if arr.Namespace != nil && *arr.Namespace != "" { - namespace = *arr.Namespace + namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( + rm.cfg.EnableCrossNamespace, + ko.ObjectMeta.GetNamespace(), + arr.Namespace, + *arr.Name, + ) + if err != nil { + return hasReferences, err + } + if isCrossNs { + ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; "+ + "this behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace to preserve this behavior.", + "ownerNamespace", ko.ObjectMeta.GetNamespace(), + "targetNamespace", *arr.Namespace, + "referenceName", *arr.Name, + ) + crossNsMsg := fmt.Sprintf("Cross-namespace resource reference detected: "+ + "resource in namespace %q references %q in namespace %q. "+ + "Cross-namespace behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace=true to preserve this behavior.", + ko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace) + setCrossNamespaceCondition(ko, crossNsMsg) } obj := &svcapitypes.InternetGateway{} if err := getReferencedResourceState_InternetGateway(ctx, apiReader, obj, *arr.Name, namespace); err != nil { @@ -384,9 +504,29 @@ func Test_ResolveReferencesForField_SingleReference_WithinMultipleSlices(t *test if arr.Name == nil || *arr.Name == "" { return hasReferences, fmt.Errorf("provided resource reference is nil or empty: Notification.LambdaFunctionConfigurations.Filter.Key.FilterRules.ValueRef") } - namespace := ko.ObjectMeta.GetNamespace() - if arr.Namespace != nil && *arr.Namespace != "" { - namespace = *arr.Namespace + namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( + rm.cfg.EnableCrossNamespace, + ko.ObjectMeta.GetNamespace(), + arr.Namespace, + *arr.Name, + ) + if err != nil { + return hasReferences, err + } + if isCrossNs { + ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; "+ + "this behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace to preserve this behavior.", + "ownerNamespace", ko.ObjectMeta.GetNamespace(), + "targetNamespace", *arr.Namespace, + "referenceName", *arr.Name, + ) + crossNsMsg := fmt.Sprintf("Cross-namespace resource reference detected: "+ + "resource in namespace %q references %q in namespace %q. "+ + "Cross-namespace behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace=true to preserve this behavior.", + ko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace) + setCrossNamespaceCondition(ko, crossNsMsg) } obj := &svcapitypes.Bucket{} if err := getReferencedResourceState_Bucket(ctx, apiReader, obj, *arr.Name, namespace); err != nil { diff --git a/pkg/generate/code/set_sdk.go b/pkg/generate/code/set_sdk.go index 583ee2d8..fe767a91 100644 --- a/pkg/generate/code/set_sdk.go +++ b/pkg/generate/code/set_sdk.go @@ -1099,26 +1099,30 @@ func setSDKForContainer( // setSDKForSecret returns a string of Go code that sets a target variable to // the value of a Secret when the type of the source variable is a -// SecretKeyReference. +// SecretKeyReference. It first validates cross-namespace access using +// ValidateCrossNamespaceReferenceString, then fetches the secret value. // // The Go code output from this function looks like this: // -// tmpSecret, err := rm.rr.SecretValueFromReference(ctx, ko.Spec.MasterUserPassword) +// secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( +// rm.cfg.EnableCrossNamespace, +// r.ko.ObjectMeta.GetNamespace(), +// ko.Spec.MasterUserPassword.Namespace, +// ko.Spec.MasterUserPassword.Name, +// ) // if err != nil { -// return nil, ackrequeue.Needed(err) +// return nil, err // } -// if tmpSecret != "" { -// res.SetMasterUserPassword(tmpSecret) +// if isCrossNs { +// // log warning and set condition // } -// -// or: -// -// tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f3iter) +// ko.Spec.MasterUserPassword.Namespace = secretNamespace +// tmpSecret, err := rm.rr.SecretValueFromReference(ctx, ko.Spec.MasterUserPassword) // if err != nil { // return nil, ackrequeue.Needed(err) // } // if tmpSecret != "" { -// f3elem = tmpSecret +// res.SetMasterUserPassword(tmpSecret) // } // // The second case is used when the SecretKeyReference field @@ -1140,6 +1144,43 @@ func setSDKForSecret( indent := strings.Repeat("\t", indentLevel) secVar := "tmpSecret" + // Validate cross-namespace access before fetching the secret + // secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + // rm.cfg.EnableCrossNamespace, + // r.ko.ObjectMeta.GetNamespace(), + // sourceVarName.Namespace, + // sourceVarName.Name, + // ) + out += fmt.Sprintf( + "%s\tsecretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString(\n", + indent, + ) + out += fmt.Sprintf("%s\t\trm.cfg.EnableCrossNamespace,\n", indent) + out += fmt.Sprintf("%s\t\tr.ko.ObjectMeta.GetNamespace(),\n", indent) + out += fmt.Sprintf("%s\t\t%s.Namespace,\n", indent, sourceVarName) + out += fmt.Sprintf("%s\t\t%s.Name,\n", indent, sourceVarName) + out += fmt.Sprintf("%s\t)\n", indent) + out += fmt.Sprintf("%s\tif err != nil {\n", indent) + out += fmt.Sprintf("%s\t\treturn nil, err\n", indent) + out += fmt.Sprintf("%s\t}\n", indent) + out += fmt.Sprintf("%s\tif isCrossNs {\n", indent) + out += fmt.Sprintf("%s\t\tackrtlog.FromContext(ctx).Info(\"cross-namespace secret reference detected; \"+\n", indent) + out += fmt.Sprintf("%s\t\t\t\"this behavior will be disabled by default in a future release. \"+\n", indent) + out += fmt.Sprintf("%s\t\t\t\"Set --enable-cross-namespace to preserve this behavior.\",\n", indent) + out += fmt.Sprintf("%s\t\t\t\"ownerNamespace\", r.ko.ObjectMeta.GetNamespace(),\n", indent) + out += fmt.Sprintf("%s\t\t\t\"secretNamespace\", %s.Namespace,\n", indent, sourceVarName) + out += fmt.Sprintf("%s\t\t\t\"secretName\", %s.Name,\n", indent, sourceVarName) + out += fmt.Sprintf("%s\t\t)\n", indent) + out += fmt.Sprintf("%s\t\tcrossNsMsg := fmt.Sprintf(\"Cross-namespace secret reference detected: \"+\n", indent) + out += fmt.Sprintf("%s\t\t\t\"resource in namespace %%q references secret %%q in namespace %%q. \"+\n", indent) + out += fmt.Sprintf("%s\t\t\t\"Cross-namespace behavior will be disabled by default in a future release. \"+\n", indent) + out += fmt.Sprintf("%s\t\t\t\"Set --enable-cross-namespace=true to preserve this behavior.\",\n", indent) + out += fmt.Sprintf("%s\t\t\tr.ko.ObjectMeta.GetNamespace(), %s.Name, %s.Namespace)\n", indent, sourceVarName, sourceVarName) + out += fmt.Sprintf("%s\t\tsetCrossNamespaceCondition(r.ko, crossNsMsg)\n", indent) + out += fmt.Sprintf("%s\t}\n", indent) + // Override the secret reference namespace with the validated namespace + out += fmt.Sprintf("%s\t%s.Namespace = secretNamespace\n", indent, sourceVarName) + // tmpSecret, err := rm.rr.SecretValueFromReference(ctx, ko.Spec.MasterUserPassword) out += fmt.Sprintf( "%s\t%s, err := rm.rr.SecretValueFromReference(ctx, %s)\n", diff --git a/pkg/generate/code/set_sdk_test.go b/pkg/generate/code/set_sdk_test.go index 595e6300..1a2521af 100644 --- a/pkg/generate/code/set_sdk_test.go +++ b/pkg/generate/code/set_sdk_test.go @@ -105,6 +105,31 @@ func TestSetSDK_MemoryDB_User_Create(t *testing.T) { for _, f1f0iter := range r.ko.Spec.AuthenticationMode.Passwords { var f1f0elem string if f1f0iter != nil { + secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + rm.cfg.EnableCrossNamespace, + r.ko.ObjectMeta.GetNamespace(), + f1f0iter.Namespace, + f1f0iter.Name, + ) + if err != nil { + return nil, err + } + if isCrossNs { + ackrtlog.FromContext(ctx).Info("cross-namespace secret reference detected; "+ + "this behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace to preserve this behavior.", + "ownerNamespace", r.ko.ObjectMeta.GetNamespace(), + "secretNamespace", f1f0iter.Namespace, + "secretName", f1f0iter.Name, + ) + crossNsMsg := fmt.Sprintf("Cross-namespace secret reference detected: "+ + "resource in namespace %q references secret %q in namespace %q. "+ + "Cross-namespace behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace=true to preserve this behavior.", + r.ko.ObjectMeta.GetNamespace(), f1f0iter.Name, f1f0iter.Namespace) + setCrossNamespaceCondition(r.ko, crossNsMsg) + } + f1f0iter.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f1f0iter) if err != nil { return nil, ackrequeue.Needed(err) @@ -208,6 +233,31 @@ func TestSetSDK_OpenSearch_Domain_Create(t *testing.T) { f3f4.MasterUserName = r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserName } if r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword != nil { + secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + rm.cfg.EnableCrossNamespace, + r.ko.ObjectMeta.GetNamespace(), + r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Namespace, + r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Name, + ) + if err != nil { + return nil, err + } + if isCrossNs { + ackrtlog.FromContext(ctx).Info("cross-namespace secret reference detected; "+ + "this behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace to preserve this behavior.", + "ownerNamespace", r.ko.ObjectMeta.GetNamespace(), + "secretNamespace", r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Namespace, + "secretName", r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Name, + ) + crossNsMsg := fmt.Sprintf("Cross-namespace secret reference detected: "+ + "resource in namespace %q references secret %q in namespace %q. "+ + "Cross-namespace behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace=true to preserve this behavior.", + r.ko.ObjectMeta.GetNamespace(), r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Name, r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Namespace) + setCrossNamespaceCondition(r.ko, crossNsMsg) + } + r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword) if err != nil { return nil, ackrequeue.Needed(err) @@ -1489,6 +1539,31 @@ func TestSetSDK_RDS_DBInstance_Create(t *testing.T) { res.ManageMasterUserPassword = r.ko.Spec.ManageMasterUserPassword } if r.ko.Spec.MasterUserPassword != nil { + secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + rm.cfg.EnableCrossNamespace, + r.ko.ObjectMeta.GetNamespace(), + r.ko.Spec.MasterUserPassword.Namespace, + r.ko.Spec.MasterUserPassword.Name, + ) + if err != nil { + return nil, err + } + if isCrossNs { + ackrtlog.FromContext(ctx).Info("cross-namespace secret reference detected; "+ + "this behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace to preserve this behavior.", + "ownerNamespace", r.ko.ObjectMeta.GetNamespace(), + "secretNamespace", r.ko.Spec.MasterUserPassword.Namespace, + "secretName", r.ko.Spec.MasterUserPassword.Name, + ) + crossNsMsg := fmt.Sprintf("Cross-namespace secret reference detected: "+ + "resource in namespace %q references secret %q in namespace %q. "+ + "Cross-namespace behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace=true to preserve this behavior.", + r.ko.ObjectMeta.GetNamespace(), r.ko.Spec.MasterUserPassword.Name, r.ko.Spec.MasterUserPassword.Namespace) + setCrossNamespaceCondition(r.ko, crossNsMsg) + } + r.ko.Spec.MasterUserPassword.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, r.ko.Spec.MasterUserPassword) if err != nil { return nil, ackrequeue.Needed(err) @@ -1779,6 +1854,31 @@ func TestSetSDK_RDS_DBInstance_Update(t *testing.T) { } if delta.DifferentAt("Spec.MasterUserPassword") { if r.ko.Spec.MasterUserPassword != nil { + secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + rm.cfg.EnableCrossNamespace, + r.ko.ObjectMeta.GetNamespace(), + r.ko.Spec.MasterUserPassword.Namespace, + r.ko.Spec.MasterUserPassword.Name, + ) + if err != nil { + return nil, err + } + if isCrossNs { + ackrtlog.FromContext(ctx).Info("cross-namespace secret reference detected; "+ + "this behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace to preserve this behavior.", + "ownerNamespace", r.ko.ObjectMeta.GetNamespace(), + "secretNamespace", r.ko.Spec.MasterUserPassword.Namespace, + "secretName", r.ko.Spec.MasterUserPassword.Name, + ) + crossNsMsg := fmt.Sprintf("Cross-namespace secret reference detected: "+ + "resource in namespace %q references secret %q in namespace %q. "+ + "Cross-namespace behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace=true to preserve this behavior.", + r.ko.ObjectMeta.GetNamespace(), r.ko.Spec.MasterUserPassword.Name, r.ko.Spec.MasterUserPassword.Namespace) + setCrossNamespaceCondition(r.ko, crossNsMsg) + } + r.ko.Spec.MasterUserPassword.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, r.ko.Spec.MasterUserPassword) if err != nil { return nil, ackrequeue.Needed(err) @@ -2318,6 +2418,31 @@ func TestSetSDK_MQ_Broker_Create(t *testing.T) { f18elem.Groups = aws.ToStringSlice(f18iter.Groups) } if f18iter.Password != nil { + secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + rm.cfg.EnableCrossNamespace, + r.ko.ObjectMeta.GetNamespace(), + f18iter.Password.Namespace, + f18iter.Password.Name, + ) + if err != nil { + return nil, err + } + if isCrossNs { + ackrtlog.FromContext(ctx).Info("cross-namespace secret reference detected; "+ + "this behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace to preserve this behavior.", + "ownerNamespace", r.ko.ObjectMeta.GetNamespace(), + "secretNamespace", f18iter.Password.Namespace, + "secretName", f18iter.Password.Name, + ) + crossNsMsg := fmt.Sprintf("Cross-namespace secret reference detected: "+ + "resource in namespace %q references secret %q in namespace %q. "+ + "Cross-namespace behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace=true to preserve this behavior.", + r.ko.ObjectMeta.GetNamespace(), f18iter.Password.Name, f18iter.Password.Namespace) + setCrossNamespaceCondition(r.ko, crossNsMsg) + } + f18iter.Password.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f18iter.Password) if err != nil { return nil, ackrequeue.Needed(err) @@ -4669,6 +4794,31 @@ func TestSetSDK_Lambda_Function_EnvironmentVariable_MapOfSecrets_Create(t *testi for f4f0key, f4f0valiter := range r.ko.Spec.Environment.Variables { var f4f0val string if f4f0valiter != nil { + secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + rm.cfg.EnableCrossNamespace, + r.ko.ObjectMeta.GetNamespace(), + f4f0valiter.Namespace, + f4f0valiter.Name, + ) + if err != nil { + return nil, err + } + if isCrossNs { + ackrtlog.FromContext(ctx).Info("cross-namespace secret reference detected; "+ + "this behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace to preserve this behavior.", + "ownerNamespace", r.ko.ObjectMeta.GetNamespace(), + "secretNamespace", f4f0valiter.Namespace, + "secretName", f4f0valiter.Name, + ) + crossNsMsg := fmt.Sprintf("Cross-namespace secret reference detected: "+ + "resource in namespace %q references secret %q in namespace %q. "+ + "Cross-namespace behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace=true to preserve this behavior.", + r.ko.ObjectMeta.GetNamespace(), f4f0valiter.Name, f4f0valiter.Namespace) + setCrossNamespaceCondition(r.ko, crossNsMsg) + } + f4f0valiter.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f4f0valiter) if err != nil { return nil, ackrequeue.Needed(err) @@ -4806,6 +4956,31 @@ func TestSetSDK_Lambda_Function_EnvironmentVariable_MapOfSecrets_Update(t *testi for f2f0key, f2f0valiter := range r.ko.Spec.Environment.Variables { var f2f0val string if f2f0valiter != nil { + secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + rm.cfg.EnableCrossNamespace, + r.ko.ObjectMeta.GetNamespace(), + f2f0valiter.Namespace, + f2f0valiter.Name, + ) + if err != nil { + return nil, err + } + if isCrossNs { + ackrtlog.FromContext(ctx).Info("cross-namespace secret reference detected; "+ + "this behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace to preserve this behavior.", + "ownerNamespace", r.ko.ObjectMeta.GetNamespace(), + "secretNamespace", f2f0valiter.Namespace, + "secretName", f2f0valiter.Name, + ) + crossNsMsg := fmt.Sprintf("Cross-namespace secret reference detected: "+ + "resource in namespace %q references secret %q in namespace %q. "+ + "Cross-namespace behavior will be disabled by default in a future release. "+ + "Set --enable-cross-namespace=true to preserve this behavior.", + r.ko.ObjectMeta.GetNamespace(), f2f0valiter.Name, f2f0valiter.Namespace) + setCrossNamespaceCondition(r.ko, crossNsMsg) + } + f2f0valiter.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f2f0valiter) if err != nil { return nil, ackrequeue.Needed(err) diff --git a/templates/helm/templates/deployment.yaml.tpl b/templates/helm/templates/deployment.yaml.tpl index a8219bac..1e55f061 100644 --- a/templates/helm/templates/deployment.yaml.tpl +++ b/templates/helm/templates/deployment.yaml.tpl @@ -104,6 +104,8 @@ spec: - "$(FEATURE_GATES)" {{ "{{- end }}" }} - {{ "--enable-carm={{ .Values.enableCARM }}" }} + - {{ "--enable-cross-namespace={{ .Values.enableCrossNamespace }}" }} + - {{ "--enable-cross-namespace-references={{ .Values.enableCrossNamespaceReferences }}" }} image: {{ "{{ .Values.image.repository }}:{{ .Values.image.tag }}" }} imagePullPolicy: {{ "{{ .Values.image.pullPolicy }}" }} name: controller diff --git a/templates/helm/values.schema.json.tpl b/templates/helm/values.schema.json.tpl index dcd0eeb3..cca512c3 100644 --- a/templates/helm/values.schema.json.tpl +++ b/templates/helm/values.schema.json.tpl @@ -280,6 +280,11 @@ "description": "Parameter to enable or disable cross account resource management.", "type": "boolean", "default": true + }, + "enableCrossNamespace": { + "description": "Enable cross-namespace behavior (resource references, secret references, field exports). When false, the controller rejects any operation that crosses namespace boundaries.", + "type": "boolean", + "default": true }, "serviceAccount": { "description": "ServiceAccount settings", diff --git a/templates/helm/values.yaml.tpl b/templates/helm/values.yaml.tpl index 15cf4d09..b69fb7dd 100644 --- a/templates/helm/values.yaml.tpl +++ b/templates/helm/values.yaml.tpl @@ -180,6 +180,17 @@ leaderElection: # Enable Cross Account Resource Management (default = true). Set this to false to disable cross account resource management. enableCARM: true +# Enable cross-namespace behavior including resource references, secret references, +# and field exports (default = true). When false, the controller rejects any operation +# that crosses namespace boundaries. +enableCrossNamespace: true + +# Enables cross-namespace resolution of AWSResourceReference entries. +# When false (default), the controller rejects any reference whose +# Namespace field differs from the namespace of the resource containing +# the reference. +enableCrossNamespaceReferences: false + # Configuration for feature gates. These are optional controller features that # can be individually enabled ("true") or disabled ("false") by adding key/value # pairs below. diff --git a/templates/pkg/resource/references.go.tpl b/templates/pkg/resource/references.go.tpl index 91da645b..0b9c82e1 100644 --- a/templates/pkg/resource/references.go.tpl +++ b/templates/pkg/resource/references.go.tpl @@ -15,6 +15,8 @@ import ( {{ if .CRD.HasReferenceFields -}} ackv1alpha1 "github.com/aws-controllers-k8s/runtime/apis/core/v1alpha1" ackerr "github.com/aws-controllers-k8s/runtime/pkg/errors" + ackrt "github.com/aws-controllers-k8s/runtime/pkg/runtime" + ackrtlog "github.com/aws-controllers-k8s/runtime/pkg/runtime/log" {{ end -}} acktypes "github.com/aws-controllers-k8s/runtime/pkg/types" {{ $servicePackageName := .ServicePackageName -}} @@ -31,6 +33,11 @@ import ( ) {{ if .CRD.HasReferenceFields -}} +// Hack to avoid import errors during build... +var ( + _ = &ackrtlog.ResourceLogger{} +) + {{ range $fieldName := .CRD.SortedFieldNames -}} {{ $field := (index $.CRD.Fields $fieldName) -}} {{ if and $field.HasReference (not (eq $field.ReferencedServiceName $servicePackageName)) -}} @@ -134,3 +141,6 @@ func (rm *resourceManager) resolveReferenceFor{{ $field.FieldPathWithUnderscore {{ end -}} {{ end -}} +{{ if .CRD.HasReferenceFields -}} +{{ end -}} + diff --git a/templates/pkg/resource/sdk.go.tpl b/templates/pkg/resource/sdk.go.tpl index 30929e8f..4751395d 100644 --- a/templates/pkg/resource/sdk.go.tpl +++ b/templates/pkg/resource/sdk.go.tpl @@ -15,6 +15,7 @@ import ( ackcompare "github.com/aws-controllers-k8s/runtime/pkg/compare" ackerr "github.com/aws-controllers-k8s/runtime/pkg/errors" ackrequeue "github.com/aws-controllers-k8s/runtime/pkg/requeue" + ackrt "github.com/aws-controllers-k8s/runtime/pkg/runtime" ackrtlog "github.com/aws-controllers-k8s/runtime/pkg/runtime/log" "github.com/aws/aws-sdk-go-v2/aws" svcsdk "github.com/aws/aws-sdk-go-v2/service/{{ .ServicePackageName }}" @@ -39,6 +40,7 @@ var ( _ = fmt.Sprintf("") _ = &ackrequeue.NoRequeue{} _ = &aws.Config{} + _ = ackrt.ValidateCrossNamespaceReferenceString ) // sdkFind returns SDK-specific information about a supplied resource @@ -339,3 +341,29 @@ func (rm *resourceManager) terminalAWSError(err error) bool { {{- if $hookCode := Hook .CRD "sdk_file_end" }} {{ $hookCode }} {{- end }} + +// setCrossNamespaceCondition sets the ACK.CrossNamespaceOptInRequired condition +// on the resource to notify users that their cross-namespace usage will require +// explicit opt-in in a future release. +func setCrossNamespaceCondition(ko *svcapitypes.{{ .CRD.Names.Camel }}, message string) { + if ko.Status.Conditions == nil { + ko.Status.Conditions = []*ackv1alpha1.Condition{} + } + var crossNsCond *ackv1alpha1.Condition + for _, c := range ko.Status.Conditions { + if c.Type == ackv1alpha1.ConditionTypeCrossNamespaceOptInRequired { + crossNsCond = c + break + } + } + if crossNsCond == nil { + crossNsCond = &ackv1alpha1.Condition{ + Type: ackv1alpha1.ConditionTypeCrossNamespaceOptInRequired, + } + ko.Status.Conditions = append(ko.Status.Conditions, crossNsCond) + } + now := metav1.Now() + crossNsCond.LastTransitionTime = &now + crossNsCond.Status = corev1.ConditionTrue + crossNsCond.Message = &message +} From 30bdd708ddc94889d99d4d34ac5217ada38f9fc7 Mon Sep 17 00:00:00 2001 From: Hao Wang Date: Wed, 27 May 2026 15:28:07 -0700 Subject: [PATCH 2/6] fix: Address PR review comments from knottnt - Update ResolveReferencesForField function comment to reflect new generated output with ValidateCrossNamespaceReference call, three return values, and cross-namespace warning/condition logic - Remove stale --enable-cross-namespace-references flag from deployment.yaml.tpl (superseded by --enable-cross-namespace) - Remove stale enableCrossNamespaceReferences value from values.yaml.tpl (superseded by enableCrossNamespace) --- pkg/generate/code/resource_reference.go | 53 +++++++++++--------- templates/helm/templates/deployment.yaml.tpl | 1 - templates/helm/values.yaml.tpl | 6 --- 3 files changed, 28 insertions(+), 32 deletions(-) diff --git a/pkg/generate/code/resource_reference.go b/pkg/generate/code/resource_reference.go index 573445af..1d696707 100644 --- a/pkg/generate/code/resource_reference.go +++ b/pkg/generate/code/resource_reference.go @@ -122,6 +122,11 @@ func ReferenceFieldsValidation( // are related to the given concrete field, determining whether its in a valid // condition and updating the concrete field with the referenced value. // +// The generated code calls ackrt.ValidateCrossNamespaceReference to check +// whether the reference targets a different namespace. If the cross-namespace +// flag is disabled, the helper returns an error. If enabled and cross-namespace, +// a warning is logged and a condition is set on the resource. +// // Sample output (resolving a singular reference): // // if ko.Spec.APIRef != nil && ko.Spec.APIRef.From != nil { @@ -130,6 +135,19 @@ func ReferenceFieldsValidation( // if arr.Name == nil || *arr.Name == "" { // return hasReferences, fmt.Errorf("provided resource reference is nil or empty: APIRef") // } +// namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( +// rm.cfg.EnableCrossNamespace, +// ko.ObjectMeta.GetNamespace(), +// arr.Namespace, +// *arr.Name, +// ) +// if err != nil { +// return hasReferences, err +// } +// if isCrossNs { +// ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; ...") +// setCrossNamespaceCondition(ko, crossNsMsg) +// } // obj := &svcapitypes.API{} // if err := getReferencedResourceState_API(ctx, apiReader, obj, *arr.Name, namespace); err != nil { // return hasReferences, err @@ -146,6 +164,16 @@ func ReferenceFieldsValidation( // if arr.Name == nil || *arr.Name == "" { // return hasReferences, fmt.Errorf("provided resource reference is nil or empty: SecurityGroupRefs") // } +// namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( +// rm.cfg.EnableCrossNamespace, +// ko.ObjectMeta.GetNamespace(), +// arr.Namespace, +// *arr.Name, +// ) +// if err != nil { +// return hasReferences, err +// } +// if isCrossNs { ... } // obj := &ec2apitypes.SecurityGroup{} // if err := getReferencedResourceState_SecurityGroup(ctx, apiReader, obj, *arr.Name, namespace); err != nil { // return hasReferences, err @@ -156,31 +184,6 @@ func ReferenceFieldsValidation( // ko.Spec.SecurityGroupIDs = append(ko.Spec.SecurityGroupIDs, (*string)(obj.Status.ID)) // } // } -// -// Sample output (resolving nested lists of structs containing references): -// -// if ko.Spec.Notification != nil { -// for f0idx, f0iter := range ko.Spec.Notification.LambdaFunctionConfigurations { -// if f0iter.Filter != nil { -// if f0iter.Filter.Key != nil { -// for f1idx, f1iter := range f0iter.Filter.Key.FilterRules { -// if f1iter.ValueRef != nil && f1iter.ValueRef.From != nil { -// hasReferences = true -// arr := f1iter.ValueRef.From -// if arr.Name == nil || *arr.Name == "" { -// return hasReferences, fmt.Errorf("provided resource reference is nil or empty: Notification.LambdaFunctionConfigurations.Filter.Key.FilterRules.ValueRef") -// } -// obj := &svcapitypes.Bucket{} -// if err := getReferencedResourceState_Bucket(ctx, apiReader, obj, *arr.Name, namespace); err != nil { -// return hasReferences, err -// } -// ko.Spec.Notification.LambdaFunctionConfigurations[f0idx].Filter.Key.FilterRules[f1idx].Value = (*string)(obj.Spec.Name) -// } -// } -// } -// } -// } -// } func ResolveReferencesForField(field *model.Field, sourceVarName string, indentLevel int) (string, error) { isListOfRefs := field.ShapeRef.Shape.Type == "list" diff --git a/templates/helm/templates/deployment.yaml.tpl b/templates/helm/templates/deployment.yaml.tpl index 1e55f061..7d478d7f 100644 --- a/templates/helm/templates/deployment.yaml.tpl +++ b/templates/helm/templates/deployment.yaml.tpl @@ -105,7 +105,6 @@ spec: {{ "{{- end }}" }} - {{ "--enable-carm={{ .Values.enableCARM }}" }} - {{ "--enable-cross-namespace={{ .Values.enableCrossNamespace }}" }} - - {{ "--enable-cross-namespace-references={{ .Values.enableCrossNamespaceReferences }}" }} image: {{ "{{ .Values.image.repository }}:{{ .Values.image.tag }}" }} imagePullPolicy: {{ "{{ .Values.image.pullPolicy }}" }} name: controller diff --git a/templates/helm/values.yaml.tpl b/templates/helm/values.yaml.tpl index b69fb7dd..aafedbcf 100644 --- a/templates/helm/values.yaml.tpl +++ b/templates/helm/values.yaml.tpl @@ -185,12 +185,6 @@ enableCARM: true # that crosses namespace boundaries. enableCrossNamespace: true -# Enables cross-namespace resolution of AWSResourceReference entries. -# When false (default), the controller rejects any reference whose -# Namespace field differs from the namespace of the resource containing -# the reference. -enableCrossNamespaceReferences: false - # Configuration for feature gates. These are optional controller features that # can be individually enabled ("true") or disabled ("false") by adding key/value # pairs below. From e944078b0bc4c43fff3e17096da3d69d0420ce66 Mon Sep 17 00:00:00 2001 From: Hao Wang Date: Thu, 28 May 2026 16:49:07 -0700 Subject: [PATCH 3/6] fix: Address review comments from michaelhtm - Replace inlined cross-namespace warning + condition logic with calls to the new ackrt.HandleCrossNamespaceReference runtime helper. This collapses ~14 lines of generated code per cross-namespace check into a single helper call. Applies to both resource references (resource_reference.go) and secret references (set_sdk.go). - Remove the per-package setCrossNamespaceCondition function from the sdk.go.tpl template; the runtime helper now owns the lookup-or-create pattern, avoiding 26 lines of generated code per resource. - Drop the now-unused ackrtlog import and var-block from the references.go.tpl template since the runtime helper handles logging. - Remove the empty {{ if .CRD.HasReferenceFields -}}{{ end -}} block at the bottom of references.go.tpl that was left over from the previous refactor. - Restore the third sample output (resolving nested lists of structs containing references) in the ResolveReferencesForField doc comment, updated to reflect the new generated output. - Update set_sdk_test.go and resource_reference_test.go expected outputs to match the simplified generated code. Requires runtime helpers added in aws-controllers-k8s/runtime PR ( HandleCrossNamespaceReference, SetCrossNamespaceOptInRequired, CrossNamespaceRefKindResource, CrossNamespaceRefKindSecret). --- pkg/generate/code/resource_reference.go | 54 ++++++--- pkg/generate/code/resource_reference_test.go | 112 +++++-------------- pkg/generate/code/set_sdk.go | 24 ++-- pkg/generate/code/set_sdk_test.go | 112 +++++-------------- templates/pkg/resource/references.go.tpl | 10 -- templates/pkg/resource/sdk.go.tpl | 26 ----- 6 files changed, 106 insertions(+), 232 deletions(-) diff --git a/pkg/generate/code/resource_reference.go b/pkg/generate/code/resource_reference.go index 1d696707..e0937900 100644 --- a/pkg/generate/code/resource_reference.go +++ b/pkg/generate/code/resource_reference.go @@ -125,7 +125,8 @@ func ReferenceFieldsValidation( // The generated code calls ackrt.ValidateCrossNamespaceReference to check // whether the reference targets a different namespace. If the cross-namespace // flag is disabled, the helper returns an error. If enabled and cross-namespace, -// a warning is logged and a condition is set on the resource. +// ackrt.HandleCrossNamespaceReference logs a deprecation warning and sets the +// ACK.CrossNamespaceOptInRequired condition on the resource. // // Sample output (resolving a singular reference): // @@ -145,8 +146,11 @@ func ReferenceFieldsValidation( // return hasReferences, err // } // if isCrossNs { -// ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; ...") -// setCrossNamespaceCondition(ko, crossNsMsg) +// ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( +// ctx, ko.Status.Conditions, +// ackrt.CrossNamespaceRefKindResource, +// ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, +// ) // } // obj := &svcapitypes.API{} // if err := getReferencedResourceState_API(ctx, apiReader, obj, *arr.Name, namespace); err != nil { @@ -184,6 +188,34 @@ func ReferenceFieldsValidation( // ko.Spec.SecurityGroupIDs = append(ko.Spec.SecurityGroupIDs, (*string)(obj.Status.ID)) // } // } +// +// Sample output (resolving nested lists of structs containing references): +// +// if ko.Spec.Notification != nil { +// for f0idx, f0iter := range ko.Spec.Notification.LambdaFunctionConfigurations { +// if f0iter.Filter != nil { +// if f0iter.Filter.Key != nil { +// for f1idx, f1iter := range f0iter.Filter.Key.FilterRules { +// if f1iter.ValueRef != nil && f1iter.ValueRef.From != nil { +// hasReferences = true +// arr := f1iter.ValueRef.From +// if arr.Name == nil || *arr.Name == "" { +// return hasReferences, fmt.Errorf("provided resource reference is nil or empty: Notification.LambdaFunctionConfigurations.Filter.Key.FilterRules.ValueRef") +// } +// namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( ... ) +// if err != nil { return hasReferences, err } +// if isCrossNs { ... } +// obj := &svcapitypes.Bucket{} +// if err := getReferencedResourceState_Bucket(ctx, apiReader, obj, *arr.Name, namespace); err != nil { +// return hasReferences, err +// } +// ko.Spec.Notification.LambdaFunctionConfigurations[f0idx].Filter.Key.FilterRules[f1idx].Value = (*string)(obj.Spec.Name) +// } +// } +// } +// } +// } +// } func ResolveReferencesForField(field *model.Field, sourceVarName string, indentLevel int) (string, error) { isListOfRefs := field.ShapeRef.Shape.Type == "list" @@ -241,19 +273,11 @@ func ResolveReferencesForField(field *model.Field, sourceVarName string, indentL outPrefix += fmt.Sprintf("%s\treturn hasReferences, err\n", innerIndent) outPrefix += fmt.Sprintf("%s}\n", innerIndent) outPrefix += fmt.Sprintf("%sif isCrossNs {\n", innerIndent) - outPrefix += fmt.Sprintf("%s\tackrtlog.FromContext(ctx).Info(\"cross-namespace resource reference detected; \"+\n", innerIndent) - outPrefix += fmt.Sprintf("%s\t\t\"this behavior will be disabled by default in a future release. \"+\n", innerIndent) - outPrefix += fmt.Sprintf("%s\t\t\"Set --enable-cross-namespace to preserve this behavior.\",\n", innerIndent) - outPrefix += fmt.Sprintf("%s\t\t\"ownerNamespace\", ko.ObjectMeta.GetNamespace(),\n", innerIndent) - outPrefix += fmt.Sprintf("%s\t\t\"targetNamespace\", *arr.Namespace,\n", innerIndent) - outPrefix += fmt.Sprintf("%s\t\t\"referenceName\", *arr.Name,\n", innerIndent) + outPrefix += fmt.Sprintf("%s\tko.Status.Conditions = ackrt.HandleCrossNamespaceReference(\n", innerIndent) + outPrefix += fmt.Sprintf("%s\t\tctx, ko.Status.Conditions,\n", innerIndent) + outPrefix += fmt.Sprintf("%s\t\tackrt.CrossNamespaceRefKindResource,\n", innerIndent) + outPrefix += fmt.Sprintf("%s\t\tko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name,\n", innerIndent) outPrefix += fmt.Sprintf("%s\t)\n", innerIndent) - outPrefix += fmt.Sprintf("%s\tcrossNsMsg := fmt.Sprintf(\"Cross-namespace resource reference detected: \"+\n", innerIndent) - outPrefix += fmt.Sprintf("%s\t\t\"resource in namespace %%q references %%q in namespace %%q. \"+\n", innerIndent) - outPrefix += fmt.Sprintf("%s\t\t\"Cross-namespace behavior will be disabled by default in a future release. \"+\n", innerIndent) - outPrefix += fmt.Sprintf("%s\t\t\"Set --enable-cross-namespace=true to preserve this behavior.\",\n", innerIndent) - outPrefix += fmt.Sprintf("%s\t\tko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace)\n", innerIndent) - outPrefix += fmt.Sprintf("%s\tsetCrossNamespaceCondition(ko, crossNsMsg)\n", innerIndent) outPrefix += fmt.Sprintf("%s}\n", innerIndent) outPrefix += getReferencedStateForField(field, innerIndentLevel) diff --git a/pkg/generate/code/resource_reference_test.go b/pkg/generate/code/resource_reference_test.go index 25a14b21..7076c601 100644 --- a/pkg/generate/code/resource_reference_test.go +++ b/pkg/generate/code/resource_reference_test.go @@ -154,19 +154,11 @@ func Test_ResolveReferencesForField_SingleReference(t *testing.T) { return hasReferences, err } if isCrossNs { - ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; "+ - "this behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace to preserve this behavior.", - "ownerNamespace", ko.ObjectMeta.GetNamespace(), - "targetNamespace", *arr.Namespace, - "referenceName", *arr.Name, + ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( + ctx, ko.Status.Conditions, + ackrt.CrossNamespaceRefKindResource, + ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, ) - crossNsMsg := fmt.Sprintf("Cross-namespace resource reference detected: "+ - "resource in namespace %q references %q in namespace %q. "+ - "Cross-namespace behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace=true to preserve this behavior.", - ko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace) - setCrossNamespaceCondition(ko, crossNsMsg) } obj := &svcapitypes.API{} if err := getReferencedResourceState_API(ctx, apiReader, obj, *arr.Name, namespace); err != nil { @@ -210,19 +202,11 @@ func Test_ResolveReferencesForField_ReferencingARN(t *testing.T) { return hasReferences, err } if isCrossNs { - ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; "+ - "this behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace to preserve this behavior.", - "ownerNamespace", ko.ObjectMeta.GetNamespace(), - "targetNamespace", *arr.Namespace, - "referenceName", *arr.Name, + ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( + ctx, ko.Status.Conditions, + ackrt.CrossNamespaceRefKindResource, + ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, ) - crossNsMsg := fmt.Sprintf("Cross-namespace resource reference detected: "+ - "resource in namespace %q references %q in namespace %q. "+ - "Cross-namespace behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace=true to preserve this behavior.", - ko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace) - setCrossNamespaceCondition(ko, crossNsMsg) } obj := &svcapitypes.Policy{} if err := getReferencedResourceState_Policy(ctx, apiReader, obj, *arr.Name, namespace); err != nil { @@ -267,19 +251,11 @@ func Test_ResolveReferencesForField_SliceOfReferences(t *testing.T) { return hasReferences, err } if isCrossNs { - ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; "+ - "this behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace to preserve this behavior.", - "ownerNamespace", ko.ObjectMeta.GetNamespace(), - "targetNamespace", *arr.Namespace, - "referenceName", *arr.Name, + ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( + ctx, ko.Status.Conditions, + ackrt.CrossNamespaceRefKindResource, + ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, ) - crossNsMsg := fmt.Sprintf("Cross-namespace resource reference detected: "+ - "resource in namespace %q references %q in namespace %q. "+ - "Cross-namespace behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace=true to preserve this behavior.", - ko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace) - setCrossNamespaceCondition(ko, crossNsMsg) } obj := &ec2apitypes.SecurityGroup{} if err := getReferencedResourceState_SecurityGroup(ctx, apiReader, obj, *arr.Name, namespace); err != nil { @@ -328,19 +304,11 @@ func Test_ResolveReferencesForField_NestedSingleReference(t *testing.T) { return hasReferences, err } if isCrossNs { - ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; "+ - "this behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace to preserve this behavior.", - "ownerNamespace", ko.ObjectMeta.GetNamespace(), - "targetNamespace", *arr.Namespace, - "referenceName", *arr.Name, + ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( + ctx, ko.Status.Conditions, + ackrt.CrossNamespaceRefKindResource, + ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, ) - crossNsMsg := fmt.Sprintf("Cross-namespace resource reference detected: "+ - "resource in namespace %q references %q in namespace %q. "+ - "Cross-namespace behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace=true to preserve this behavior.", - ko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace) - setCrossNamespaceCondition(ko, crossNsMsg) } obj := &svcapitypes.API{} if err := getReferencedResourceState_API(ctx, apiReader, obj, *arr.Name, namespace); err != nil { @@ -389,19 +357,11 @@ func Test_ResolveReferencesForField_SingleReference_DeeplyNested(t *testing.T) { return hasReferences, err } if isCrossNs { - ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; "+ - "this behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace to preserve this behavior.", - "ownerNamespace", ko.ObjectMeta.GetNamespace(), - "targetNamespace", *arr.Namespace, - "referenceName", *arr.Name, + ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( + ctx, ko.Status.Conditions, + ackrt.CrossNamespaceRefKindResource, + ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, ) - crossNsMsg := fmt.Sprintf("Cross-namespace resource reference detected: "+ - "resource in namespace %q references %q in namespace %q. "+ - "Cross-namespace behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace=true to preserve this behavior.", - ko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace) - setCrossNamespaceCondition(ko, crossNsMsg) } obj := &svcapitypes.Bucket{} if err := getReferencedResourceState_Bucket(ctx, apiReader, obj, *arr.Name, namespace); err != nil { @@ -450,19 +410,11 @@ func Test_ResolveReferencesForField_SingleReference_WithinSlice(t *testing.T) { return hasReferences, err } if isCrossNs { - ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; "+ - "this behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace to preserve this behavior.", - "ownerNamespace", ko.ObjectMeta.GetNamespace(), - "targetNamespace", *arr.Namespace, - "referenceName", *arr.Name, + ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( + ctx, ko.Status.Conditions, + ackrt.CrossNamespaceRefKindResource, + ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, ) - crossNsMsg := fmt.Sprintf("Cross-namespace resource reference detected: "+ - "resource in namespace %q references %q in namespace %q. "+ - "Cross-namespace behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace=true to preserve this behavior.", - ko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace) - setCrossNamespaceCondition(ko, crossNsMsg) } obj := &svcapitypes.InternetGateway{} if err := getReferencedResourceState_InternetGateway(ctx, apiReader, obj, *arr.Name, namespace); err != nil { @@ -514,19 +466,11 @@ func Test_ResolveReferencesForField_SingleReference_WithinMultipleSlices(t *test return hasReferences, err } if isCrossNs { - ackrtlog.FromContext(ctx).Info("cross-namespace resource reference detected; "+ - "this behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace to preserve this behavior.", - "ownerNamespace", ko.ObjectMeta.GetNamespace(), - "targetNamespace", *arr.Namespace, - "referenceName", *arr.Name, + ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( + ctx, ko.Status.Conditions, + ackrt.CrossNamespaceRefKindResource, + ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, ) - crossNsMsg := fmt.Sprintf("Cross-namespace resource reference detected: "+ - "resource in namespace %q references %q in namespace %q. "+ - "Cross-namespace behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace=true to preserve this behavior.", - ko.ObjectMeta.GetNamespace(), *arr.Name, *arr.Namespace) - setCrossNamespaceCondition(ko, crossNsMsg) } obj := &svcapitypes.Bucket{} if err := getReferencedResourceState_Bucket(ctx, apiReader, obj, *arr.Name, namespace); err != nil { diff --git a/pkg/generate/code/set_sdk.go b/pkg/generate/code/set_sdk.go index fe767a91..50c73d69 100644 --- a/pkg/generate/code/set_sdk.go +++ b/pkg/generate/code/set_sdk.go @@ -1114,7 +1114,13 @@ func setSDKForContainer( // return nil, err // } // if isCrossNs { -// // log warning and set condition +// r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( +// ctx, r.ko.Status.Conditions, +// ackrt.CrossNamespaceRefKindSecret, +// r.ko.ObjectMeta.GetNamespace(), +// ko.Spec.MasterUserPassword.Namespace, +// ko.Spec.MasterUserPassword.Name, +// ) // } // ko.Spec.MasterUserPassword.Namespace = secretNamespace // tmpSecret, err := rm.rr.SecretValueFromReference(ctx, ko.Spec.MasterUserPassword) @@ -1164,19 +1170,11 @@ func setSDKForSecret( out += fmt.Sprintf("%s\t\treturn nil, err\n", indent) out += fmt.Sprintf("%s\t}\n", indent) out += fmt.Sprintf("%s\tif isCrossNs {\n", indent) - out += fmt.Sprintf("%s\t\tackrtlog.FromContext(ctx).Info(\"cross-namespace secret reference detected; \"+\n", indent) - out += fmt.Sprintf("%s\t\t\t\"this behavior will be disabled by default in a future release. \"+\n", indent) - out += fmt.Sprintf("%s\t\t\t\"Set --enable-cross-namespace to preserve this behavior.\",\n", indent) - out += fmt.Sprintf("%s\t\t\t\"ownerNamespace\", r.ko.ObjectMeta.GetNamespace(),\n", indent) - out += fmt.Sprintf("%s\t\t\t\"secretNamespace\", %s.Namespace,\n", indent, sourceVarName) - out += fmt.Sprintf("%s\t\t\t\"secretName\", %s.Name,\n", indent, sourceVarName) + out += fmt.Sprintf("%s\t\tr.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference(\n", indent) + out += fmt.Sprintf("%s\t\t\tctx, r.ko.Status.Conditions,\n", indent) + out += fmt.Sprintf("%s\t\t\tackrt.CrossNamespaceRefKindSecret,\n", indent) + out += fmt.Sprintf("%s\t\t\tr.ko.ObjectMeta.GetNamespace(), %s.Namespace, %s.Name,\n", indent, sourceVarName, sourceVarName) out += fmt.Sprintf("%s\t\t)\n", indent) - out += fmt.Sprintf("%s\t\tcrossNsMsg := fmt.Sprintf(\"Cross-namespace secret reference detected: \"+\n", indent) - out += fmt.Sprintf("%s\t\t\t\"resource in namespace %%q references secret %%q in namespace %%q. \"+\n", indent) - out += fmt.Sprintf("%s\t\t\t\"Cross-namespace behavior will be disabled by default in a future release. \"+\n", indent) - out += fmt.Sprintf("%s\t\t\t\"Set --enable-cross-namespace=true to preserve this behavior.\",\n", indent) - out += fmt.Sprintf("%s\t\t\tr.ko.ObjectMeta.GetNamespace(), %s.Name, %s.Namespace)\n", indent, sourceVarName, sourceVarName) - out += fmt.Sprintf("%s\t\tsetCrossNamespaceCondition(r.ko, crossNsMsg)\n", indent) out += fmt.Sprintf("%s\t}\n", indent) // Override the secret reference namespace with the validated namespace out += fmt.Sprintf("%s\t%s.Namespace = secretNamespace\n", indent, sourceVarName) diff --git a/pkg/generate/code/set_sdk_test.go b/pkg/generate/code/set_sdk_test.go index 1a2521af..3957fd9d 100644 --- a/pkg/generate/code/set_sdk_test.go +++ b/pkg/generate/code/set_sdk_test.go @@ -115,19 +115,11 @@ func TestSetSDK_MemoryDB_User_Create(t *testing.T) { return nil, err } if isCrossNs { - ackrtlog.FromContext(ctx).Info("cross-namespace secret reference detected; "+ - "this behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace to preserve this behavior.", - "ownerNamespace", r.ko.ObjectMeta.GetNamespace(), - "secretNamespace", f1f0iter.Namespace, - "secretName", f1f0iter.Name, + r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( + ctx, r.ko.Status.Conditions, + ackrt.CrossNamespaceRefKindSecret, + r.ko.ObjectMeta.GetNamespace(), f1f0iter.Namespace, f1f0iter.Name, ) - crossNsMsg := fmt.Sprintf("Cross-namespace secret reference detected: "+ - "resource in namespace %q references secret %q in namespace %q. "+ - "Cross-namespace behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace=true to preserve this behavior.", - r.ko.ObjectMeta.GetNamespace(), f1f0iter.Name, f1f0iter.Namespace) - setCrossNamespaceCondition(r.ko, crossNsMsg) } f1f0iter.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f1f0iter) @@ -243,19 +235,11 @@ func TestSetSDK_OpenSearch_Domain_Create(t *testing.T) { return nil, err } if isCrossNs { - ackrtlog.FromContext(ctx).Info("cross-namespace secret reference detected; "+ - "this behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace to preserve this behavior.", - "ownerNamespace", r.ko.ObjectMeta.GetNamespace(), - "secretNamespace", r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Namespace, - "secretName", r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Name, + r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( + ctx, r.ko.Status.Conditions, + ackrt.CrossNamespaceRefKindSecret, + r.ko.ObjectMeta.GetNamespace(), r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Namespace, r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Name, ) - crossNsMsg := fmt.Sprintf("Cross-namespace secret reference detected: "+ - "resource in namespace %q references secret %q in namespace %q. "+ - "Cross-namespace behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace=true to preserve this behavior.", - r.ko.ObjectMeta.GetNamespace(), r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Name, r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Namespace) - setCrossNamespaceCondition(r.ko, crossNsMsg) } r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword) @@ -1549,19 +1533,11 @@ func TestSetSDK_RDS_DBInstance_Create(t *testing.T) { return nil, err } if isCrossNs { - ackrtlog.FromContext(ctx).Info("cross-namespace secret reference detected; "+ - "this behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace to preserve this behavior.", - "ownerNamespace", r.ko.ObjectMeta.GetNamespace(), - "secretNamespace", r.ko.Spec.MasterUserPassword.Namespace, - "secretName", r.ko.Spec.MasterUserPassword.Name, + r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( + ctx, r.ko.Status.Conditions, + ackrt.CrossNamespaceRefKindSecret, + r.ko.ObjectMeta.GetNamespace(), r.ko.Spec.MasterUserPassword.Namespace, r.ko.Spec.MasterUserPassword.Name, ) - crossNsMsg := fmt.Sprintf("Cross-namespace secret reference detected: "+ - "resource in namespace %q references secret %q in namespace %q. "+ - "Cross-namespace behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace=true to preserve this behavior.", - r.ko.ObjectMeta.GetNamespace(), r.ko.Spec.MasterUserPassword.Name, r.ko.Spec.MasterUserPassword.Namespace) - setCrossNamespaceCondition(r.ko, crossNsMsg) } r.ko.Spec.MasterUserPassword.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, r.ko.Spec.MasterUserPassword) @@ -1864,19 +1840,11 @@ func TestSetSDK_RDS_DBInstance_Update(t *testing.T) { return nil, err } if isCrossNs { - ackrtlog.FromContext(ctx).Info("cross-namespace secret reference detected; "+ - "this behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace to preserve this behavior.", - "ownerNamespace", r.ko.ObjectMeta.GetNamespace(), - "secretNamespace", r.ko.Spec.MasterUserPassword.Namespace, - "secretName", r.ko.Spec.MasterUserPassword.Name, + r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( + ctx, r.ko.Status.Conditions, + ackrt.CrossNamespaceRefKindSecret, + r.ko.ObjectMeta.GetNamespace(), r.ko.Spec.MasterUserPassword.Namespace, r.ko.Spec.MasterUserPassword.Name, ) - crossNsMsg := fmt.Sprintf("Cross-namespace secret reference detected: "+ - "resource in namespace %q references secret %q in namespace %q. "+ - "Cross-namespace behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace=true to preserve this behavior.", - r.ko.ObjectMeta.GetNamespace(), r.ko.Spec.MasterUserPassword.Name, r.ko.Spec.MasterUserPassword.Namespace) - setCrossNamespaceCondition(r.ko, crossNsMsg) } r.ko.Spec.MasterUserPassword.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, r.ko.Spec.MasterUserPassword) @@ -2428,19 +2396,11 @@ func TestSetSDK_MQ_Broker_Create(t *testing.T) { return nil, err } if isCrossNs { - ackrtlog.FromContext(ctx).Info("cross-namespace secret reference detected; "+ - "this behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace to preserve this behavior.", - "ownerNamespace", r.ko.ObjectMeta.GetNamespace(), - "secretNamespace", f18iter.Password.Namespace, - "secretName", f18iter.Password.Name, + r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( + ctx, r.ko.Status.Conditions, + ackrt.CrossNamespaceRefKindSecret, + r.ko.ObjectMeta.GetNamespace(), f18iter.Password.Namespace, f18iter.Password.Name, ) - crossNsMsg := fmt.Sprintf("Cross-namespace secret reference detected: "+ - "resource in namespace %q references secret %q in namespace %q. "+ - "Cross-namespace behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace=true to preserve this behavior.", - r.ko.ObjectMeta.GetNamespace(), f18iter.Password.Name, f18iter.Password.Namespace) - setCrossNamespaceCondition(r.ko, crossNsMsg) } f18iter.Password.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f18iter.Password) @@ -4804,19 +4764,11 @@ func TestSetSDK_Lambda_Function_EnvironmentVariable_MapOfSecrets_Create(t *testi return nil, err } if isCrossNs { - ackrtlog.FromContext(ctx).Info("cross-namespace secret reference detected; "+ - "this behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace to preserve this behavior.", - "ownerNamespace", r.ko.ObjectMeta.GetNamespace(), - "secretNamespace", f4f0valiter.Namespace, - "secretName", f4f0valiter.Name, + r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( + ctx, r.ko.Status.Conditions, + ackrt.CrossNamespaceRefKindSecret, + r.ko.ObjectMeta.GetNamespace(), f4f0valiter.Namespace, f4f0valiter.Name, ) - crossNsMsg := fmt.Sprintf("Cross-namespace secret reference detected: "+ - "resource in namespace %q references secret %q in namespace %q. "+ - "Cross-namespace behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace=true to preserve this behavior.", - r.ko.ObjectMeta.GetNamespace(), f4f0valiter.Name, f4f0valiter.Namespace) - setCrossNamespaceCondition(r.ko, crossNsMsg) } f4f0valiter.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f4f0valiter) @@ -4966,19 +4918,11 @@ func TestSetSDK_Lambda_Function_EnvironmentVariable_MapOfSecrets_Update(t *testi return nil, err } if isCrossNs { - ackrtlog.FromContext(ctx).Info("cross-namespace secret reference detected; "+ - "this behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace to preserve this behavior.", - "ownerNamespace", r.ko.ObjectMeta.GetNamespace(), - "secretNamespace", f2f0valiter.Namespace, - "secretName", f2f0valiter.Name, + r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( + ctx, r.ko.Status.Conditions, + ackrt.CrossNamespaceRefKindSecret, + r.ko.ObjectMeta.GetNamespace(), f2f0valiter.Namespace, f2f0valiter.Name, ) - crossNsMsg := fmt.Sprintf("Cross-namespace secret reference detected: "+ - "resource in namespace %q references secret %q in namespace %q. "+ - "Cross-namespace behavior will be disabled by default in a future release. "+ - "Set --enable-cross-namespace=true to preserve this behavior.", - r.ko.ObjectMeta.GetNamespace(), f2f0valiter.Name, f2f0valiter.Namespace) - setCrossNamespaceCondition(r.ko, crossNsMsg) } f2f0valiter.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f2f0valiter) diff --git a/templates/pkg/resource/references.go.tpl b/templates/pkg/resource/references.go.tpl index 0b9c82e1..6f9506b7 100644 --- a/templates/pkg/resource/references.go.tpl +++ b/templates/pkg/resource/references.go.tpl @@ -16,7 +16,6 @@ import ( ackv1alpha1 "github.com/aws-controllers-k8s/runtime/apis/core/v1alpha1" ackerr "github.com/aws-controllers-k8s/runtime/pkg/errors" ackrt "github.com/aws-controllers-k8s/runtime/pkg/runtime" - ackrtlog "github.com/aws-controllers-k8s/runtime/pkg/runtime/log" {{ end -}} acktypes "github.com/aws-controllers-k8s/runtime/pkg/types" {{ $servicePackageName := .ServicePackageName -}} @@ -33,11 +32,6 @@ import ( ) {{ if .CRD.HasReferenceFields -}} -// Hack to avoid import errors during build... -var ( - _ = &ackrtlog.ResourceLogger{} -) - {{ range $fieldName := .CRD.SortedFieldNames -}} {{ $field := (index $.CRD.Fields $fieldName) -}} {{ if and $field.HasReference (not (eq $field.ReferencedServiceName $servicePackageName)) -}} @@ -140,7 +134,3 @@ func (rm *resourceManager) resolveReferenceFor{{ $field.FieldPathWithUnderscore {{ end -}} {{ end -}} {{ end -}} - -{{ if .CRD.HasReferenceFields -}} -{{ end -}} - diff --git a/templates/pkg/resource/sdk.go.tpl b/templates/pkg/resource/sdk.go.tpl index 4751395d..faf37f67 100644 --- a/templates/pkg/resource/sdk.go.tpl +++ b/templates/pkg/resource/sdk.go.tpl @@ -341,29 +341,3 @@ func (rm *resourceManager) terminalAWSError(err error) bool { {{- if $hookCode := Hook .CRD "sdk_file_end" }} {{ $hookCode }} {{- end }} - -// setCrossNamespaceCondition sets the ACK.CrossNamespaceOptInRequired condition -// on the resource to notify users that their cross-namespace usage will require -// explicit opt-in in a future release. -func setCrossNamespaceCondition(ko *svcapitypes.{{ .CRD.Names.Camel }}, message string) { - if ko.Status.Conditions == nil { - ko.Status.Conditions = []*ackv1alpha1.Condition{} - } - var crossNsCond *ackv1alpha1.Condition - for _, c := range ko.Status.Conditions { - if c.Type == ackv1alpha1.ConditionTypeCrossNamespaceOptInRequired { - crossNsCond = c - break - } - } - if crossNsCond == nil { - crossNsCond = &ackv1alpha1.Condition{ - Type: ackv1alpha1.ConditionTypeCrossNamespaceOptInRequired, - } - ko.Status.Conditions = append(ko.Status.Conditions, crossNsCond) - } - now := metav1.Now() - crossNsCond.LastTransitionTime = &now - crossNsCond.Status = corev1.ConditionTrue - crossNsCond.Message = &message -} From 77c3c719b8cfa8320f0d4e34597ff6da17ce27e6 Mon Sep 17 00:00:00 2001 From: Hao Wang Date: Fri, 29 May 2026 12:55:14 -0700 Subject: [PATCH 4/6] fix: Use combined ResolveCrossNamespaceReference helper Address review feedback from michaelhtm (#699) to fold the entire validate + handle flow into a single helper call. The generated code no longer needs to inspect or branch on isCrossNs. - resource_reference.go: replace ValidateCrossNamespaceReference + Handle block with single ResolveCrossNamespaceReference call (3 returns -> 2) - set_sdk.go: same simplification for secret references using ResolveCrossNamespaceReferenceString - Update doc comments in both generators to reflect the new output - Update 7 test expectations in resource_reference_test.go and 7 in set_sdk_test.go Requires runtime helpers added in aws-controllers-k8s/runtime#249 (ResolveCrossNamespaceReference, ResolveCrossNamespaceReferenceString). --- pkg/generate/code/resource_reference.go | 49 +++++------- pkg/generate/code/resource_reference_test.go | 84 +++++++------------- pkg/generate/code/set_sdk.go | 40 ++++------ pkg/generate/code/set_sdk_test.go | 84 +++++++------------- 4 files changed, 91 insertions(+), 166 deletions(-) diff --git a/pkg/generate/code/resource_reference.go b/pkg/generate/code/resource_reference.go index e0937900..93024238 100644 --- a/pkg/generate/code/resource_reference.go +++ b/pkg/generate/code/resource_reference.go @@ -122,11 +122,11 @@ func ReferenceFieldsValidation( // are related to the given concrete field, determining whether its in a valid // condition and updating the concrete field with the referenced value. // -// The generated code calls ackrt.ValidateCrossNamespaceReference to check -// whether the reference targets a different namespace. If the cross-namespace -// flag is disabled, the helper returns an error. If enabled and cross-namespace, -// ackrt.HandleCrossNamespaceReference logs a deprecation warning and sets the -// ACK.CrossNamespaceOptInRequired condition on the resource. +// The generated code calls ackrt.ResolveCrossNamespaceReference to validate +// the reference and, when the reference targets a different namespace and +// the cross-namespace flag is enabled, emit a deprecation warning and set +// the ACK.CrossNamespaceOptInRequired condition on the resource. When the +// flag is disabled, the helper returns a terminal error. // // Sample output (resolving a singular reference): // @@ -136,8 +136,11 @@ func ReferenceFieldsValidation( // if arr.Name == nil || *arr.Name == "" { // return hasReferences, fmt.Errorf("provided resource reference is nil or empty: APIRef") // } -// namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( +// namespace, err := ackrt.ResolveCrossNamespaceReference( +// ctx, // rm.cfg.EnableCrossNamespace, +// &ko.Status.Conditions, +// ackrt.CrossNamespaceRefKindResource, // ko.ObjectMeta.GetNamespace(), // arr.Namespace, // *arr.Name, @@ -145,13 +148,6 @@ func ReferenceFieldsValidation( // if err != nil { // return hasReferences, err // } -// if isCrossNs { -// ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( -// ctx, ko.Status.Conditions, -// ackrt.CrossNamespaceRefKindResource, -// ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, -// ) -// } // obj := &svcapitypes.API{} // if err := getReferencedResourceState_API(ctx, apiReader, obj, *arr.Name, namespace); err != nil { // return hasReferences, err @@ -168,16 +164,10 @@ func ReferenceFieldsValidation( // if arr.Name == nil || *arr.Name == "" { // return hasReferences, fmt.Errorf("provided resource reference is nil or empty: SecurityGroupRefs") // } -// namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( -// rm.cfg.EnableCrossNamespace, -// ko.ObjectMeta.GetNamespace(), -// arr.Namespace, -// *arr.Name, -// ) +// namespace, err := ackrt.ResolveCrossNamespaceReference( ... ) // if err != nil { // return hasReferences, err // } -// if isCrossNs { ... } // obj := &ec2apitypes.SecurityGroup{} // if err := getReferencedResourceState_SecurityGroup(ctx, apiReader, obj, *arr.Name, namespace); err != nil { // return hasReferences, err @@ -202,9 +192,10 @@ func ReferenceFieldsValidation( // if arr.Name == nil || *arr.Name == "" { // return hasReferences, fmt.Errorf("provided resource reference is nil or empty: Notification.LambdaFunctionConfigurations.Filter.Key.FilterRules.ValueRef") // } -// namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( ... ) -// if err != nil { return hasReferences, err } -// if isCrossNs { ... } +// namespace, err := ackrt.ResolveCrossNamespaceReference( ... ) +// if err != nil { +// return hasReferences, err +// } // obj := &svcapitypes.Bucket{} // if err := getReferencedResourceState_Bucket(ctx, apiReader, obj, *arr.Name, namespace); err != nil { // return hasReferences, err @@ -263,8 +254,11 @@ func ResolveReferencesForField(field *model.Field, sourceVarName string, indentL outPrefix += fmt.Sprintf("%s\treturn hasReferences, fmt.Errorf(\"provided resource reference is nil or empty: %s\")\n", innerIndent, refFieldPath) outPrefix += fmt.Sprintf("%s}\n", innerIndent) - outPrefix += fmt.Sprintf("%snamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference(\n", innerIndent) + outPrefix += fmt.Sprintf("%snamespace, err := ackrt.ResolveCrossNamespaceReference(\n", innerIndent) + outPrefix += fmt.Sprintf("%s\tctx,\n", innerIndent) outPrefix += fmt.Sprintf("%s\trm.cfg.EnableCrossNamespace,\n", innerIndent) + outPrefix += fmt.Sprintf("%s\t&ko.Status.Conditions,\n", innerIndent) + outPrefix += fmt.Sprintf("%s\tackrt.CrossNamespaceRefKindResource,\n", innerIndent) outPrefix += fmt.Sprintf("%s\tko.ObjectMeta.GetNamespace(),\n", innerIndent) outPrefix += fmt.Sprintf("%s\tarr.Namespace,\n", innerIndent) outPrefix += fmt.Sprintf("%s\t*arr.Name,\n", innerIndent) @@ -272,13 +266,6 @@ func ResolveReferencesForField(field *model.Field, sourceVarName string, indentL outPrefix += fmt.Sprintf("%sif err != nil {\n", innerIndent) outPrefix += fmt.Sprintf("%s\treturn hasReferences, err\n", innerIndent) outPrefix += fmt.Sprintf("%s}\n", innerIndent) - outPrefix += fmt.Sprintf("%sif isCrossNs {\n", innerIndent) - outPrefix += fmt.Sprintf("%s\tko.Status.Conditions = ackrt.HandleCrossNamespaceReference(\n", innerIndent) - outPrefix += fmt.Sprintf("%s\t\tctx, ko.Status.Conditions,\n", innerIndent) - outPrefix += fmt.Sprintf("%s\t\tackrt.CrossNamespaceRefKindResource,\n", innerIndent) - outPrefix += fmt.Sprintf("%s\t\tko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name,\n", innerIndent) - outPrefix += fmt.Sprintf("%s\t)\n", innerIndent) - outPrefix += fmt.Sprintf("%s}\n", innerIndent) outPrefix += getReferencedStateForField(field, innerIndentLevel) diff --git a/pkg/generate/code/resource_reference_test.go b/pkg/generate/code/resource_reference_test.go index 7076c601..34e6d0d7 100644 --- a/pkg/generate/code/resource_reference_test.go +++ b/pkg/generate/code/resource_reference_test.go @@ -144,8 +144,11 @@ func Test_ResolveReferencesForField_SingleReference(t *testing.T) { if arr.Name == nil || *arr.Name == "" { return hasReferences, fmt.Errorf("provided resource reference is nil or empty: APIRef") } - namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( + namespace, err := ackrt.ResolveCrossNamespaceReference( + ctx, rm.cfg.EnableCrossNamespace, + &ko.Status.Conditions, + ackrt.CrossNamespaceRefKindResource, ko.ObjectMeta.GetNamespace(), arr.Namespace, *arr.Name, @@ -153,13 +156,6 @@ func Test_ResolveReferencesForField_SingleReference(t *testing.T) { if err != nil { return hasReferences, err } - if isCrossNs { - ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( - ctx, ko.Status.Conditions, - ackrt.CrossNamespaceRefKindResource, - ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, - ) - } obj := &svcapitypes.API{} if err := getReferencedResourceState_API(ctx, apiReader, obj, *arr.Name, namespace); err != nil { return hasReferences, err @@ -192,8 +188,11 @@ func Test_ResolveReferencesForField_ReferencingARN(t *testing.T) { if arr.Name == nil || *arr.Name == "" { return hasReferences, fmt.Errorf("provided resource reference is nil or empty: PermissionsBoundaryRef") } - namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( + namespace, err := ackrt.ResolveCrossNamespaceReference( + ctx, rm.cfg.EnableCrossNamespace, + &ko.Status.Conditions, + ackrt.CrossNamespaceRefKindResource, ko.ObjectMeta.GetNamespace(), arr.Namespace, *arr.Name, @@ -201,13 +200,6 @@ func Test_ResolveReferencesForField_ReferencingARN(t *testing.T) { if err != nil { return hasReferences, err } - if isCrossNs { - ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( - ctx, ko.Status.Conditions, - ackrt.CrossNamespaceRefKindResource, - ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, - ) - } obj := &svcapitypes.Policy{} if err := getReferencedResourceState_Policy(ctx, apiReader, obj, *arr.Name, namespace); err != nil { return hasReferences, err @@ -241,8 +233,11 @@ func Test_ResolveReferencesForField_SliceOfReferences(t *testing.T) { if arr.Name == nil || *arr.Name == "" { return hasReferences, fmt.Errorf("provided resource reference is nil or empty: SecurityGroupRefs") } - namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( + namespace, err := ackrt.ResolveCrossNamespaceReference( + ctx, rm.cfg.EnableCrossNamespace, + &ko.Status.Conditions, + ackrt.CrossNamespaceRefKindResource, ko.ObjectMeta.GetNamespace(), arr.Namespace, *arr.Name, @@ -250,13 +245,6 @@ func Test_ResolveReferencesForField_SliceOfReferences(t *testing.T) { if err != nil { return hasReferences, err } - if isCrossNs { - ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( - ctx, ko.Status.Conditions, - ackrt.CrossNamespaceRefKindResource, - ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, - ) - } obj := &ec2apitypes.SecurityGroup{} if err := getReferencedResourceState_SecurityGroup(ctx, apiReader, obj, *arr.Name, namespace); err != nil { return hasReferences, err @@ -294,8 +282,11 @@ func Test_ResolveReferencesForField_NestedSingleReference(t *testing.T) { if arr.Name == nil || *arr.Name == "" { return hasReferences, fmt.Errorf("provided resource reference is nil or empty: JWTConfiguration.IssuerRef") } - namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( + namespace, err := ackrt.ResolveCrossNamespaceReference( + ctx, rm.cfg.EnableCrossNamespace, + &ko.Status.Conditions, + ackrt.CrossNamespaceRefKindResource, ko.ObjectMeta.GetNamespace(), arr.Namespace, *arr.Name, @@ -303,13 +294,6 @@ func Test_ResolveReferencesForField_NestedSingleReference(t *testing.T) { if err != nil { return hasReferences, err } - if isCrossNs { - ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( - ctx, ko.Status.Conditions, - ackrt.CrossNamespaceRefKindResource, - ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, - ) - } obj := &svcapitypes.API{} if err := getReferencedResourceState_API(ctx, apiReader, obj, *arr.Name, namespace); err != nil { return hasReferences, err @@ -347,8 +331,11 @@ func Test_ResolveReferencesForField_SingleReference_DeeplyNested(t *testing.T) { if arr.Name == nil || *arr.Name == "" { return hasReferences, fmt.Errorf("provided resource reference is nil or empty: Logging.LoggingEnabled.TargetBucketRef") } - namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( + namespace, err := ackrt.ResolveCrossNamespaceReference( + ctx, rm.cfg.EnableCrossNamespace, + &ko.Status.Conditions, + ackrt.CrossNamespaceRefKindResource, ko.ObjectMeta.GetNamespace(), arr.Namespace, *arr.Name, @@ -356,13 +343,6 @@ func Test_ResolveReferencesForField_SingleReference_DeeplyNested(t *testing.T) { if err != nil { return hasReferences, err } - if isCrossNs { - ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( - ctx, ko.Status.Conditions, - ackrt.CrossNamespaceRefKindResource, - ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, - ) - } obj := &svcapitypes.Bucket{} if err := getReferencedResourceState_Bucket(ctx, apiReader, obj, *arr.Name, namespace); err != nil { return hasReferences, err @@ -400,8 +380,11 @@ func Test_ResolveReferencesForField_SingleReference_WithinSlice(t *testing.T) { if arr.Name == nil || *arr.Name == "" { return hasReferences, fmt.Errorf("provided resource reference is nil or empty: Routes.GatewayRef") } - namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( + namespace, err := ackrt.ResolveCrossNamespaceReference( + ctx, rm.cfg.EnableCrossNamespace, + &ko.Status.Conditions, + ackrt.CrossNamespaceRefKindResource, ko.ObjectMeta.GetNamespace(), arr.Namespace, *arr.Name, @@ -409,13 +392,6 @@ func Test_ResolveReferencesForField_SingleReference_WithinSlice(t *testing.T) { if err != nil { return hasReferences, err } - if isCrossNs { - ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( - ctx, ko.Status.Conditions, - ackrt.CrossNamespaceRefKindResource, - ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, - ) - } obj := &svcapitypes.InternetGateway{} if err := getReferencedResourceState_InternetGateway(ctx, apiReader, obj, *arr.Name, namespace); err != nil { return hasReferences, err @@ -456,8 +432,11 @@ func Test_ResolveReferencesForField_SingleReference_WithinMultipleSlices(t *test if arr.Name == nil || *arr.Name == "" { return hasReferences, fmt.Errorf("provided resource reference is nil or empty: Notification.LambdaFunctionConfigurations.Filter.Key.FilterRules.ValueRef") } - namespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReference( + namespace, err := ackrt.ResolveCrossNamespaceReference( + ctx, rm.cfg.EnableCrossNamespace, + &ko.Status.Conditions, + ackrt.CrossNamespaceRefKindResource, ko.ObjectMeta.GetNamespace(), arr.Namespace, *arr.Name, @@ -465,13 +444,6 @@ func Test_ResolveReferencesForField_SingleReference_WithinMultipleSlices(t *test if err != nil { return hasReferences, err } - if isCrossNs { - ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( - ctx, ko.Status.Conditions, - ackrt.CrossNamespaceRefKindResource, - ko.ObjectMeta.GetNamespace(), *arr.Namespace, *arr.Name, - ) - } obj := &svcapitypes.Bucket{} if err := getReferencedResourceState_Bucket(ctx, apiReader, obj, *arr.Name, namespace); err != nil { return hasReferences, err diff --git a/pkg/generate/code/set_sdk.go b/pkg/generate/code/set_sdk.go index 50c73d69..c18ef0fc 100644 --- a/pkg/generate/code/set_sdk.go +++ b/pkg/generate/code/set_sdk.go @@ -1099,13 +1099,17 @@ func setSDKForContainer( // setSDKForSecret returns a string of Go code that sets a target variable to // the value of a Secret when the type of the source variable is a -// SecretKeyReference. It first validates cross-namespace access using -// ValidateCrossNamespaceReferenceString, then fetches the secret value. +// SecretKeyReference. It first calls ResolveCrossNamespaceReferenceString to +// validate cross-namespace access (and emit a deprecation warning + condition +// when the reference is cross-namespace), then fetches the secret value. // // The Go code output from this function looks like this: // -// secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( +// secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( +// ctx, // rm.cfg.EnableCrossNamespace, +// &r.ko.Status.Conditions, +// ackrt.CrossNamespaceRefKindSecret, // r.ko.ObjectMeta.GetNamespace(), // ko.Spec.MasterUserPassword.Namespace, // ko.Spec.MasterUserPassword.Name, @@ -1113,15 +1117,6 @@ func setSDKForContainer( // if err != nil { // return nil, err // } -// if isCrossNs { -// r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( -// ctx, r.ko.Status.Conditions, -// ackrt.CrossNamespaceRefKindSecret, -// r.ko.ObjectMeta.GetNamespace(), -// ko.Spec.MasterUserPassword.Namespace, -// ko.Spec.MasterUserPassword.Name, -// ) -// } // ko.Spec.MasterUserPassword.Namespace = secretNamespace // tmpSecret, err := rm.rr.SecretValueFromReference(ctx, ko.Spec.MasterUserPassword) // if err != nil { @@ -1150,18 +1145,24 @@ func setSDKForSecret( indent := strings.Repeat("\t", indentLevel) secVar := "tmpSecret" - // Validate cross-namespace access before fetching the secret - // secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + // Resolve cross-namespace access before fetching the secret + // secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( + // ctx, // rm.cfg.EnableCrossNamespace, + // &r.ko.Status.Conditions, + // ackrt.CrossNamespaceRefKindSecret, // r.ko.ObjectMeta.GetNamespace(), // sourceVarName.Namespace, // sourceVarName.Name, // ) out += fmt.Sprintf( - "%s\tsecretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString(\n", + "%s\tsecretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString(\n", indent, ) + out += fmt.Sprintf("%s\t\tctx,\n", indent) out += fmt.Sprintf("%s\t\trm.cfg.EnableCrossNamespace,\n", indent) + out += fmt.Sprintf("%s\t\t&r.ko.Status.Conditions,\n", indent) + out += fmt.Sprintf("%s\t\tackrt.CrossNamespaceRefKindSecret,\n", indent) out += fmt.Sprintf("%s\t\tr.ko.ObjectMeta.GetNamespace(),\n", indent) out += fmt.Sprintf("%s\t\t%s.Namespace,\n", indent, sourceVarName) out += fmt.Sprintf("%s\t\t%s.Name,\n", indent, sourceVarName) @@ -1169,14 +1170,7 @@ func setSDKForSecret( out += fmt.Sprintf("%s\tif err != nil {\n", indent) out += fmt.Sprintf("%s\t\treturn nil, err\n", indent) out += fmt.Sprintf("%s\t}\n", indent) - out += fmt.Sprintf("%s\tif isCrossNs {\n", indent) - out += fmt.Sprintf("%s\t\tr.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference(\n", indent) - out += fmt.Sprintf("%s\t\t\tctx, r.ko.Status.Conditions,\n", indent) - out += fmt.Sprintf("%s\t\t\tackrt.CrossNamespaceRefKindSecret,\n", indent) - out += fmt.Sprintf("%s\t\t\tr.ko.ObjectMeta.GetNamespace(), %s.Namespace, %s.Name,\n", indent, sourceVarName, sourceVarName) - out += fmt.Sprintf("%s\t\t)\n", indent) - out += fmt.Sprintf("%s\t}\n", indent) - // Override the secret reference namespace with the validated namespace + // Override the secret reference namespace with the resolved namespace out += fmt.Sprintf("%s\t%s.Namespace = secretNamespace\n", indent, sourceVarName) // tmpSecret, err := rm.rr.SecretValueFromReference(ctx, ko.Spec.MasterUserPassword) diff --git a/pkg/generate/code/set_sdk_test.go b/pkg/generate/code/set_sdk_test.go index 3957fd9d..46af3454 100644 --- a/pkg/generate/code/set_sdk_test.go +++ b/pkg/generate/code/set_sdk_test.go @@ -105,8 +105,11 @@ func TestSetSDK_MemoryDB_User_Create(t *testing.T) { for _, f1f0iter := range r.ko.Spec.AuthenticationMode.Passwords { var f1f0elem string if f1f0iter != nil { - secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( + ctx, rm.cfg.EnableCrossNamespace, + &r.ko.Status.Conditions, + ackrt.CrossNamespaceRefKindSecret, r.ko.ObjectMeta.GetNamespace(), f1f0iter.Namespace, f1f0iter.Name, @@ -114,13 +117,6 @@ func TestSetSDK_MemoryDB_User_Create(t *testing.T) { if err != nil { return nil, err } - if isCrossNs { - r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( - ctx, r.ko.Status.Conditions, - ackrt.CrossNamespaceRefKindSecret, - r.ko.ObjectMeta.GetNamespace(), f1f0iter.Namespace, f1f0iter.Name, - ) - } f1f0iter.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f1f0iter) if err != nil { @@ -225,8 +221,11 @@ func TestSetSDK_OpenSearch_Domain_Create(t *testing.T) { f3f4.MasterUserName = r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserName } if r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword != nil { - secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( + ctx, rm.cfg.EnableCrossNamespace, + &r.ko.Status.Conditions, + ackrt.CrossNamespaceRefKindSecret, r.ko.ObjectMeta.GetNamespace(), r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Namespace, r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Name, @@ -234,13 +233,6 @@ func TestSetSDK_OpenSearch_Domain_Create(t *testing.T) { if err != nil { return nil, err } - if isCrossNs { - r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( - ctx, r.ko.Status.Conditions, - ackrt.CrossNamespaceRefKindSecret, - r.ko.ObjectMeta.GetNamespace(), r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Namespace, r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Name, - ) - } r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword) if err != nil { @@ -1523,8 +1515,11 @@ func TestSetSDK_RDS_DBInstance_Create(t *testing.T) { res.ManageMasterUserPassword = r.ko.Spec.ManageMasterUserPassword } if r.ko.Spec.MasterUserPassword != nil { - secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( + ctx, rm.cfg.EnableCrossNamespace, + &r.ko.Status.Conditions, + ackrt.CrossNamespaceRefKindSecret, r.ko.ObjectMeta.GetNamespace(), r.ko.Spec.MasterUserPassword.Namespace, r.ko.Spec.MasterUserPassword.Name, @@ -1532,13 +1527,6 @@ func TestSetSDK_RDS_DBInstance_Create(t *testing.T) { if err != nil { return nil, err } - if isCrossNs { - r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( - ctx, r.ko.Status.Conditions, - ackrt.CrossNamespaceRefKindSecret, - r.ko.ObjectMeta.GetNamespace(), r.ko.Spec.MasterUserPassword.Namespace, r.ko.Spec.MasterUserPassword.Name, - ) - } r.ko.Spec.MasterUserPassword.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, r.ko.Spec.MasterUserPassword) if err != nil { @@ -1830,8 +1818,11 @@ func TestSetSDK_RDS_DBInstance_Update(t *testing.T) { } if delta.DifferentAt("Spec.MasterUserPassword") { if r.ko.Spec.MasterUserPassword != nil { - secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( + ctx, rm.cfg.EnableCrossNamespace, + &r.ko.Status.Conditions, + ackrt.CrossNamespaceRefKindSecret, r.ko.ObjectMeta.GetNamespace(), r.ko.Spec.MasterUserPassword.Namespace, r.ko.Spec.MasterUserPassword.Name, @@ -1839,13 +1830,6 @@ func TestSetSDK_RDS_DBInstance_Update(t *testing.T) { if err != nil { return nil, err } - if isCrossNs { - r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( - ctx, r.ko.Status.Conditions, - ackrt.CrossNamespaceRefKindSecret, - r.ko.ObjectMeta.GetNamespace(), r.ko.Spec.MasterUserPassword.Namespace, r.ko.Spec.MasterUserPassword.Name, - ) - } r.ko.Spec.MasterUserPassword.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, r.ko.Spec.MasterUserPassword) if err != nil { @@ -2386,8 +2370,11 @@ func TestSetSDK_MQ_Broker_Create(t *testing.T) { f18elem.Groups = aws.ToStringSlice(f18iter.Groups) } if f18iter.Password != nil { - secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( + ctx, rm.cfg.EnableCrossNamespace, + &r.ko.Status.Conditions, + ackrt.CrossNamespaceRefKindSecret, r.ko.ObjectMeta.GetNamespace(), f18iter.Password.Namespace, f18iter.Password.Name, @@ -2395,13 +2382,6 @@ func TestSetSDK_MQ_Broker_Create(t *testing.T) { if err != nil { return nil, err } - if isCrossNs { - r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( - ctx, r.ko.Status.Conditions, - ackrt.CrossNamespaceRefKindSecret, - r.ko.ObjectMeta.GetNamespace(), f18iter.Password.Namespace, f18iter.Password.Name, - ) - } f18iter.Password.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f18iter.Password) if err != nil { @@ -4754,8 +4734,11 @@ func TestSetSDK_Lambda_Function_EnvironmentVariable_MapOfSecrets_Create(t *testi for f4f0key, f4f0valiter := range r.ko.Spec.Environment.Variables { var f4f0val string if f4f0valiter != nil { - secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( + ctx, rm.cfg.EnableCrossNamespace, + &r.ko.Status.Conditions, + ackrt.CrossNamespaceRefKindSecret, r.ko.ObjectMeta.GetNamespace(), f4f0valiter.Namespace, f4f0valiter.Name, @@ -4763,13 +4746,6 @@ func TestSetSDK_Lambda_Function_EnvironmentVariable_MapOfSecrets_Create(t *testi if err != nil { return nil, err } - if isCrossNs { - r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( - ctx, r.ko.Status.Conditions, - ackrt.CrossNamespaceRefKindSecret, - r.ko.ObjectMeta.GetNamespace(), f4f0valiter.Namespace, f4f0valiter.Name, - ) - } f4f0valiter.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f4f0valiter) if err != nil { @@ -4908,8 +4884,11 @@ func TestSetSDK_Lambda_Function_EnvironmentVariable_MapOfSecrets_Update(t *testi for f2f0key, f2f0valiter := range r.ko.Spec.Environment.Variables { var f2f0val string if f2f0valiter != nil { - secretNamespace, isCrossNs, err := ackrt.ValidateCrossNamespaceReferenceString( + secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( + ctx, rm.cfg.EnableCrossNamespace, + &r.ko.Status.Conditions, + ackrt.CrossNamespaceRefKindSecret, r.ko.ObjectMeta.GetNamespace(), f2f0valiter.Namespace, f2f0valiter.Name, @@ -4917,13 +4896,6 @@ func TestSetSDK_Lambda_Function_EnvironmentVariable_MapOfSecrets_Update(t *testi if err != nil { return nil, err } - if isCrossNs { - r.ko.Status.Conditions = ackrt.HandleCrossNamespaceReference( - ctx, r.ko.Status.Conditions, - ackrt.CrossNamespaceRefKindSecret, - r.ko.ObjectMeta.GetNamespace(), f2f0valiter.Namespace, f2f0valiter.Name, - ) - } f2f0valiter.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f2f0valiter) if err != nil { From eab25a9e820dbf3d6afbf6f7f513cd7e27e9f3b9 Mon Sep 17 00:00:00 2001 From: Hao Wang Date: Wed, 3 Jun 2026 16:57:00 -0700 Subject: [PATCH 5/6] chore: Bump runtime to cross-namespace helper commit Point at runtime pseudo-version v0.59.2-0.20260603224255-14be98880374 (commit 14be988, PR #249) which adds the ResolveCrossNamespaceReference and ResolveCrossNamespaceReferenceString helpers that generated code now calls. This is a temporary pin for testing; revert to the tagged release (v0.60.0) once it is published upstream. --- go.mod | 2 +- go.sum | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index ddf68a39..c684db7d 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.25.0 require ( github.com/aws-controllers-k8s/pkg v0.0.23 - github.com/aws-controllers-k8s/runtime v0.59.1 + github.com/aws-controllers-k8s/runtime v0.59.2-0.20260603224255-14be98880374 github.com/aws/aws-sdk-go v1.49.0 github.com/aws/aws-sdk-go-v2 v1.32.7 github.com/dlclark/regexp2 v1.10.0 // indirect diff --git a/go.sum b/go.sum index 904359f4..fe2a7c2f 100644 --- a/go.sum +++ b/go.sum @@ -64,10 +64,8 @@ github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:l github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws-controllers-k8s/pkg v0.0.23 h1:iqu8jKQUnyP/c6TiVcXySQYpkATui0iXFC5ax9x01oM= github.com/aws-controllers-k8s/pkg v0.0.23/go.mod h1:VvdjLWmR6IJ3KU8KByKiq/lJE8M+ur2piXysXKTGUS0= -github.com/aws-controllers-k8s/runtime v0.59.0 h1:VECkUXw3e8WLQo52o3Mw0u1WOrfAzugv8A5fFoaEhxU= -github.com/aws-controllers-k8s/runtime v0.59.0/go.mod h1:ljWD1IdtVx/qC7C4lVobF4vLNhno/xX5A78BOke1Ksk= -github.com/aws-controllers-k8s/runtime v0.59.1 h1:7UDKl9/dif8oNjxx/5Z5ciUfuyn86MS4BvoG9LqF6h4= -github.com/aws-controllers-k8s/runtime v0.59.1/go.mod h1:ljWD1IdtVx/qC7C4lVobF4vLNhno/xX5A78BOke1Ksk= +github.com/aws-controllers-k8s/runtime v0.59.2-0.20260603224255-14be98880374 h1:qeu0+TU976/aCVWA9rGG2UTbOkvRkA6HfG+4ZnNd2Lc= +github.com/aws-controllers-k8s/runtime v0.59.2-0.20260603224255-14be98880374/go.mod h1:ljWD1IdtVx/qC7C4lVobF4vLNhno/xX5A78BOke1Ksk= github.com/aws/aws-sdk-go v1.49.0 h1:g9BkW1fo9GqKfwg2+zCD+TW/D36Ux+vtfJ8guF4AYmY= github.com/aws/aws-sdk-go v1.49.0/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go-v2 v1.32.7 h1:ky5o35oENWi0JYWUZkB7WYvVPP+bcRF5/Iq7JWSb5Rw= From f0dc0d8eb3a28973285f7e2a26c6801e403651ee Mon Sep 17 00:00:00 2001 From: Hao Wang Date: Thu, 4 Jun 2026 16:59:35 -0700 Subject: [PATCH 6/6] fix: Move secret cross-namespace validation into runtime Drop the per-call secret validation block from generated sdk.go. The generated code only wrapped SecretValueFromReference call sites in sdk.go, missing custom update functions (e.g. RDS db_cluster) and hooks that call SecretValueFromReference directly. Validation now lives entirely in the runtime's SecretValueFromReference (aws-controllers-k8s/runtime), so every caller is covered without generated boilerplate. - set_sdk.go: generated secret code reverts to a plain SecretValueFromReference call; no ResolveCrossNamespaceReferenceString - sdk.go.tpl: drop the now-unused ackrt import and its suppression entry - set_sdk_test.go: remove the validation block from 7 expected outputs Addresses review feedback from knottnt on #699. --- pkg/generate/code/set_sdk.go | 53 ++++-------------- pkg/generate/code/set_sdk_test.go | 91 ------------------------------- templates/pkg/resource/sdk.go.tpl | 2 - 3 files changed, 10 insertions(+), 136 deletions(-) diff --git a/pkg/generate/code/set_sdk.go b/pkg/generate/code/set_sdk.go index c18ef0fc..1152819a 100644 --- a/pkg/generate/code/set_sdk.go +++ b/pkg/generate/code/set_sdk.go @@ -1099,25 +1099,15 @@ func setSDKForContainer( // setSDKForSecret returns a string of Go code that sets a target variable to // the value of a Secret when the type of the source variable is a -// SecretKeyReference. It first calls ResolveCrossNamespaceReferenceString to -// validate cross-namespace access (and emit a deprecation warning + condition -// when the reference is cross-namespace), then fetches the secret value. +// SecretKeyReference. +// +// Cross-namespace validation (and the Phase 1 deprecation warning) is +// performed inside the runtime's SecretValueFromReference, so it is not +// emitted here. This ensures every caller is covered, including custom +// update functions and hooks that call SecretValueFromReference directly. // // The Go code output from this function looks like this: // -// secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( -// ctx, -// rm.cfg.EnableCrossNamespace, -// &r.ko.Status.Conditions, -// ackrt.CrossNamespaceRefKindSecret, -// r.ko.ObjectMeta.GetNamespace(), -// ko.Spec.MasterUserPassword.Namespace, -// ko.Spec.MasterUserPassword.Name, -// ) -// if err != nil { -// return nil, err -// } -// ko.Spec.MasterUserPassword.Namespace = secretNamespace // tmpSecret, err := rm.rr.SecretValueFromReference(ctx, ko.Spec.MasterUserPassword) // if err != nil { // return nil, ackrequeue.Needed(err) @@ -1145,33 +1135,10 @@ func setSDKForSecret( indent := strings.Repeat("\t", indentLevel) secVar := "tmpSecret" - // Resolve cross-namespace access before fetching the secret - // secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( - // ctx, - // rm.cfg.EnableCrossNamespace, - // &r.ko.Status.Conditions, - // ackrt.CrossNamespaceRefKindSecret, - // r.ko.ObjectMeta.GetNamespace(), - // sourceVarName.Namespace, - // sourceVarName.Name, - // ) - out += fmt.Sprintf( - "%s\tsecretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString(\n", - indent, - ) - out += fmt.Sprintf("%s\t\tctx,\n", indent) - out += fmt.Sprintf("%s\t\trm.cfg.EnableCrossNamespace,\n", indent) - out += fmt.Sprintf("%s\t\t&r.ko.Status.Conditions,\n", indent) - out += fmt.Sprintf("%s\t\tackrt.CrossNamespaceRefKindSecret,\n", indent) - out += fmt.Sprintf("%s\t\tr.ko.ObjectMeta.GetNamespace(),\n", indent) - out += fmt.Sprintf("%s\t\t%s.Namespace,\n", indent, sourceVarName) - out += fmt.Sprintf("%s\t\t%s.Name,\n", indent, sourceVarName) - out += fmt.Sprintf("%s\t)\n", indent) - out += fmt.Sprintf("%s\tif err != nil {\n", indent) - out += fmt.Sprintf("%s\t\treturn nil, err\n", indent) - out += fmt.Sprintf("%s\t}\n", indent) - // Override the secret reference namespace with the resolved namespace - out += fmt.Sprintf("%s\t%s.Namespace = secretNamespace\n", indent, sourceVarName) + // Cross-namespace validation for the secret reference is performed inside + // the runtime's SecretValueFromReference, so that every call site is + // covered (including custom update functions and hooks). No per-call + // validation is generated here. // tmpSecret, err := rm.rr.SecretValueFromReference(ctx, ko.Spec.MasterUserPassword) out += fmt.Sprintf( diff --git a/pkg/generate/code/set_sdk_test.go b/pkg/generate/code/set_sdk_test.go index 46af3454..595e6300 100644 --- a/pkg/generate/code/set_sdk_test.go +++ b/pkg/generate/code/set_sdk_test.go @@ -105,19 +105,6 @@ func TestSetSDK_MemoryDB_User_Create(t *testing.T) { for _, f1f0iter := range r.ko.Spec.AuthenticationMode.Passwords { var f1f0elem string if f1f0iter != nil { - secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( - ctx, - rm.cfg.EnableCrossNamespace, - &r.ko.Status.Conditions, - ackrt.CrossNamespaceRefKindSecret, - r.ko.ObjectMeta.GetNamespace(), - f1f0iter.Namespace, - f1f0iter.Name, - ) - if err != nil { - return nil, err - } - f1f0iter.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f1f0iter) if err != nil { return nil, ackrequeue.Needed(err) @@ -221,19 +208,6 @@ func TestSetSDK_OpenSearch_Domain_Create(t *testing.T) { f3f4.MasterUserName = r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserName } if r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword != nil { - secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( - ctx, - rm.cfg.EnableCrossNamespace, - &r.ko.Status.Conditions, - ackrt.CrossNamespaceRefKindSecret, - r.ko.ObjectMeta.GetNamespace(), - r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Namespace, - r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Name, - ) - if err != nil { - return nil, err - } - r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, r.ko.Spec.AdvancedSecurityOptions.MasterUserOptions.MasterUserPassword) if err != nil { return nil, ackrequeue.Needed(err) @@ -1515,19 +1489,6 @@ func TestSetSDK_RDS_DBInstance_Create(t *testing.T) { res.ManageMasterUserPassword = r.ko.Spec.ManageMasterUserPassword } if r.ko.Spec.MasterUserPassword != nil { - secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( - ctx, - rm.cfg.EnableCrossNamespace, - &r.ko.Status.Conditions, - ackrt.CrossNamespaceRefKindSecret, - r.ko.ObjectMeta.GetNamespace(), - r.ko.Spec.MasterUserPassword.Namespace, - r.ko.Spec.MasterUserPassword.Name, - ) - if err != nil { - return nil, err - } - r.ko.Spec.MasterUserPassword.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, r.ko.Spec.MasterUserPassword) if err != nil { return nil, ackrequeue.Needed(err) @@ -1818,19 +1779,6 @@ func TestSetSDK_RDS_DBInstance_Update(t *testing.T) { } if delta.DifferentAt("Spec.MasterUserPassword") { if r.ko.Spec.MasterUserPassword != nil { - secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( - ctx, - rm.cfg.EnableCrossNamespace, - &r.ko.Status.Conditions, - ackrt.CrossNamespaceRefKindSecret, - r.ko.ObjectMeta.GetNamespace(), - r.ko.Spec.MasterUserPassword.Namespace, - r.ko.Spec.MasterUserPassword.Name, - ) - if err != nil { - return nil, err - } - r.ko.Spec.MasterUserPassword.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, r.ko.Spec.MasterUserPassword) if err != nil { return nil, ackrequeue.Needed(err) @@ -2370,19 +2318,6 @@ func TestSetSDK_MQ_Broker_Create(t *testing.T) { f18elem.Groups = aws.ToStringSlice(f18iter.Groups) } if f18iter.Password != nil { - secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( - ctx, - rm.cfg.EnableCrossNamespace, - &r.ko.Status.Conditions, - ackrt.CrossNamespaceRefKindSecret, - r.ko.ObjectMeta.GetNamespace(), - f18iter.Password.Namespace, - f18iter.Password.Name, - ) - if err != nil { - return nil, err - } - f18iter.Password.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f18iter.Password) if err != nil { return nil, ackrequeue.Needed(err) @@ -4734,19 +4669,6 @@ func TestSetSDK_Lambda_Function_EnvironmentVariable_MapOfSecrets_Create(t *testi for f4f0key, f4f0valiter := range r.ko.Spec.Environment.Variables { var f4f0val string if f4f0valiter != nil { - secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( - ctx, - rm.cfg.EnableCrossNamespace, - &r.ko.Status.Conditions, - ackrt.CrossNamespaceRefKindSecret, - r.ko.ObjectMeta.GetNamespace(), - f4f0valiter.Namespace, - f4f0valiter.Name, - ) - if err != nil { - return nil, err - } - f4f0valiter.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f4f0valiter) if err != nil { return nil, ackrequeue.Needed(err) @@ -4884,19 +4806,6 @@ func TestSetSDK_Lambda_Function_EnvironmentVariable_MapOfSecrets_Update(t *testi for f2f0key, f2f0valiter := range r.ko.Spec.Environment.Variables { var f2f0val string if f2f0valiter != nil { - secretNamespace, err := ackrt.ResolveCrossNamespaceReferenceString( - ctx, - rm.cfg.EnableCrossNamespace, - &r.ko.Status.Conditions, - ackrt.CrossNamespaceRefKindSecret, - r.ko.ObjectMeta.GetNamespace(), - f2f0valiter.Namespace, - f2f0valiter.Name, - ) - if err != nil { - return nil, err - } - f2f0valiter.Namespace = secretNamespace tmpSecret, err := rm.rr.SecretValueFromReference(ctx, f2f0valiter) if err != nil { return nil, ackrequeue.Needed(err) diff --git a/templates/pkg/resource/sdk.go.tpl b/templates/pkg/resource/sdk.go.tpl index faf37f67..30929e8f 100644 --- a/templates/pkg/resource/sdk.go.tpl +++ b/templates/pkg/resource/sdk.go.tpl @@ -15,7 +15,6 @@ import ( ackcompare "github.com/aws-controllers-k8s/runtime/pkg/compare" ackerr "github.com/aws-controllers-k8s/runtime/pkg/errors" ackrequeue "github.com/aws-controllers-k8s/runtime/pkg/requeue" - ackrt "github.com/aws-controllers-k8s/runtime/pkg/runtime" ackrtlog "github.com/aws-controllers-k8s/runtime/pkg/runtime/log" "github.com/aws/aws-sdk-go-v2/aws" svcsdk "github.com/aws/aws-sdk-go-v2/service/{{ .ServicePackageName }}" @@ -40,7 +39,6 @@ var ( _ = fmt.Sprintf("") _ = &ackrequeue.NoRequeue{} _ = &aws.Config{} - _ = ackrt.ValidateCrossNamespaceReferenceString ) // sdkFind returns SDK-specific information about a supplied resource