@@ -207,10 +207,13 @@ func (r *NamespaceScopeReconciler) UpdateConfigMap(instance *operatorv1.Namespac
207
207
208
208
func (r * NamespaceScopeReconciler ) PushRbacToNamespace (instance * operatorv1.NamespaceScope ) error {
209
209
fromNs := instance .Namespace
210
- saNames , err := r .GetServiceAccountFromNamespace (instance , fromNs )
210
+ saNames , err := r .GetServiceAccountFromNamespace (instance . Spec . RestartLabels , fromNs )
211
211
if err != nil {
212
212
return err
213
213
}
214
+ labels := map [string ]string {
215
+ "namespace-scope-configmap" : instance .Namespace + "-" + instance .Spec .ConfigmapName ,
216
+ }
214
217
215
218
operatorNs , err := util .GetOperatorNamespace ()
216
219
if err != nil {
@@ -222,10 +225,17 @@ func (r *NamespaceScopeReconciler) PushRbacToNamespace(instance *operatorv1.Name
222
225
if toNs == operatorNs {
223
226
continue
224
227
}
225
- if err := r .generateRBACForNSS (instance , fromNs , toNs ); err != nil {
228
+
229
+ if err := r .CreateRole (labels , toNs ); err != nil {
230
+ if errors .IsForbidden (err ) {
231
+ r .Recorder .Eventf (instance , corev1 .EventTypeWarning , "Forbidden" , "cannot create resource roles in API group rbac.authorization.k8s.io in the namespace %s" , toNs )
232
+ }
226
233
return err
227
234
}
228
- if err := r .generateRBACToNamespace (instance , saNames , fromNs , toNs ); err != nil {
235
+ if err := r .CreateUpdateRoleBinding (labels , saNames , fromNs , toNs ); err != nil {
236
+ if errors .IsForbidden (err ) {
237
+ r .Recorder .Eventf (instance , corev1 .EventTypeWarning , "Forbidden" , "cannot create resource rolebindings in API group rbac.authorization.k8s.io in the namespace %s" , toNs )
238
+ }
229
239
return err
230
240
}
231
241
}
@@ -323,26 +333,32 @@ func (r *NamespaceScopeReconciler) DeleteAllRbac(instance *operatorv1.NamespaceS
323
333
return nil
324
334
}
325
335
326
- func (r * NamespaceScopeReconciler ) generateRBACForNSS (instance * operatorv1.NamespaceScope , fromNs , toNs string ) error {
327
- labels := map [string ]string {
328
- "namespace-scope-configmap" : instance .Namespace + "-" + instance .Spec .ConfigmapName ,
336
+ func (r * NamespaceScopeReconciler ) GetServiceAccountFromNamespace (labels map [string ]string , namespace string ) ([]string , error ) {
337
+ pods := & corev1.PodList {}
338
+ opts := []client.ListOption {
339
+ client .MatchingLabels (labels ),
340
+ client .InNamespace (namespace ),
329
341
}
330
- if err := r .createRoleForNSS (labels , toNs ); err != nil {
331
- if errors .IsForbidden (err ) {
332
- r .Recorder .Eventf (instance , corev1 .EventTypeWarning , "Forbidden" , "cannot create resource roles in API group rbac.authorization.k8s.io in the namespace %s" , toNs )
333
- }
334
- return err
342
+
343
+ if err := r .List (ctx , pods , opts ... ); err != nil {
344
+ klog .Errorf ("Cannot list pods with labels %v in namespace %s: %v" , labels , namespace , err )
345
+ return nil , err
335
346
}
336
- if err := r .createRoleBindingForNSS (labels , fromNs , toNs ); err != nil {
337
- if errors .IsForbidden (err ) {
338
- r .Recorder .Eventf (instance , corev1 .EventTypeWarning , "Forbidden" , "cannot create resource rolebindings in API group rbac.authorization.k8s.io in the namespace %s" , toNs )
347
+
348
+ // By default, set ibm-namespace-scope-operator service account
349
+ var saNames = []string {"ibm-namespace-scope-operator" }
350
+
351
+ for _ , pod := range pods .Items {
352
+ if len (pod .Spec .ServiceAccountName ) != 0 {
353
+ saNames = append (saNames , pod .Spec .ServiceAccountName )
339
354
}
340
- return err
341
355
}
342
- return nil
356
+ saNames = util .ToStringSlice (util .MakeSet (saNames ))
357
+
358
+ return saNames , nil
343
359
}
344
360
345
- func (r * NamespaceScopeReconciler ) createRoleForNSS (labels map [string ]string , toNs string ) error {
361
+ func (r * NamespaceScopeReconciler ) CreateRole (labels map [string ]string , toNs string ) error {
346
362
name := constant .NamespaceScopeManagedPrefix + labels ["namespace-scope-configmap" ]
347
363
namespace := toNs
348
364
role := & rbacv1.Role {
@@ -370,16 +386,31 @@ func (r *NamespaceScopeReconciler) createRoleForNSS(labels map[string]string, to
370
386
return nil
371
387
}
372
388
373
- func (r * NamespaceScopeReconciler ) createRoleBindingForNSS (labels map [string ]string , fromNs , toNs string ) error {
389
+ func (r * NamespaceScopeReconciler ) DeleteRole (labels map [string ]string , toNs string ) error {
390
+ opts := []client.DeleteAllOfOption {
391
+ client .MatchingLabels (labels ),
392
+ client .InNamespace (toNs ),
393
+ }
394
+ if err := r .DeleteAllOf (ctx , & rbacv1.Role {}, opts ... ); err != nil {
395
+ klog .Errorf ("Failed to delete role with labels %v in namespace %s: %v" , labels , toNs , err )
396
+ return err
397
+ }
398
+ klog .Infof ("Deleted role with labels %v in namespace %s" , labels , toNs )
399
+ return nil
400
+ }
401
+
402
+ func (r * NamespaceScopeReconciler ) CreateUpdateRoleBinding (labels map [string ]string , saNames []string , fromNs , toNs string ) error {
374
403
name := constant .NamespaceScopeManagedPrefix + labels ["namespace-scope-configmap" ]
375
404
namespace := toNs
376
405
subjects := []rbacv1.Subject {}
377
- subject := rbacv1.Subject {
378
- Kind : "ServiceAccount" ,
379
- Name : constant .NamespaceScopeServiceAccount ,
380
- Namespace : fromNs ,
406
+ for _ , saName := range saNames {
407
+ subject := rbacv1.Subject {
408
+ Kind : "ServiceAccount" ,
409
+ Name : saName ,
410
+ Namespace : fromNs ,
411
+ }
412
+ subjects = append (subjects , subject )
381
413
}
382
- subjects = append (subjects , subject )
383
414
roleBinding := & rbacv1.RoleBinding {
384
415
ObjectMeta : metav1.ObjectMeta {
385
416
Name : name ,
@@ -396,6 +427,9 @@ func (r *NamespaceScopeReconciler) createRoleBindingForNSS(labels map[string]str
396
427
397
428
if err := r .Create (ctx , roleBinding ); err != nil {
398
429
if errors .IsAlreadyExists (err ) {
430
+ if err := r .UpdateRoleBinding (roleBinding ); err != nil {
431
+ return err
432
+ }
399
433
return nil
400
434
}
401
435
klog .Errorf ("Failed to create rolebinding %s/%s: %v" , namespace , name , err )
@@ -405,172 +439,19 @@ func (r *NamespaceScopeReconciler) createRoleBindingForNSS(labels map[string]str
405
439
return nil
406
440
}
407
441
408
- func (r * NamespaceScopeReconciler ) generateRBACToNamespace (instance * operatorv1.NamespaceScope , saNames []string , fromNs , toNs string ) error {
409
- labels := map [string ]string {
410
- "namespace-scope-configmap" : instance .Namespace + "-" + instance .Spec .ConfigmapName ,
411
- }
412
- for _ , sa := range saNames {
413
- roleList , err := r .GetRolesFromServiceAccount (sa , fromNs )
414
- if err != nil {
415
- return err
416
- }
417
-
418
- if err := r .CreateRole (roleList , labels , fromNs , toNs ); err != nil {
419
- if errors .IsForbidden (err ) {
420
- r .Recorder .Eventf (instance , corev1 .EventTypeWarning , "Forbidden" , "cannot create resource roles in API group rbac.authorization.k8s.io in the namespace %s" , toNs )
421
- }
422
- return err
423
- }
424
- if err := r .CreateRoleBinding (roleList , labels , sa , fromNs , toNs ); err != nil {
425
- if errors .IsForbidden (err ) {
426
- r .Recorder .Eventf (instance , corev1 .EventTypeWarning , "Forbidden" , "cannot create resource rolebindings in API group rbac.authorization.k8s.io in the namespace %s" , toNs )
427
- }
428
- return err
429
- }
430
- }
431
- return nil
432
- }
433
-
434
- func (r * NamespaceScopeReconciler ) GetServiceAccountFromNamespace (instance * operatorv1.NamespaceScope , namespace string ) ([]string , error ) {
435
- labels := instance .Spec .RestartLabels
436
- pods := & corev1.PodList {}
437
- opts := []client.ListOption {
438
- client .MatchingLabels (labels ),
439
- client .InNamespace (namespace ),
440
- }
441
-
442
- if err := r .List (ctx , pods , opts ... ); err != nil {
443
- klog .Errorf ("Cannot list pods with labels %v in namespace %s: %v" , labels , namespace , err )
444
- return nil , err
445
- }
446
-
447
- // By default, set ibm-namespace-scope-operator service account
448
- var saNames = []string {"ibm-namespace-scope-operator" }
449
-
450
- for _ , pod := range pods .Items {
451
- if len (pod .Spec .ServiceAccountName ) != 0 {
452
- saNames = append (saNames , pod .Spec .ServiceAccountName )
453
- }
454
- }
455
-
456
- if len (instance .Spec .ServiceAccountMembers ) != 0 {
457
- for _ , sa := range instance .Spec .ServiceAccountMembers {
458
- serviceaccount := & corev1.ServiceAccount {}
459
- if err := r .Get (ctx , types.NamespacedName {Namespace : namespace , Name : sa }, serviceaccount ); err != nil {
460
- klog .Errorf ("Failed to get service account %s in namespace %s" , sa , namespace )
461
- continue
462
- }
463
- saNames = append (saNames , sa )
464
- }
465
- }
466
-
467
- saNames = util .ToStringSlice (util .MakeSet (saNames ))
468
-
469
- return saNames , nil
470
- }
471
-
472
- func (r * NamespaceScopeReconciler ) GetRolesFromServiceAccount (sa string , namespace string ) ([]string , error ) {
473
- roleBindings := & rbacv1.RoleBindingList {}
474
- opts := []client.ListOption {
475
- client .InNamespace (namespace ),
476
- }
477
-
478
- if err := r .List (ctx , roleBindings , opts ... ); err != nil {
479
- klog .Errorf ("Cannot list rolebindings with in namespace %s: %v" , namespace , err )
480
- return nil , err
481
- }
482
-
483
- var roleNameList []string
484
- for _ , roleBinding := range roleBindings .Items {
485
- for _ , subject := range roleBinding .Subjects {
486
- if subject .Name == sa && subject .Kind == "ServiceAccount" {
487
- roleNameList = append (roleNameList , roleBinding .RoleRef .Name )
488
- }
489
- }
490
- }
491
-
492
- return util .ToStringSlice (util .MakeSet (roleNameList )), nil
493
- }
494
-
495
- func (r * NamespaceScopeReconciler ) CreateRole (roleNames []string , labels map [string ]string , fromNs string , toNs string ) error {
496
- for _ , roleName := range roleNames {
497
- originalRole := & rbacv1.Role {}
498
- if err := r .Get (ctx , types.NamespacedName {Name : roleName , Namespace : fromNs }, originalRole ); err != nil {
499
- klog .Errorf ("Failed to get role %s in namespace %s: %v" , roleName , fromNs , err )
500
- return err
501
- }
502
- name := strings .Split (roleName , "." )[0 ] + "-" + labels ["namespace-scope-configmap" ]
503
- namespace := toNs
504
- role := & rbacv1.Role {
505
- ObjectMeta : metav1.ObjectMeta {
506
- Name : name ,
507
- Namespace : namespace ,
508
- Labels : labels ,
509
- },
510
- Rules : originalRole .Rules ,
511
- }
512
- if err := r .Create (ctx , role ); err != nil {
513
- if errors .IsAlreadyExists (err ) {
514
- if err := r .Update (ctx , role ); err != nil {
515
- klog .Errorf ("Failed to update role %s/%s: %v" , namespace , name , err )
516
- return err
517
- }
518
- return nil
519
- }
520
- klog .Errorf ("Failed to create role %s/%s: %v" , namespace , name , err )
521
- return err
522
- }
523
- klog .Infof ("Created role %s/%s" , namespace , name )
524
- }
525
- return nil
526
- }
527
-
528
- func (r * NamespaceScopeReconciler ) DeleteRole (labels map [string ]string , toNs string ) error {
529
- opts := []client.DeleteAllOfOption {
530
- client .MatchingLabels (labels ),
531
- client .InNamespace (toNs ),
442
+ func (r * NamespaceScopeReconciler ) UpdateRoleBinding (newRoleBinding * rbacv1.RoleBinding ) error {
443
+ currentRoleBinding := & rbacv1.RoleBinding {}
444
+ currentRoleBindingKey := types.NamespacedName {Name : newRoleBinding .Name , Namespace : newRoleBinding .Namespace }
445
+ if err := r .Get (ctx , currentRoleBindingKey , currentRoleBinding ); err != nil {
446
+ klog .Errorf ("Cannot get rolebinding %s: %v" , currentRoleBindingKey .String (), err )
532
447
}
533
- if err := r .DeleteAllOf (ctx , & rbacv1.Role {}, opts ... ); err != nil {
534
- klog .Errorf ("Failed to delete role with labels %v in namespace %s: %v" , labels , toNs , err )
535
- return err
536
- }
537
- klog .Infof ("Deleted role with labels %v in namespace %s" , labels , toNs )
538
- return nil
539
- }
540
-
541
- func (r * NamespaceScopeReconciler ) CreateRoleBinding (roleNames []string , labels map [string ]string , saName , fromNs , toNs string ) error {
542
- for _ , roleName := range roleNames {
543
- name := strings .Split (roleName , "." )[0 ] + "-" + labels ["namespace-scope-configmap" ]
544
- namespace := toNs
545
- subjects := []rbacv1.Subject {}
546
- subject := rbacv1.Subject {
547
- Kind : "ServiceAccount" ,
548
- Name : saName ,
549
- Namespace : fromNs ,
550
- }
551
- subjects = append (subjects , subject )
552
- roleBinding := & rbacv1.RoleBinding {
553
- ObjectMeta : metav1.ObjectMeta {
554
- Name : name ,
555
- Namespace : namespace ,
556
- Labels : labels ,
557
- },
558
- Subjects : subjects ,
559
- RoleRef : rbacv1.RoleRef {
560
- Kind : "Role" ,
561
- Name : name ,
562
- APIGroup : "rbac.authorization.k8s.io" ,
563
- },
564
- }
565
-
566
- if err := r .Create (ctx , roleBinding ); err != nil {
567
- if errors .IsAlreadyExists (err ) {
568
- return nil
569
- }
570
- klog .Errorf ("Failed to create rolebinding %s/%s: %v" , namespace , name , err )
448
+ if len (newRoleBinding .Subjects ) != len (currentRoleBinding .Subjects ) {
449
+ if err := r .Update (ctx , newRoleBinding ); err != nil {
450
+ klog .Errorf ("Failed to update rolebinding %s: %v" , currentRoleBindingKey .String (), err )
571
451
return err
572
452
}
573
- klog .Infof ("Created rolebinding %s/%s" , namespace , name )
453
+ klog .Infof ("Updated rolebinding %s" , currentRoleBindingKey .String ())
454
+ return nil
574
455
}
575
456
return nil
576
457
}
0 commit comments