@@ -82,7 +82,9 @@ func (r *ClusterPermissionReconciler) Reconcile(ctx context.Context, req ctrl.Re
8282 log .Info ("validating ClusterPermission" )
8383
8484 /* Validations */
85- if clusterPermission .Spec .ClusterRoleBinding == nil && clusterPermission .Spec .RoleBindings == nil {
85+ if clusterPermission .Spec .ClusterRoleBinding == nil &&
86+ (clusterPermission .Spec .ClusterRoleBindings == nil || len (* clusterPermission .Spec .ClusterRoleBindings ) == 0 ) &&
87+ (clusterPermission .Spec .RoleBindings == nil || len (* clusterPermission .Spec .RoleBindings ) == 0 ) {
8688 log .Info ("no bindings defined for ClusterPermission" )
8789
8890 err := r .updateStatus (ctx , & clusterPermission , & metav1.Condition {
@@ -117,7 +119,7 @@ func (r *ClusterPermissionReconciler) Reconcile(ctx context.Context, req ctrl.Re
117119
118120 log .Info ("preparing ManifestWork payload" )
119121
120- clusterRole , clusterRoleBinding , roles , roleBindings , err := r .generateManifestWorkPayload (
122+ clusterRole , clusterRoleBindings , roles , roleBindings , err := r .generateManifestWorkPayload (
121123 ctx , & clusterPermission )
122124 if err != nil {
123125 log .Error (err , "failed to generate payload" )
@@ -134,7 +136,7 @@ func (r *ClusterPermissionReconciler) Reconcile(ctx context.Context, req ctrl.Re
134136
135137 mwName := generateManifestWorkName (clusterPermission )
136138 manifestWork := buildManifestWork (clusterPermission , mwName ,
137- clusterRole , clusterRoleBinding , roles , roleBindings )
139+ clusterRole , clusterRoleBindings , roles , roleBindings )
138140
139141 var mw workv1.ManifestWork
140142 err = r .Get (ctx , types.NamespacedName {Name : mwName , Namespace : clusterPermission .Namespace }, & mw )
@@ -255,9 +257,9 @@ func (r *ClusterPermissionReconciler) generateSubjects(ctx context.Context,
255257
256258// generateManifestWorkPayload creates the payload for the ManifestWork based on the ClusterPermission spec
257259func (r * ClusterPermissionReconciler ) generateManifestWorkPayload (ctx context.Context , clusterPermission * cpv1alpha1.ClusterPermission ) (
258- * rbacv1.ClusterRole , * rbacv1.ClusterRoleBinding , []rbacv1.Role , []rbacv1.RoleBinding , error ) {
260+ * rbacv1.ClusterRole , [] rbacv1.ClusterRoleBinding , []rbacv1.Role , []rbacv1.RoleBinding , error ) {
259261 var clusterRole * rbacv1.ClusterRole
260- var clusterRoleBinding * rbacv1.ClusterRoleBinding
262+ var clusterRoleBindings [] rbacv1.ClusterRoleBinding
261263 var roles []rbacv1.Role
262264 var roleBindings []rbacv1.RoleBinding
263265
@@ -304,16 +306,63 @@ func (r *ClusterPermissionReconciler) generateManifestWorkPayload(ctx context.Co
304306 clusterRoleBindingRoleRef = * clusterPermission .Spec .ClusterRoleBinding .RoleRef
305307 }
306308
307- clusterRoleBinding = & rbacv1.ClusterRoleBinding {
308- TypeMeta : metav1.TypeMeta {
309- APIVersion : rbacv1 .SchemeGroupVersion .String (),
310- Kind : "ClusterRoleBinding" ,
311- },
312- ObjectMeta : metav1.ObjectMeta {
313- Name : clusterRoleBindingName ,
314- },
315- RoleRef : clusterRoleBindingRoleRef ,
316- Subjects : subjects ,
309+ // We make the behaviour consistent with how subject and subjects are handled in ClusterRoleBinding
310+ // subjects will just override subject if both are provided
311+ if clusterPermission .Spec .ClusterRoleBindings == nil || len (* clusterPermission .Spec .ClusterRoleBindings ) == 0 {
312+ clusterRoleBindings = append (clusterRoleBindings , rbacv1.ClusterRoleBinding {
313+ TypeMeta : metav1.TypeMeta {
314+ APIVersion : rbacv1 .SchemeGroupVersion .String (),
315+ Kind : "ClusterRoleBinding" ,
316+ },
317+ ObjectMeta : metav1.ObjectMeta {
318+ Name : clusterRoleBindingName ,
319+ },
320+ RoleRef : clusterRoleBindingRoleRef ,
321+ Subjects : subjects ,
322+ })
323+ }
324+ }
325+
326+ // ClusterRoleBindings payload (plural)
327+ if clusterPermission .Spec .ClusterRoleBindings != nil && len (* clusterPermission .Spec .ClusterRoleBindings ) > 0 {
328+ for _ , clusterRoleBinding := range * clusterPermission .Spec .ClusterRoleBindings {
329+ crbSubjects := getSubjects (clusterRoleBinding .Subject , clusterRoleBinding .Subjects )
330+ if err := r .validateSubject (ctx , crbSubjects , clusterPermission .Namespace ); err != nil {
331+ return nil , nil , nil , nil , err
332+ }
333+
334+ subjects , err := r .generateSubjects (ctx , crbSubjects , clusterPermission .Namespace )
335+ if err != nil {
336+ return nil , nil , nil , nil , err
337+ }
338+
339+ // default to ClusterPermission name unless using custom name
340+ clusterRoleBindingName := clusterPermission .Name
341+ if clusterRoleBinding .Name != "" {
342+ clusterRoleBindingName = clusterRoleBinding .Name
343+ }
344+
345+ // default to creating a ClusterRole unless using existing ClusterRole
346+ clusterRoleBindingRoleRef := rbacv1.RoleRef {
347+ APIGroup : rbacv1 .GroupName ,
348+ Kind : "ClusterRole" ,
349+ Name : clusterPermission .Name ,
350+ }
351+ if clusterRoleBinding .RoleRef != nil {
352+ clusterRoleBindingRoleRef = * clusterRoleBinding .RoleRef
353+ }
354+
355+ clusterRoleBindings = append (clusterRoleBindings , rbacv1.ClusterRoleBinding {
356+ TypeMeta : metav1.TypeMeta {
357+ APIVersion : rbacv1 .SchemeGroupVersion .String (),
358+ Kind : "ClusterRoleBinding" ,
359+ },
360+ ObjectMeta : metav1.ObjectMeta {
361+ Name : clusterRoleBindingName ,
362+ },
363+ RoleRef : clusterRoleBindingRoleRef ,
364+ Subjects : subjects ,
365+ })
317366 }
318367 }
319368
@@ -479,5 +528,5 @@ func (r *ClusterPermissionReconciler) generateManifestWorkPayload(ctx context.Co
479528 }
480529 }
481530
482- return clusterRole , clusterRoleBinding , roles , roleBindings , nil
531+ return clusterRole , clusterRoleBindings , roles , roleBindings , nil
483532}
0 commit comments