@@ -153,9 +153,13 @@ func (r *NamespaceScopeReconciler) Reconcile(ctx context.Context, req ctrl.Reque
153
153
return ctrl.Result {}, err
154
154
}
155
155
156
- reg , _ := regexp .Compile (`^nss-managed-role-from.*` )
156
+ reg , err := regexp .Compile (`^nss-(managed|runtime)-role-from.*` )
157
+ if err != nil {
158
+ klog .Errorf ("Failed to compile regular expression: %v" , err )
159
+ return ctrl.Result {}, err
160
+ }
157
161
for _ , namespaceMember := range instance .Spec .NamespaceMembers {
158
- if rolesList , _ := r .GetRolesFromNamespace (ctx , namespaceMember ); len (rolesList ) != 0 {
162
+ if rolesList , _ := r .GetRolesFromNamespace (ctx , instance , namespaceMember ); len (rolesList ) != 0 {
159
163
var summarizedRules []rbacv1.PolicyRule
160
164
for _ , role := range rolesList {
161
165
if ! reg .MatchString (role .Name ) {
@@ -283,9 +287,6 @@ func (r *NamespaceScopeReconciler) PushRbacToNamespace(ctx context.Context, inst
283
287
if toNs == operatorNs {
284
288
continue
285
289
}
286
- if err := r .generateRBACForNSS (ctx , instance , fromNs , toNs ); err != nil {
287
- return err
288
- }
289
290
if err := r .generateRBACToNamespace (ctx , instance , saNames , fromNs , toNs ); err != nil {
290
291
return err
291
292
}
@@ -401,26 +402,6 @@ func (r *NamespaceScopeReconciler) DeleteAllRbac(ctx context.Context, instance *
401
402
return nil
402
403
}
403
404
404
- func (r * NamespaceScopeReconciler ) generateRBACForNSS (ctx context.Context , instance * operatorv1.NamespaceScope , fromNs , toNs string ) error {
405
- labels := map [string ]string {
406
- "namespace-scope-configmap" : instance .Namespace + "-" + instance .Spec .ConfigmapName ,
407
- }
408
- if err := r .createRoleForNSS (ctx , labels , fromNs , toNs ); err != nil {
409
- if errors .IsForbidden (err ) {
410
- r .Recorder .Eventf (instance , corev1 .EventTypeWarning , "Forbidden" , "cannot create resource roles in API group rbac.authorization.k8s.io in the namespace %s. Please authorize service account ibm-namespace-scope-operator namespace admin permission of %s namespace" , toNs , toNs )
411
- }
412
- return err
413
- }
414
- if err := r .createRoleBindingForNSS (ctx , labels , fromNs , toNs ); err != nil {
415
- if errors .IsForbidden (err ) {
416
- r .Recorder .Eventf (instance , corev1 .EventTypeWarning , "Forbidden" , "cannot create resource rolebindings in API group rbac.authorization.k8s.io in the namespace %s. Please authorize service account ibm-namespace-scope-operator namespace admin permission of %s namespace" , toNs , toNs )
417
- }
418
- return err
419
- }
420
-
421
- return nil
422
- }
423
-
424
405
func (r * NamespaceScopeReconciler ) generateRuntimeRoleForNSS (ctx context.Context , instance * operatorv1.NamespaceScope , summarizedRules []rbacv1.PolicyRule , fromNs , toNs string ) error {
425
406
if err := r .createRuntimeRoleForNSS (ctx , summarizedRules , fromNs , toNs ); err != nil {
426
407
if errors .IsAlreadyExists (err ) {
@@ -479,69 +460,6 @@ func (r *NamespaceScopeReconciler) updateRuntimeRoleForNSS(ctx context.Context,
479
460
return nil
480
461
}
481
462
482
- func (r * NamespaceScopeReconciler ) createRoleForNSS (ctx context.Context , labels map [string ]string , fromNs , toNs string ) error {
483
- name := constant .NamespaceScopeManagedPrefix + fromNs
484
- namespace := toNs
485
- role := & rbacv1.Role {
486
- ObjectMeta : metav1.ObjectMeta {
487
- Name : name ,
488
- Namespace : namespace ,
489
- Labels : labels ,
490
- },
491
- Rules : []rbacv1.PolicyRule {
492
- {
493
- Verbs : []string {"create" , "delete" , "get" , "list" , "patch" , "update" , "watch" , "deletecollection" },
494
- APIGroups : []string {"*" },
495
- Resources : []string {"*" },
496
- },
497
- },
498
- }
499
- if err := r .Create (ctx , role ); err != nil {
500
- if errors .IsAlreadyExists (err ) {
501
- return nil
502
- }
503
- klog .Errorf ("Failed to create role %s/%s: %v" , namespace , name , err )
504
- return err
505
- }
506
- klog .Infof ("Created role %s/%s" , namespace , name )
507
- return nil
508
- }
509
-
510
- func (r * NamespaceScopeReconciler ) createRoleBindingForNSS (ctx context.Context , labels map [string ]string , fromNs , toNs string ) error {
511
- name := constant .NamespaceScopeManagedPrefix + fromNs
512
- namespace := toNs
513
- subjects := []rbacv1.Subject {}
514
- subject := rbacv1.Subject {
515
- Kind : "ServiceAccount" ,
516
- Name : constant .NamespaceScopeServiceAccount ,
517
- Namespace : fromNs ,
518
- }
519
- subjects = append (subjects , subject )
520
- roleBinding := & rbacv1.RoleBinding {
521
- ObjectMeta : metav1.ObjectMeta {
522
- Name : name ,
523
- Namespace : namespace ,
524
- Labels : labels ,
525
- },
526
- Subjects : subjects ,
527
- RoleRef : rbacv1.RoleRef {
528
- Kind : "Role" ,
529
- Name : constant .NamespaceScopeManagedPrefix + fromNs ,
530
- APIGroup : "rbac.authorization.k8s.io" ,
531
- },
532
- }
533
-
534
- if err := r .Create (ctx , roleBinding ); err != nil {
535
- if errors .IsAlreadyExists (err ) {
536
- return nil
537
- }
538
- klog .Errorf ("Failed to create rolebinding %s/%s: %v" , namespace , name , err )
539
- return err
540
- }
541
- klog .Infof ("Created rolebinding %s/%s" , namespace , name )
542
- return nil
543
- }
544
-
545
463
func (r * NamespaceScopeReconciler ) generateRBACToNamespace (ctx context.Context , instance * operatorv1.NamespaceScope , saNames []string , fromNs , toNs string ) error {
546
464
labels := map [string ]string {
547
465
"namespace-scope-configmap" : instance .Namespace + "-" + instance .Spec .ConfigmapName ,
@@ -571,7 +489,7 @@ func (r *NamespaceScopeReconciler) generateRBACToNamespace(ctx context.Context,
571
489
return nil
572
490
}
573
491
574
- func (r * NamespaceScopeReconciler ) GetRolesFromNamespace (ctx context.Context , namespace string ) ([]rbacv1.Role , error ) {
492
+ func (r * NamespaceScopeReconciler ) GetRolesFromNamespace (ctx context.Context , instance * operatorv1. NamespaceScope , namespace string ) ([]rbacv1.Role , error ) {
575
493
rolesList := & rbacv1.RoleList {}
576
494
577
495
opts := []client.ListOption {
@@ -588,7 +506,7 @@ func (r *NamespaceScopeReconciler) GetRolesFromNamespace(ctx context.Context, na
588
506
589
507
roles := []rbacv1.Role {}
590
508
for _ , role := range rolesList .Items {
591
- if _ , ok := role .Labels [constant .NamespaceScopeConfigmapLabelKey ]; ok {
509
+ if value , ok := role .Labels [constant .NamespaceScopeConfigmapLabelKey ]; ok && value == instance . Namespace + "-" + instance . Spec . ConfigmapName {
592
510
roles = append (roles , role )
593
511
}
594
512
}
@@ -657,6 +575,17 @@ func (r *NamespaceScopeReconciler) GetRolesFromServiceAccount(ctx context.Contex
657
575
}
658
576
659
577
func (r * NamespaceScopeReconciler ) CreateRole (ctx context.Context , roleNames []string , labels map [string ]string , saName , fromNs , toNs string ) error {
578
+ // Get the permissions that NamespaceScope Operator has from the toNs
579
+ nssManagedRole := & rbacv1.Role {}
580
+ if err := r .Reader .Get (ctx , types.NamespacedName {Name : constant .NamespaceScopeManagedPrefix + fromNs , Namespace : toNs }, nssManagedRole ); err != nil {
581
+ if errors .IsNotFound (err ) {
582
+ klog .Errorf ("Role %s not found in namespace %s: %v" , constant .NamespaceScopeManagedPrefix + fromNs , toNs , err )
583
+ return err
584
+ }
585
+ klog .Errorf ("Failed to get role %s in namespace %s: %v" , constant .NamespaceScopeManagedPrefix + fromNs , toNs , err )
586
+ return err
587
+ }
588
+
660
589
for _ , roleName := range roleNames {
661
590
originalRole := & rbacv1.Role {}
662
591
if err := r .Reader .Get (ctx , types.NamespacedName {Name : roleName , Namespace : fromNs }, originalRole ); err != nil {
@@ -670,7 +599,7 @@ func (r *NamespaceScopeReconciler) CreateRole(ctx context.Context, roleNames []s
670
599
hashedServiceAccount := sha256 .Sum256 ([]byte (roleName + saName + fromNs ))
671
600
name := strings .Split (roleName , "." )[0 ] + "-" + hex .EncodeToString (hashedServiceAccount [:7 ])
672
601
namespace := toNs
673
- rules := rulesFilter (originalRole .Rules )
602
+ rules := rulesFilter (roleName , fromNs , toNs , originalRole . Rules , nssManagedRole .Rules )
674
603
role := & rbacv1.Role {
675
604
ObjectMeta : metav1.ObjectMeta {
676
605
Name : name ,
@@ -938,19 +867,48 @@ func (r *NamespaceScopeReconciler) checkGetNSAuth(ctx context.Context) bool {
938
867
return sar .Status .Allowed
939
868
}
940
869
941
- func rulesFilter (orgRule []rbacv1.PolicyRule ) []rbacv1.PolicyRule {
870
+ func rulesFilter (roleName , fromNs , toNs string , orgRule , nssManagedRule []rbacv1.PolicyRule ) []rbacv1.PolicyRule {
942
871
verbMap := make (map [string ]struct {})
943
872
verbs := []string {"create" , "delete" , "get" , "list" , "patch" , "update" , "watch" , "deletecollection" }
944
873
for _ , v := range verbs {
945
874
verbMap [v ] = struct {}{}
946
875
}
876
+ needRuleAppending := false
877
+ for i := 0 ; i < len (orgRule ); {
878
+ // filter out the wildcard in APIGroups
879
+ for j := 0 ; j < len (orgRule [i ].APIGroups ); {
880
+ if orgRule [i ].APIGroups [j ] == "*" {
881
+ orgRule [i ].APIGroups = append (orgRule [i ].APIGroups [:j ], orgRule [i ].APIGroups [j + 1 :]... )
882
+ klog .Warningf ("Role %s in namespace %s has wildcard * in APIGroups, which is removed from its copied Role in namespace %s" , roleName , fromNs , toNs )
883
+ needRuleAppending = true
884
+ continue
885
+ }
886
+ j ++
887
+ }
888
+ if len (orgRule [i ].APIGroups ) == 0 {
889
+ orgRule = append (orgRule [:i ], orgRule [i + 1 :]... )
890
+ continue
891
+ }
892
+ // filter out the wildcard in Resources
893
+ for j := 0 ; j < len (orgRule [i ].Resources ); {
894
+ if orgRule [i ].Resources [j ] == "*" {
895
+ orgRule [i ].Resources = append (orgRule [i ].Resources [:j ], orgRule [i ].Resources [j + 1 :]... )
896
+ klog .Warningf ("Role %s in namespace %s has wildcard * in Resources, which is removed from its copied Role in namespace %s" , roleName , fromNs , toNs )
897
+ needRuleAppending = true
898
+ continue
899
+ }
900
+ j ++
901
+ }
902
+ if len (orgRule [i ].Resources ) == 0 {
903
+ orgRule = append (orgRule [:i ], orgRule [i + 1 :]... )
904
+ continue
905
+ }
947
906
948
- for i := 0 ; i < len (orgRule ); i ++ {
949
- j := 0
950
- for j < len (orgRule [i ].Verbs ) {
907
+ for j := 0 ; j < len (orgRule [i ].Verbs ); {
951
908
if orgRule [i ].Verbs [j ] == "*" {
952
909
orgRule [i ].Verbs = append (orgRule [i ].Verbs [:j ], orgRule [i ].Verbs [j + 1 :]... )
953
910
orgRule [i ].Verbs = append (orgRule [i ].Verbs , verbs ... )
911
+ klog .Warningf ("Role %s in namespace %s has wildcard * in Verbs, which is replaced with all verbs in its copied Role in namespace %s" , roleName , fromNs , toNs )
954
912
continue
955
913
}
956
914
if _ , ok := verbMap [orgRule [i ].Verbs [j ]]; ! ok {
@@ -959,10 +917,19 @@ func rulesFilter(orgRule []rbacv1.PolicyRule) []rbacv1.PolicyRule {
959
917
}
960
918
j ++
961
919
}
920
+
962
921
if len (orgRule [i ].Verbs ) == 0 {
963
922
orgRule = append (orgRule [:i ], orgRule [i + 1 :]... )
923
+ continue
964
924
}
925
+ i ++
965
926
}
927
+
928
+ if needRuleAppending {
929
+ orgRule = append (orgRule , nssManagedRule ... )
930
+ klog .Infof ("Role %s has been appended with role %s in namespace %s" , roleName , constant .NamespaceScopeManagedPrefix + fromNs , toNs )
931
+ }
932
+
966
933
return orgRule
967
934
}
968
935
@@ -1065,7 +1032,7 @@ func (r *NamespaceScopeReconciler) CSVReconcile(ctx context.Context, req ctrl.Re
1065
1032
_ , patchWebhook := csv .Annotations [constant .WebhookMark ]
1066
1033
if patchWebhook {
1067
1034
klog .Infof ("Patching webhookconfiguration for CSV %s" , csv .Name )
1068
- if err := r .patchWebhook (ctx , instance , & csv , managedWebhookList , patchedWebhookList , validatedMembers ); err != nil {
1035
+ if err := r .patchWebhook (ctx , instance , & csv , & managedWebhookList , & patchedWebhookList , validatedMembers ); err != nil {
1069
1036
return ctrl.Result {}, err
1070
1037
}
1071
1038
}
@@ -1166,7 +1133,7 @@ func (r *NamespaceScopeReconciler) CheckListDifference(ctx context.Context, inst
1166
1133
}
1167
1134
1168
1135
func (r * NamespaceScopeReconciler ) patchWebhook (ctx context.Context , instance * operatorv1.NamespaceScope , csv * olmv1alpha1.ClusterServiceVersion ,
1169
- managedWebhookList []string , patchedWebhookList []string , validatedMembers []string ) error {
1136
+ managedWebhookList * []string , patchedWebhookList * []string , validatedMembers []string ) error {
1170
1137
// get webhooklists
1171
1138
mWebhookList , vWebhookList , err := r .getWebhooks (ctx , csv .Name , instance .Namespace )
1172
1139
if err != nil {
@@ -1175,19 +1142,19 @@ func (r *NamespaceScopeReconciler) patchWebhook(ctx context.Context, instance *o
1175
1142
// add them to the list
1176
1143
for _ , mwbh := range mWebhookList .Items {
1177
1144
webhook := mwbh
1178
- managedWebhookList = append (managedWebhookList , mwbh .GetName ())
1145
+ * managedWebhookList = append (* managedWebhookList , mwbh .GetName ())
1179
1146
if err := r .patchMutatingWebhook (ctx , & webhook , validatedMembers , csv .Name , csv .Namespace ); err != nil {
1180
1147
return err
1181
1148
}
1182
- patchedWebhookList = append (patchedWebhookList , mwbh .GetName ())
1149
+ * patchedWebhookList = append (* patchedWebhookList , mwbh .GetName ())
1183
1150
}
1184
1151
for _ , vwbh := range vWebhookList .Items {
1185
1152
webhook := vwbh
1186
- managedWebhookList = append (managedWebhookList , vwbh .GetName ())
1153
+ * managedWebhookList = append (* managedWebhookList , vwbh .GetName ())
1187
1154
if err := r .patchValidatingWebhook (ctx , & webhook , validatedMembers , csv .Name , csv .Namespace ); err != nil {
1188
1155
return err
1189
1156
}
1190
- patchedWebhookList = append (patchedWebhookList , vwbh .GetName ())
1157
+ * patchedWebhookList = append (* patchedWebhookList , vwbh .GetName ())
1191
1158
}
1192
1159
return nil
1193
1160
}
0 commit comments