Skip to content

Commit 4719e7c

Browse files
committed
Keep legacy update parser as runtime source of truth.
Run new update parser in shadow mode behind an env flag and assert old/new parity, with tests validating parser output equivalence. Made-with: Cursor
1 parent 6e0c42b commit 4719e7c

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

provider-kubeconfig.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,34 @@ def _parse_permission_rules(self, perms):
8585
rule_list.append(rule_group)
8686
return rule_list, resources
8787

88+
def _parse_permission_rules_old(self, perms):
89+
"""Legacy update parser path kept for parity verification."""
90+
rule_list = []
91+
resources = []
92+
for api_group, res_actions in perms.items():
93+
for res in res_actions:
94+
for resource, verbs in res.items():
95+
if resource not in resources:
96+
resources.append(resource.strip())
97+
rule_group = {}
98+
if api_group == "non-apigroup":
99+
if "nonResourceURL" in resource:
100+
parts = resource.split("nonResourceURL::")
101+
non_res = parts[1].strip() if len(parts) > 1 else parts[0].strip()
102+
rule_group["nonResourceURLs"] = [non_res]
103+
rule_group["verbs"] = verbs
104+
else:
105+
rule_group["apiGroups"] = [api_group]
106+
rule_group["verbs"] = verbs
107+
if "resourceName" in resource:
108+
parts = resource.split("/resourceName::")
109+
rule_group["resources"] = [parts[0].strip()]
110+
rule_group["resourceNames"] = [parts[1].strip()]
111+
else:
112+
rule_group["resources"] = [resource]
113+
rule_list.append(rule_group)
114+
return rule_list, resources
115+
88116
def _read_perm_configmap_resources(self, sa, namespace, kubeconfig):
89117
cfg_map_name = sa + "-perms"
90118
cfg_map_filename = sa + "-perms.txt"
@@ -231,6 +259,12 @@ def _assert_all_resources_parity(self, label, old_resources, new_resources):
231259
f"Only in new: {new_only}"
232260
)
233261

262+
def _assert_update_parser_parity(self, perms):
263+
old_rule_list, old_resources = self._parse_permission_rules_old(perms)
264+
new_rule_list, new_resources = self._parse_permission_rules(perms)
265+
self._assert_rule_parity("update-parser", old_rule_list, new_rule_list)
266+
self._assert_all_resources_parity("update-parser", old_resources, new_resources)
267+
234268
def _build_consumer_rules_old(self):
235269
# Read all resources
236270
ruleGroup1 = {}
@@ -651,7 +685,12 @@ def _apply_provider_rbac(self, sa, namespace, kubeconfig):
651685
def _update_rbac(self, permissionfile, sa, namespace, kubeconfig):
652686
"""Add permissions from JSON/YAML file to provider (update command)."""
653687
perms = self._load_permission_data(permissionfile)
654-
rule_list, new_resources = self._parse_permission_rules(perms)
688+
old_rule_list, old_resources = self._parse_permission_rules_old(perms)
689+
if os.getenv("KUBEPLUS_UPDATE_EQ_CHECK", "0") == "1":
690+
self._assert_update_parser_parity(perms)
691+
# Keep old update parser path as source of truth.
692+
rule_list = old_rule_list
693+
new_resources = old_resources
655694

656695
role = {
657696
"apiVersion": "rbac.authorization.k8s.io/v1",

tests/test_provider_kubeconfig.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,21 @@ def test_load_permission_data_accepts_yaml(self):
133133
finally:
134134
os.remove(path)
135135

136+
def test_update_old_and_new_parsers_match(self):
137+
perms = {
138+
"apps": [
139+
{"deployments": ["get", "create"]},
140+
{"deployments/resourceName::sample": ["get"]},
141+
],
142+
"non-apigroup": [
143+
{"nonResourceURL::/metrics": ["get"]},
144+
],
145+
}
146+
old_rules, old_resources = self.generator._parse_permission_rules_old(perms)
147+
new_rules, new_resources = self.generator._parse_permission_rules(perms)
148+
self.generator._assert_rule_parity("test-update-parser", old_rules, new_rules)
149+
self.generator._assert_all_resources_parity("test-update-parser", old_resources, new_resources)
150+
136151

137152
class TestKubeconfigIntegration(unittest.TestCase):
138153
"""

0 commit comments

Comments
 (0)