Skip to content

Commit 61a954c

Browse files
CLI: add subcommand access for principals (#1019)
* Access subcommand access for principals * Access subcommand access for principals
1 parent 810bb67 commit 61a954c

File tree

4 files changed

+69
-1
lines changed

4 files changed

+69
-1
lines changed

regtests/client/python/cli/command/principals.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# specific language governing permissions and limitations
1717
# under the License.
1818
#
19+
import json
1920
from dataclasses import dataclass
2021
from typing import Dict, Optional, List
2122

@@ -35,6 +36,7 @@ class PrincipalsCommand(Command):
3536
3637
Example commands:
3738
* ./polaris principals create user
39+
* ./polaris principals access user
3840
* ./polaris principals list
3941
* ./polaris principals list --principal-role filter-to-this-role
4042
"""
@@ -48,6 +50,22 @@ class PrincipalsCommand(Command):
4850
set_properties: Dict[str, StrictStr]
4951
remove_properties: List[str]
5052

53+
def _get_catalogs(self, api: PolarisDefaultApi):
54+
for catalog in api.list_catalogs().catalogs:
55+
yield catalog.to_dict()['name']
56+
57+
def _get_principal_roles(self, api: PolarisDefaultApi):
58+
for principal_role in api.list_principal_roles_assigned(self.principal_name).roles:
59+
yield principal_role.to_dict()['name']
60+
61+
def _get_catalog_roles(self, api: PolarisDefaultApi, principal_role_name: str, catalog_name: str):
62+
for catalog_role in api.list_catalog_roles_for_principal_role(principal_role_name, catalog_name).roles:
63+
yield catalog_role.to_dict()['name']
64+
65+
def _get_privileges(self, api: PolarisDefaultApi, catalog_name: str, catalog_role_name: str):
66+
for grant in api.list_grants_for_catalog_role(catalog_name, catalog_role_name).grants:
67+
yield grant.to_dict()
68+
5169
def validate(self):
5270
pass
5371

@@ -93,5 +111,34 @@ def execute(self, api: PolarisDefaultApi) -> None:
93111
properties=new_properties
94112
)
95113
api.update_principal(self.principal_name, request)
114+
elif self.principals_subcommand == Subcommands.ACCESS:
115+
principal = api.get_principal(self.principal_name).to_dict()['name']
116+
principal_roles = self._get_principal_roles(api)
117+
118+
# Initialize the result structure
119+
result = {
120+
'principal': principal,
121+
'principal_roles': []
122+
}
123+
124+
# Construct the result structure for each principal role
125+
for principal_role in principal_roles:
126+
role_data = {
127+
'name': principal_role,
128+
'catalog_roles': []
129+
}
130+
# For each catalog role, get associated privileges
131+
for catalog in self._get_catalogs(api):
132+
catalog_roles = self._get_catalog_roles(api, principal_role, catalog)
133+
for catalog_role in catalog_roles:
134+
catalog_data = {
135+
'name': catalog_role,
136+
'catalog': catalog,
137+
'privileges': []
138+
}
139+
catalog_data['privileges'] = list(self._get_privileges(api, catalog_data['catalog'], catalog_role))
140+
role_data['catalog_roles'].append(catalog_data)
141+
result['principal_roles'].append(role_data)
142+
print(json.dumps(result))
96143
else:
97144
raise Exception(f"{self.principals_subcommand} is not supported in the CLI")

regtests/client/python/cli/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class Subcommands:
8080
VIEW = 'view'
8181
GRANT = 'grant'
8282
REVOKE = 'revoke'
83+
ACCESS = 'access'
8384

8485

8586
class Actions:

regtests/client/python/cli/options/option_tree.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ def get_tree() -> List[Option]:
123123
Option(Subcommands.UPDATE, args=[
124124
Argument(Arguments.SET_PROPERTY, str, Hints.SET_PROPERTY, allow_repeats=True),
125125
Argument(Arguments.REMOVE_PROPERTY, str, Hints.REMOVE_PROPERTY, allow_repeats=True),
126-
], input_name=Arguments.PRINCIPAL)
126+
], input_name=Arguments.PRINCIPAL),
127+
Option(Subcommands.ACCESS, input_name=Arguments.PRINCIPAL),
127128
]),
128129
Option(Commands.PRINCIPAL_ROLES, 'manage principal roles', children=[
129130
Option(Subcommands.CREATE, args=[

site/content/in-dev/unreleased/command-line-interface.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ The `principals` command is used to manage principals within Polaris.
256256
4. list
257257
5. rotate-credentials
258258
6. update
259+
7. access
259260

260261
#### create
261262

@@ -372,6 +373,24 @@ polaris principals update --property key=value --property other_key=other_value
372373
polaris principals update --property are_other_keys_removed=yes some_user
373374
```
374375

376+
#### access
377+
378+
The `access` subcommand retrieves entities relation about a principal.
379+
380+
```
381+
input: polaris principals access --help
382+
options:
383+
access
384+
Positional arguments:
385+
principal
386+
```
387+
388+
##### Examples
389+
390+
```
391+
polaris principals access quickstart_user
392+
```
393+
375394
### Principal Roles
376395

377396
The `principal-roles` command is used to create, discover, and manage principal roles within Polaris. Additionally, this command can identify principals or catalog roles associated with a principal role, and can be used to grant a principal role to a principal.

0 commit comments

Comments
 (0)