WIP: feat(namespacesync): add NamespaceSyncController for per-namespace resource management#3581
Draft
jkhelil wants to merge 7 commits into
Draft
WIP: feat(namespacesync): add NamespaceSyncController for per-namespace resource management#3581jkhelil wants to merge 7 commits into
jkhelil wants to merge 7 commits into
Conversation
…source management Add a new watch-based NamespaceSyncController that replaces the scan-based per-namespace reconciliation loop in rbac.go. The new controller uses Kubernetes informers to react to namespace, ServiceAccount, Secret, and TektonConfig events, eliminating O(N) API server calls on every TektonConfig reconcile. New typed API in TektonConfig.spec.platforms.openShift.namespaceSync: - createPipelineSA: manage the pipeline ServiceAccount (replaces createRbacResource) - createCABundles: manage CA bundle ConfigMaps (replaces createCABundleConfigMaps) - createEditRoleBinding: manage openshift-pipelines-edit RoleBinding (replaces legacyPipelineRbac) - createSCCRoleBinding: manage pipelines-scc-rolebinding (defaults true) - secretBindings: bind registry secrets (by name or label selector) to the pipeline SA Key behaviors: - Pipeline SA self-heals on add/update/delete events - Named secret bindings are removed from the pipeline SA when the secret is deleted - Label-based bindings re-evaluate on every secret add/delete event - TektonConfig updates only trigger a full namespace sweep when the NamespaceSync config itself changes (reflect.DeepEqual guard prevents thundering herd) - Legacy spec.params entries are migrated to the typed fields on first reconcile Design doc: docs/plans/2026-06-26-namespace-sync-controller-design.md Signed-off-by: Abdeljaouad Khelil <akhelil@redhat.com> Assisted-by: Claude Sonnet 4.6 Co-authored-by: Cursor <cursoragent@cursor.com>
When TektonConfig.spec.platforms.openShift.namespaceSync is configured (which is now the default), the NamespaceSyncController owns all per-namespace resources (pipeline SA, CA bundles, SCC RoleBinding, edit RoleBinding, secret bindings). The legacy rbac.go createResources loop now skips per-namespace iteration and only maintains cluster-scoped resources: - ensurePreRequisites: RBACInstallerSet, pipelines-scc-clusterrole, SCC validation - removeAndUpdateNSFromCI: ClusterInterceptors ClusterRoleBinding cleanup - handleClusterRoleBinding: keep openshift-pipelines-clusterinterceptors in sync using existing pipeline SAs collected via the new collectExistingPipelineSAs helper This commit can be reverted independently to restore the legacy scan-based per-namespace reconciliation without losing the NamespaceSyncController changes. Signed-off-by: Abdeljaouad Khelil <akhelil@redhat.com> Assisted-by: Claude Sonnet 4.6 Co-authored-by: Cursor <cursoragent@cursor.com>
…RoleBinding The openshift-pipelines-clusterinterceptors ClusterRoleBinding grants the pipeline SA in every user namespace get/list/watch access to ClusterInterceptors, which EventListeners need to resolve webhook interceptors. The previous implementation in rbac.go rebuilt the full subject list on every TektonConfig reconcile (O(N) API calls). NamespaceSyncController now manages this ClusterRoleBinding with a per-namespace patch: - Pipeline SA created / namespace reconciled → subject is added (idempotent). - Pipeline SA deleted → reconcile of that namespace removes the subject. - RetryOnConflict handles concurrent updates from parallel namespace workers. - ClusterRole is bootstrapped once; it never changes so no update path needed. Five new tests cover: creation, no-op when SA absent, idempotency, multi-namespace accumulation, and subject removal on SA deletion. Signed-off-by: Abdeljaoued Khelil <abdeljaouedkhelil@example.com> Assisted-by: Claude Sonnet 4.6 Co-authored-by: Cursor <cursoragent@cursor.com>
Now that NamespaceSyncController handles the openshift-pipelines-clusterinterceptors ClusterRoleBinding incrementally per namespace, rbac.go no longer needs to: - Accumulate all pipeline SAs via collectExistingPipelineSAs - Rebuild the full subject list via handleClusterRoleBinding The NamespaceSync guard in createResources is simplified: it now only calls ensurePreRequisites (cluster-scoped SCC ClusterRole + validation) before returning; all other RBAC and secret binding work is owned by the new controller. Signed-off-by: Abdeljaoued Khelil <abdeljaouedkhelil@example.com> Assisted-by: Claude Sonnet 4.6 Co-authored-by: Cursor <cursoragent@cursor.com>
…ped work Now that NamespaceSyncController owns all per-namespace resources (pipeline SA, CA bundles, SCC RoleBinding, edit RoleBinding, secret bindings, ClusterInterceptors subjects) and NamespaceSync is always defaulted to non-nil, the legacy per-namespace branch of rbac.go is permanently unreachable. Removed (~1 350 lines): - shouldIgnoreNamespace, needsRBAC, needsCABundle, getNamespacesToBeReconciled - processRBAC, handleSCCInNamespace, getSCCRoleInNamespace, patchNamespaceLabel - ensureSA, createSA, ensureSCCRoleInNamespace - ensurePipelinesSCCRoleBinding, createSCCRoleBinding, updateRoleBinding - ensureCABundles, ensureCABundlesInNamespace, createCABundleConfigMaps - createServiceCABundleConfigMap, patchNamespaceTrustedConfigLabel - ensureRoleBindings, createRoleBinding, isLegacyRBACEnabled - handleClusterRoleBinding, bulkUpdateClusterRoleBinding, bulkCreateClusterRoleBinding - createClusterRole, removeAndUpdateNSFromCI, removeIndex - updateOwnerRefs, removeAndUpdate, hasSubject, CompareSubjects, mergeSubjects - hasOwnerRefernce, cleanUpRBACNameChange (TODO: remove after v0.55.0 - now done) - NamespaceServiceAccount, NamespacesToReconcile types Kept: - createResources → only calls ensurePreRequisites (cluster-scoped) - ensurePreRequisites: InstallerSet, SCC validation, pipelines-scc-clusterrole - ensurePipelinesSCClusterRole: dynamic ClusterRole for default SCC - EnsureRBACInstallerSet, cleanUp, setDefault, removeObsoleteRBACInstallerSet extension.go: removed rbacInformer field (no longer needed), removed cleanUpRBACNameChange call, removed unused rbacV1 and rbacInformer imports. rbac_test.go: replaced 500-line dead-path test with focused tests for createResources (prerequisites path) and setDefault. Signed-off-by: Abdeljaoued Khelil <abdeljaouedkhelil@example.com> Assisted-by: Claude Sonnet 4.6 Co-authored-by: Cursor <cursoragent@cursor.com>
Add the namespacesync controller to the lifecycle container's -controllers arg so it actually runs on OpenShift. Add the namespaceSync field schema to the TektonConfig CRD so the API server accepts it. Embed reconciler.LeaderAwareFuncs in the Reconciler struct to satisfy Knative sharedmain's leader-election requirement. Signed-off-by: Jawed khelil <jkhelil@redhat.com> Assisted-by: Claude Sonnet 4.6 (via Cursor) Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: 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 |
The e2e test referenced tconfig.PipelineRoleBinding from the tektonconfig package, which no longer exists after the rbac.go cleanup. Export the constant from namespacesync (its new owner) and update the test import alias accordingly. Signed-off-by: Jawed khelil <jkhelil@redhat.com> Assisted-by: Claude Sonnet 4.6 (via Cursor) Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
Introduces a new
NamespaceSyncControllerthat replaces thescan-based batch processing in
rbac.gowith an event-driven,per-namespace reconciler. Addresses RFE-7814 (flexible service
account binding for Quay Robot credentials).
What this does
NamespaceSyncController— a watch-based controller thatreacts to Namespace, ServiceAccount, Secret, and TektonConfig
events to ensure per-namespace Tekton resources are present and
up to date in every user namespace
pipelineSA, SCC RoleBinding, edit RoleBinding, andCA bundle ConfigMaps in each namespace
openshift-pipelines-clusterinterceptorsCRBincrementally (add/remove only the affected namespace's subject)
spec.platforms.openshift .namespaceSync.secretBindings(the core RFE-7814 use case)spec.platforms.openshift.namespaceSyncAPI field toTektonConfig, replacing legacy
spec.paramsentriesrbac.goLeaderAwareFuncsembedding (required by Knative sharedmain)namespaceSyncschema to the TektonConfig CRDStatus
Work in progress — more e2e tests needed before merge:
make test lintfull passVerified on cluster
All per-namespace resources (pipeline SA, SCC RoleBinding, edit
RoleBinding, CA bundles, CRB subject) created correctly in new
namespaces within seconds. Established namespaces unaffected.
Submitter Checklist
make test lintbefore submitting a PRRelease Notes
Made with Cursor