diff --git a/pkg/rbac/parser.go b/pkg/rbac/parser.go index 5ed27a849..059acbb32 100644 --- a/pkg/rbac/parser.go +++ b/pkg/rbac/parser.go @@ -59,6 +59,9 @@ type Rule struct { // Namespace specifies the scope of the Rule. // If not set, the Rule belongs to the generated ClusterRole. // If set, the Rule belongs to a Role, whose namespace is specified by this field. + // The generated Role name will be suffixed with the namespace (e.g., "manager-role-namespace") + // to ensure uniqueness when multiple namespace-scoped Roles are generated. This suffix is + // ONLY applied to namespace-scoped Roles, not to ClusterRoles. Namespace string `marker:",optional"` } @@ -347,7 +350,7 @@ func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]any, error APIVersion: rbacv1.SchemeGroupVersion.String(), }, ObjectMeta: metav1.ObjectMeta{ - Name: roleName, + Name: fmt.Sprintf("%s-%s", roleName, ns), Namespace: ns, }, Rules: policyRules, diff --git a/pkg/rbac/testdata/controller.go b/pkg/rbac/testdata/controller.go index 984557e50..172eeba6a 100644 --- a/pkg/rbac/testdata/controller.go +++ b/pkg/rbac/testdata/controller.go @@ -37,3 +37,5 @@ package controller // +kubebuilder:rbac:groups=core;"";some-other-to-deduplicate-with-core,resources=me,verbs=list;get // +kubebuilder:rbac:groups=deduplicate-groups5,resources=abc,verbs=get;update;patch;create,namespace=here // +kubebuilder:rbac:groups=deduplicate-groups5,resources=abc,verbs=*,namespace=here +// +kubebuilder:rbac:groups=apps,namespace=infrastructure,resources=deployments,verbs=get;list;watch;update;patch +// +kubebuilder:rbac:groups="",namespace=users,resources=secrets,verbs=get;list;watch diff --git a/pkg/rbac/testdata/role.yaml b/pkg/rbac/testdata/role.yaml index a28e37a92..e603b6148 100644 --- a/pkg/rbac/testdata/role.yaml +++ b/pkg/rbac/testdata/role.yaml @@ -132,7 +132,7 @@ rules: apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: manager-role + name: manager-role-here namespace: here rules: - apiGroups: @@ -145,7 +145,24 @@ rules: apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: manager-role + name: manager-role-infrastructure + namespace: infrastructure +rules: +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: manager-role-park namespace: park rules: - apiGroups: @@ -158,7 +175,22 @@ rules: apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: manager-role + name: manager-role-users + namespace: users +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: manager-role-zoo namespace: zoo rules: - apiGroups: @@ -168,4 +200,3 @@ rules: - jobs verbs: - get - diff --git a/pkg/rbac/zz_generated.markerhelp.go b/pkg/rbac/zz_generated.markerhelp.go index 085898ab5..4fe7b42ea 100644 --- a/pkg/rbac/zz_generated.markerhelp.go +++ b/pkg/rbac/zz_generated.markerhelp.go @@ -82,7 +82,7 @@ func (Rule) Help() *markers.DefinitionHelp { }, "Namespace": { Summary: "specifies the scope of the Rule.", - Details: "If not set, the Rule belongs to the generated ClusterRole.\nIf set, the Rule belongs to a Role, whose namespace is specified by this field.", + Details: "If not set, the Rule belongs to the generated ClusterRole.\nIf set, the Rule belongs to a Role, whose namespace is specified by this field.\nThe generated Role name will be suffixed with the namespace (e.g., \"manager-role-namespace\")\nto ensure uniqueness when multiple namespace-scoped Roles are generated. This suffix is\nONLY applied to namespace-scoped Roles, not to ClusterRoles.", }, }, }