Skip to content

Commit feb7f87

Browse files
committed
at-scope
1 parent 6273ccf commit feb7f87

File tree

2 files changed

+23
-15
lines changed

2 files changed

+23
-15
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,10 @@ def load_arguments(self, _):
323323

324324
with self.argument_context('role assignment') as c:
325325
c.argument('role', help='role name or id', completer=get_role_definition_name_completion_list)
326-
c.argument('show_all', options_list=['--all'], action='store_true', help='show all assignments under the current subscription')
326+
c.argument('show_all', options_list=['--all'], action='store_true',
327+
deprecate_info=c.deprecate(target='--all'),
328+
help="Show all assignments under the current subscription. This argument is deprecated. "
329+
"Use '--at-scope false' instead.")
327330
c.argument('include_inherited', action='store_true', help='include assignments applied on parent scopes')
328331
c.argument('can_delegate', action='store_true', help='when set, the assignee will be able to create further role assignments to the same role')
329332
c.argument('assignee', help='represent a user, group, or service principal. supported format: object id, user sign-in name, or service principal name')
@@ -339,6 +342,9 @@ def load_arguments(self, _):
339342
c.argument('condition_version', is_preview=True, min_api='2020-04-01-preview', help='Version of the condition syntax. If --condition is specified without --condition-version, default to 2.0.')
340343
c.argument('assignment_name', name_arg_type,
341344
help='A GUID for the role assignment. It must be unique and different for each role assignment. If omitted, a new GUID is generated.')
345+
c.argument('at_scope', arg_type=get_three_state_flag(),
346+
help='Lists role assignments for only the specified scope, not including the role assignments at '
347+
'subscopes.')
342348

343349
with self.argument_context('role assignment list') as c:
344350
c.argument('fill_principal_name', arg_type=get_three_state_flag(),

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

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,8 @@ def _create_role_assignment(cli_ctx, role, assignee, resource_group_name=None, s
235235
def list_role_assignments(cmd, assignee=None, role=None, resource_group_name=None,
236236
scope=None, include_inherited=False,
237237
show_all=False, include_groups=False, include_classic_administrators=False,
238-
fill_principal_name=True):
238+
fill_principal_name=True,
239+
at_scope=True):
239240
'''
240241
:param include_groups: include extra assignments to the groups of which the user is a
241242
member(transitively).
@@ -258,7 +259,8 @@ def list_role_assignments(cmd, assignee=None, role=None, resource_group_name=Non
258259

259260
assignments = _search_role_assignments(cmd.cli_ctx, assignments_client, definitions_client,
260261
scope, assignee, role,
261-
include_inherited, include_groups)
262+
include_inherited, include_groups,
263+
at_scope=at_scope)
262264

263265
results = todict(assignments) if assignments else []
264266
if include_classic_administrators:
@@ -571,7 +573,8 @@ def delete_role_assignments(cmd, ids=None, assignee=None, role=None, resource_gr
571573

572574

573575
def _search_role_assignments(cli_ctx, assignments_client, definitions_client,
574-
scope, assignee, role, include_inherited, include_groups):
576+
scope, assignee, role, include_inherited, include_groups,
577+
at_scope=None):
575578
assignee_object_id = None
576579
if assignee:
577580
assignee_object_id = _resolve_object_id(cli_ctx, assignee, fallback_to_object_id=True)
@@ -580,9 +583,12 @@ def _search_role_assignments(cli_ctx, assignments_client, definitions_client,
580583
# "atScope()" and "principalId eq '{value}'" query cannot be used together (API limitation).
581584
# always use "scope" if provided, so we can get assignments beyond subscription e.g. management groups
582585
if scope:
583-
f = 'atScope()' # atScope() excludes role assignments at subscopes
586+
filters = []
587+
if at_scope:
588+
filters.append('atScope()') # atScope() excludes role assignments at subscopes
584589
if assignee_object_id and include_groups:
585-
f = f + " and assignedTo('{}')".format(assignee_object_id)
590+
filters.append("assignedTo('{}')".format(assignee_object_id))
591+
f = ' and '.join(filters) if filters else None
586592
assignments = list(assignments_client.list_for_scope(scope=scope, filter=f))
587593
elif assignee_object_id:
588594
if include_groups:
@@ -595,15 +601,11 @@ def _search_role_assignments(cli_ctx, assignments_client, definitions_client,
595601

596602
worker = MultiAPIAdaptor(cli_ctx)
597603
if assignments:
598-
assignments = [a for a in assignments if (
599-
# If no scope, list all assignments
600-
not scope or
601-
# If scope is provided with include_inherited, list assignments at and above the scope.
602-
# Note that assignments below the scope are already excluded by atScope()
603-
include_inherited or
604-
# If scope is provided, list assignments at the scope
605-
worker.get_role_property(a, 'scope').lower() == scope.lower()
606-
)]
604+
# Limitation: If scope is a management group, the filtering cannot keep subscope assignments,
605+
# because a subscope assignment's scope doesn't start with management group scope.
606+
if scope and not include_inherited:
607+
assignments = [a for a in assignments if (
608+
worker.get_role_property(a, 'scope').lower().startswith(scope.lower()))]
607609

608610
if role:
609611
role_id = _resolve_role_id(role, scope, definitions_client)

0 commit comments

Comments
 (0)