@@ -142,6 +142,27 @@ def _assert_rule_parity(self, label, old_rules, new_rules):
142142 f"Only in new: { new_only } "
143143 )
144144
145+ def _all_resources_from_rules (self , rules , skip_wildcard = False ):
146+ resources = []
147+ for rule in rules :
148+ for res in rule .get ("resources" , []):
149+ if skip_wildcard and res == "*" :
150+ continue
151+ resources .append (res )
152+ return sorted (set (resources ))
153+
154+ def _assert_all_resources_parity (self , label , old_resources , new_resources ):
155+ old_set = set (old_resources )
156+ new_set = set (new_resources )
157+ if old_set != new_set :
158+ old_only = sorted (old_set - new_set )
159+ new_only = sorted (new_set - old_set )
160+ raise AssertionError (
161+ f"{ label } all_resources mismatch.\n "
162+ f"Only in old: { old_only } \n "
163+ f"Only in new: { new_only } "
164+ )
165+
145166 def _build_consumer_rules_old (self ):
146167 # Read all resources
147168 ruleGroup1 = {}
@@ -488,10 +509,14 @@ def _apply_consumer_rbac(self, sa, namespace, kubeconfig):
488509 """Apply ClusterRole and ClusterRoleBinding for consumer (read + apps + impersonate + portforward)."""
489510 old_rule_list = self ._build_consumer_rules_old ()
490511 new_rule_list = self ._build_consumer_rules_new ()
512+ old_all_resources = self ._all_resources_from_rules (old_rule_list )
513+ new_all_resources = self ._all_resources_from_rules (new_rule_list )
491514 if os .getenv ("KUBEPLUS_RBAC_EQ_CHECK" , "0" ) == "1" :
492515 self ._assert_rule_parity ("consumer" , old_rule_list , new_rule_list )
516+ self ._assert_all_resources_parity ("consumer" , old_all_resources , new_all_resources )
493517 # Keep old path as source of truth in this PR.
494518 rule_list = old_rule_list
519+ all_resources = old_all_resources
495520 role = {
496521 "apiVersion" : "rbac.authorization.k8s.io/v1" ,
497522 "kind" : "ClusterRole" ,
@@ -508,11 +533,9 @@ def _apply_consumer_rbac(self, sa, namespace, kubeconfig):
508533 "roleRef" : {"kind" : "ClusterRole" , "name" : sa , "apiGroup" : "rbac.authorization.k8s.io" },
509534 }
510535 create_role_rolebinding (role_binding , sa + "-rolebinding-impersonate.yaml" , kubeconfig )
511-
512- all_resources = [res for r in rule_list for res in r .get ("resources" , [])]
513536 cfg_map_filename = sa + "-perms.txt"
514537 with open (cfg_map_filename , "w" , encoding = "utf-8" ) as fp :
515- fp .write (str (sorted ( set ( all_resources )) ))
538+ fp .write (str (all_resources ))
516539 run_command (
517540 "kubectl create configmap " + sa + "-perms -n " + namespace
518541 + " --from-file=" + cfg_map_filename + kubeconfig
@@ -523,16 +546,14 @@ def _apply_provider_rbac(self, sa, namespace, kubeconfig):
523546 """Apply ClusterRole and ClusterRoleBinding for provider (full platform operator permissions)."""
524547 old_rule_list = self ._build_provider_rules_old ()
525548 new_rule_list = self ._build_provider_rules_new ()
549+ old_all_resources = self ._all_resources_from_rules (old_rule_list , skip_wildcard = True )
550+ new_all_resources = self ._all_resources_from_rules (new_rule_list , skip_wildcard = True )
526551 if os .getenv ("KUBEPLUS_RBAC_EQ_CHECK" , "0" ) == "1" :
527552 self ._assert_rule_parity ("provider" , old_rule_list , new_rule_list )
553+ self ._assert_all_resources_parity ("provider" , old_all_resources , new_all_resources )
528554 # Keep old path as source of truth in this PR.
529555 rule_list = old_rule_list
530- # Preserve master semantics: do not include wildcard resources in perms inventory.
531- all_resources = [
532- res for r in rule_list
533- for res in r .get ("resources" , [])
534- if res != "*"
535- ]
556+ all_resources = old_all_resources
536557
537558 role = {
538559 "apiVersion" : "rbac.authorization.k8s.io/v1" ,
@@ -553,7 +574,7 @@ def _apply_provider_rbac(self, sa, namespace, kubeconfig):
553574
554575 cfg_map_filename = sa + "-perms.txt"
555576 with open (cfg_map_filename , "w" , encoding = "utf-8" ) as fp :
556- fp .write (str (sorted ( set ( all_resources )) ))
577+ fp .write (str (all_resources ))
557578 run_command (
558579 "kubectl create configmap " + sa + "-perms -n " + namespace
559580 + " --from-file=" + cfg_map_filename + kubeconfig
0 commit comments