mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-24 05:40:23 -07:00
initial commit of azure_rm inventory plugin (#44944)
* crusty refactor of azure_rm to support auth from non-modules
This commit is contained in:
parent
c2fa0d2c4b
commit
2822fd8d9b
3 changed files with 839 additions and 245 deletions
|
@ -277,7 +277,6 @@ class AzureRMModuleBase(object):
|
|||
self.fail("Do you have azure>={1} installed? Try `pip install ansible[azure]`"
|
||||
"- {0}".format(HAS_AZURE_EXC, AZURE_MIN_RELEASE))
|
||||
|
||||
self._cloud_environment = None
|
||||
self._network_client = None
|
||||
self._storage_client = None
|
||||
self._resource_client = None
|
||||
|
@ -285,116 +284,23 @@ class AzureRMModuleBase(object):
|
|||
self._dns_client = None
|
||||
self._web_client = None
|
||||
self._marketplace_client = None
|
||||
self._containerservice_client = None
|
||||
self._sql_client = None
|
||||
self._mysql_client = None
|
||||
self._postgresql_client = None
|
||||
self._containerregistry_client = None
|
||||
self._containerinstance_client = None
|
||||
self._containerservice_client = None
|
||||
self._traffic_manager_management_client = None
|
||||
self._monitor_client = None
|
||||
self._adfs_authority_url = None
|
||||
self._resource = None
|
||||
|
||||
self.check_mode = self.module.check_mode
|
||||
self.api_profile = self.module.params.get('api_profile')
|
||||
self.facts_module = facts_module
|
||||
# self.debug = self.module.params.get('debug')
|
||||
|
||||
# authenticate
|
||||
self.credentials = self._get_credentials(self.module.params)
|
||||
if not self.credentials:
|
||||
if HAS_AZURE_CLI_CORE:
|
||||
self.fail("Failed to get credentials. Either pass as parameters, set environment variables, "
|
||||
"define a profile in ~/.azure/credentials, or log in with Azure CLI (`az login`).")
|
||||
else:
|
||||
self.fail("Failed to get credentials. Either pass as parameters, set environment variables, "
|
||||
"define a profile in ~/.azure/credentials, or install Azure CLI and log in (`az login`).")
|
||||
|
||||
# cert validation mode precedence: module-arg, credential profile, env, "validate"
|
||||
self._cert_validation_mode = self.module.params['cert_validation_mode'] or self.credentials.get('cert_validation_mode') or \
|
||||
os.environ.get('AZURE_CERT_VALIDATION_MODE') or 'validate'
|
||||
|
||||
if self._cert_validation_mode not in ['validate', 'ignore']:
|
||||
self.fail('invalid cert_validation_mode: {0}'.format(self._cert_validation_mode))
|
||||
|
||||
# if cloud_environment specified, look up/build Cloud object
|
||||
raw_cloud_env = self.credentials.get('cloud_environment')
|
||||
if self.credentials.get('credentials') is not None and raw_cloud_env is not None:
|
||||
self._cloud_environment = raw_cloud_env
|
||||
elif not raw_cloud_env:
|
||||
self._cloud_environment = azure_cloud.AZURE_PUBLIC_CLOUD # SDK default
|
||||
else:
|
||||
# try to look up "well-known" values via the name attribute on azure_cloud members
|
||||
all_clouds = [x[1] for x in inspect.getmembers(azure_cloud) if isinstance(x[1], azure_cloud.Cloud)]
|
||||
matched_clouds = [x for x in all_clouds if x.name == raw_cloud_env]
|
||||
if len(matched_clouds) == 1:
|
||||
self._cloud_environment = matched_clouds[0]
|
||||
elif len(matched_clouds) > 1:
|
||||
self.fail("Azure SDK failure: more than one cloud matched for cloud_environment name '{0}'".format(raw_cloud_env))
|
||||
else:
|
||||
if not urlparse.urlparse(raw_cloud_env).scheme:
|
||||
self.fail("cloud_environment must be an endpoint discovery URL or one of {0}".format([x.name for x in all_clouds]))
|
||||
try:
|
||||
self._cloud_environment = azure_cloud.get_cloud_from_metadata_endpoint(raw_cloud_env)
|
||||
except Exception as e:
|
||||
self.fail("cloud_environment {0} could not be resolved: {1}".format(raw_cloud_env, e.message), exception=traceback.format_exc(e))
|
||||
|
||||
if self.credentials.get('subscription_id', None) is None and self.credentials.get('credentials') is None:
|
||||
self.fail("Credentials did not include a subscription_id value.")
|
||||
self.log("setting subscription_id")
|
||||
self.subscription_id = self.credentials['subscription_id']
|
||||
|
||||
# get authentication authority
|
||||
# for adfs, user could pass in authority or not.
|
||||
# for others, use default authority from cloud environment
|
||||
if self.credentials.get('adfs_authority_url') is None:
|
||||
self._adfs_authority_url = self._cloud_environment.endpoints.active_directory
|
||||
else:
|
||||
self._adfs_authority_url = self.credentials.get('adfs_authority_url')
|
||||
|
||||
# get resource from cloud environment
|
||||
self._resource = self._cloud_environment.endpoints.active_directory_resource_id
|
||||
|
||||
if self.credentials.get('credentials') is not None:
|
||||
# AzureCLI credentials
|
||||
self.azure_credentials = self.credentials['credentials']
|
||||
elif self.credentials.get('client_id') is not None and \
|
||||
self.credentials.get('secret') is not None and \
|
||||
self.credentials.get('tenant') is not None:
|
||||
self.azure_credentials = ServicePrincipalCredentials(client_id=self.credentials['client_id'],
|
||||
secret=self.credentials['secret'],
|
||||
tenant=self.credentials['tenant'],
|
||||
cloud_environment=self._cloud_environment,
|
||||
verify=self._cert_validation_mode == 'validate')
|
||||
|
||||
elif self.credentials.get('ad_user') is not None and \
|
||||
self.credentials.get('password') is not None and \
|
||||
self.credentials.get('client_id') is not None and \
|
||||
self.credentials.get('tenant') is not None:
|
||||
|
||||
self.azure_credentials = self.acquire_token_with_username_password(
|
||||
self._adfs_authority_url,
|
||||
self._resource,
|
||||
self.credentials['ad_user'],
|
||||
self.credentials['password'],
|
||||
self.credentials['client_id'],
|
||||
self.credentials['tenant'])
|
||||
|
||||
elif self.credentials.get('ad_user') is not None and self.credentials.get('password') is not None:
|
||||
tenant = self.credentials.get('tenant')
|
||||
if not tenant:
|
||||
tenant = 'common' # SDK default
|
||||
|
||||
self.azure_credentials = UserPassCredentials(self.credentials['ad_user'],
|
||||
self.credentials['password'],
|
||||
tenant=tenant,
|
||||
cloud_environment=self._cloud_environment,
|
||||
verify=self._cert_validation_mode == 'validate')
|
||||
else:
|
||||
self.fail("Failed to authenticate with provided credentials. Some attributes were missing. "
|
||||
"Credentials must include client_id, secret and tenant or ad_user and password, or "
|
||||
"ad_user, password, client_id, tenant and adfs_authority_url(optional) for ADFS authentication, or "
|
||||
"be logged in using AzureCLI.")
|
||||
# delegate auth to AzureRMAuth class (shared with all plugin types)
|
||||
self.azure_auth = AzureRMAuth(fail_impl=self.fail, **self.module.params)
|
||||
|
||||
# common parameter validation
|
||||
if self.module.params.get('tags'):
|
||||
|
@ -404,17 +310,6 @@ class AzureRMModuleBase(object):
|
|||
res = self.exec_module(**self.module.params)
|
||||
self.module.exit_json(**res)
|
||||
|
||||
def acquire_token_with_username_password(self, authority, resource, username, password, client_id, tenant):
|
||||
authority_uri = authority
|
||||
|
||||
if tenant is not None:
|
||||
authority_uri = authority + '/' + tenant
|
||||
|
||||
context = AuthenticationContext(authority_uri)
|
||||
token_response = context.acquire_token_with_username_password(resource, username, password, client_id)
|
||||
|
||||
return AADTokenCredentials(token_response)
|
||||
|
||||
def check_client_version(self, client_type):
|
||||
# Ensure Azure modules are at least 2.0.0rc5.
|
||||
package_version = AZURE_PKG_VERSIONS.get(client_type.__name__, None)
|
||||
|
@ -541,138 +436,6 @@ class AzureRMModuleBase(object):
|
|||
except Exception as exc:
|
||||
self.fail("Error retrieving resource group {0} - {1}".format(resource_group, str(exc)))
|
||||
|
||||
def _get_profile(self, profile="default"):
|
||||
path = expanduser("~/.azure/credentials")
|
||||
try:
|
||||
config = configparser.ConfigParser()
|
||||
config.read(path)
|
||||
except Exception as exc:
|
||||
self.fail("Failed to access {0}. Check that the file exists and you have read "
|
||||
"access. {1}".format(path, str(exc)))
|
||||
credentials = dict()
|
||||
for key in AZURE_CREDENTIAL_ENV_MAPPING:
|
||||
try:
|
||||
credentials[key] = config.get(profile, key, raw=True)
|
||||
except:
|
||||
pass
|
||||
|
||||
if credentials.get('subscription_id'):
|
||||
return credentials
|
||||
|
||||
return None
|
||||
|
||||
def _get_msi_credentials(self, subscription_id_param=None):
|
||||
credentials = MSIAuthentication()
|
||||
subscription_id = subscription_id_param or os.environ.get(AZURE_CREDENTIAL_ENV_MAPPING['subscription_id'], None)
|
||||
if not subscription_id:
|
||||
try:
|
||||
# use the first subscription of the MSI
|
||||
subscription_client = SubscriptionClient(credentials)
|
||||
subscription = next(subscription_client.subscriptions.list())
|
||||
subscription_id = str(subscription.subscription_id)
|
||||
except Exception as exc:
|
||||
self.fail("Failed to get MSI token: {0}. "
|
||||
"Please check whether your machine enabled MSI or grant access to any subscription.".format(str(exc)))
|
||||
return {
|
||||
'credentials': credentials,
|
||||
'subscription_id': subscription_id
|
||||
}
|
||||
|
||||
def _get_azure_cli_credentials(self):
|
||||
credentials, subscription_id = get_azure_cli_credentials()
|
||||
cloud_environment = get_cli_active_cloud()
|
||||
|
||||
cli_credentials = {
|
||||
'credentials': credentials,
|
||||
'subscription_id': subscription_id,
|
||||
'cloud_environment': cloud_environment
|
||||
}
|
||||
return cli_credentials
|
||||
|
||||
def _get_env_credentials(self):
|
||||
env_credentials = dict()
|
||||
for attribute, env_variable in AZURE_CREDENTIAL_ENV_MAPPING.items():
|
||||
env_credentials[attribute] = os.environ.get(env_variable, None)
|
||||
|
||||
if env_credentials['profile']:
|
||||
credentials = self._get_profile(env_credentials['profile'])
|
||||
return credentials
|
||||
|
||||
if env_credentials.get('subscription_id') is not None:
|
||||
return env_credentials
|
||||
|
||||
return None
|
||||
|
||||
def _get_credentials(self, params):
|
||||
# Get authentication credentials.
|
||||
self.log('Getting credentials')
|
||||
|
||||
arg_credentials = dict()
|
||||
for attribute, env_variable in AZURE_CREDENTIAL_ENV_MAPPING.items():
|
||||
arg_credentials[attribute] = params.get(attribute, None)
|
||||
|
||||
auth_source = params.get('auth_source', None)
|
||||
if not auth_source:
|
||||
auth_source = os.environ.get('ANSIBLE_AZURE_AUTH_SOURCE', 'auto')
|
||||
|
||||
if auth_source == 'msi':
|
||||
self.log('Retrieving credenitals from MSI')
|
||||
return self._get_msi_credentials(arg_credentials['subscription_id'])
|
||||
|
||||
if auth_source == 'cli':
|
||||
if not HAS_AZURE_CLI_CORE:
|
||||
self.fail("Azure auth_source is `cli`, but azure-cli package is not available. Try `pip install azure-cli --upgrade`")
|
||||
try:
|
||||
self.log('Retrieving credentials from Azure CLI profile')
|
||||
cli_credentials = self._get_azure_cli_credentials()
|
||||
return cli_credentials
|
||||
except CLIError as err:
|
||||
self.fail("Azure CLI profile cannot be loaded - {0}".format(err))
|
||||
|
||||
if auth_source == 'env':
|
||||
self.log('Retrieving credentials from environment')
|
||||
env_credentials = self._get_env_credentials()
|
||||
return env_credentials
|
||||
|
||||
if auth_source == 'credential_file':
|
||||
self.log("Retrieving credentials from credential file")
|
||||
profile = params.get('profile', 'default')
|
||||
default_credentials = self._get_profile(profile)
|
||||
return default_credentials
|
||||
|
||||
# auto, precedence: module parameters -> environment variables -> default profile in ~/.azure/credentials
|
||||
# try module params
|
||||
if arg_credentials['profile'] is not None:
|
||||
self.log('Retrieving credentials with profile parameter.')
|
||||
credentials = self._get_profile(arg_credentials['profile'])
|
||||
return credentials
|
||||
|
||||
if arg_credentials['subscription_id']:
|
||||
self.log('Received credentials from parameters.')
|
||||
return arg_credentials
|
||||
|
||||
# try environment
|
||||
env_credentials = self._get_env_credentials()
|
||||
if env_credentials:
|
||||
self.log('Received credentials from env.')
|
||||
return env_credentials
|
||||
|
||||
# try default profile from ~./azure/credentials
|
||||
default_credentials = self._get_profile()
|
||||
if default_credentials:
|
||||
self.log('Retrieved default profile credentials from ~/.azure/credentials.')
|
||||
return default_credentials
|
||||
|
||||
try:
|
||||
if HAS_AZURE_CLI_CORE:
|
||||
self.log('Retrieving credentials from AzureCLI profile')
|
||||
cli_credentials = self._get_azure_cli_credentials()
|
||||
return cli_credentials
|
||||
except CLIError as ce:
|
||||
self.log('Error getting AzureCLI profile credentials - {0}'.format(ce))
|
||||
|
||||
return None
|
||||
|
||||
def parse_resource_to_dict(self, resource):
|
||||
'''
|
||||
Return a dict of the give resource, which contains name and resource group.
|
||||
|
@ -947,9 +710,9 @@ class AzureRMModuleBase(object):
|
|||
|
||||
if not base_url:
|
||||
# most things are resource_manager, don't make everyone specify
|
||||
base_url = self._cloud_environment.endpoints.resource_manager
|
||||
base_url = self.azure_auth._cloud_environment.endpoints.resource_manager
|
||||
|
||||
client_kwargs = dict(credentials=self.azure_credentials, subscription_id=self.subscription_id, base_url=base_url)
|
||||
client_kwargs = dict(credentials=self.azure_auth.azure_credentials, subscription_id=self.azure_auth.subscription_id, base_url=base_url)
|
||||
|
||||
api_profile_dict = {}
|
||||
|
||||
|
@ -992,11 +755,24 @@ class AzureRMModuleBase(object):
|
|||
if VSCODEEXT_USER_AGENT_KEY in os.environ:
|
||||
client.config.add_user_agent(os.environ[VSCODEEXT_USER_AGENT_KEY])
|
||||
|
||||
if self._cert_validation_mode == 'ignore':
|
||||
if self.azure_auth._cert_validation_mode == 'ignore':
|
||||
client.config.session_configuration_callback = self._validation_ignore_callback
|
||||
|
||||
return client
|
||||
|
||||
# passthru methods to AzureAuth instance for backcompat
|
||||
@property
|
||||
def credentials(self):
|
||||
return self.azure_auth.credentials
|
||||
|
||||
@property
|
||||
def _cloud_environment(self):
|
||||
return self.azure_auth._cloud_environment
|
||||
|
||||
@property
|
||||
def subscription_id(self):
|
||||
return self.azure_auth.subscription_id
|
||||
|
||||
@property
|
||||
def storage_client(self):
|
||||
self.log('Getting storage client...')
|
||||
|
@ -1152,3 +928,281 @@ class AzureRMModuleBase(object):
|
|||
self._monitor_client = self.get_mgmt_svc_client(MonitorManagementClient,
|
||||
base_url=self._cloud_environment.endpoints.resource_manager)
|
||||
return self._monitor_client
|
||||
|
||||
|
||||
class AzureRMAuthException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class AzureRMAuth(object):
|
||||
def __init__(self, auth_source='auto', profile=None, subscription_id=None, client_id=None, secret=None,
|
||||
tenant=None, ad_user=None, password=None, cloud_environment='AzureCloud', cert_validation_mode='validate',
|
||||
api_profile='latest', adfs_authority_url=None, fail_impl=None, **kwargs):
|
||||
|
||||
if fail_impl:
|
||||
self._fail_impl = fail_impl
|
||||
else:
|
||||
self._fail_impl = self._default_fail_impl
|
||||
|
||||
self._cloud_environment = None
|
||||
self._adfs_authority_url = None
|
||||
|
||||
# authenticate
|
||||
self.credentials = self._get_credentials(
|
||||
dict(auth_source=auth_source, profile=profile, subscription_id=subscription_id, client_id=client_id, secret=secret,
|
||||
tenant=tenant, ad_user=ad_user, password=password, cloud_environment=cloud_environment,
|
||||
cert_validation_mode=cert_validation_mode, api_profile=api_profile, adfs_authority_url=adfs_authority_url))
|
||||
|
||||
if not self.credentials:
|
||||
if HAS_AZURE_CLI_CORE:
|
||||
self.fail("Failed to get credentials. Either pass as parameters, set environment variables, "
|
||||
"define a profile in ~/.azure/credentials, or log in with Azure CLI (`az login`).")
|
||||
else:
|
||||
self.fail("Failed to get credentials. Either pass as parameters, set environment variables, "
|
||||
"define a profile in ~/.azure/credentials, or install Azure CLI and log in (`az login`).")
|
||||
|
||||
# cert validation mode precedence: module-arg, credential profile, env, "validate"
|
||||
self._cert_validation_mode = cert_validation_mode or self.credentials.get('cert_validation_mode') or \
|
||||
os.environ.get('AZURE_CERT_VALIDATION_MODE') or 'validate'
|
||||
|
||||
if self._cert_validation_mode not in ['validate', 'ignore']:
|
||||
self.fail('invalid cert_validation_mode: {0}'.format(self._cert_validation_mode))
|
||||
|
||||
# if cloud_environment specified, look up/build Cloud object
|
||||
raw_cloud_env = self.credentials.get('cloud_environment')
|
||||
if self.credentials.get('credentials') is not None and raw_cloud_env is not None:
|
||||
self._cloud_environment = raw_cloud_env
|
||||
elif not raw_cloud_env:
|
||||
self._cloud_environment = azure_cloud.AZURE_PUBLIC_CLOUD # SDK default
|
||||
else:
|
||||
# try to look up "well-known" values via the name attribute on azure_cloud members
|
||||
all_clouds = [x[1] for x in inspect.getmembers(azure_cloud) if isinstance(x[1], azure_cloud.Cloud)]
|
||||
matched_clouds = [x for x in all_clouds if x.name == raw_cloud_env]
|
||||
if len(matched_clouds) == 1:
|
||||
self._cloud_environment = matched_clouds[0]
|
||||
elif len(matched_clouds) > 1:
|
||||
self.fail("Azure SDK failure: more than one cloud matched for cloud_environment name '{0}'".format(raw_cloud_env))
|
||||
else:
|
||||
if not urlparse.urlparse(raw_cloud_env).scheme:
|
||||
self.fail("cloud_environment must be an endpoint discovery URL or one of {0}".format([x.name for x in all_clouds]))
|
||||
try:
|
||||
self._cloud_environment = azure_cloud.get_cloud_from_metadata_endpoint(raw_cloud_env)
|
||||
except Exception as e:
|
||||
self.fail("cloud_environment {0} could not be resolved: {1}".format(raw_cloud_env, e.message), exception=traceback.format_exc(e))
|
||||
|
||||
if self.credentials.get('subscription_id', None) is None and self.credentials.get('credentials') is None:
|
||||
self.fail("Credentials did not include a subscription_id value.")
|
||||
self.log("setting subscription_id")
|
||||
self.subscription_id = self.credentials['subscription_id']
|
||||
|
||||
# get authentication authority
|
||||
# for adfs, user could pass in authority or not.
|
||||
# for others, use default authority from cloud environment
|
||||
if self.credentials.get('adfs_authority_url') is None:
|
||||
self._adfs_authority_url = self._cloud_environment.endpoints.active_directory
|
||||
else:
|
||||
self._adfs_authority_url = self.credentials.get('adfs_authority_url')
|
||||
|
||||
# get resource from cloud environment
|
||||
self._resource = self._cloud_environment.endpoints.active_directory_resource_id
|
||||
|
||||
if self.credentials.get('credentials') is not None:
|
||||
# AzureCLI credentials
|
||||
self.azure_credentials = self.credentials['credentials']
|
||||
elif self.credentials.get('client_id') is not None and \
|
||||
self.credentials.get('secret') is not None and \
|
||||
self.credentials.get('tenant') is not None:
|
||||
self.azure_credentials = ServicePrincipalCredentials(client_id=self.credentials['client_id'],
|
||||
secret=self.credentials['secret'],
|
||||
tenant=self.credentials['tenant'],
|
||||
cloud_environment=self._cloud_environment,
|
||||
verify=self._cert_validation_mode == 'validate')
|
||||
|
||||
elif self.credentials.get('ad_user') is not None and \
|
||||
self.credentials.get('password') is not None and \
|
||||
self.credentials.get('client_id') is not None and \
|
||||
self.credentials.get('tenant') is not None:
|
||||
|
||||
self.azure_credentials = self.acquire_token_with_username_password(
|
||||
self._adfs_authority_url,
|
||||
self._resource,
|
||||
self.credentials['ad_user'],
|
||||
self.credentials['password'],
|
||||
self.credentials['client_id'],
|
||||
self.credentials['tenant'])
|
||||
|
||||
elif self.credentials.get('ad_user') is not None and self.credentials.get('password') is not None:
|
||||
tenant = self.credentials.get('tenant')
|
||||
if not tenant:
|
||||
tenant = 'common' # SDK default
|
||||
|
||||
self.azure_credentials = UserPassCredentials(self.credentials['ad_user'],
|
||||
self.credentials['password'],
|
||||
tenant=tenant,
|
||||
cloud_environment=self._cloud_environment,
|
||||
verify=self._cert_validation_mode == 'validate')
|
||||
else:
|
||||
self.fail("Failed to authenticate with provided credentials. Some attributes were missing. "
|
||||
"Credentials must include client_id, secret and tenant or ad_user and password, or "
|
||||
"ad_user, password, client_id, tenant and adfs_authority_url(optional) for ADFS authentication, or "
|
||||
"be logged in using AzureCLI.")
|
||||
|
||||
def fail(self, msg, exception=None, **kwargs):
|
||||
self._fail_impl(msg)
|
||||
|
||||
def _default_fail_impl(self, msg, exception=None, **kwargs):
|
||||
raise AzureRMAuthException(msg)
|
||||
|
||||
def _get_profile(self, profile="default"):
|
||||
path = expanduser("~/.azure/credentials")
|
||||
try:
|
||||
config = configparser.ConfigParser()
|
||||
config.read(path)
|
||||
except Exception as exc:
|
||||
self.fail("Failed to access {0}. Check that the file exists and you have read "
|
||||
"access. {1}".format(path, str(exc)))
|
||||
credentials = dict()
|
||||
for key in AZURE_CREDENTIAL_ENV_MAPPING:
|
||||
try:
|
||||
credentials[key] = config.get(profile, key, raw=True)
|
||||
except:
|
||||
pass
|
||||
|
||||
if credentials.get('subscription_id'):
|
||||
return credentials
|
||||
|
||||
return None
|
||||
|
||||
def _get_msi_credentials(self, subscription_id_param=None):
|
||||
credentials = MSIAuthentication()
|
||||
subscription_id = subscription_id_param or os.environ.get(AZURE_CREDENTIAL_ENV_MAPPING['subscription_id'], None)
|
||||
if not subscription_id:
|
||||
try:
|
||||
# use the first subscription of the MSI
|
||||
subscription_client = SubscriptionClient(credentials)
|
||||
subscription = next(subscription_client.subscriptions.list())
|
||||
subscription_id = str(subscription.subscription_id)
|
||||
except Exception as exc:
|
||||
self.fail("Failed to get MSI token: {0}. "
|
||||
"Please check whether your machine enabled MSI or grant access to any subscription.".format(str(exc)))
|
||||
return {
|
||||
'credentials': credentials,
|
||||
'subscription_id': subscription_id
|
||||
}
|
||||
|
||||
def _get_azure_cli_credentials(self):
|
||||
credentials, subscription_id = get_azure_cli_credentials()
|
||||
cloud_environment = get_cli_active_cloud()
|
||||
|
||||
cli_credentials = {
|
||||
'credentials': credentials,
|
||||
'subscription_id': subscription_id,
|
||||
'cloud_environment': cloud_environment
|
||||
}
|
||||
return cli_credentials
|
||||
|
||||
def _get_env_credentials(self):
|
||||
env_credentials = dict()
|
||||
for attribute, env_variable in AZURE_CREDENTIAL_ENV_MAPPING.items():
|
||||
env_credentials[attribute] = os.environ.get(env_variable, None)
|
||||
|
||||
if env_credentials['profile']:
|
||||
credentials = self._get_profile(env_credentials['profile'])
|
||||
return credentials
|
||||
|
||||
if env_credentials.get('subscription_id') is not None:
|
||||
return env_credentials
|
||||
|
||||
return None
|
||||
|
||||
# TODO: use explicit kwargs instead of intermediate dict
|
||||
def _get_credentials(self, params):
|
||||
# Get authentication credentials.
|
||||
self.log('Getting credentials')
|
||||
|
||||
arg_credentials = dict()
|
||||
for attribute, env_variable in AZURE_CREDENTIAL_ENV_MAPPING.items():
|
||||
arg_credentials[attribute] = params.get(attribute, None)
|
||||
|
||||
auth_source = params.get('auth_source', None)
|
||||
if not auth_source:
|
||||
auth_source = os.environ.get('ANSIBLE_AZURE_AUTH_SOURCE', 'auto')
|
||||
|
||||
if auth_source == 'msi':
|
||||
self.log('Retrieving credenitals from MSI')
|
||||
return self._get_msi_credentials(arg_credentials['subscription_id'])
|
||||
|
||||
if auth_source == 'cli':
|
||||
if not HAS_AZURE_CLI_CORE:
|
||||
self.fail("Azure auth_source is `cli`, but azure-cli package is not available. Try `pip install azure-cli --upgrade`")
|
||||
try:
|
||||
self.log('Retrieving credentials from Azure CLI profile')
|
||||
cli_credentials = self._get_azure_cli_credentials()
|
||||
return cli_credentials
|
||||
except CLIError as err:
|
||||
self.fail("Azure CLI profile cannot be loaded - {0}".format(err))
|
||||
|
||||
if auth_source == 'env':
|
||||
self.log('Retrieving credentials from environment')
|
||||
env_credentials = self._get_env_credentials()
|
||||
return env_credentials
|
||||
|
||||
if auth_source == 'credential_file':
|
||||
self.log("Retrieving credentials from credential file")
|
||||
profile = params.get('profile', 'default')
|
||||
default_credentials = self._get_profile(profile)
|
||||
return default_credentials
|
||||
|
||||
# auto, precedence: module parameters -> environment variables -> default profile in ~/.azure/credentials
|
||||
# try module params
|
||||
if arg_credentials['profile'] is not None:
|
||||
self.log('Retrieving credentials with profile parameter.')
|
||||
credentials = self._get_profile(arg_credentials['profile'])
|
||||
return credentials
|
||||
|
||||
if arg_credentials['subscription_id']:
|
||||
self.log('Received credentials from parameters.')
|
||||
return arg_credentials
|
||||
|
||||
# try environment
|
||||
env_credentials = self._get_env_credentials()
|
||||
if env_credentials:
|
||||
self.log('Received credentials from env.')
|
||||
return env_credentials
|
||||
|
||||
# try default profile from ~./azure/credentials
|
||||
default_credentials = self._get_profile()
|
||||
if default_credentials:
|
||||
self.log('Retrieved default profile credentials from ~/.azure/credentials.')
|
||||
return default_credentials
|
||||
|
||||
try:
|
||||
if HAS_AZURE_CLI_CORE:
|
||||
self.log('Retrieving credentials from AzureCLI profile')
|
||||
cli_credentials = self._get_azure_cli_credentials()
|
||||
return cli_credentials
|
||||
except CLIError as ce:
|
||||
self.log('Error getting AzureCLI profile credentials - {0}'.format(ce))
|
||||
|
||||
return None
|
||||
|
||||
def acquire_token_with_username_password(self, authority, resource, username, password, client_id, tenant):
|
||||
authority_uri = authority
|
||||
|
||||
if tenant is not None:
|
||||
authority_uri = authority + '/' + tenant
|
||||
|
||||
context = AuthenticationContext(authority_uri)
|
||||
token_response = context.acquire_token_with_username_password(resource, username, password, client_id)
|
||||
|
||||
return AADTokenCredentials(token_response)
|
||||
|
||||
def log(self, msg, pretty_print=False):
|
||||
pass
|
||||
# Use only during module development
|
||||
# if self.debug:
|
||||
# log_file = open('azure_rm.log', 'a')
|
||||
# if pretty_print:
|
||||
# log_file.write(json.dumps(msg, indent=4, sort_keys=True))
|
||||
# else:
|
||||
# log_file.write(msg + u'\n')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue