def update_adla_catalog_credential(client, account_name, database_name, credential_name, credential_user_name, uri, credential_user_password=None, new_credential_user_password=None): if not credential_user_password: try: credential_user_password = prompt_pass('Current Password:'******'Please specify --user-name --password and --new-password in non-interactive mode.') if not new_credential_user_password: try: new_credential_user_password = prompt_pass('New Password:'******'Please specify --user-name --password and --new-password in non-interactive mode.') update_params = DataLakeAnalyticsCatalogCredentialUpdateParameters(credential_user_password, new_credential_user_password, uri, credential_user_name) client.update_credential(account_name, database_name, credential_name, update_params)
def create_image_registry_credentials(registry_login_server, registry_username, registry_password, image): """Create image registry credentials. """ image_registry_credentials = None if registry_login_server: if not registry_username: raise CLIError('Please specify --registry-username in order to use custom image registry.') if not registry_password: try: registry_password = prompt_pass(msg='Image registry password: '******'Please specify --registry-password in order to use custom image registry.') image_registry_credentials = [ImageRegistryCredential(server=registry_login_server, username=registry_username, password=registry_password)] elif ACR_SERVER_SUFFIX in image: if not registry_password: try: registry_password = prompt_pass(msg='Image registry password: '******'Please specify --registry-password in order to use Azure Container Registry.') acr_server = image.split("/")[0] if image.split("/") else None acr_username = image.split(ACR_SERVER_SUFFIX)[0] if image.split(ACR_SERVER_SUFFIX) else None if acr_server and acr_username: image_registry_credentials = [ImageRegistryCredential(server=acr_server, username=acr_username, password=registry_password)] else: raise CLIError('Failed to parse ACR server or username from image name; please explicitly specify --registry-server and --registry-username.') return image_registry_credentials
def _validate_user_credentials(registry_name, path, resultIndex, username=None, password=None): registry, _ = get_registry_by_name(registry_name) login_server = registry.login_server #pylint: disable=no-member if username: if not password: try: password = prompt_pass(msg='Password: '******'Please specify both username and password in non-interactive mode.') return _obtain_data_from_registry(login_server, path, resultIndex, username, password) try: cred = acr_credential_show(registry_name) username = cred.username password = cred.password return _obtain_data_from_registry(login_server, path, resultIndex, username, password) except: #pylint: disable=bare-except pass try: username = prompt('Username: '******'Password: '******'Unable to authenticate using admin login credentials or admin is not enabled. ' + 'Please specify both username and password in non-interactive mode.') return _obtain_data_from_registry(login_server, path, resultIndex, username, password)
def _validate_user_credentials(registry_name, path, resultIndex, username=None, password=None): registry, _ = get_registry_by_name(registry_name) login_server = registry.login_server # pylint: disable=no-member if username: if not password: try: password = prompt_pass(msg='Password: '******'Please specify both username and password in non-interactive mode.') return _obtain_data_from_registry(login_server, path, resultIndex, username, password) try: cred = acr_credential_show(registry_name) username = cred.username password = cred.passwords[0].value return _obtain_data_from_registry(login_server, path, resultIndex, username, password) except: # pylint: disable=bare-except pass try: username = prompt('Username: '******'Password: '******'Unable to authenticate using admin login credentials or admin is not enabled. ' + 'Please specify both username and password in non-interactive mode.') return _obtain_data_from_registry(login_server, path, resultIndex, username, password)
def _get_credentials(registry_name, resource_group_name, username, password, only_refresh_token, repository=None, permission='*'): """Try to get AAD authorization tokens or admin user credentials. :param str registry_name: The name of container registry :param str resource_group_name: The name of resource group :param str username: The username used to log into the container registry :param str password: The password used to log into the container registry :param bool only_refresh_token: Whether to ask for only refresh token, or for both refresh and access tokens :param str repository: Repository for which the access token is requested :param str permission: The requested permission on the repository, '*' or 'pull' """ registry, _ = get_registry_by_name(registry_name, resource_group_name) login_server = registry.login_server # 1. if username was specified, verify that password was also specified if username: if not password: try: password = prompt_pass(msg='Password: '******'Please specify both username and password in non-interactive mode.') return login_server, username, password # 2. if we don't yet have credentials, attempt to get a refresh token if not password and registry.sku.name in MANAGED_REGISTRY_SKU: try: username = "******" if only_refresh_token else None password = _get_aad_token(login_server, only_refresh_token, repository, permission) return login_server, username, password except CLIError as e: logger.warning("Unable to get AAD authorization tokens with message: %s", str(e)) # 3. if we still don't have credentials, attempt to get the admin credentials (if enabled) if not password: try: cred = acr_credential_show(registry_name) username = cred.username password = cred.passwords[0].value return login_server, username, password except CLIError as e: logger.warning("Unable to get admin user credentials with message: %s", str(e)) # 4. if we still don't have credentials, prompt the user if not password: try: username = prompt('Username: '******'Password: '******'Unable to authenticate using AAD or admin login credentials. ' + 'Please specify both username and password in non-interactive mode.')
def _validate_user_credentials(registry_name, resource_group_name, path, username=None, password=None, repository=None, result_index=None, request_method=None): registry, _ = get_registry_by_name(registry_name, resource_group_name) sku_tier = registry.sku.tier login_server = registry.login_server # 1. if username was specified, verify that password was also specified if username: if not password: try: password = prompt_pass(msg='Password: '******'Please specify both username and password in non-interactive mode.') return request_method(login_server, path, username, password, result_index) if sku_tier == SkuTier.managed.value: # 2. if we don't yet have credentials, attempt to get an access token try: managed_registry_validation(registry_name, resource_group_name) access_token = get_login_access_token(login_server, repository) return request_method(login_server, path, None, access_token, result_index) except NotFound as e: raise CLIError(str(e)) except Unauthorized as e: logger.warning("Unable to authenticate using AAD tokens: %s", str(e)) except Exception as e: # pylint: disable=broad-except logger.warning("AAD authentication failed with message: %s", str(e)) # 3. if we still don't have credentials, attempt to get the admin credentials (if enabled) try: cred = acr_credential_show(registry_name) username = cred.username password = cred.passwords[0].value return request_method(login_server, path, username, password, result_index) except NotFound as e: raise CLIError(str(e)) except Unauthorized as e: logger.warning("Unable to authenticate using admin login credentials: %s", str(e)) except Exception as e: # pylint: disable=broad-except logger.warning("Admin user authentication failed with message: %s", str(e)) # 4. if we still don't have credentials, prompt the user try: username = prompt('Username: '******'Password: '******'Unable to authenticate using AAD tokens or admin login credentials. ' + 'Please specify both username and password in non-interactive mode.') return request_method(login_server, path, username, password, result_index)
def acr_login(registry_name, resource_group_name=None, username=None, password=None): """Login to a container registry through Docker. :param str registry_name: The name of container registry :param str resource_group_name: The name of resource group :param str username: The username used to log into the container registry :param str password: The password used to log into the container registry """ try: call(["docker", "ps"], stdout=PIPE, stderr=PIPE) except: raise CLIError("Please verify whether docker is installed and running properly") registry, _ = get_registry_by_name(registry_name, resource_group_name) sku_tier = registry.sku.tier login_server = registry.login_server # 1. if username was specified, verify that password was also specified if username and not password: try: password = prompt_pass(msg='Password: '******'Please specify both username and password in non-interactive mode.') if sku_tier == SkuTier.managed.value: # 2. if we don't yet have credentials, attempt to get a refresh token if not password: try: username = "******" password = get_login_refresh_token(login_server) except Exception as e: # pylint: disable=broad-except logger.warning("AAD authentication failed with message: %s", str(e)) # 3. if we still don't have credentials, attempt to get the admin credentials (if enabled) if not password: try: cred = acr_credential_show(registry_name) username = cred.username password = cred.passwords[0].value except Exception as e: # pylint: disable=broad-except logger.warning("Admin user authentication failed with message: %s", str(e)) # 4. if we still don't have credentials, prompt the user if not password: try: username = prompt('Username: '******'Password: '******'Unable to authenticate using AAD or admin login credentials. ' + 'Please specify both username and password in non-interactive mode.') call(["docker", "login", "--username", username, "--password", password, login_server])
def login(username=None, password=None, service_principal=None, tenant=None, allow_no_subscriptions=False, msi=False, msi_port=DefaultStr(50342)): """Log in to access Azure subscriptions""" import os import re from adal.adal_error import AdalError import requests # quick argument usage check if (any([username, password, service_principal, tenant, allow_no_subscriptions]) and any([msi, not getattr(msi_port, 'is_default', None)])): raise CLIError("usage error: '--msi/--msi-port' are not applicable with other arguments") interactive = False profile = Profile() if _in_cloud_console(): console_tokens = os.environ.get('AZURE_CONSOLE_TOKENS', None) if console_tokens: return profile.find_subscriptions_in_cloud_console(re.split(';|,', console_tokens)) else: raise CLIError(_CLOUD_CONSOLE_ERR_TEMPLATE.format('login')) if msi: return profile.find_subscriptions_in_vm_with_msi(msi_port) if username: if not password: try: password = prompt_pass('Password: '******'Please specify both username and password in non-interactive mode.') else: interactive = True try: subscriptions = profile.find_subscriptions_on_login( interactive, username, password, service_principal, tenant, allow_no_subscriptions=allow_no_subscriptions) except AdalError as err: # try polish unfriendly server errors if username: msg = str(err) suggestion = "For cross-check, try 'az login' to authenticate through browser." if ('ID3242:' in msg) or ('Server returned an unknown AccountType' in msg): raise CLIError("The user name might be invalid. " + suggestion) if 'Server returned error in RSTR - ErrorCode' in msg: raise CLIError("Logging in through command line is not supported. " + suggestion) raise CLIError(err) except requests.exceptions.ConnectionError as err: raise CLIError('Please ensure you have network connection. Error detail: ' + str(err)) all_subscriptions = list(subscriptions) for sub in all_subscriptions: sub['cloudName'] = sub.pop('environmentName', None) return all_subscriptions
def validate_authentication_type(namespace, formula=None): if formula and formula.formula_content: if formula.formula_content.is_authentication_with_ssh_key is True: namespace.authentication_type = 'ssh' namespace.ssh_key = formula.formula_content.ssh_key elif formula.formula_content.is_authentication_with_ssh_key is False: namespace.admin_username = formula.formula_content.user_name namespace.admin_password = formula.formula_content.password namespace.authentication_type = 'password' # validate proper arguments supplied based on the authentication type if namespace.authentication_type == 'password': if namespace.ssh_key or namespace.generate_ssh_keys: raise ValueError( "incorrect usage for authentication-type 'password': "******"[--admin-username USERNAME] --admin-password PASSWORD") if not namespace.admin_password: # prompt for admin password if not supplied from azure.cli.core.prompting import prompt_pass, NoTTYException try: namespace.admin_password = prompt_pass('Admin Password: '******'Please specify both username and password in non-interactive mode.') elif namespace.authentication_type == 'ssh': if namespace.os_type != 'Linux': raise CLIError("incorrect authentication-type '{}' for os type '{}'".format( namespace.authentication_type, namespace.os_type)) if namespace.admin_password: raise ValueError('Admin password cannot be used with SSH authentication type') validate_ssh_key(namespace) else: raise CLIError("incorrect value for authentication-type: {}".format(namespace.authentication_type))
def _prompt_for_parameters(missing_parameters): result = {} for param_name in missing_parameters: prompt_str = 'Please provide a value for \'{}\' (? for help): '.format(param_name) param = missing_parameters[param_name] param_type = param.get('type', 'string') description = 'Missing description' metadata = param.get('metadata', None) if metadata is not None: description = metadata.get('description', description) allowed_values = param.get('allowedValues', None) while True: if allowed_values is not None: ix = prompt_choice_list(prompt_str, allowed_values, help_string=description) result[param_name] = allowed_values[ix] break elif param_type == 'securestring': value = prompt_pass(prompt_str, help_string=description) elif param_type == 'int': int_value = prompt_int(prompt_str, help_string=description) result[param_name] = int_value break elif param_type == 'bool': value = prompt_t_f(prompt_str, help_string=description) result[param_name] = value break else: value = prompt(prompt_str, help_string=description) if len(value) > 0: break return {}
def login(username=None, password=None, service_principal=None, tenant=None, allow_no_subscriptions=False, msi=False, msi_port=DefaultStr(50342)): """Log in to access Azure subscriptions""" import os import re from adal.adal_error import AdalError import requests # quick argument usage check if (any([username, password, service_principal, tenant, allow_no_subscriptions]) and any([msi, not getattr(msi_port, 'is_default', None)])): raise CLIError("usage error: '--msi/--msi-port' are not applicable with other arguments") interactive = False profile = Profile() if in_cloud_console(): console_tokens = os.environ.get('AZURE_CONSOLE_TOKENS', None) if console_tokens: return profile.find_subscriptions_in_cloud_console(re.split(';|,', console_tokens)) logger.warning(_CLOUD_CONSOLE_WARNING_TEMPLATE, 'login') return if msi: return profile.find_subscriptions_in_vm_with_msi(msi_port) if username: if not password: try: password = prompt_pass('Password: '******'Please specify both username and password in non-interactive mode.') else: interactive = True try: subscriptions = profile.find_subscriptions_on_login( interactive, username, password, service_principal, tenant, allow_no_subscriptions=allow_no_subscriptions) except AdalError as err: # try polish unfriendly server errors if username: msg = str(err) suggestion = "For cross-check, try 'az login' to authenticate through browser." if ('ID3242:' in msg) or ('Server returned an unknown AccountType' in msg): raise CLIError("The user name might be invalid. " + suggestion) if 'Server returned error in RSTR - ErrorCode' in msg: raise CLIError("Logging in through command line is not supported. " + suggestion) raise CLIError(err) except requests.exceptions.ConnectionError as err: raise CLIError('Please ensure you have network connection. Error detail: ' + str(err)) all_subscriptions = list(subscriptions) for sub in all_subscriptions: sub['cloudName'] = sub.pop('environmentName', None) return all_subscriptions
def _prompt_for_parameters(missing_parameters): result = {} for param_name in missing_parameters: prompt_str = 'Please provide a value for \'{}\' (? for help): '.format(param_name) param = missing_parameters[param_name] param_type = param.get('type', 'string') description = 'Missing description' metadata = param.get('metadata', None) if metadata is not None: description = metadata.get('description', description) allowed_values = param.get('allowedValues', None) while True: if allowed_values is not None: ix = prompt_choice_list(prompt_str, allowed_values, help_string=description) result[param_name] = allowed_values[ix] break elif param_type == 'securestring': value = prompt_pass(prompt_str, help_string=description) result[param_name] = value elif param_type == 'int': int_value = prompt_int(prompt_str, help_string=description) result[param_name] = int_value break elif param_type == 'bool': value = prompt_t_f(prompt_str, help_string=description) result[param_name] = value break else: value = prompt(prompt_str, help_string=description) result[param_name] = value if value: break return result
def _validate_vm_create_auth(namespace): if namespace.storage_profile == StorageProfile.ManagedSpecializedOSDisk: return if len(namespace.admin_username) < 6 or namespace.admin_username.lower( ) == 'root': # prompt for admin username if inadequate from azure.cli.core.prompting import prompt, NoTTYException try: logger.warning( "Cannot use admin username: %s. Admin username should be at " "least 6 characters and cannot be 'root'", namespace.admin_username) namespace.admin_username = prompt('Admin Username: '******'Please specify a valid admin username in non-interactive mode.' ) if not namespace.os_type: raise CLIError( "Unable to resolve OS type. Specify '--os-type' argument.") if not namespace.authentication_type: # apply default auth type (password for Windows, ssh for Linux) by examining the OS type namespace.authentication_type = 'password' if namespace.os_type == 'windows' else 'ssh' if namespace.os_type == 'windows' and namespace.authentication_type == 'ssh': raise CLIError('SSH not supported for Windows VMs.') # validate proper arguments supplied based on the authentication type if namespace.authentication_type == 'password': if namespace.ssh_key_value or namespace.ssh_dest_key_path: raise ValueError( "incorrect usage for authentication-type 'password': "******"[--admin-username USERNAME] --admin-password PASSWORD") if not namespace.admin_password: # prompt for admin password if not supplied from azure.cli.core.prompting import prompt_pass, NoTTYException try: namespace.admin_password = prompt_pass('Admin Password: '******'Please specify both username and password in non-interactive mode.' ) elif namespace.authentication_type == 'ssh': if namespace.admin_password: raise ValueError( 'Admin password cannot be used with SSH authentication type') validate_ssh_key(namespace) if not namespace.ssh_dest_key_path: namespace.ssh_dest_key_path = \ '/home/{}/.ssh/authorized_keys'.format(namespace.admin_username)
def validate_authentication_type(namespace, formula=None): if formula and formula.formula_content: if formula.formula_content.is_authentication_with_ssh_key is True: namespace.authentication_type = 'ssh' namespace.ssh_key = formula.formula_content.ssh_key elif formula.formula_content.is_authentication_with_ssh_key is False: namespace.admin_username = formula.formula_content.user_name namespace.admin_password = formula.formula_content.password namespace.authentication_type = 'password' # validate proper arguments supplied based on the authentication type if namespace.authentication_type == 'password': password_usage_error = "incorrect usage for authentication-type 'password': "******"[--admin-username USERNAME] --admin-password PASSWORD | " \ "[--admin-username USERNAME] --saved-secret SECRETNAME" if namespace.ssh_key or namespace.generate_ssh_keys or ( namespace.saved_secret and namespace.admin_password): raise ValueError(password_usage_error) # Respect user's provided saved secret name for password authentication if namespace.saved_secret: namespace.admin_password = "******".format(namespace.saved_secret) if not namespace.admin_password: # prompt for admin password if not supplied from azure.cli.core.prompting import prompt_pass, NoTTYException try: namespace.admin_password = prompt_pass('Admin Password: '******'Please specify both username and password in non-interactive mode.' ) elif namespace.authentication_type == 'ssh': if namespace.os_type != 'Linux': raise CLIError( "incorrect authentication-type '{}' for os type '{}'".format( namespace.authentication_type, namespace.os_type)) ssh_usage_error = "incorrect usage for authentication-type 'ssh': " \ "[--admin-username USERNAME] | " \ "[--admin-username USERNAME] --ssh-key KEY | " \ "[--admin-username USERNAME] --generate-ssh-keys | " \ "[--admin-username USERNAME] --saved-secret SECRETNAME" if namespace.admin_password or (namespace.saved_secret and (namespace.ssh_key or namespace.generate_ssh_keys)): raise ValueError(ssh_usage_error) # Respect user's provided saved secret name for ssh authentication if namespace.saved_secret: namespace.ssh_key = "[[{}]]".format(namespace.saved_secret) else: validate_ssh_key(namespace) else: raise CLIError("incorrect value for authentication-type: {}".format( namespace.authentication_type))
def _config_env_public_azure(_): from adal.adal_error import AdalError from azure.cli.core.commands.client_factory import get_mgmt_service_client from azure.mgmt.resource import ResourceManagementClient from azure.cli.core._profile import Profile # Determine if user logged in try: list(get_mgmt_service_client(ResourceManagementClient).resources.list()) except CLIError: # Not logged in login_successful = False while not login_successful: method_index = prompt_choice_list(MSG_PROMPT_LOGIN, LOGIN_METHOD_LIST) answers['login_index'] = method_index answers['login_options'] = str(LOGIN_METHOD_LIST) profile = Profile() interactive = False username = None password = None service_principal = None tenant = None if method_index == 0: # device auth interactive = True elif method_index == 1: # username and password username = prompt('Username: '******'Password: '******'Service principal: ') tenant = prompt('Tenant: ') password = prompt_pass(msg='Client secret: ') elif method_index == 3: # skip return try: profile.find_subscriptions_on_login( interactive, username, password, service_principal, tenant) login_successful = True logger.warning('Login successful!') except AdalError as err: logger.error('Login error!') logger.error(err)
def _config_env_public_azure(_): from adal.adal_error import AdalError from azure.cli.core.commands.client_factory import get_mgmt_service_client from azure.mgmt.resource import ResourceManagementClient from azure.cli.core._profile import Profile # Determine if user logged in try: list( get_mgmt_service_client(ResourceManagementClient).resources.list()) except CLIError: # Not logged in login_successful = False while not login_successful: method_index = prompt_choice_list(MSG_PROMPT_LOGIN, LOGIN_METHOD_LIST) answers['login_index'] = method_index answers['login_options'] = str(LOGIN_METHOD_LIST) profile = Profile() interactive = False username = None password = None service_principal = None tenant = None if method_index == 0: # device auth interactive = True elif method_index == 1: # username and password username = prompt('Username: '******'Password: '******'Service principal: ') tenant = prompt('Tenant: ') password = prompt_pass(msg='Client secret: ') elif method_index == 3: # skip return try: profile.find_subscriptions_on_login(interactive, username, password, service_principal, tenant) login_successful = True logger.warning('Login successful!') except AdalError as err: logger.error('Login error!') logger.error(err)
def _load_key(key_filename): pkey = None try: pkey = paramiko.RSAKey.from_private_key_file(key_filename, None) except paramiko.PasswordRequiredException: key_pass = prompt_pass('Password for private key:') pkey = paramiko.RSAKey.from_private_key_file(key_filename, key_pass) if pkey is None: raise CLIError('failed to load key: {}'.format(key_filename)) return pkey
def _load_key(key_filename): pkey = None try: pkey = paramiko.RSAKey.from_private_key_file(key_filename, None) except paramiko.PasswordRequiredException: key_pass = prompt_pass('Password:'******'failed to load key: {}'.format(key_filename)) return pkey
def login(username=None, password=None, service_principal=None, tenant=None, allow_no_subscriptions=False): """Log in to access Azure subscriptions""" import os import re from adal.adal_error import AdalError import requests interactive = False profile = Profile() if username: if not password: # in a VM with managed service identity? result = profile.init_if_in_msi_env(username) if result: return result try: password = prompt_pass('Password: '******'Please specify both username and password in non-interactive mode.') else: # in a cloud console? console_tokens = os.environ.get('AZURE_CONSOLE_TOKENS', None) if console_tokens: return profile.find_subscriptions_in_cloud_console(re.split(';|,', console_tokens)) interactive = True try: subscriptions = profile.find_subscriptions_on_login( interactive, username, password, service_principal, tenant, allow_no_subscriptions=allow_no_subscriptions) except AdalError as err: # try polish unfriendly server errors if username: msg = str(err) suggestion = "For cross-check, try 'az login' to authenticate through browser." if ('ID3242:' in msg) or ('Server returned an unknown AccountType' in msg): raise CLIError("The user name might be invalid. " + suggestion) if 'Server returned error in RSTR - ErrorCode' in msg: raise CLIError("Logging in through command line is not supported. " + suggestion) raise CLIError(err) except requests.exceptions.ConnectionError as err: raise CLIError('Please ensure you have network connection. Error detail: ' + str(err)) all_subscriptions = list(subscriptions) for sub in all_subscriptions: sub['cloudName'] = sub.pop('environmentName', None) return all_subscriptions
def add_reference(service_name, target_group, target_name, reference_name, env_variables, namespace_name, reference_type): """ Adds a references to an Azure resource """ instance_type = None created_variables = [] # If target_group and target_name are not set # it means we are dealing with a generic reference if reference_type == 'custom' and not target_group and not target_name: instance_type = 'Generic' if not env_variables: raise CLIError('Environment variables were not provided') dict_vars = _get_dictionary(env_variables) created_variables = _create_custom_reference(service_name, reference_name, dict_vars, namespace_name) else: instance, client = get_reference_type(target_group, target_name, reference_type) instance_type = instance.type if instance_type == 'Microsoft.DocumentDB/databaseAccounts': results = client.list_connection_strings(target_group, target_name) if len(results.connection_strings) <= 0: raise CLIError('No connection strings found') connection_string = results.connection_strings[0].connection_string created_variables = create_connection_string_reference( service_name, reference_name, connection_string, namespace_name) elif instance_type == 'Microsoft.Sql/servers': sql_admin_login = instance.administrator_login if not sql_admin_login: sql_admin_login = prompt('Administrator login:'******'Password:'******'Microsoft.ServiceBus': connection_string = instance.list_keys( target_group, target_name, 'RootManageSharedAccessKey').primary_connection_string created_variables = create_connection_string_reference( service_name, reference_name, connection_string) else: raise CLIError('Could not determine the reference type') project_settings = settings.Project() project_settings.add_reference(service_name, reference_name, instance_type) return created_variables, instance_type
def _validate_vm_vmss_create_auth(namespace): if namespace.storage_profile in [ StorageProfile.ManagedSpecializedOSDisk, StorageProfile.SASpecializedOSDisk ]: return namespace.admin_username = _validate_admin_username( namespace.admin_username, namespace.os_type) if not namespace.os_type: raise CLIError( "Unable to resolve OS type. Specify '--os-type' argument.") if not namespace.authentication_type: # apply default auth type (password for Windows, ssh for Linux) by examining the OS type namespace.authentication_type = 'password' \ if (namespace.os_type.lower() == 'windows' or namespace.admin_password) else 'ssh' if namespace.os_type.lower( ) == 'windows' and namespace.authentication_type == 'ssh': raise CLIError('SSH not supported for Windows VMs.') # validate proper arguments supplied based on the authentication type if namespace.authentication_type == 'password': if namespace.ssh_key_value or namespace.ssh_dest_key_path: raise ValueError( "incorrect usage for authentication-type 'password': "******"[--admin-username USERNAME] --admin-password PASSWORD") from azure.cli.core.prompting import prompt_pass, NoTTYException try: if not namespace.admin_password: namespace.admin_password = prompt_pass('Admin Password: '******'Please specify password in non-interactive mode.') # validate password _validate_admin_password(namespace.admin_password, namespace.os_type) elif namespace.authentication_type == 'ssh': if namespace.admin_password: raise ValueError( 'Admin password cannot be used with SSH authentication type') validate_ssh_key(namespace) if not namespace.ssh_dest_key_path: namespace.ssh_dest_key_path = \ '/home/{}/.ssh/authorized_keys'.format(namespace.admin_username)
def validate_authentication_type(namespace, formula=None): if formula and formula.formula_content: if formula.formula_content.is_authentication_with_ssh_key is True: namespace.authentication_type = 'ssh' namespace.ssh_key = formula.formula_content.ssh_key elif formula.formula_content.is_authentication_with_ssh_key is False: namespace.admin_username = formula.formula_content.user_name namespace.admin_password = formula.formula_content.password namespace.authentication_type = 'password' # validate proper arguments supplied based on the authentication type if namespace.authentication_type == 'password': password_usage_error = "incorrect usage for authentication-type 'password': "******"[--admin-username USERNAME] --admin-password PASSWORD | " \ "[--admin-username USERNAME] --saved-secret SECRETNAME" if namespace.ssh_key or namespace.generate_ssh_keys or (namespace.saved_secret and namespace.admin_password): raise ValueError(password_usage_error) # Respect user's provided saved secret name for password authentication if namespace.saved_secret: namespace.admin_password = "******".format(namespace.saved_secret) if not namespace.admin_password: # prompt for admin password if not supplied from azure.cli.core.prompting import prompt_pass, NoTTYException try: namespace.admin_password = prompt_pass('Admin Password: '******'Please specify both username and password in non-interactive mode.') elif namespace.authentication_type == 'ssh': if namespace.os_type != 'Linux': raise CLIError("incorrect authentication-type '{}' for os type '{}'".format( namespace.authentication_type, namespace.os_type)) ssh_usage_error = "incorrect usage for authentication-type 'ssh': " \ "[--admin-username USERNAME] | " \ "[--admin-username USERNAME] --ssh-key KEY | " \ "[--admin-username USERNAME] --generate-ssh-keys | " \ "[--admin-username USERNAME] --saved-secret SECRETNAME" if namespace.admin_password or (namespace.saved_secret and (namespace.ssh_key or namespace.generate_ssh_keys)): raise ValueError(ssh_usage_error) # Respect user's provided saved secret name for ssh authentication if namespace.saved_secret: namespace.ssh_key = "[[{}]]".format(namespace.saved_secret) else: validate_ssh_key(namespace) else: raise CLIError("incorrect value for authentication-type: {}".format(namespace.authentication_type))
def _validate_vm_create_auth(namespace): if namespace.storage_profile == StorageProfile.ManagedSpecializedOSDisk: return if len(namespace.admin_username) < 6 or namespace.admin_username.lower() == 'root': # prompt for admin username if inadequate from azure.cli.core.prompting import prompt, NoTTYException try: logger.warning("Cannot use admin username: %s. Admin username should be at " "least 6 characters and cannot be 'root'", namespace.admin_username) namespace.admin_username = prompt('Admin Username: '******'Please specify a valid admin username in non-interactive mode.') if not namespace.os_type: raise CLIError("Unable to resolve OS type. Specify '--os-type' argument.") if not namespace.authentication_type: # apply default auth type (password for Windows, ssh for Linux) by examining the OS type namespace.authentication_type = 'password' if namespace.os_type == 'windows' else 'ssh' if namespace.os_type == 'windows' and namespace.authentication_type == 'ssh': raise CLIError('SSH not supported for Windows VMs.') # validate proper arguments supplied based on the authentication type if namespace.authentication_type == 'password': if namespace.ssh_key_value or namespace.ssh_dest_key_path: raise ValueError( "incorrect usage for authentication-type 'password': "******"[--admin-username USERNAME] --admin-password PASSWORD") if not namespace.admin_password: # prompt for admin password if not supplied from azure.cli.core.prompting import prompt_pass, NoTTYException try: namespace.admin_password = prompt_pass('Admin Password: '******'Please specify both username and password in non-interactive mode.') elif namespace.authentication_type == 'ssh': if namespace.admin_password: raise ValueError('Admin password cannot be used with SSH authentication type') validate_ssh_key(namespace) if not namespace.ssh_dest_key_path: namespace.ssh_dest_key_path = \ '/home/{}/.ssh/authorized_keys'.format(namespace.admin_username)
def set_deployment_user(user_name, password=None): ''' Update deployment credentials.(Note, all webapps in your subscription will be impacted) ''' client = web_client_factory() user = User(location='not-really-needed') #TODO: open bug for this one is not needed user.publishing_user_name = user_name if password is None: try: password = prompt_pass(msg='Password: '******'Please specify both username and password in non-interactive mode.') user.publishing_password = password result = client.update_publishing_user(user) return result
def set_deployment_user(user_name, password=None): ''' Update deployment credentials.(Note, all webapps in your subscription will be impacted) ''' client = web_client_factory() user = User(location='not-really-needed') user.publishing_user_name = user_name if password is None: try: password = prompt_pass(msg='Password: '******'Please specify both username and password in non-interactive mode.') user.publishing_password = password result = client.update_publishing_user(user) return result
def _validate_vm_vmss_create_auth(namespace): if namespace.storage_profile in [StorageProfile.ManagedSpecializedOSDisk, StorageProfile.SASpecializedOSDisk]: return namespace.admin_username = _validate_admin_username(namespace.admin_username, namespace.os_type) if not namespace.os_type: raise CLIError("Unable to resolve OS type. Specify '--os-type' argument.") if not namespace.authentication_type: # apply default auth type (password for Windows, ssh for Linux) by examining the OS type namespace.authentication_type = 'password' \ if (namespace.os_type.lower() == 'windows' or namespace.admin_password) else 'ssh' if namespace.os_type.lower() == 'windows' and namespace.authentication_type == 'ssh': raise CLIError('SSH not supported for Windows VMs.') # validate proper arguments supplied based on the authentication type if namespace.authentication_type == 'password': if namespace.ssh_key_value or namespace.ssh_dest_key_path: raise ValueError( "incorrect usage for authentication-type 'password': "******"[--admin-username USERNAME] --admin-password PASSWORD") from azure.cli.core.prompting import prompt_pass, NoTTYException try: if not namespace.admin_password: namespace.admin_password = prompt_pass('Admin Password: '******'Please specify password in non-interactive mode.') # validate password _validate_admin_password(namespace.admin_password, namespace.os_type) elif namespace.authentication_type == 'ssh': if namespace.admin_password: raise ValueError('Admin password cannot be used with SSH authentication type') validate_ssh_key(namespace) if not namespace.ssh_dest_key_path: namespace.ssh_dest_key_path = \ '/home/{}/.ssh/authorized_keys'.format(namespace.admin_username)
def create_azure_file_volume(azure_file_volume_share_name, azure_file_volume_account_name, azure_file_volume_account_key): """Create Azure File volume. """ azure_file_volume = None if azure_file_volume_share_name: if not azure_file_volume_account_name: raise CLIError('Please specify --azure-file-volume-account-name in order to use Azure File volume.') if not azure_file_volume_account_key: try: azure_file_volume_account_key = prompt_pass(msg='Azure File storage account key: ') except NoTTYException: raise CLIError('Please specify --azure-file-volume-account-key in order to use Azure File volume.') azure_file_volume = AzureFileVolume(share_name=azure_file_volume_share_name, storage_account_name=azure_file_volume_account_name, storage_account_key=azure_file_volume_account_key) return [Volume(name=AZURE_FILE_VOLUME_NAME, azure_file=azure_file_volume)] if azure_file_volume else None
def create_adla_catalog_credential(client, account_name, database_name, credential_name, credential_user_name, uri, credential_user_password=None): if not credential_user_password: try: credential_user_password = prompt_pass('Password:'******'Please specify both --user-name and --password in non-interactive mode.') create_params = DataLakeAnalyticsCatalogCredentialCreateParameters(credential_user_password, uri, credential_user_name) client.create_credential(account_name, database_name, credential_name, create_params)
def login(username=None, password=None, service_principal=None, tenant=None): """Log in to access Azure subscriptions""" from adal.adal_error import AdalError import requests interactive = False if username: if not password: try: password = prompt_pass('Password: '******'Please specify both username and password in non-interactive mode.' ) else: interactive = True profile = Profile() try: subscriptions = profile.find_subscriptions_on_login( interactive, username, password, service_principal, tenant) except AdalError as err: # try polish unfriendly server errors if username: msg = str(err) suggestion = "For cross-check, try 'az login' to authenticate through browser." if ('ID3242:' in msg) or ('Server returned an unknown AccountType' in msg): raise CLIError("The user name might be invalid. " + suggestion) if 'Server returned error in RSTR - ErrorCode' in msg: raise CLIError( "Logging in through command line is not supported. " + suggestion) raise CLIError(err) except requests.exceptions.ConnectionError as err: raise CLIError( 'Please ensure you have network connection. Error detail: ' + str(err)) all_subscriptions = list(subscriptions) for sub in all_subscriptions: sub['cloudName'] = sub.pop('environmentName', None) return all_subscriptions
def login(username=None, password=None, service_principal=None, tenant=None, allow_no_subscriptions=False): """Log in to access Azure subscriptions""" from adal.adal_error import AdalError import requests interactive = False if username: if not password: try: password = prompt_pass('Password: '******'Please specify both username and password in non-interactive mode.') else: interactive = True profile = Profile() try: subscriptions = profile.find_subscriptions_on_login( interactive, username, password, service_principal, tenant, allow_no_subscriptions=allow_no_subscriptions) except AdalError as err: # try polish unfriendly server errors if username: msg = str(err) suggestion = "For cross-check, try 'az login' to authenticate through browser." if ('ID3242:' in msg) or ('Server returned an unknown AccountType' in msg): raise CLIError("The user name might be invalid. " + suggestion) if 'Server returned error in RSTR - ErrorCode' in msg: raise CLIError("Logging in through command line is not supported. " + suggestion) raise CLIError(err) except requests.exceptions.ConnectionError as err: raise CLIError('Please ensure you have network connection. Error detail: ' + str(err)) all_subscriptions = list(subscriptions) for sub in all_subscriptions: sub['cloudName'] = sub.pop('environmentName', None) return all_subscriptions
def create_container(client, resource_group_name, name, image, location=None, cpu=1, memory=1.5, port=80, os_type='Linux', ip_address=None, command_line=None, environment_variables=None, registry_login_server=None, registry_username=None, registry_password=None): """"Create a container group. """ container_resource_requirements = None if cpu is not None or memory is not None: container_resource_requests = ResourceRequests(memory_in_gb=memory, cpu=cpu) container_resource_requirements = ResourceRequirements(requests=container_resource_requests) image_registry_credentials = None if registry_login_server is not None: if registry_username is None: try: registry_username = prompt_pass(msg='Image registry username: '******'Please specify --username in non-interactive mode.') if registry_password is None: try: registry_password = prompt_pass(msg='Image registry password: '******'Please specify --registry-password in non-interactive mode.') image_registry_credentials = [ImageRegistryCredential(server=registry_login_server, username=registry_username, password=registry_password)] elif ACR_SERVER_SUFFIX in image: if registry_password is None: try: registry_password = prompt_pass(msg='Image registry password: '******'Please specify --registry-password in non-interactive mode.') acr_server = image.split("/")[0] if image.split("/") else None acr_username = image.split(ACR_SERVER_SUFFIX)[0] if image.split(ACR_SERVER_SUFFIX) else None if acr_server is not None and acr_username is not None: image_registry_credentials = [ImageRegistryCredential(server=acr_server, username=acr_username, password=registry_password)] else: raise CLIError('Failed to parse ACR server or username from image name; please explicitly specify --registry-server and --registry-username.') command = None if command_line is not None: command = shlex.split(command_line) container = Container(name=name, image=image, resources=container_resource_requirements, command=command, ports=[ContainerPort(port=port)], environment_variables=environment_variables) cgroup_ip_address = None if ip_address is not None and ip_address.lower() == 'public': cgroup_ip_address = IpAddress(ports=[Port(protocol=ContainerGroupNetworkProtocol.tcp, port=port)]) cgroup_os_type = OperatingSystemTypes.linux if os_type.lower() == "linux" else OperatingSystemTypes.windows cgroup = ContainerGroup(location=location, containers=[container], os_type=cgroup_os_type, ip_address=cgroup_ip_address, image_registry_credentials=image_registry_credentials) return client.container_groups.create_or_update(resource_group_name, name, cgroup)
def password_validator(ns): if not ns.administrator_login_password: try: ns.administrator_login_password = prompt_pass(msg='Admin Password: '******'Please specify password in non-interactive mode.')
def _get_credentials(registry_name, resource_group_name, username, password, only_refresh_token, repository=None, permission='*'): """Try to get AAD authorization tokens or admin user credentials. :param str registry_name: The name of container registry :param str resource_group_name: The name of resource group :param str username: The username used to log into the container registry :param str password: The password used to log into the container registry :param bool only_refresh_token: Whether to ask for only refresh token, or for both refresh and access tokens :param str repository: Repository for which the access token is requested :param str permission: The requested permission on the repository, '*' or 'pull' """ registry, _ = get_registry_by_name(registry_name, resource_group_name) login_server = registry.login_server # 1. if username was specified, verify that password was also specified if username: if not password: try: password = prompt_pass(msg='Password: '******'Please specify both username and password in non-interactive mode.' ) return login_server, username, password # 2. if we don't yet have credentials, attempt to get a refresh token if not password and registry.sku.name in MANAGED_REGISTRY_SKU: try: username = "******" if only_refresh_token else None password = _get_aad_token(login_server, only_refresh_token, repository, permission) return login_server, username, password except CLIError as e: logger.warning( "Unable to get AAD authorization tokens with message: %s", str(e)) # 3. if we still don't have credentials, attempt to get the admin credentials (if enabled) if not password: try: cred = acr_credential_show(registry_name) username = cred.username password = cred.passwords[0].value return login_server, username, password except CLIError as e: logger.warning( "Unable to get admin user credentials with message: %s", str(e)) # 4. if we still don't have credentials, prompt the user if not password: try: username = prompt('Username: '******'Password: '******'Unable to authenticate using AAD or admin login credentials. ' + 'Please specify both username and password in non-interactive mode.' )