From 1758442e6696a0efdcd654fe8a893874205d7ffe Mon Sep 17 00:00:00 2001 From: jiasli <4003950+jiasli@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:31:51 +0800 Subject: [PATCH] role-definition-show --- .../azure/cli/command_modules/role/_help.py | 10 ++ .../azure/cli/command_modules/role/_params.py | 17 ++- .../cli/command_modules/role/commands.py | 1 + .../azure/cli/command_modules/role/custom.py | 14 +++ ...est_built_in_role_definition_scenario.yaml | 115 +++++++++++++++++- .../role/tests/latest/test_role.py | 19 +++ 6 files changed, 169 insertions(+), 7 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/role/_help.py b/src/azure-cli/azure/cli/command_modules/role/_help.py index a21fa63e1d8..c2b34bc3459 100644 --- a/src/azure-cli/azure/cli/command_modules/role/_help.py +++ b/src/azure-cli/azure/cli/command_modules/role/_help.py @@ -864,6 +864,16 @@ short-summary: List role definitions. """ +helps['role definition show'] = """ +type: command +short-summary: Show a role definition. +examples: + - name: Show the 'Reader' role definition with its name (GUID). + text: az role definition show --scope /subscriptions/00000000-0000-0000-0000-000000000000 --name acdd72a7-3385-48ef-bd42-f606fba81ae7 + - name: Show the 'Reader' role definition with its resource ID. + text: az role definition show --id /subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7 +""" + helps['role definition update'] = """ type: command short-summary: Update a role definition. diff --git a/src/azure-cli/azure/cli/command_modules/role/_params.py b/src/azure-cli/azure/cli/command_modules/role/_params.py index 7f97b2ba2d7..58eb43022a0 100644 --- a/src/azure-cli/azure/cli/command_modules/role/_params.py +++ b/src/azure-cli/azure/cli/command_modules/role/_params.py @@ -369,8 +369,23 @@ class PrincipalType(str, Enum): c.argument('yes', options_list=['--yes', '-y'], action='store_true', help='Currently no-op.') with self.argument_context('role definition') as c: - c.argument('role_definition_id', options_list=['--name', '-n'], help='the role definition name') c.argument('custom_role_only', arg_type=get_three_state_flag(), help='custom roles only(vs. build-in ones)') c.argument('role_definition', help="json formatted content which defines the new role.") + + with self.argument_context('role definition list') as c: + c.argument('name', arg_type=name_arg_type, completer=get_role_definition_name_completion_list, + help="Matches the role definition's name (GUID) or roleName (e.g. 'Reader') property. " + "If a GUID is provided, for better performance, use `az role definition show` command.") + + with self.argument_context('role definition show') as c: + c.argument('name', arg_type=name_arg_type, help="The role definition's name (GUID)") + c.argument('role_id', options_list=['--id'], + help='The fully qualified role definition ID. Use the format, ' + '/subscriptions/{guid}/providers/Microsoft.Authorization/roleDefinitions/{roleDefinitionId} ' + 'for subscription level role definitions, or ' + '/providers/Microsoft.Authorization/roleDefinitions/{roleDefinitionId} ' + 'for tenant level role definitions.') + + with self.argument_context('role definition delete') as c: c.argument('name', arg_type=name_arg_type, completer=get_role_definition_name_completion_list, help="Matches the role definition's name (GUID) or roleName (e.g. 'Reader') property.") diff --git a/src/azure-cli/azure/cli/command_modules/role/commands.py b/src/azure-cli/azure/cli/command_modules/role/commands.py index e087793cbff..83af7c1b09d 100644 --- a/src/azure-cli/azure/cli/command_modules/role/commands.py +++ b/src/azure-cli/azure/cli/command_modules/role/commands.py @@ -69,6 +69,7 @@ def load_command_table(self, _): g.custom_command('delete', 'delete_role_definition') g.custom_command('create', 'create_role_definition') g.custom_command('update', 'update_role_definition') + g.custom_show_command('show', 'show_role_definition') with self.command_group('role assignment') as g: g.custom_command('delete', 'delete_role_assignments', validator=process_assignment_namespace) diff --git a/src/azure-cli/azure/cli/command_modules/role/custom.py b/src/azure-cli/azure/cli/command_modules/role/custom.py index f7731268fe7..5977c2abd22 100644 --- a/src/azure-cli/azure/cli/command_modules/role/custom.py +++ b/src/azure-cli/azure/cli/command_modules/role/custom.py @@ -71,6 +71,20 @@ def list_role_definitions(cmd, name=None, resource_group_name=None, scope=None, return _search_role_definitions(cmd.cli_ctx, definitions_client, name, [scope], custom_role_only) +def show_role_definition(cmd, scope=None, name=None, role_id=None): + if not any((scope, name, role_id)): + raise CLIError('Usage error: Provide --scope and --name, or --id') + if not role_id and not (name and scope): + raise CLIError('Usage error: Provide both --scope and --name') + + definitions_client = _auth_client_factory(cmd.cli_ctx, scope).role_definitions + # https://learn.microsoft.com/en-us/rest/api/authorization/role-definitions/get-by-id?view=rest-authorization-2022-04-01&tabs=HTTP + if role_id: + return definitions_client.get_by_id(role_id) + # https://learn.microsoft.com/en-us/rest/api/authorization/role-definitions/get?view=rest-authorization-2022-04-01&tabs=HTTP + return definitions_client.get(scope, name) + + def create_role_definition(cmd, role_definition): return _create_update_role_definition(cmd, role_definition, for_update=False) diff --git a/src/azure-cli/azure/cli/command_modules/role/tests/latest/recordings/test_built_in_role_definition_scenario.yaml b/src/azure-cli/azure/cli/command_modules/role/tests/latest/recordings/test_built_in_role_definition_scenario.yaml index 6662773d6f5..d86a5bbc878 100644 --- a/src/azure-cli/azure/cli/command_modules/role/tests/latest/recordings/test_built_in_role_definition_scenario.yaml +++ b/src/azure-cli/azure/cli/command_modules/role/tests/latest/recordings/test_built_in_role_definition_scenario.yaml @@ -1,4 +1,98 @@ interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - role definition show + Connection: + - keep-alive + ParameterSetName: + - --scope --name + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.12.8 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7?api-version=2022-05-01-preview + response: + body: + string: '{"properties":{"roleName":"Reader","type":"BuiltInRole","description":"View + all resources, but does not allow you to make any changes.","assignableScopes":["/"],"permissions":[{"actions":["*/read"],"notActions":[],"dataActions":[],"notDataActions":[]}],"createdOn":"2015-02-02T21:55:09.8806423Z","updatedOn":"2021-11-11T20:13:47.8628684Z","createdBy":null,"updatedBy":null},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7","type":"Microsoft.Authorization/roleDefinitions","name":"acdd72a7-3385-48ef-bd42-f606fba81ae7"}' + headers: + cache-control: + - no-cache + content-length: + - '615' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 14 Jan 2025 08:31:34 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + x-msedge-ref: + - 'Ref A: C061AE716EE2452680D4CB1A7E20FF7A Ref B: MAA201060515053 Ref C: 2025-01-14T08:31:33Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - role definition show + Connection: + - keep-alive + ParameterSetName: + - --id + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.12.8 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7?api-version=2022-05-01-preview + response: + body: + string: '{"properties":{"roleName":"Reader","type":"BuiltInRole","description":"View + all resources, but does not allow you to make any changes.","assignableScopes":["/"],"permissions":[{"actions":["*/read"],"notActions":[],"dataActions":[],"notDataActions":[]}],"createdOn":"2015-02-02T21:55:09.8806423Z","updatedOn":"2021-11-11T20:13:47.8628684Z","createdBy":null,"updatedBy":null},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7","type":"Microsoft.Authorization/roleDefinitions","name":"acdd72a7-3385-48ef-bd42-f606fba81ae7"}' + headers: + cache-control: + - no-cache + content-length: + - '615' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 14 Jan 2025 08:31:34 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '3749' + x-msedge-ref: + - 'Ref A: B175DFADEA244A9596A747FEEEFB2C5D Ref B: MAA201060515021 Ref C: 2025-01-14T08:31:34Z' + status: + code: 200 + message: OK - request: body: null headers: @@ -28,7 +122,7 @@ interactions: content-type: - application/json; charset=utf-8 date: - - Fri, 10 Jan 2025 08:17:57 GMT + - Tue, 14 Jan 2025 08:31:34 GMT expires: - '-1' pragma: @@ -42,7 +136,7 @@ interactions: x-ms-ratelimit-remaining-subscription-global-reads: - '3749' x-msedge-ref: - - 'Ref A: 7F6EAE2E153640A894E4F7971729E661 Ref B: MAA201060516025 Ref C: 2025-01-10T08:17:58Z' + - 'Ref A: C294E8E0D0AA4D70B126A61CF34BABD9 Ref B: MAA201060513021 Ref C: 2025-01-14T08:31:35Z' status: code: 200 message: OK @@ -1638,16 +1732,25 @@ interactions: Autonomous Database Administrator\",\"type\":\"BuiltInRole\",\"description\":\"Grants full access to manage all Autonomous Database resources\",\"assignableScopes\":[\"/\"],\"permissions\":[{\"actions\":[\"Oracle.Database/autonomousDatabases/*/read\",\"Oracle.Database/autonomousDatabases/*/write\",\"Oracle.Database/autonomousDatabases/*/delete\",\"Oracle.Database/autonomousDatabases/*/action\",\"Oracle.Database/Locations/*/read\",\"Oracle.Database/Locations/*/write\",\"Oracle.Database/Operations/read\",\"Oracle.Database/oracleSubscriptions/*/read\",\"Oracle.Database/oracleSubscriptions/*/action\",\"Microsoft.Resources/subscriptions/resourceGroups/read\",\"Microsoft.Resources/deployments/*\",\"Microsoft.Network/virtualNetworks/read\",\"Microsoft.Network/virtualNetworks/subnets/read\",\"Microsoft.Network/virtualNetworks/subnets/write\",\"Microsoft.Network/locations/operations/read\"],\"notActions\":[],\"dataActions\":[],\"notDataActions\":[]}],\"createdOn\":\"2024-12-04T16:02:04.8857247Z\",\"updatedOn\":\"2024-12-04T16:02:04.8857247Z\",\"createdBy\":null,\"updatedBy\":null},\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/59c05558-2358-462d-ba19-afbd7118936d\",\"type\":\"Microsoft.Authorization/roleDefinitions\",\"name\":\"59c05558-2358-462d-ba19-afbd7118936d\"},{\"properties\":{\"roleName\":\"Azure AI Safety Evaluator\",\"type\":\"BuiltInRole\",\"description\":\"This role - can perform all actions under workspace evaluations and simulations.\",\"assignableScopes\":[\"/\"],\"permissions\":[{\"actions\":[\"Microsoft.MachineLearningServices/workspaces/evaluations/*\",\"Microsoft.MachineLearningServices/workspaces/simulations/*\"],\"notActions\":[],\"dataActions\":[],\"notDataActions\":[]}],\"createdOn\":\"2024-12-18T16:29:45.1650072Z\",\"updatedOn\":\"2024-12-18T16:29:45.1650072Z\",\"createdBy\":null,\"updatedBy\":null},\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/11102f94-c441-49e6-a78b-ef80e0188abc\",\"type\":\"Microsoft.Authorization/roleDefinitions\",\"name\":\"11102f94-c441-49e6-a78b-ef80e0188abc\"}]}" + can perform all actions under workspace evaluations and simulations.\",\"assignableScopes\":[\"/\"],\"permissions\":[{\"actions\":[\"Microsoft.MachineLearningServices/workspaces/evaluations/*\",\"Microsoft.MachineLearningServices/workspaces/simulations/*\"],\"notActions\":[],\"dataActions\":[],\"notDataActions\":[]}],\"createdOn\":\"2024-12-18T16:29:45.1650072Z\",\"updatedOn\":\"2024-12-18T16:29:45.1650072Z\",\"createdBy\":null,\"updatedBy\":null},\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/11102f94-c441-49e6-a78b-ef80e0188abc\",\"type\":\"Microsoft.Authorization/roleDefinitions\",\"name\":\"11102f94-c441-49e6-a78b-ef80e0188abc\"},{\"properties\":{\"roleName\":\"Container + Registry Tasks Contributor\",\"type\":\"BuiltInRole\",\"description\":\"Provides + permissions to configure, read, list, trigger, or cancel Container Registry + Tasks, Task Runs, Task Logs, Quick Runs, Quick Builds, and Task Agent Pools. + Permissions granted for Tasks management can be used for full registry data + plane permissions including reading/writing/deleting container images in registries. + Permissions granted for Tasks management can also be used to run customer + authored build directives and run scripts to build software artifacts.\",\"assignableScopes\":[\"/\"],\"permissions\":[{\"actions\":[\"Microsoft.ContainerRegistry/registries/agentpools/read\",\"Microsoft.ContainerRegistry/registries/agentpools/write\",\"Microsoft.ContainerRegistry/registries/agentpools/delete\",\"Microsoft.ContainerRegistry/registries/agentpools/listQueueStatus/action\",\"Microsoft.ContainerRegistry/registries/agentpools/operationResults/status/read\",\"Microsoft.ContainerRegistry/registries/agentpools/operationStatuses/read\",\"Microsoft.ContainerRegistry/registries/tasks/read\",\"Microsoft.ContainerRegistry/registries/tasks/write\",\"Microsoft.ContainerRegistry/registries/tasks/delete\",\"Microsoft.ContainerRegistry/registries/tasks/listDetails/action\",\"Microsoft.ContainerRegistry/registries/scheduleRun/action\",\"Microsoft.ContainerRegistry/registries/listBuildSourceUploadUrl/action\",\"Microsoft.ContainerRegistry/registries/runs/read\",\"Microsoft.ContainerRegistry/registries/runs/write\",\"Microsoft.ContainerRegistry/registries/runs/listLogSasUrl/action\",\"Microsoft.ContainerRegistry/registries/runs/cancel/action\",\"Microsoft.ContainerRegistry/registries/taskruns/read\",\"Microsoft.ContainerRegistry/registries/taskruns/write\",\"Microsoft.ContainerRegistry/registries/taskruns/delete\",\"Microsoft.ContainerRegistry/registries/taskruns/listDetails/action\",\"Microsoft.ContainerRegistry/registries/taskruns/operationStatuses/read\",\"Microsoft.Resources/deployments/*\",\"Microsoft.Resources/subscriptions/resourceGroups/read\",\"Microsoft.ContainerRegistry/registries/read\"],\"notActions\":[],\"dataActions\":[],\"notDataActions\":[]}],\"createdOn\":\"2025-01-13T16:06:06.8277690Z\",\"updatedOn\":\"2025-01-13T16:06:06.8277690Z\",\"createdBy\":null,\"updatedBy\":null},\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/fb382eab-e894-4461-af04-94435c366c3f\",\"type\":\"Microsoft.Authorization/roleDefinitions\",\"name\":\"fb382eab-e894-4461-af04-94435c366c3f\"},{\"properties\":{\"roleName\":\"Azure + Backup Snapshot Contributor\",\"type\":\"BuiltInRole\",\"description\":\"Provide + permissions to backup identity to manage RPC snapshots\",\"assignableScopes\":[\"/\"],\"permissions\":[{\"actions\":[\"Microsoft.Compute/virtualMachines/read\",\"Microsoft.Compute/virtualMachines/write\",\"Microsoft.Compute/restorePointCollections/read\",\"Microsoft.Compute/restorePointCollections/write\",\"Microsoft.Compute/restorePointCollections/restorePoints/write\",\"Microsoft.Compute/restorePointCollections/restorePoints/read\",\"Microsoft.Compute/disks/read\",\"Microsoft.Compute/disks/write\",\"Microsoft.Compute/disks/delete\",\"Microsoft.Compute/disks/beginGetAccess/action\"],\"notActions\":[],\"dataActions\":[],\"notDataActions\":[]}],\"createdOn\":\"2025-01-13T16:06:06.8277690Z\",\"updatedOn\":\"2025-01-13T16:06:06.8277690Z\",\"createdBy\":null,\"updatedBy\":null},\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/afc680e2-a938-412d-b213-9a49efa7fb83\",\"type\":\"Microsoft.Authorization/roleDefinitions\",\"name\":\"afc680e2-a938-412d-b213-9a49efa7fb83\"}]}" headers: cache-control: - no-cache content-length: - - '792919' + - '796487' content-type: - application/json; charset=utf-8 date: - - Fri, 10 Jan 2025 08:17:58 GMT + - Tue, 14 Jan 2025 08:31:35 GMT expires: - '-1' pragma: @@ -1661,7 +1764,7 @@ interactions: x-ms-ratelimit-remaining-subscription-global-reads: - '3749' x-msedge-ref: - - 'Ref A: 57281F819E2749AF82F1DCE477577B17 Ref B: MAA201060514053 Ref C: 2025-01-10T08:17:58Z' + - 'Ref A: CED333ECC3644E28BEA0E8BD9D1C7ABC Ref B: MAA201060515023 Ref C: 2025-01-14T08:31:35Z' status: code: 200 message: OK diff --git a/src/azure-cli/azure/cli/command_modules/role/tests/latest/test_role.py b/src/azure-cli/azure/cli/command_modules/role/tests/latest/test_role.py index 2b295151c9c..1a70801e628 100644 --- a/src/azure-cli/azure/cli/command_modules/role/tests/latest/test_role.py +++ b/src/azure-cli/azure/cli/command_modules/role/tests/latest/test_role.py @@ -200,6 +200,25 @@ class RoleDefinitionScenarioTest(RoleScenarioTestBase): @AllowLargeResponse() def test_built_in_role_definition_scenario(self): + self.kwargs['sub_scope'] = '/subscriptions/{}'.format(self.cmd('account show').get_output_in_json()['id']) + + # Show Reader built-in role definition by scope and name + self.cmd('role definition show --scope {sub_scope} --name acdd72a7-3385-48ef-bd42-f606fba81ae7', + checks=[ + self.check('name', 'acdd72a7-3385-48ef-bd42-f606fba81ae7'), + self.check('roleName', 'Reader'), + self.check('roleType', 'BuiltInRole') + ]) + + # Show Reader built-in role definition by resource ID + self.cmd('role definition show --id ' + '{sub_scope}/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7', + checks=[ + self.check('name', 'acdd72a7-3385-48ef-bd42-f606fba81ae7'), + self.check('roleName', 'Reader'), + self.check('roleType', 'BuiltInRole') + ]) + # List Reader built-in role definition by roleName self.cmd('role definition list --name Reader', checks=[