def _resolve_object_id(cmd, assignee, fallback_to_object_id=False): if not assignee: return None client = cf_graph_client_factory(cmd.cli_ctx) result = None try: if assignee.find('@') >= 0: # looks like a user principal name result = list( client.users.list( filter="userPrincipalName eq '{}'".format(assignee))) if not result: result = list( client.service_principals.list( filter="servicePrincipalNames/any(c:c eq '{}')".format( assignee))) if not result and is_guid(assignee): return assignee # 2+ matches should never happen, so we only check 'no match' here if not result: raise CLIError( "Cannot find user or service principal in graph database for '{assignee}'. " "If the assignee is an appId, make sure the corresponding service principal is created " "with 'az ad sp create --id {assignee}'.".format( assignee=assignee)) return result[0].object_id except (CloudError, GraphErrorException): if fallback_to_object_id and is_guid(assignee): return assignee raise
def _resolve_object_id(cmd, assignee, fallback_to_object_id=False): if assignee is None: return None client = cf_graph_client_factory(cmd.cli_ctx) result = None try: result = list(client.users.list(filter="userPrincipalName eq '{0}' or mail eq '{0}' or displayName eq '{0}'" .format(assignee))) if not result: result = list(client.service_principals.list(filter="displayName eq '{}'".format(assignee))) if not result: result = list(client.groups.list(filter="mail eq '{}'".format(assignee))) if not result and is_guid(assignee): # assume an object id, let us verify it result = _get_object_stubs(client, [assignee]) # 2+ matches should never happen, so we only check 'no match' here if not result: raise CLIError("Cannot find user or group or service principal in graph database for '{assignee}'. " "If the assignee is a principal id, make sure the corresponding principal is created " "with 'az ad sp create --id {assignee}'.".format(assignee=assignee)) if len(result) > 1: raise CLIError("Find more than one user or group or service principal in graph database for '{assignee}'. " "Please using --assignee-object-id GUID to specify assignee accurately" .format(assignee=assignee)) return result[0].object_id except (CloudError, GraphErrorException): if fallback_to_object_id and is_guid(assignee): return assignee raise
def validate_tenant(cmd, namespace): """ Make sure tenant is a GUID. If domain name is provided, resolve to GUID. https://docs.microsoft.com/azure/active-directory/develop/v2-protocols-oidc#fetch-the-openid-connect-metadata-document """ from azure.cli.core.util import is_guid if namespace.tenant is not None and not is_guid(namespace.tenant): import requests active_directory_endpoint = cmd.cli_ctx.cloud.endpoints.active_directory url = '{}/{}/.well-known/openid-configuration'.format( active_directory_endpoint, namespace.tenant) response = requests.get(url, verify=not should_disable_connection_verify()) if response.status_code != 200: from knack.util import CLIError raise CLIError( "Failed to resolve tenant '{}'.\n\nError detail: {}".format( namespace.tenant, response.text)) # Example issuer: https://sts.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47/ tenant_id = response.json()['issuer'].split("/")[3] logger.debug('Resolved tenant domain name %s to GUID %s', namespace.tenant, tenant_id) namespace.tenant = tenant_id
def create_role_assignment(cmd, workspace_name, role, assignee=None, assignee_object_id=None, scope=None, assignee_principal_type=None, item_type=None, item=None, assignment_id=None): """Check parameters are provided correctly, then call _create_role_assignment.""" if assignment_id and not is_guid(assignment_id): raise InvalidArgumentValueError('usage error: --id GUID') if bool(assignee) == bool(assignee_object_id): raise ArgumentUsageError('usage error: --assignee STRING | --assignee-object-id GUID') if assignee_principal_type and not assignee_object_id: raise ArgumentUsageError('usage error: --assignee-object-id GUID [--assignee-principal-type]') if bool(item) != bool(item_type): raise ArgumentUsageError('usage error: --item-type STRING --item STRING') try: return _create_role_assignment(cmd, workspace_name, role, assignee or assignee_object_id, scope, item, item_type, resolve_assignee=(not assignee_object_id), assignee_principal_type=assignee_principal_type, assignment_id=assignment_id) except Exception as ex: # pylint: disable=broad-except if _error_caused_by_role_assignment_exists(ex): # for idempotent return list_role_assignments(cmd, workspace_name, role=role, assignee=assignee, assignee_object_id=assignee_object_id, scope=scope, item=item, item_type=item_type) raise
def _resolve_role_id(cmd, role, workspace_name): role_id = None if not role: return role_id if is_guid(role): role_id = role else: role_definition_client = cf_synapse_role_definitions(cmd.cli_ctx, workspace_name) role_definition = role_definition_client.list_role_definitions() role_dict = {x.name.lower(): x.id for x in role_definition if x.name} if role.lower() not in role_dict: raise CLIError("Role '{}' doesn't exist.".format(role)) role_id = role_dict[role.lower()] return role_id
def _process_sp_name(sp_name): from azure.cli.core.util import is_guid return sp_name if is_guid(sp_name) else 'http://{}'.format(sp_name)