You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
LockedResourceReconciler enforces a locked resource with a merge patch computed from a diff between the rendered object and the live one. A merge patch cannot say "this field is no longer rendered", so:
excludedPaths can only be honoured by omission, so consumers exclude .metadata wholesale. With the merge patch, a label added by anyone else was a permanent difference, so the namespace-configuration-operator excluded all of .metadata by default and thereby stopped enforcing the labels and annotations its own templates render.
Indexed excluded paths are mangled (.data['0'] read as a list index releases all of data; a key named -1 rejected on a pointer round trip).
The global template cache races under concurrent reconciles (concurrent map writes; a fatal on a busy operator).
Proposal
Enforce with server-side apply: one forced apply per reconcile under a fixed field manager. The API server then restores drift on owned fields, removes fields the template no longer renders, leaves fields owned by other managers alone, and a no-op apply writes nothing. excludedPaths keep their meaning ("set once, then left alone") by ownership rather than omission: before each apply the reconciler releases the excluded paths from its own managedFields entry, at the unit the server tracks (learned from one dry-run apply per reconciler, so an exclusion inside an atomic list such as RBAC rules releases that unit). An optional LegacyFieldManagers fold lets a consumer that knows its history migrate objects created by the merge-patch enforcer.
Consumer running it: https://github.com/ephico2real2/namespace-configuration-operator (go.mod replace to the fork; deployed and verified on an OpenShift cluster: drift on a rendered label restored within seconds, a foreign label kept, the managed objects' only field manager is the apply manager).
Proof: envtest-backed tests in pkg/util/lockedresourcecontroller/resource-reconciler_ssa_test.go; three adversarial review passes recorded in docs/REVIEW_ssa-enforcer.md in the PR, every verdict re-measured.
Happy to split the PR (cache fix, path parsing, SSA enforcer) if that helps review.
Problem
LockedResourceReconcilerenforces a locked resource with a merge patch computed from a diff between the rendered object and the live one. A merge patch cannot say "this field is no longer rendered", so:ResourceQuotafield set to0stays after its conditional stops rendering it). My earlier fix, Fix issue #194: Remove fields with value 0 when conditionals change #103, injected nulls and computed a diff; the review there suggested server-side apply as the simpler mechanism.excludedPathscan only be honoured by omission, so consumers exclude.metadatawholesale. With the merge patch, a label added by anyone else was a permanent difference, so the namespace-configuration-operator excluded all of.metadataby default and thereby stopped enforcing the labels and annotations its own templates render..data['0']read as a list index releases all ofdata; a key named-1rejected on a pointer round trip).Proposal
Enforce with server-side apply: one forced apply per reconcile under a fixed field manager. The API server then restores drift on owned fields, removes fields the template no longer renders, leaves fields owned by other managers alone, and a no-op apply writes nothing.
excludedPathskeep their meaning ("set once, then left alone") by ownership rather than omission: before each apply the reconciler releases the excluded paths from its ownmanagedFieldsentry, at the unit the server tracks (learned from one dry-run apply per reconciler, so an exclusion inside an atomic list such as RBACrulesreleases that unit). An optionalLegacyFieldManagersfold lets a consumer that knows its history migrate objects created by the merge-patch enforcer.Implementation, tested and running
feat/ssa-enforcer, on top of upstream master), which supersedes Fix issue #194: Remove fields with value 0 when conditionals change #103.replaceto the fork; deployed and verified on an OpenShift cluster: drift on a rendered label restored within seconds, a foreign label kept, the managed objects' only field manager is the apply manager).pkg/util/lockedresourcecontroller/resource-reconciler_ssa_test.go; three adversarial review passes recorded indocs/REVIEW_ssa-enforcer.mdin the PR, every verdict re-measured.Happy to split the PR (cache fix, path parsing, SSA enforcer) if that helps review.