@@ -7,10 +7,10 @@ import (
77
88 rbacv1 "k8s.io/api/rbac/v1"
99 "k8s.io/apimachinery/pkg/runtime/schema"
10- "k8s.io/utils/ptr"
1110 "sigs.k8s.io/controller-runtime/pkg/client"
1211
13- slicesutil "github.com/operator-framework/operator-controller/internal/shared/util/filter"
12+ "github.com/operator-framework/operator-controller/internal/shared/util/filter"
13+ slicesutil "github.com/operator-framework/operator-controller/internal/shared/util/slices"
1414)
1515
1616var (
@@ -45,21 +45,16 @@ var (
4545 }
4646)
4747
48- // GenerateResourceManagerClusterRole generates a ClusterRole with permissions to manage objs resources. The
48+ // GenerateResourceManagerClusterRolePerms generates a ClusterRole permissions to manage objs resources. The
4949// permissions also aggregate any permissions from any ClusterRoles in objs allowing the holder to also assign
5050// the RBAC therein to another service account. Note: assumes objs have been created by convert.Convert.
51- // The returned ClusterRole will not have set .metadata.name
52- func GenerateResourceManagerClusterRole (objs []client.Object ) * rbacv1.ClusterRole {
53- rules := slices .Concat (
51+ func GenerateResourceManagerClusterRolePerms (objs []client.Object ) []rbacv1.PolicyRule {
52+ return slices .Concat (
5453 // cluster scoped resource creation and management rules
55- generatePolicyRules (slicesutil .Filter (objs , isClusterScopedResource )),
54+ generatePolicyRules (filter .Filter (objs , isClusterScopedResource )),
5655 // controller rbac scope
57- collectRBACResourcePolicyRules (slicesutil .Filter (objs , slicesutil .And (isGeneratedResource , isOfKind ("ClusterRole" )))),
56+ collectRBACResourcePolicyRules (filter .Filter (objs , filter .And (isGeneratedResource , isOfKind ("ClusterRole" )))),
5857 )
59- if len (rules ) == 0 {
60- return nil
61- }
62- return ptr .To (newClusterRole ("" , rules ))
6358}
6459
6560// GenerateClusterExtensionFinalizerPolicyRule generates a policy rule that allows the holder to update
@@ -73,26 +68,27 @@ func GenerateClusterExtensionFinalizerPolicyRule(clusterExtensionName string) rb
7368 }
7469}
7570
76- // GenerateResourceManagerRoles generates one or more Roles with permissions to manage objs resources in their
71+ // GenerateResourceManagerRolePerms generates role permissions to manage objs resources in their
7772// namespaces. The permissions also include any permissions defined in any Roles in objs within the namespace, allowing
7873// the holder to also assign the RBAC therein to another service account.
7974// Note: currently assumes objs have been created by convert.Convert.
8075// The returned Roles will not have set .metadata.name
81- func GenerateResourceManagerRoles (objs []client.Object ) []* rbacv1.Role {
82- return mapToSlice (slicesutil .GroupBy (slicesutil .Filter (objs , isNamespaceScopedResource ), namespaceName ), generateRole )
83- }
84-
85- func generateRole (namespace string , namespaceObjs []client.Object ) * rbacv1.Role {
86- return ptr .To (newRole (
87- namespace ,
88- "" ,
89- slices .Concat (
90- // namespace scoped resource creation and management rules
91- generatePolicyRules (namespaceObjs ),
92- // controller rbac scope
93- collectRBACResourcePolicyRules (slicesutil .Filter (namespaceObjs , slicesutil .And (isOfKind ("Role" ), isGeneratedResource ))),
94- ),
95- ))
76+ func GenerateResourceManagerRolePerms (objs []client.Object ) map [string ][]rbacv1.PolicyRule {
77+ out := map [string ][]rbacv1.PolicyRule {}
78+ namespaceScopedObjs := filter .Filter (objs , isNamespaceScopedResource )
79+ for _ , obj := range namespaceScopedObjs {
80+ namespace := obj .GetNamespace ()
81+ if _ , ok := out [namespace ]; ! ok {
82+ objsInNamespace := filter .Filter (namespaceScopedObjs , isInNamespace (namespace ))
83+ out [namespace ] = slices .Concat (
84+ // namespace scoped resource creation and management rules
85+ generatePolicyRules (objsInNamespace ),
86+ // controller rbac scope
87+ collectRBACResourcePolicyRules (filter .Filter (objsInNamespace , filter .And (isOfKind ("Role" ), isGeneratedResource ))),
88+ )
89+ }
90+ }
91+ return out
9692}
9793
9894func generatePolicyRules (objs []client.Object ) []rbacv1.PolicyRule {
@@ -143,7 +139,7 @@ func isNamespaceScopedResource(o client.Object) bool {
143139 return slices .Contains (namespaceScopedResources , o .GetObjectKind ().GroupVersionKind ().Kind )
144140}
145141
146- func isOfKind (kind string ) slicesutil .Predicate [client.Object ] {
142+ func isOfKind (kind string ) filter .Predicate [client.Object ] {
147143 return func (o client.Object ) bool {
148144 return o .GetObjectKind ().GroupVersionKind ().Kind == kind
149145 }
@@ -155,12 +151,14 @@ func isGeneratedResource(o client.Object) bool {
155151 return ok
156152}
157153
158- func groupKind (obj client.Object ) schema.GroupKind {
159- return obj .GetObjectKind ().GroupVersionKind ().GroupKind ()
154+ func isInNamespace (namespace string ) filter.Predicate [client.Object ] {
155+ return func (o client.Object ) bool {
156+ return o .GetNamespace () == namespace
157+ }
160158}
161159
162- func namespaceName (obj client.Object ) string {
163- return obj .GetNamespace ()
160+ func groupKind (obj client.Object ) schema. GroupKind {
161+ return obj .GetObjectKind (). GroupVersionKind (). GroupKind ()
164162}
165163
166164func toResourceName (o client.Object ) string {
0 commit comments