feat(runtime): Add --enable-cross-namespace flag#239
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: sapphirew The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Introduce a single CLI flag that controls all three categories of cross-namespace behavior: resource references, secret references, and field exports. Phase 1 defaults to true with deprecation warnings. Changes: - Rename --enable-cross-namespace-references to --enable-cross-namespace - Change default from false to true (Phase 1 warning behavior) - Update ValidateCrossNamespaceReference to return (string, bool, error) - Add ValidateCrossNamespaceReferenceString convenience wrapper - Add ACK.CrossNamespaceDeprecation condition type - Integrate cross-namespace check into SecretValueFromReference - Integrate cross-namespace check into field export reconciler - Add table-driven unit tests for both helper functions - Update error messages to reference new flag name
4a9648c to
4eb656a
Compare
|
/retest |
cheeseandcereal
left a comment
There was a problem hiding this comment.
First-pass review against the ACK rubric. Single squashed commit (rule I passes); no generator.yaml/helm/E2E surface in this PR (rules A–H, J don't apply — this is runtime). Most concerns are around scope alignment between the PR description and what actually ships on this branch.
|
|
||
| // Determine the namespace to use for fetching the secret. | ||
| // Cross-namespace validation, logging, and condition-setting are handled | ||
| // by the generated code before calling this method. |
There was a problem hiding this comment.
The PR description says this PR "Integrate[s] cross-namespace check into SecretValueFromReference", but this hunk does the opposite — it removes namespace logic and the comment defers validation to "the generated code before calling this method." That generated-side change isn't in this PR (and would live in code-generator, not runtime).
Net effect on this branch: --enable-cross-namespace=false does not block cross-namespace secret references — only field exports get gated, and resource references are gated indirectly by WithReferencesResolvedCondition. Two ways to close this:
- Wire
ValidateCrossNamespaceReferenceString(r.cfg.EnableCrossNamespace, ownerNamespace, ref.Namespace, ref.Name)intoSecretValueFromReferencehere, parallel tofield_export_reconciler.go. Keeps the runtime self-contained for tagged releases. - If you'd rather centralize in codegen, please trim the PR description to match scope and link the follow-up code-generator PR.
There was a problem hiding this comment.
Addressed in #248 - updated PR description to clarify that cross-namespace validation for secrets is handled by generated code in aws-controllers-k8s/code-generator#699.
SecretValueFromReference here only extracts ownerNamespace; validation is deferred to the caller
| "targetNamespace", r.getTargetNamespace(&desired), | ||
| "targetName", *desired.Spec.To.Name, | ||
| ) | ||
| r.setCrossNsOptInRequiredCondition(&desired) |
There was a problem hiding this comment.
*desired.Spec.To.Name is dereferenced unconditionally on the log line above — but validateFieldExportNamespace (line 204) explicitly guards desired.Spec.To.Name != nil before reading the same field. Pre-existing writeToConfigMap/writeToSecret paths already deref unguarded too, so this PR isn't introducing the panic, but the inconsistency within new code is worth resolving: either drop the nil-guard in validateFieldExportNamespace (callers downstream already assume non-nil), or thread the safe targetName through and use it here. Pick one and be consistent.
There was a problem hiding this comment.
Fixed in #248 - using nil-safe targetName variable with guard check before deref, consistent with validateFieldExportNamespace.
| Status: corev1.ConditionTrue, | ||
| Message: &message, | ||
| } | ||
| desired.Status.Conditions = append(desired.Status.Conditions, condition) |
There was a problem hiding this comment.
setCrossNsOptInRequiredCondition appends unconditionally. Safe today because resetConditions runs at the top of Sync (line 151), but it diverges from the lookup-or-create pattern used by patchRecoverableCondition (line 517) and patchTerminalCondition (line 551). If resetConditions is ever moved or skipped, this will accumulate duplicates silently. Prefer the existing pattern (search by type, update if present, append if not) so this code reads the same as its neighbors.
There was a problem hiding this comment.
Fixed in #248 — now uses lookup-or-create pattern (search by type, update if present, append if not) matching patchRecoverableCondition/patchTerminalCondition.
| // reference specifies a Namespace that differs from the namespace of the | ||
| // resource containing the reference, and the | ||
| // --enable-cross-namespace flag is not enabled. | ||
| ResourceReferenceCrossNamespaceNotAllowed = fmt.Errorf( |
There was a problem hiding this comment.
--enable-cross-namespace is a bool flag; Set --enable-cross-namespace=true to allow it. is what operators actually need to type. Worth flipping the message text. Also: while the flag still defaults to true, this terminal error will only ever fire when an operator explicitly opted out — so the wording is fine. When the default flips, consider also referencing the ACK.CrossNamespaceOptInRequired condition so users can audit their fleet before the flip lands.
There was a problem hiding this comment.
Fixed in #248 — error message now says Set --enable-cross-namespace=true to allow it
| if enableCrossNamespace { | ||
| return *refNamespace, true, nil | ||
| } | ||
| return "", false, ackerr.ResourceReferenceCrossNamespaceNotAllowedFor( |
There was a problem hiding this comment.
Minor: returning "" for resolvedNamespace alongside the error is technically fine — the contract says callers must check err first — but it's a foot-gun if a future caller ignores the error and falls through to an empty-namespace Get. Either return ownerNamespace defensively (so a misuse fails closed on the owner ns rather than cluster-scoped), or return *refNamespace so the rejected value is at least diagnostic.
There was a problem hiding this comment.
Fixed in #248 - returns ownerNamespace instead of "" so a misuse fails closed on the owner namespace.
| rm.AssertNotCalled(t, "ReadOne", ctx, desired) | ||
| // No downstream operations should occur | ||
| rm.AssertNotCalled(t, "Create", ctx, desired) | ||
| rm.AssertNotCalled(t, "Update") |
There was a problem hiding this comment.
Good coverage on the reference-resolution rejection path. Three gaps still uncovered for the new code paths most likely to regress later:
field_export_reconciler.Syncrejection branch (line 158–159) whenEnableCrossNamespace=falseand the FieldExport target is a different namespace.setCrossNsOptInRequiredConditionis set on the FieldExport when flag=true and namespaces differ (the deprecation-warning happy path).WithReferencesResolvedCondition(pkg/condition/condition.go:317-318): a unit test asserting the newResourceReferenceCrossNamespaceNotAllowedbranch resolves toConditionFalse(notConditionUnknown).
Non-blocking, but easy adds while the helper signature is fresh.
| // and we'll use the custom role to manage the AWSResource | ||
| ConditionTypeIAMRoleSelected ConditionType = "ACK.IAMRoleSelected" | ||
| // ConditionTypeCrossNamespaceOptInRequired indicates that the resource uses | ||
| // cross-namespace behavior (resource references, secret references, or |
There was a problem hiding this comment.
Naming inconsistency: PR description calls this ACK.CrossNamespaceDeprecation, the type added here is ACK.CrossNamespaceOptInRequired. The latter is the better of the two (describes the action operators must take), but please update the PR body so downstream release notes don't spread the wrong name — and be aware that the condition Type string is part of the user-visible API.
There was a problem hiding this comment.
Fixed in #248 - PR description updated to use ACK.CrossNamespaceOptInRequired.
|
The ec2-controller-test failure is unrelated to this PR. It's a known issue where system tags (services.k8s.aws/*) leak into spec.tags. A possible fix should be #246 |
|
/retest |
|
Doc changes is added - aws-controllers-k8s/docs#37 |
|
Addressed the comments in #248 |
Issue #, if available:
Description of changes:
Introduce a single CLI flag that controls all three categories of cross-namespace behavior: resource references, secret references, and field exports. It defaults to true with deprecation warnings to start with. It will default to false later in order to follow best security practice.
Changes:
--enable-cross-namespaceCLI flag with default valuetrueBy submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.