Add revoke action and YAML support for permission updates#1461
Add revoke action and YAML support for permission updates#1461anniegracehu wants to merge 18 commits intocloud-ark:masterfrom
Conversation
Support permission updates and revocations from both JSON and YAML files, reuse shared parsing/configmap helpers, and extend tests to cover revoke CLI validation and multi-format permission file parsing. Made-with: Cursor
5e4ab35 to
6e0c42b
Compare
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
Inline legacy update parsing in _update_rbac for source-of-truth behavior and keep old/new parity assertions behind KUBEPLUS_UPDATE_EQ_CHECK, while removing extra helper methods. Made-with: Cursor
Use _load_permission_data only in _update_rbac and keep the original rule loop. Drop dual-parser parity and its test. Match _parse_permission_rules to legacy by always appending rule_group. Return early from revoke when no update ClusterRole exists to avoid rewriting perms configmap. Made-with: Cursor
Add _parse_update_rules_legacy for a single legacy implementation, optional KUBEPLUS_UPDATE_EQ_CHECK assertion against _parse_permission_rules in _update_rbac, and a unit test including non-apigroup edge cases. Made-with: Cursor
Remove duplicate _parse_update_rules_legacy and env parity self-check; add a focused test for non-apigroup edge case. Made-with: Cursor
Provide a minimal permissions file to validate update/revoke against an existing service account during manual testing. Made-with: Cursor
Provide three paired examples under tests/permission_files to validate update/revoke behavior with auth can-i for both input formats. Made-with: Cursor
Parse all JSON and YAML fixtures in tests/permission_files through provider-kubeconfig helpers to validate real file-based inputs used in manual update/revoke checks. Made-with: Cursor
Use tests/permission_files fixtures for manual checks and test coverage instead of the old tests/manual file. Made-with: Cursor
Verify update/revoke using matching JSON and YAML permission fixtures produce the same auth can-i transition on an existing service account (deny -> allow -> deny). Made-with: Cursor
Use standard '' key notation instead of explicit ? mapping form for readability while preserving equivalent fixture semantics. Made-with: Cursor
Prefer <sa>-update for revoke, then fall back to <sa> if needed; keep perms configmap sync and add integration coverage. Normalize permission fixtures so JSON/YAML stay equivalent and single-key per rule entry. Made-with: Cursor
Replace explicit '? ""' mapping form with standard '' key notation for readability and consistency. Made-with: Cursor
devdattakulkarni
left a comment
There was a problem hiding this comment.
Added some comments.
| if resource not in resources: | ||
| resources.append(resource.strip()) | ||
| rule_group = {} | ||
| if api_group == "non-apigroup": |
There was a problem hiding this comment.
This is present in the old permission file.
| - get | ||
| - update | ||
| - patch | ||
| configmaps/resourceName::cert-manager-cainjector-leader-election-core: |
There was a problem hiding this comment.
This should be -configmaps/resourceName::
| revoke_rule_list, revoke_resources = self._parse_permission_rules(perms) | ||
| revoke_norm = set(tuple(sorted(r.items())) for r in self._normalize_rule_list(revoke_rule_list)) | ||
|
|
||
| role_name = sa + "-update" |
There was a problem hiding this comment.
Here we are assuming that the role name (sa-"update") already exists on the cluster.
| remaining_rules = [] | ||
| for rule in existing_rules: | ||
| norm = self._normalize_rule(rule) | ||
| norm_key = tuple(sorted(norm.items())) |
There was a problem hiding this comment.
Could we add a small example in comment. What would be norm_key and what would be the rule.
| ) | ||
| def _revoke_rbac(self, permissionfile, sa, namespace, kubeconfig): | ||
| """Revoke permissions from JSON/YAML file for provider/consumer update role.""" | ||
| perms = self._load_permission_data(permissionfile) |
There was a problem hiding this comment.
Suppose originally the SA has following perms:
- ""
pod:- get, delete
Suppose permissionfile has the following:
- ""
pod:- delete
After revoke, we want the SA to have the following perms:
- ""
pod:- get
| norm = self._normalize_rule(rule) | ||
| norm_key = tuple(sorted(norm.items())) | ||
| if norm_key not in revoke_norm: | ||
| remaining_rules.append(rule) |
There was a problem hiding this comment.
Iterate through the existing rules on the SA. If the rule does not exist in the revoke_norm then add it to the remaining rules.
Handle null rules safely, only fall back to base role on NotFound, apply minimal role objects during revoke updates, and use system temp files in tests while validating verb-level revoke behavior. Made-with: Cursor
Fix NotFound fallback checks, preserve labels/annotations on role rewrite, handle null rules safely, keep configmap resources when scope/verbs remain, and add integration coverage for multi-resource and wildcard revoke behavior. Made-with: Cursor
Consolidate follow-up bug fixes into a single, readable revoke path that preserves intended RBAC semantics (including nonResourceURL matching, base-role fallback, and scoped multi-resource revocation) while trimming test complexity to focused behavior coverage.
948d3d2 to
9475a4b
Compare
Restructure revoke logic for readability with plain-language scope comments, inline flow-oriented rule rewriting, and reduced helper complexity while keeping documented revoke behavior and test coverage aligned. Made-with: Cursor
Summary
revokeaction toprovider-kubeconfig.pyupdateandrevoke<sa>-permsconfigmap synchronized when updating and revoking permissionsrevokeCLI validation and permission file parsingtests/manual/update-revoke-perms.yamlTest plan
python3 -m unittest tests/test_provider_kubeconfig.pyManual update/revoke e2e (existing SA)
Use an existing service account (example:
argocd-application-controllerinargocd) and verify update/revoke without creating a new SA.