Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Role] az role assignment list/delete: Support --assignee-object-id #30469

Draft
wants to merge 1 commit into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/azure-cli/azure/cli/command_modules/role/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,10 +312,12 @@ def load_arguments(self, _):
c.argument('include_inherited', action='store_true', help='include assignments applied on parent scopes')
c.argument('can_delegate', action='store_true', help='when set, the assignee will be able to create further role assignments to the same role')
c.argument('assignee', help='represent a user, group, or service principal. supported format: object id, user sign-in name, or service principal name')
c.argument('assignee_object_id', help="Use this parameter instead of '--assignee' to bypass Graph API invocation in case of insufficient privileges. "
"This parameter only works with object ids for users, groups, service principals, and "
"managed identities. For managed identities use the principal id. For service principals, "
"use the object id and not the app id.")
c.argument('assignee_object_id',
help="Use this parameter instead of '--assignee' to bypass Microsoft Graph API invocation in case "
"you do not have sufficient privileges or network connections to Microsoft Graph API. "
"This parameter only works with object ids for users, groups, service principals, and "
"managed identities. For managed identities, use the principal id. For service principals, "
"use the object id and not the app id.")
c.argument('ids', nargs='+', help='space-separated role assignment ids')
c.argument('include_classic_administrators', arg_type=get_three_state_flag(),
help='list default role assignments for subscription classic administrators, aka co-admins',
Expand Down
34 changes: 22 additions & 12 deletions src/azure-cli/azure/cli/command_modules/role/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,14 @@ def _create_role_assignment(cli_ctx, role, assignee, resource_group_name=None, s
condition=condition, condition_version=condition_version)


def list_role_assignments(cmd, assignee=None, role=None, resource_group_name=None,
def list_role_assignments(cmd,
assignee=None, assignee_object_id=None,
role=None, resource_group_name=None,
scope=None, include_inherited=False,
show_all=False, include_groups=False, include_classic_administrators=False):
'''
:param include_groups: include extra assignments to the groups of which the user is a
member(transitively).
'''
# include_groups: include extra assignments to the groups of which the user is a member(transitively).
assignee_object_id = _resolve_assignee(cmd.cli_ctx, assignee, assignee_object_id)

if include_classic_administrators:
logger.warning(CLASSIC_ADMINISTRATOR_WARNING)

Expand All @@ -236,7 +237,7 @@ def list_role_assignments(cmd, assignee=None, role=None, resource_group_name=Non
definitions_client._config.subscription_id)

assignments = _search_role_assignments(cmd.cli_ctx, assignments_client, definitions_client,
scope, assignee, role,
scope, assignee_object_id, role,
include_inherited, include_groups)

results = todict(assignments) if assignments else []
Expand Down Expand Up @@ -500,8 +501,12 @@ def _get_displayable_name(graph_object):
return graph_object['displayName'] or ''


def delete_role_assignments(cmd, ids=None, assignee=None, role=None, resource_group_name=None,
def delete_role_assignments(cmd, ids=None,
assignee=None, assignee_object_id=None,
role=None, resource_group_name=None,
scope=None, include_inherited=False, yes=None):
assignee_object_id = _resolve_assignee(cmd.cli_ctx, assignee, assignee_object_id)

factory = _auth_client_factory(cmd.cli_ctx, scope)
assignments_client = factory.role_assignments
definitions_client = factory.role_definitions
Expand Down Expand Up @@ -548,11 +553,7 @@ def delete_role_assignments(cmd, ids=None, assignee=None, role=None, resource_gr


def _search_role_assignments(cli_ctx, assignments_client, definitions_client,
scope, assignee, role, include_inherited, include_groups):
assignee_object_id = None
if assignee:
assignee_object_id = _resolve_object_id(cli_ctx, assignee, fallback_to_object_id=True)

scope, assignee_object_id, role, include_inherited, include_groups):
# https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-list-rest
# "atScope()" and "principalId eq '{value}'" query cannot be used together (API limitation).
# always use "scope" if provided, so we can get assignments beyond subscription e.g. management groups
Expand Down Expand Up @@ -590,6 +591,15 @@ def _search_role_assignments(cli_ctx, assignments_client, definitions_client,
return assignments


def _resolve_assignee(cli_ctx, assignee, assignee_object_id):
if assignee and assignee_object_id:
raise CLIError('Usage error: Please provide only one of --assignee or --assignee-object-id.')
if assignee_object_id:
return assignee_object_id
if assignee:
return _resolve_object_id(cli_ctx, assignee, fallback_to_object_id=True)


def _build_role_scope(resource_group_name, scope, subscription_id):
subscription_scope = '/subscriptions/' + subscription_id
if scope:
Expand Down
Loading