def test_get_expanded_subscription_info(self): storage_mock = {'subscriptions': None} profile = Profile(storage_mock) consolidated = Profile._normalize_properties(self.user1, [self.subscription1], False) profile._set_subscriptions(consolidated) sub_id = self.id1.split('/')[-1] #testing dump of existing logged in account extended_info = profile.get_expanded_subscription_info() self.assertEqual(self.user1, extended_info['userName']) self.assertEqual(sub_id, extended_info['subscriptionId']) self.assertEqual(self.display_name1, extended_info['subscriptionName']) self.assertEqual('https://login.microsoftonline.com', extended_info['endpoints'].active_directory) #testing dump of service principal by 'create-for-rbac' extended_info = profile.get_expanded_subscription_info( name='great-sp', password='******') self.assertEqual(sub_id, extended_info['subscriptionId']) self.assertEqual(self.display_name1, extended_info['subscriptionName']) self.assertEqual('great-sp', extended_info['client']) self.assertEqual('https://login.microsoftonline.com', extended_info['endpoints'].active_directory)
def test_get_expanded_subscription_info(self): storage_mock = {'subscriptions': None} profile = Profile(storage_mock) consolidated = Profile._normalize_properties(self.user1, [self.subscription1], False) profile._set_subscriptions(consolidated) sub_id = self.id1.split('/')[-1] #testing dump of existing logged in account extended_info = profile.get_expanded_subscription_info() self.assertEqual(self.user1, extended_info['userName']) self.assertEqual(sub_id, extended_info['subscriptionId']) self.assertEqual(self.display_name1, extended_info['subscriptionName']) self.assertEqual('https://login.microsoftonline.com', extended_info['endpoints'].active_directory) #testing dump of service principal by 'create-for-rbac' extended_info = profile.get_expanded_subscription_info(name='great-sp', password='******') self.assertEqual(sub_id, extended_info['subscriptionId']) self.assertEqual(self.display_name1, extended_info['subscriptionName']) self.assertEqual('great-sp', extended_info['client']) self.assertEqual('https://login.microsoftonline.com', extended_info['endpoints'].active_directory)
def test_get_expanded_subscription_info_for_logged_in_service_principal(self, mock_auth_context): mock_auth_context.acquire_token_with_client_credentials.return_value = self.token_entry1 mock_arm_client = mock.MagicMock() mock_arm_client.subscriptions.list.return_value = [self.subscription1] finder = SubscriptionFinder(lambda _, _2: mock_auth_context, None, lambda _: mock_arm_client) storage_mock = {'subscriptions': []} profile = Profile(storage_mock, use_global_creds_cache=False) profile._management_resource_uri = 'https://management.core.windows.net/' profile.find_subscriptions_on_login(False, '1234', 'my-secret', True, self.tenant_id, False, finder) # action extended_info = profile.get_expanded_subscription_info() # assert self.assertEqual(self.id1.split('/')[-1], extended_info['subscriptionId']) self.assertEqual(self.display_name1, extended_info['subscriptionName']) self.assertEqual('1234', extended_info['client']) self.assertEqual('https://login.microsoftonline.com', extended_info['endpoints'].active_directory)
def show_subscription(subscription=None, expanded_view=None): profile = Profile() if not expanded_view: return profile.get_subscription(subscription) logger.warning("'--expanded-view' is deprecating and will be removed in a future release. You can get the same " "information using 'az cloud show'") return profile.get_expanded_subscription_info(subscription)
def show_subscription(subscription=None, expanded_view=None): profile = Profile() if not expanded_view: return profile.get_subscription(subscription) logger.warning( "'--expanded-view' is deprecating and will be removed in a future release. You can get the same " "information using 'az cloud show'") return profile.get_expanded_subscription_info(subscription)
def create_service_principal_for_rbac(name=None, password=None, years=1, #pylint:disable=too-many-arguments scopes=None, role=None, expanded_view=None): '''create a service principal that can access or modify resources :param str name: an unique uri. If missing, the command will generate one. :param str password: the password used to login. If missing, command will generate one. :param str years: Years the password will be valid. :param str scopes: space separated scopes the service principal's role assignment applies to. :param str role: role the service principal has on the resources. only use with 'resource-ids'. ''' if bool(scopes) != bool(role): raise CLIError("'--scopes' and '--role' must be used together.") client = _graph_client_factory() start_date = datetime.datetime.utcnow() app_display_name = 'azure-cli-' + start_date.strftime('%Y-%m-%d-%H-%M-%S') if name is None: name = 'http://' + app_display_name # just a valid uri, no need to exist end_date = start_date + relativedelta(years=years) password = password or str(uuid.uuid4()) aad_application = create_application(client.applications, display_name=app_display_name, #pylint: disable=too-many-function-args homepage='http://'+app_display_name, identifier_uris=[name], available_to_other_tenants=False, password=password, start_date=start_date, end_date=end_date) #pylint: disable=no-member aad_sp = _create_service_principal(aad_application.app_id, bool(scopes)) oid = aad_sp.output.object_id if scopes else aad_sp.object_id if scopes: #It is possible the SP has not been propagated to all servers, so creating assignments #might fail. The reliable workaround is to call out the server where creation occurred. #pylint: disable=protected-access session_key = aad_sp.response.headers._store['ocp-aad-session-key'][1] for scope in scopes: _create_role_assignment(role, oid, None, scope, ocp_aad_session_key=session_key) if expanded_view: from azure.cli.core._profile import Profile profile = Profile() result = profile.get_expanded_subscription_info(scopes[0].split('/')[2] if scopes else None, aad_application.app_id, password) else: result = { 'appId': aad_application.app_id, 'password': password, 'name': name, 'tenant': client.config.tenant_id } return result
def create_service_principal_for_rbac(name=None, password=None, years=1, #pylint:disable=too-many-arguments scopes=None, role=None, expanded_view=None): '''create a service principal that can access or modify resources :param str name: an unique uri. If missing, the command will generate one. :param str password: the password used to login. If missing, command will generate one. :param str years: Years the password will be valid. :param str scopes: space separated scopes the service principal's role assignment applies to. :param str role: role the service principal has on the resources. only use with 'resource-ids'. ''' if bool(scopes) != bool(role): raise CLIError("'--scopes' and '--role' must be used together.") client = _graph_client_factory() start_date = datetime.datetime.now() app_display_name = 'azure-cli-' + start_date.strftime('%Y-%m-%d-%H-%M-%S') if name is None: name = 'http://' + app_display_name # just a valid uri, no need to exist end_date = start_date + relativedelta(years=years) password = password or str(uuid.uuid4()) aad_application = create_application(client.applications, display_name=app_display_name, #pylint: disable=too-many-function-args homepage='http://'+app_display_name, identifier_uris=[name], available_to_other_tenants=False, password=password, start_date=start_date, end_date=end_date) #pylint: disable=no-member aad_sp = _create_service_principal(aad_application.app_id, bool(scopes)) oid = aad_sp.output.object_id if scopes else aad_sp.object_id if scopes: #It is possible the SP has not been propagated to all servers, so creating assignments #might fail. The reliable workaround is to call out the server where creation occurred. #pylint: disable=protected-access session_key = aad_sp.response.headers._store['ocp-aad-session-key'][1] for scope in scopes: _create_role_assignment(role, oid, None, scope, ocp_aad_session_key=session_key) if expanded_view: from azure.cli.core._profile import Profile profile = Profile() result = profile.get_expanded_subscription_info(scopes[0].split('/')[2] if scopes else None, aad_application.app_id, password) else: result = { 'appId': aad_application.app_id, 'password': password, 'name': name, 'tenant': client.config.tenant_id } return result
def create_service_principal_for_rbac( # pylint:disable=too-many-statements,too-many-locals, too-many-branches name=None, password=None, years=None, create_cert=False, cert=None, scopes=None, role='Contributor', expanded_view=None, skip_assignment=False, keyvault=None): import time import pytz graph_client = _graph_client_factory() role_client = _auth_client_factory().role_assignments scopes = scopes or ['/subscriptions/' + role_client.config.subscription_id] years = years or 1 sp_oid = None _RETRY_TIMES = 36 app_display_name = None if name and '://' not in name: app_display_name = name name = "http://" + name # normalize be a valid graph service principal name if name: query_exp = 'servicePrincipalNames/any(x:x eq \'{}\')'.format(name) aad_sps = list(graph_client.service_principals.list(filter=query_exp)) if aad_sps: raise CLIError("'{}' already exists.".format(name)) app_start_date = datetime.datetime.now(pytz.utc) app_end_date = app_start_date + relativedelta(years=years or 1) app_display_name = app_display_name or ('azure-cli-' + app_start_date.strftime('%Y-%m-%d-%H-%M-%S')) if name is None: name = 'http://' + app_display_name # just a valid uri, no need to exist password, public_cert_string, cert_file, cert_start_date, cert_end_date = \ _process_service_principal_creds(years, app_start_date, app_end_date, cert, create_cert, password, keyvault) app_start_date, app_end_date, cert_start_date, cert_end_date = \ _validate_app_dates(app_start_date, app_end_date, cert_start_date, cert_end_date) aad_application = create_application(graph_client.applications, display_name=app_display_name, homepage='http://' + app_display_name, identifier_uris=[name], available_to_other_tenants=False, password=password, key_value=public_cert_string, start_date=app_start_date, end_date=app_end_date) # pylint: disable=no-member app_id = aad_application.app_id # retry till server replication is done for l in range(0, _RETRY_TIMES): try: aad_sp = _create_service_principal(app_id, resolve_app=False) break except Exception as ex: # pylint: disable=broad-except # pylint: disable=line-too-long if l < _RETRY_TIMES and ( ' does not reference ' in str(ex) or ' does not exist ' in str(ex)): time.sleep(5) logger.warning('Retrying service principal creation: %s/%s', l + 1, _RETRY_TIMES) else: logger.warning( "Creating service principal failed for appid '%s'. Trace followed:\n%s", name, ex.response.headers if hasattr(ex, 'response') else ex) # pylint: disable=no-member raise sp_oid = aad_sp.object_id # retry while server replication is done if not skip_assignment: # pylint: disable=line-too-long for scope in scopes: for l in range(0, _RETRY_TIMES): try: _create_role_assignment(role, sp_oid, None, scope, resolve_assignee=False) break except Exception as ex: if l < _RETRY_TIMES and ' does not exist in the directory ' in str(ex): time.sleep(5) logger.warning('Retrying role assignment creation: %s/%s', l + 1, _RETRY_TIMES) continue else: # dump out history for diagnoses logger.warning('Role assignment creation failed.\n') if getattr(ex, 'response', None) is not None: logger.warning('role assignment response headers: %s\n', ex.response.headers) # pylint: disable=no-member raise if expanded_view: logger.warning("'--expanded-view' is deprecating and will be removed in a future release. " "You can get the same information using 'az cloud show'") from azure.cli.core._profile import Profile profile = Profile() result = profile.get_expanded_subscription_info(scopes[0].split('/')[2] if scopes else None, app_id, password) else: result = { 'appId': app_id, 'password': password, 'name': name, 'displayName': app_display_name, 'tenant': graph_client.config.tenant_id } if cert_file: # pylint: disable=line-too-long logger.warning( "Please copy %s to a safe place. When run 'az login' provide the file path to the --password argument", cert_file) result['fileWithCertAndPrivateKey'] = cert_file return result
def create_service_principal_for_rbac(name=None, password=None, years=1, #pylint:disable=too-many-arguments,too-many-statements,too-many-locals, too-many-branches create_cert=False, cert=None, scopes=None, role='Contributor', expanded_view=None, skip_assignment=False): '''create a service principal and configure its access to Azure resources :param str name: a display name or an app id uri. Command will generate one if missing. :param str password: the password used to login. If missing, command will generate one. :param str cert: PEM formatted public certificate. Do not include private key info. :param str years: Years the password will be valid. :param str scopes: space separated scopes the service principal's role assignment applies to. Defaults to the root of the current subscription. :param str role: role the service principal has on the resources. ''' import time graph_client = _graph_client_factory() role_client = _auth_client_factory().role_assignments scopes = scopes or ['/subscriptions/' + role_client.config.subscription_id] sp_oid = None _RETRY_TIMES = 36 app_display_name = None if name and not '://' in name: app_display_name = name name = "http://" + name #normalize be a valid graph service principal name if name: query_exp = 'servicePrincipalNames/any(x:x eq \'{}\')'.format(name) aad_sps = list(graph_client.service_principals.list(filter=query_exp)) if aad_sps: raise CLIError("'{}' already exists.".format(name)) #pylint: disable=protected-access public_cert_string = None cert_file = None password = None if len([x for x in [cert, create_cert, password] if x]) > 1: raise CLIError('Usage error: --cert | --create-cert | --password') if create_cert: public_cert_string, cert_file = _create_self_signed_cert(years) elif cert: public_cert_string = cert else: password = password or str(uuid.uuid4()) start_date = datetime.datetime.utcnow() app_display_name = app_display_name or ('azure-cli-' + start_date.strftime('%Y-%m-%d-%H-%M-%S')) if name is None: name = 'http://' + app_display_name # just a valid uri, no need to exist end_date = start_date + relativedelta(years=years) aad_application = create_application(graph_client.applications, display_name=app_display_name, #pylint: disable=too-many-function-args homepage='http://'+app_display_name, identifier_uris=[name], available_to_other_tenants=False, password=password, key_value=public_cert_string, start_date=start_date, end_date=end_date) #pylint: disable=no-member app_id = aad_application.app_id #retry till server replication is done for l in range(0, _RETRY_TIMES): try: aad_sp = _create_service_principal(app_id, resolve_app=False) break except Exception as ex: #pylint: disable=broad-except #pylint: disable=line-too-long if l < _RETRY_TIMES and 'The appId of the service principal does not reference a valid application object' in str(ex): time.sleep(5) logger.warning('Retrying service principal creation: %s/%s', l+1, _RETRY_TIMES) else: logger.warning("Creating service principal failed for appid '%s'. Trace followed:\n%s", name, ex.response.headers if hasattr(ex, 'response') else ex) #pylint: disable=no-member raise sp_oid = aad_sp.object_id #retry while server replication is done if not skip_assignment: # pylint: disable=line-too-long for scope in scopes: for l in range(0, _RETRY_TIMES): try: _create_role_assignment(role, sp_oid, None, scope, resolve_assignee=False) break except Exception as ex: if l < _RETRY_TIMES and ' does not exist in the directory ' in str(ex): time.sleep(5) logger.warning('Retrying role assignment creation: %s/%s', l+1, _RETRY_TIMES) continue else: #dump out history for diagnoses logger.warning('Role assignment creation failed.\n') if getattr(ex, 'response', None) is not None: logger.warning('role assignment response headers: %s\n', ex.response.headers) #pylint: disable=no-member raise if expanded_view: from azure.cli.core._profile import Profile profile = Profile() result = profile.get_expanded_subscription_info(scopes[0].split('/')[2] if scopes else None, app_id, password) else: result = { 'appId': app_id, 'password': password, 'name': name, 'displayName': app_display_name, 'tenant': graph_client.config.tenant_id } if cert_file: # pylint: disable=line-too-long logger.warning("Please copy %s to a safe place. When run 'az login' provide the file path to the --password argument", cert_file) result['fileWithCertAndPrivateKey'] = cert_file return result
def show_subscription(subscription=None, expanded_view=None): profile = Profile() if not expanded_view: return profile.get_subscription(subscription) else: return profile.get_expanded_subscription_info(subscription)
def create_service_principal_for_rbac( # pylint:disable=too-many-arguments,too-many-statements,too-many-locals, too-many-branches name=None, password=None, years=1, create_cert=False, cert=None, scopes=None, role='Contributor', expanded_view=None, skip_assignment=False): '''create a service principal and configure its access to Azure resources :param str name: a display name or an app id uri. Command will generate one if missing. :param str password: the password used to login. If missing, command will generate one. :param str cert: PEM formatted public certificate. Do not include private key info. :param str years: Years the password will be valid. :param str scopes: space separated scopes the service principal's role assignment applies to. Defaults to the root of the current subscription. :param str role: role the service principal has on the resources. ''' import time graph_client = _graph_client_factory() role_client = _auth_client_factory().role_assignments scopes = scopes or ['/subscriptions/' + role_client.config.subscription_id] sp_oid = None _RETRY_TIMES = 36 app_display_name = None if name and '://' not in name: app_display_name = name name = "http://" + name # normalize be a valid graph service principal name if name: query_exp = 'servicePrincipalNames/any(x:x eq \'{}\')'.format(name) aad_sps = list(graph_client.service_principals.list(filter=query_exp)) if aad_sps: raise CLIError("'{}' already exists.".format(name)) # pylint: disable=protected-access public_cert_string = None cert_file = None if len([x for x in [cert, create_cert, password] if x]) > 1: raise CLIError('Usage error: --cert | --create-cert | --password') if create_cert: public_cert_string, cert_file = _create_self_signed_cert(years) elif cert: public_cert_string = cert else: password = password or str(uuid.uuid4()) start_date = datetime.datetime.utcnow() app_display_name = app_display_name or ('azure-cli-' + start_date.strftime('%Y-%m-%d-%H-%M-%S')) if name is None: name = 'http://' + app_display_name # just a valid uri, no need to exist end_date = start_date + relativedelta(years=years) aad_application = create_application(graph_client.applications, display_name=app_display_name, # pylint: disable=too-many-function-args homepage='http://' + app_display_name, identifier_uris=[name], available_to_other_tenants=False, password=password, key_value=public_cert_string, start_date=start_date, end_date=end_date) # pylint: disable=no-member app_id = aad_application.app_id # retry till server replication is done for l in range(0, _RETRY_TIMES): try: aad_sp = _create_service_principal(app_id, resolve_app=False) break except Exception as ex: # pylint: disable=broad-except # pylint: disable=line-too-long if l < _RETRY_TIMES and ( ' does not reference ' in str(ex) or ' does not exist ' in str(ex)): time.sleep(5) logger.warning('Retrying service principal creation: %s/%s', l + 1, _RETRY_TIMES) else: logger.warning( "Creating service principal failed for appid '%s'. Trace followed:\n%s", name, ex.response.headers if hasattr(ex, 'response') else ex) # pylint: disable=no-member raise sp_oid = aad_sp.object_id # retry while server replication is done if not skip_assignment: # pylint: disable=line-too-long for scope in scopes: for l in range(0, _RETRY_TIMES): try: _create_role_assignment(role, sp_oid, None, scope, resolve_assignee=False) break except Exception as ex: if l < _RETRY_TIMES and ' does not exist in the directory ' in str(ex): time.sleep(5) logger.warning('Retrying role assignment creation: %s/%s', l + 1, _RETRY_TIMES) continue else: # dump out history for diagnoses logger.warning('Role assignment creation failed.\n') if getattr(ex, 'response', None) is not None: logger.warning('role assignment response headers: %s\n', ex.response.headers) # pylint: disable=no-member raise if expanded_view: from azure.cli.core._profile import Profile profile = Profile() result = profile.get_expanded_subscription_info(scopes[0].split('/')[2] if scopes else None, app_id, password) else: result = { 'appId': app_id, 'password': password, 'name': name, 'displayName': app_display_name, 'tenant': graph_client.config.tenant_id } if cert_file: # pylint: disable=line-too-long logger.warning( "Please copy %s to a safe place. When run 'az login' provide the file path to the --password argument", cert_file) result['fileWithCertAndPrivateKey'] = cert_file return result
def create_service_principal_for_rbac(name=None, password=None, years=1, #pylint:disable=too-many-arguments,too-many-statements,too-many-locals scopes=None, role='Contributor', expanded_view=None): '''create a service principal and configure its access to Azure resources :param str name: a display name or an app id uri. Command will generate one if missing. :param str password: the password used to login. If missing, command will generate one. :param str years: Years the password will be valid. :param str scopes: space separated scopes the service principal's role assignment applies to. Defaults to the root of the current subscription. :param str role: role the service principal has on the resources. ''' import time graph_client = _graph_client_factory() role_client = _auth_client_factory().role_assignments scopes = scopes or ['/subscriptions/' + role_client.config.subscription_id] sp_oid = None sp_created = False _RETRY_TIMES = 24 app_display_name = None if name and not '://' in name: app_display_name = name name = "http://" + name #normalize be a valid graph service principal name if name: query_exp = 'servicePrincipalNames/any(x:x eq \'{}\')'.format(name) aad_sps = list(graph_client.service_principals.list(filter=query_exp)) if aad_sps: sp_oid = aad_sps[0].object_id app_id = aad_sps[0].app_id #pylint: disable=protected-access if not sp_oid: start_date = datetime.datetime.utcnow() app_display_name = app_display_name or ('azure-cli-' + start_date.strftime('%Y-%m-%d-%H-%M-%S')) if name is None: name = 'http://' + app_display_name # just a valid uri, no need to exist end_date = start_date + relativedelta(years=years) password = password or str(uuid.uuid4()) aad_application = create_application(graph_client.applications, display_name=app_display_name, #pylint: disable=too-many-function-args homepage='http://'+app_display_name, identifier_uris=[name], available_to_other_tenants=False, password=password, start_date=start_date, end_date=end_date) #pylint: disable=no-member app_id = aad_application.app_id #retry till server replication is done for l in range(0, _RETRY_TIMES): try: aad_sp = _create_service_principal(app_id, resolve_app=False) break except Exception as ex: #pylint: disable=broad-except #pylint: disable=line-too-long if l < _RETRY_TIMES and 'The appId of the service principal does not reference a valid application object' in str(ex): time.sleep(5) logger.warning('Retrying service principal creation: %s/%s', l+1, _RETRY_TIMES) else: logger.warning("Creating service principal failed for appid '%s'. Trace followed:\n%s", name, ex.response.headers) #pylint: disable=no-member raise sp_oid = aad_sp.object_id sp_created = True #retry while server replication is done for scope in scopes: for l in range(0, _RETRY_TIMES): try: _create_role_assignment(role, sp_oid, None, scope, resolve_assignee=False) break except Exception as ex: if l < _RETRY_TIMES and ' does not exist in the directory ' in str(ex): time.sleep(5) logger.warning('Retrying role assignment creation: %s/%s', l+1, _RETRY_TIMES) continue elif sp_created: #dump out history for diagnoses logger.warning('Role assignment creation failed. Traces followed:\n') logger.warning('Service principal response: %s\n', aad_sp.response.headers) if getattr(ex, 'response', None) is not None: logger.warning('role assignment response: %s\n', ex.response.headers) #pylint: disable=no-member raise if expanded_view: from azure.cli.core._profile import Profile profile = Profile() result = profile.get_expanded_subscription_info(scopes[0].split('/')[2] if scopes else None, app_id, password) else: result = { 'appId': app_id, 'password': password, 'name': name, 'displayName': app_display_name, 'tenant': graph_client.config.tenant_id } return result
def create_service_principal_for_rbac( # pylint:disable=too-many-statements,too-many-locals, too-many-branches name=None, password=None, years=None, create_cert=False, cert=None, scopes=None, role='Contributor', expanded_view=None, skip_assignment=False, keyvault=None): import time import pytz graph_client = _graph_client_factory() role_client = _auth_client_factory().role_assignments scopes = scopes or ['/subscriptions/' + role_client.config.subscription_id] years = years or 1 sp_oid = None _RETRY_TIMES = 36 app_display_name = None if name and '://' not in name: app_display_name = name name = "http://" + name # normalize be a valid graph service principal name if name: query_exp = 'servicePrincipalNames/any(x:x eq \'{}\')'.format(name) aad_sps = list(graph_client.service_principals.list(filter=query_exp)) if aad_sps: raise CLIError("'{}' already exists.".format(name)) app_start_date = datetime.datetime.now(pytz.utc) app_end_date = app_start_date + relativedelta(years=years or 1) app_display_name = app_display_name or ('azure-cli-' + app_start_date.strftime('%Y-%m-%d-%H-%M-%S')) if name is None: name = 'http://' + app_display_name # just a valid uri, no need to exist password, public_cert_string, cert_file, cert_start_date, cert_end_date = \ _process_service_principal_creds(years, app_start_date, app_end_date, cert, create_cert, password, keyvault) app_start_date, app_end_date, cert_start_date, cert_end_date = \ _validate_app_dates(app_start_date, app_end_date, cert_start_date, cert_end_date) aad_application = create_application(graph_client.applications, display_name=app_display_name, homepage='http://' + app_display_name, identifier_uris=[name], available_to_other_tenants=False, password=password, key_value=public_cert_string, start_date=app_start_date, end_date=app_end_date) # pylint: disable=no-member app_id = aad_application.app_id # retry till server replication is done for l in range(0, _RETRY_TIMES): try: aad_sp = _create_service_principal(app_id, resolve_app=False) break except Exception as ex: # pylint: disable=broad-except if l < _RETRY_TIMES and ( ' does not reference ' in str(ex) or ' does not exist ' in str(ex)): time.sleep(5) logger.warning('Retrying service principal creation: %s/%s', l + 1, _RETRY_TIMES) else: logger.warning( "Creating service principal failed for appid '%s'. Trace followed:\n%s", name, ex.response.headers if hasattr(ex, 'response') else ex) # pylint: disable=no-member raise sp_oid = aad_sp.object_id # retry while server replication is done if not skip_assignment: for scope in scopes: for l in range(0, _RETRY_TIMES): try: _create_role_assignment(role, sp_oid, None, scope, resolve_assignee=False) break except Exception as ex: if l < _RETRY_TIMES and ' does not exist in the directory ' in str(ex): time.sleep(5) logger.warning('Retrying role assignment creation: %s/%s', l + 1, _RETRY_TIMES) continue else: # dump out history for diagnoses logger.warning('Role assignment creation failed.\n') if getattr(ex, 'response', None) is not None: logger.warning('role assignment response headers: %s\n', ex.response.headers) # pylint: disable=no-member raise if expanded_view: logger.warning("'--expanded-view' is deprecating and will be removed in a future release. " "You can get the same information using 'az cloud show'") from azure.cli.core._profile import Profile profile = Profile() result = profile.get_expanded_subscription_info(scopes[0].split('/')[2] if scopes else None, app_id, password) else: result = { 'appId': app_id, 'password': password, 'name': name, 'displayName': app_display_name, 'tenant': graph_client.config.tenant_id } if cert_file: logger.warning( "Please copy %s to a safe place. When run 'az login' provide the file path to the --password argument", cert_file) result['fileWithCertAndPrivateKey'] = cert_file return result