Skip to content

Commit 7cddb0b

Browse files
authored
[Role] BREAKING CHANGE: az role assignment delete: Stop deleting all role assignments by default (#30470)
1 parent e52f73f commit 7cddb0b

File tree

4 files changed

+29
-21
lines changed

4 files changed

+29
-21
lines changed

src/azure-cli/azure/cli/command_modules/role/_help.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -772,11 +772,15 @@
772772
helps['role assignment delete'] = """
773773
type: command
774774
short-summary: Delete role assignments.
775+
long-summary: >-
776+
This command deletes all role assignments that satisfy the provided query condition. Before running this
777+
command, it is highly recommended to run `az role assignment list` first with the same arguments to see which
778+
role assignments will be deleted.
775779
examples:
776-
- name: Delete role assignments. (autogenerated)
777-
text: |
778-
az role assignment delete --assignee 00000000-0000-0000-0000-000000000000 --role "Storage Account Key Operator Service Role"
779-
crafted: true
780+
- name: Delete all role assignments with "Reader" role at the subscription scope.
781+
text: az role assignment delete --role Reader --scope /subscriptions/00000000-0000-0000-0000-000000000000
782+
- name: Delete all role assignments of an assignee at the subscription scope.
783+
text: az role assignment delete --assignee 00000000-0000-0000-0000-000000000000 --scope /subscriptions/00000000-0000-0000-0000-000000000000
780784
"""
781785

782786
helps['role assignment list'] = """
@@ -791,6 +795,11 @@
791795
After August 31, 2024, all classic administrators risk losing access to the subscription.
792796
Delete classic administrators who no longer need access or assign an Azure RBAC role for fine-grained access
793797
control. Learn more: https://go.microsoft.com/fwlink/?linkid=2238474
798+
examples:
799+
- name: List all role assignments with "Reader" role at the subscription scope.
800+
text: az role assignment list --role Reader --scope /subscriptions/00000000-0000-0000-0000-000000000000
801+
- name: List all role assignments of an assignee at the subscription scope.
802+
text: az role assignment list --assignee 00000000-0000-0000-0000-000000000000 --scope /subscriptions/00000000-0000-0000-0000-000000000000
794803
"""
795804

796805
helps['role assignment list-changelogs'] = """

src/azure-cli/azure/cli/command_modules/role/_params.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ class PrincipalType(str, Enum):
366366
'JSON description.')
367367

368368
with self.argument_context('role assignment delete') as c:
369-
c.argument('yes', options_list=['--yes', '-y'], action='store_true', help='Continue to delete all assignments under the subscription')
369+
c.argument('yes', options_list=['--yes', '-y'], action='store_true', help='Currently no-op.')
370370

371371
with self.argument_context('role definition') as c:
372372
c.argument('role_definition_id', options_list=['--name', '-n'], help='the role definition name')

src/azure-cli/azure/cli/command_modules/role/custom.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
from azure.cli.core.profiles import ResourceType
2929
from azure.cli.core.util import get_file_json, shell_safe_json_parse, is_guid
30+
from azure.cli.core.azclierror import ArgumentUsageError
31+
3032
from ._client_factory import _auth_client_factory, _graph_client_factory
3133
from ._multi_api_adaptor import MultiAPIAdaptor
3234
from ._msgrpah import GraphError, set_object_properties
@@ -501,7 +503,13 @@ def _get_displayable_name(graph_object):
501503

502504

503505
def delete_role_assignments(cmd, ids=None, assignee=None, role=None, resource_group_name=None,
504-
scope=None, include_inherited=False, yes=None):
506+
scope=None, include_inherited=False,
507+
yes=None): # pylint: disable=unused-argument
508+
# yes is currently a no-op
509+
if not any((ids, assignee, role, resource_group_name, scope)):
510+
raise ArgumentUsageError('Please provide at least one of these arguments: '
511+
'--ids, --assignee, --role, --resource-group, --scope')
512+
505513
factory = _auth_client_factory(cmd.cli_ctx, scope)
506514
assignments_client = factory.role_assignments
507515
definitions_client = factory.role_definitions
@@ -528,11 +536,6 @@ def delete_role_assignments(cmd, ids=None, assignee=None, role=None, resource_gr
528536
for i in ids:
529537
assignments_client.delete_by_id(i)
530538
return
531-
if not any([ids, assignee, role, resource_group_name, scope, assignee, yes]):
532-
from knack.prompting import prompt_y_n
533-
msg = 'This will delete all role assignments under the subscription. Are you sure?'
534-
if not prompt_y_n(msg, default="n"):
535-
return
536539

537540
scope = _build_role_scope(resource_group_name, scope,
538541
assignments_client._config.subscription_id)
@@ -905,7 +908,6 @@ def add_permission(client, identifier, api, api_permissions):
905908
try:
906909
access_id, access_type = e.split('=')
907910
except ValueError as ex:
908-
from azure.cli.core.azclierror import ArgumentUsageError
909911
raise ArgumentUsageError('Usage error: Please provide both permission id and type, such as '
910912
'`--api-permissions e1fe6dd8-ba31-4d61-89e7-88639da4683d=Scope`') from ex
911913
resource_access = {
@@ -1184,7 +1186,6 @@ def create_service_principal_for_rbac(
11841186
import time
11851187

11861188
if role and not scopes or not role and scopes:
1187-
from azure.cli.core.azclierror import ArgumentUsageError
11881189
raise ArgumentUsageError("Usage error: To create role assignments, specify both --role and --scopes.")
11891190

11901191
graph_client = _graph_client_factory(cmd.cli_ctx)

src/azure-cli/azure/cli/command_modules/role/tests/latest/test_role_commands_thru_mock.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -383,14 +383,12 @@ def test_list_sp_owner(self, graph_client_mock):
383383
assert len(result) == 1
384384
assert result[0]['id'] == MOCKED_USER_ID
385385

386-
@mock.patch('azure.cli.command_modules.role.custom._auth_client_factory', autospec=True)
387-
@mock.patch('knack.prompting.prompt_y_n', autospec=True)
388-
def test_role_assignment_delete_prompt(self, prompt_mock, client_mock):
389-
prompt_mock.return_value = False
390-
# action
391-
delete_role_assignments(mock.MagicMock())
392-
# assert
393-
prompt_mock.assert_called_once_with(mock.ANY, 'n')
386+
def test_role_assignment_delete_no_args_raise_error(self):
387+
from azure.cli.core.azclierror import ArgumentUsageError
388+
with self.assertRaises(ArgumentUsageError):
389+
delete_role_assignments(mock.MagicMock())
390+
with self.assertRaises(ArgumentUsageError):
391+
delete_role_assignments(mock.MagicMock(), yes=True)
394392

395393
@mock.patch('azure.cli.command_modules.role.custom._graph_client_factory', autospec=True)
396394
def test_role_list_app_owner(self, graph_client_mock):

0 commit comments

Comments
 (0)