Skip to content

Commit bec1e15

Browse files
authored
[cosmosdb-preview] Add support for Table RBAC role definition and assignment CRUD actions (#8310)
* Updating cosmosdb_preview for 12.01 preview release cli * Adding remaining changes from documentation to bump version * working table api role definition tests * Working table role assignment tests * Cleaning up new resources and removing debugging helpers * removing unused validator * Adding help updates * Fixing help * Trying to fix param help * Trying to fix param help * Trying to fix param help * Trying to fix param help * Trying to fix param help * Fixing version * Removing azext.isPreview: true, as requested by github-actions bot * Updating and rerecording tests with latest cli dev branch * updating version to 1.2.0 * Changing version to be 1.2.0 as requested by github actions bot * Chaning history.rst version from 1.3.0 to 1.2.0 as requested by reviewers
1 parent 1b8bf71 commit bec1e15

File tree

15 files changed

+4245
-16
lines changed

15 files changed

+4245
-16
lines changed

src/cosmosdb-preview/HISTORY.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
.. :changelog:
2-
32
Release History
43
===============
4+
1.2.0
5+
* Add support for Table RBAC role definition and assignment CRUD actions.
6+
7+
+++++++
58
1.2.0b1
69
* Add support for Throughput bucketing.
710

src/cosmosdb-preview/azext_cosmosdb_preview/_help.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,3 +1086,154 @@
10861086
text: |-
10871087
az cosmosdb table restore --resource-group resource_group --account-name database_account_name --table-name name_of_table_needs_to_be_restored --restore-timestamp 2020-07-13T16:03:41+0000
10881088
"""
1089+
1090+
helps['cosmosdb table role'] = """
1091+
type: group
1092+
short-summary: Manage Azure Cosmos DB Table role resources.
1093+
"""
1094+
1095+
helps['cosmosdb table role definition'] = """
1096+
type: group
1097+
short-summary: Manage Azure Cosmos DB Table role definitions.
1098+
"""
1099+
1100+
helps['cosmosdb table role definition create'] = """
1101+
type: command
1102+
short-summary: Create a Table role definition under an Azure Cosmos DB account.
1103+
examples:
1104+
- name: Create a Table role definition under an Azure Cosmos DB account using a JSON string.
1105+
text: |
1106+
az cosmosdb table role definition create --account-name MyAccount --resource-group MyResourceGroup --body '{
1107+
"Id": "be79875a-2cc4-40d5-8958-566017875b39",
1108+
"RoleName": "My Read Only Role",
1109+
"Type": "CustomRole",
1110+
"AssignableScopes": ["/dbs/mydb/colls/mycontainer"],
1111+
"Permissions": [{
1112+
"DataActions": [
1113+
"Microsoft.DocumentDB/databaseAccounts/readMetadata",
1114+
"Microsoft.DocumentDB/databaseAccounts/tables/containers/entities/read",
1115+
"Microsoft.DocumentDB/databaseAccounts/tables/containers/executeQuery",
1116+
"Microsoft.DocumentDB/databaseAccounts/tables/containers/readChangeFeed"
1117+
]
1118+
}]
1119+
}'
1120+
- name: Create a Table role definition under an Azure Cosmos DB account using a JSON file.
1121+
text: az cosmosdb table role definition create --account-name MyAccount --resource-group MyResourceGroup --body @role-definition.json
1122+
"""
1123+
1124+
helps['cosmosdb table role definition delete'] = """
1125+
type: command
1126+
short-summary: Delete a Table role definition under an Azure Cosmos DB account.
1127+
examples:
1128+
- name: Delete a Table role definition under an Azure Cosmos DB account.
1129+
text: az cosmosdb table role definition delete --account-name MyAccount --resource-group MyResourceGroup --role-definition-id be79875a-2cc4-40d5-8958-566017875b39
1130+
"""
1131+
1132+
helps['cosmosdb table role definition exists'] = """
1133+
type: command
1134+
short-summary: Check if an Azure Cosmos DB role definition exists.
1135+
examples:
1136+
- name: Check if an Azure Cosmos DB role definition exists.
1137+
text: az cosmosdb table role definition exists --account-name MyAccount --resource-group MyResourceGroup --role-definition-id be79875a-2cc4-40d5-8958-566017875b39
1138+
"""
1139+
1140+
helps['cosmosdb table role definition list'] = """
1141+
type: command
1142+
short-summary: List all Table role definitions under an Azure Cosmos DB account.
1143+
examples:
1144+
- name: List all Table role definitions under an Azure Cosmos DB account.
1145+
text: az cosmosdb table role definition list --account-name MyAccount --resource-group MyResourceGroup
1146+
"""
1147+
1148+
helps['cosmosdb table role definition show'] = """
1149+
type: command
1150+
short-summary: Show the properties of a Table role definition under an Azure Cosmos DB account.
1151+
examples:
1152+
- name: Show the properties of a Table role definition under an Azure Cosmos DB account.
1153+
text: az cosmosdb table role definition show --account-name MyAccount --resource-group MyResourceGroup --role-definition-id be79875a-2cc4-40d5-8958-566017875b39
1154+
"""
1155+
1156+
helps['cosmosdb table role definition update'] = """
1157+
type: command
1158+
short-summary: Update a Table role definition under an Azure Cosmos DB account.
1159+
examples:
1160+
- name: Update a Table role definition under an Azure Cosmos DB account.
1161+
text: az cosmosdb table role definition update --account-name MyAccount --resource-group MyResourceGroup --body @role-definition.json
1162+
"""
1163+
1164+
helps['cosmosdb table role assignment'] = """
1165+
type: group
1166+
short-summary: Manage Azure Cosmos DB Table role assignments.
1167+
"""
1168+
1169+
helps['cosmosdb table role assignment create'] = """
1170+
type: command
1171+
short-summary: Create a Table role assignment under an Azure Cosmos DB account.
1172+
examples:
1173+
- name: Create a Table role assignment under an Azure Cosmos DB account using Role Definition Name.
1174+
text: |
1175+
az cosmosdb table role assignment create --account-name MyAccount --resource-group MyResourceGroup \\
1176+
--role-assignment-id cb8ed2d7-2371-4e3c-bd31-6cc1560e84f8 \\
1177+
--role-definition-name "My Read Only Role" \\
1178+
--scope "/dbs/mydb/colls/mycontainer" \\
1179+
--principal-id 6328f5f7-dbf7-4244-bba8-fbb9d8066506
1180+
- name: Create a Table role assignment under an Azure Cosmos DB account using Role Definition ID.
1181+
text: |
1182+
az cosmosdb table role assignment create --account-name MyAccount --resource-group MyResourceGroup \\
1183+
--role-assignment-id cb8ed2d7-2371-4e3c-bd31-6cc1560e84f8 \\
1184+
--role-definition-id be79875a-2cc4-40d5-8958-566017875b39 \\
1185+
--scope "/dbs/mydb/colls/mycontainer" \\
1186+
--principal-id 6328f5f7-dbf7-4244-bba8-fbb9d8066506
1187+
"""
1188+
1189+
helps['cosmosdb table role assignment delete'] = """
1190+
type: command
1191+
short-summary: Delete a Table role assignment under an Azure Cosmos DB account.
1192+
examples:
1193+
- name: Delete a Table role assignment under an Azure Cosmos DB account.
1194+
text: az cosmosdb table role assignment delete --account-name MyAccount --resource-group MyResourceGroup --role-assignment-id cb8ed2d7-2371-4e3c-bd31-6cc1560e84f8
1195+
"""
1196+
1197+
helps['cosmosdb table role assignment exists'] = """
1198+
type: command
1199+
short-summary: Check if an Azure Cosmos DB role assignment exists.
1200+
examples:
1201+
- name: Check if an Azure Cosmos DB role assignment exists.
1202+
text: az cosmosdb table role assignment exists --account-name MyAccount --resource-group MyResourceGroup --role-assignment-id cb8ed2d7-2371-4e3c-bd31-6cc1560e84f8
1203+
"""
1204+
1205+
helps['cosmosdb table role assignment list'] = """
1206+
type: command
1207+
short-summary: List all Table role assignments under an Azure Cosmos DB account.
1208+
examples:
1209+
- name: List all Table role assignments under an Azure Cosmos DB account.
1210+
text: az cosmosdb table role assignment list --account-name MyAccount --resource-group MyResourceGroup
1211+
"""
1212+
1213+
helps['cosmosdb table role assignment show'] = """
1214+
type: command
1215+
short-summary: Show the properties of a Table role assignment under an Azure Cosmos DB account.
1216+
examples:
1217+
- name: Show the properties of a Table role assignment under an Azure Cosmos DB account.
1218+
text: az cosmosdb table role assignment show --account-name MyAccount --resource-group MyResourceGroup --role-assignment-id cb8ed2d7-2371-4e3c-bd31-6cc1560e84f8
1219+
"""
1220+
1221+
helps['cosmosdb table role assignment update'] = """
1222+
type: command
1223+
short-summary: Update a Table role assignment under an Azure Cosmos DB account.
1224+
examples:
1225+
- name: Update a Table role assignment under an Azure Cosmos DB account using Role Definition Name.
1226+
text: |
1227+
az cosmosdb table role assignment update --account-name MyAccount --resource-group MyResourceGroup \\
1228+
--role-assignment-id cb8ed2d7-2371-4e3c-bd31-6cc1560e84f8 \\
1229+
--role-definition-name "My Read Only Role" \\
1230+
--scope "/dbs/mydb/colls/mycontainer" \\
1231+
--principal-id 6328f5f7-dbf7-4244-bba8-fbb9d8066506
1232+
- name: update a Table role assignment under an Azure Cosmos DB account using Role Definition ID.
1233+
text: |
1234+
az cosmosdb table role assignment update --account-name MyAccount --resource-group MyResourceGroup \\
1235+
--role-assignment-id cb8ed2d7-2371-4e3c-bd31-6cc1560e84f8 \\
1236+
--role-definition-id be79875a-2cc4-40d5-8958-566017875b39 \\
1237+
--scope "/dbs/mydb/colls/mycontainer" \\
1238+
--principal-id 6328f5f7-dbf7-4244-bba8-fbb9d8066506
1239+
"""

src/cosmosdb-preview/azext_cosmosdb_preview/_params.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
validate_mongo_role_definition_body,
1818
validate_mongo_role_definition_id,
1919
validate_mongo_user_definition_body,
20-
validate_mongo_user_definition_id)
20+
validate_mongo_user_definition_id,
21+
validate_table_role_definition_body,
22+
validate_table_role_definition_id,
23+
validate_table_role_assignment_id)
2124

2225
from azext_cosmosdb_preview.actions import (
2326
CreateGremlinDatabaseRestoreResource,
@@ -55,6 +58,24 @@
5558
validate_client_encryption_policy)
5659

5760

61+
TABLE_ROLE_DEFINITION_EXAMPLE = """--body "{
62+
\\"Id\\": \\"be79875a-2cc4-40d5-8958-566017875b39\\",
63+
\\"RoleName\\": \\"MyTestRole\\",
64+
\\"type\\": \\"CustomRole\\",
65+
\\"description\\": \\"Custom role to read Cosmos DB metadata\\",
66+
\\"AssignableScopes\\":[\\"/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.DocumentDB/databaseAccounts/MyDBAccountName\\"],
67+
\\"Permissions\\": [{\\"dataActions\\": [\\"Microsoft.DocumentDB/databaseAccounts/readMetadata\\"]}]
68+
}"
69+
"""
70+
71+
TABLE_ROLE_ASSIGNMENT_EXAMPLE = """--body "{
72+
\\"Id\\": \\"be79875a-2cc4-40d5-8958-566017875b39\\",
73+
\\"RoleDefinitionId\\": \\"MyTestRoleAssignment\\",
74+
\\"PrincipalId\\": \\"efc9875a-2cc4-40d5-8958-566017875b39\\",
75+
\\"Scope\\":\\"/subscriptions/cfe9875a-2cc4-40d5-8958-566017875b39/resourceGroups/MyResourceGroup/providers/Microsoft.DocumentDB/databaseAccounts/MyDBAccountName\\",
76+
}"
77+
"""
78+
5879
MONGO_ROLE_DEFINITION_EXAMPLE = """--body "{
5980
\\"Id\\": \\"be79875a-2cc4-40d5-8958-566017875b39\\",
6081
\\"RoleName\\": \\"MyRWRole\\",
@@ -652,3 +673,17 @@ def load_arguments(self, _):
652673
c.argument('table_name', options_list=['--table-name', '-n'], required=True, help='Name of the CosmosDB Table name')
653674
c.argument('restore_timestamp', options_list=['--restore-timestamp', '-t'], action=UtcDatetimeAction, help="The timestamp to which the Table needs to be restored to.", required=False)
654675
c.argument('disable_ttl', options_list=['--disable-ttl'], arg_type=get_three_state_flag(), help="Enable or disable restoring with ttl disabled.", is_preview=True, required=False)
676+
677+
# table role definition
678+
with self.argument_context('cosmosdb table role definition') as c:
679+
c.argument('account_name', account_name_type, id_part=None)
680+
c.argument('role_definition_id', options_list=['--role-definition-id', '-i'], validator=validate_table_role_definition_id, help="Unique ID for the Table Role Definition.")
681+
c.argument('table_role_definition_body', options_list=['--body', '-b'], validator=validate_table_role_definition_body, completer=FilesCompleter(), help="Role Definition body with Id (Optional for create), Type (Default is CustomRole), RoleName, Description, AssignableScopes, Permissions. You can enter it as a string or as a file, e.g., --body @table-role_definition-body-file.json or " + TABLE_ROLE_DEFINITION_EXAMPLE)
682+
683+
with self.argument_context('cosmosdb table role assignment') as c:
684+
c.argument('account_name', account_name_type, id_part=None)
685+
c.argument('role_assignment_id', options_list=['--role-assignment-id', '-i'], validator=validate_table_role_assignment_id, help="Optional for Create. Unique ID for the Role Assignment. If not provided, a new GUID will be used.")
686+
c.argument('role_definition_id', options_list=['--role-definition-id', '-d'], help="Unique ID of the Role Definition that this Role Assignment refers to.")
687+
c.argument('role_definition_name', options_list=['--role-definition-name', '-n'], help="Unique Name of the Role Definition that this Role Assignment refers to. Eg. 'Contoso Reader Role'.")
688+
c.argument('scope', options_list=['--scope', '-s'], help="Data plane resource path at which this Role Assignment is being granted.")
689+
c.argument('principal_id', options_list=['--principal-id', '-p'], help="AAD Object ID of the principal to which this Role Assignment is being granted.")

src/cosmosdb-preview/azext_cosmosdb_preview/_validators.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,3 +245,47 @@ def validate_mongo_user_definition_id(ns):
245245
""" Extracts Guid user definition Id """
246246
if ns.mongo_user_definition_id is not None:
247247
ns.mongo_user_definition_id = _parse_resource_path(ns.mongo_user_definition_id, False, "mongodbUserDefinitions")
248+
249+
250+
def validate_table_role_definition_body(cmd, ns):
251+
""" Extracts role definition body """
252+
from azext_cosmosdb_preview.vendored_sdks.azure_mgmt_cosmosdb.models import RoleDefinitionType
253+
from azure.cli.core.util import get_file_json, shell_safe_json_parse
254+
import os
255+
256+
if ns.table_role_definition_body is not None:
257+
if os.path.exists(ns.table_role_definition_body):
258+
table_role_definition = get_file_json(ns.table_role_definition_body)
259+
else:
260+
table_role_definition = shell_safe_json_parse(ns.table_role_definition_body)
261+
262+
if not isinstance(table_role_definition, dict):
263+
raise InvalidArgumentValueError(
264+
'Role creation failed. Invalid table role definition. A valid dictionary JSON representation is expected.')
265+
266+
if 'RoleName' not in table_role_definition or not isinstance(table_role_definition['RoleName'], str) or len(table_role_definition['RoleName']) == 0:
267+
raise InvalidArgumentValueError(
268+
'Role creation failed. Invalid table role name. A valid string role name is expected.')
269+
270+
if 'AssignableScopes' not in table_role_definition or not isinstance(table_role_definition['AssignableScopes'], list) or len(table_role_definition['AssignableScopes']) == 0:
271+
raise InvalidArgumentValueError(
272+
'Role creation failed. Invalid Table role definition for AssignableScopes. A valid list of strings is expected.')
273+
274+
if 'Permissions' not in table_role_definition or not isinstance(table_role_definition['Permissions'], list) or len(table_role_definition['Permissions']) == 0:
275+
raise InvalidArgumentValueError(
276+
'Role creation failed. Invalid Table role Permissions. A valid List JSON representation is expected.')
277+
278+
if 'Type' not in table_role_definition:
279+
table_role_definition['Type'] = RoleDefinitionType.custom_role
280+
281+
ns.table_role_definition_body = table_role_definition
282+
283+
def validate_table_role_definition_id(ns):
284+
""" Extracts Guid role definition Id """
285+
if ns.role_definition_id is not None:
286+
ns.role_definition_id = _parse_resource_path(ns.role_definition_id, False, "tableRoleDefinitions")
287+
288+
def validate_table_role_assignment_id(ns):
289+
""" Extracts Guid role assignment Id """
290+
if ns.role_assignment_id is not None:
291+
ns.role_assignment_id = _parse_resource_path(ns.role_assignment_id, False, "tableRoleAssignments")
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
{
2-
"azext.isPreview": true,
32
"azext.minCliCoreVersion": "2.17.1"
43
}

src/cosmosdb-preview/azext_cosmosdb_preview/commands.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ def load_command_table(self, _):
4949
cosmosdb_sql_sdk = CliCommandType(
5050
operations_tmpl='azure.mgmt.cosmosdb.operations#SqlResourcesOperations.{}',
5151
client_factory=cf_sql_resources)
52+
53+
cosmosdb_rbac_table_sdk = CliCommandType(
54+
operations_tmpl='azext_cosmosdb_preview.vendored_sdks.azure_mgmt_cosmosdb.operations#TableResourcesOperations.{}',
55+
client_factory=cf_table_resources)
5256

5357
with self.command_group('managed-cassandra cluster', cosmosdb_managed_cassandra_cluster_sdk, client_factory=cf_cassandra_cluster) as g:
5458
g.custom_command('create', 'cli_cosmosdb_managed_cassandra_cluster_create', supports_no_wait=True)
@@ -94,6 +98,22 @@ def load_command_table(self, _):
9498
g.custom_command('create', 'cli_cosmosdb_sql_container_create')
9599
g.custom_command('update', 'cli_cosmosdb_sql_container_update')
96100

101+
with self.command_group('cosmosdb table role definition', cosmosdb_rbac_table_sdk, client_factory=cf_table_resources) as g:
102+
g.custom_command('create', 'cli_cosmosdb_table_role_definition_create')
103+
g.custom_command('update', 'cli_cosmosdb_table_role_definition_update')
104+
g.custom_command('exists', 'cli_cosmosdb_table_role_definition_exists')
105+
g.command('list', 'list_table_role_definitions')
106+
g.show_command('show', 'get_table_role_definition')
107+
g.command('delete', 'begin_delete_table_role_definition', confirmation=True)
108+
109+
with self.command_group('cosmosdb table role assignment', cosmosdb_rbac_table_sdk, client_factory=cf_table_resources) as g:
110+
g.custom_command('create', 'cli_cosmosdb_table_role_assignment_create')
111+
g.custom_command('update', 'cli_cosmosdb_table_role_assignment_update')
112+
g.custom_command('exists', 'cli_cosmosdb_table_role_assignment_exists')
113+
g.command('list', 'list_table_role_assignments')
114+
g.show_command('show', 'get_table_role_assignment')
115+
g.command('delete', 'begin_delete_table_role_assignment', confirmation=True)
116+
97117
# restorable accounts api sdk
98118
cosmosdb_sdk = CliCommandType(
99119
operations_tmpl='azext_cosmosdb_preview.vendored_sdks.azure_mgmt_cosmosdb.operations#DatabaseAccountsOperations.{}',

0 commit comments

Comments
 (0)