feat: namespace-scoped ControlPlane, ControlPlaneEndpoint, ControlPlaneRegistration#12
Conversation
…ration namespace-scoped Enables multi-tenant isolation via namespace-based RBAC. CPs live in org/project namespaces, and standard k8s RBAC on the namespace governs who can create/view them. Changes: - ControlPlane: scope=Cluster → scope=Namespaced - ControlPlaneEndpoint: scope=Cluster → scope=Namespaced - ControlPlaneRegistration: scope=Cluster → scope=Namespaced - All endpoint/CP lookups now include namespace from the parent resource - Management namespace naming includes CP namespace to avoid collisions - Gateway resources (HTTPRoute, ControlPlaneEndpoint) created in CP namespace - Tests updated for namespace-scoped resources ControlPlaneClass remains cluster-scoped (it's policy, not tenant data). CLI compatibility: kplane CLI creates CPs in its configured namespace (typically kplane-system or default). No CLI code changes needed. BREAKING: CRD scope change is immutable — old CRDs must be deleted and recreated. Existing ControlPlane resources must be migrated.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| return name | ||
| } | ||
| hash := sha256.Sum256([]byte(controlPlane.Name)) | ||
| hash := sha256.Sum256([]byte(cpID)) |
There was a problem hiding this comment.
Truncation uses Name instead of cpID losing namespace
Medium Severity
In managementNamespace, the new cpID variable (which includes the namespace prefix for non-default namespaces) is correctly used for both the initial name construction and the hash computation. However, trunc on line 379 still uses controlPlane.Name instead of cpID. When truncation kicks in (name exceeding 63 chars), the namespace portion is entirely dropped from the human-readable part of the management namespace name. While the hash suffix prevents actual collisions, this inconsistency defeats the purpose of including the namespace in cpID and makes the truncated names misleading.
|
|
||
| // +kubebuilder:object:root=true | ||
| // +kubebuilder:resource:scope=Cluster | ||
| // +kubebuilder:resource:scope=Namespaced |
There was a problem hiding this comment.
Default clusterPath uses non-unique Name causing data collision
High Severity
The scope change from Cluster to Namespaced means controlPlane.Name is no longer globally unique. However, clusterPathForControlPlane still defaults clusterPath to controlPlane.Name, which is the key used to partition virtual cluster data in etcd (via /clusters/<clusterPath>/). Two CPs with the same name in different namespaces would share the same virtual cluster data path. Worse, destroyClusterData uses this path to delete etcd keys — deleting one CP with DeletionPolicyDestroy would destroy another same-named CP's data. The managementNamespace function was updated with cpID to handle namespace collisions, but clusterPathForControlPlane was not.


Summary
Breaking change
CRD scope is immutable — old CRDs must be deleted and recreated.
CLI compatibility
No CLI code changes needed — CPs are created in the configured namespace.
Note
High Risk
High risk because it changes CRD scope (an immutable, breaking API change) and updates controller reconciliation/resource lookup semantics to be namespace-aware, which can affect routing/endpoint resolution and multi-tenant behavior if any namespace handling is missed.
Overview
Scope change: Updates the CRDs and kubebuilder markers so
ControlPlane,ControlPlaneEndpoint, andControlPlaneRegistrationare Namespaced instead of cluster-scoped.Controller behavior updates: Adjusts reconciliation to fetch referenced
ControlPlaneEndpoint/ControlPlaneobjects using the caller’s namespace, creates auto-managed gateway resources (ControlPlaneEndpoint,HTTPRoute) in theControlPlanenamespace, and updates management-namespace naming to include theControlPlanenamespace to avoid cross-namespace name collisions.Tests: Updates controller tests to consistently create/get/delete these resources using explicit namespaces.
Written by Cursor Bugbot for commit f7471da. This will update automatically on new commits. Configure here.