def _get_mgmt_service_client(cli_ctx, client_type, subscription_bound=True, subscription_id=None, api_version=None, base_url_bound=True, resource=None, sdk_profile=None, aux_subscriptions=None, aux_tenants=None, **kwargs): from azure.cli.core._profile import Profile from azure.cli.core.util import resource_to_scopes logger.debug('Getting management service client client_type=%s', client_type.__name__) resource = resource or cli_ctx.cloud.endpoints.active_directory_resource_id profile = Profile(cli_ctx=cli_ctx) cred, subscription_id, _ = profile.get_login_credentials( subscription_id=subscription_id, resource=resource, aux_subscriptions=aux_subscriptions, aux_tenants=aux_tenants) client_kwargs = {} if base_url_bound: client_kwargs = {'base_url': cli_ctx.cloud.endpoints.resource_manager} if api_version: client_kwargs['api_version'] = api_version if sdk_profile: client_kwargs['profile'] = sdk_profile if kwargs: client_kwargs.update(kwargs) if is_track2(client_type): client_kwargs.update(_prepare_client_kwargs_track2(cli_ctx)) client_kwargs['credential_scopes'] = resource_to_scopes(resource) # Track 2 currently lacks the ability to take external credentials. # https://github.com/Azure/azure-sdk-for-python/issues/8313 # As a temporary workaround, manually add external tokens to 'x-ms-authorization-auxiliary' header. # https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/authenticate-multi-tenant if getattr(cred, "_external_tenant_token_retriever", None): *_, external_tenant_tokens = cred.get_all_tokens( *resource_to_scopes(resource)) # Hard-code scheme to 'Bearer' as _BearerTokenCredentialPolicyBase._update_headers does. client_kwargs['headers']['x-ms-authorization-auxiliary'] = \ ', '.join("Bearer {}".format(t[1]) for t in external_tenant_tokens) if subscription_bound: client = client_type(cred, subscription_id, **client_kwargs) else: client = client_type(cred, **client_kwargs) if not is_track2(client): configure_common_settings(cli_ctx, client) return client, subscription_id
def test_resource_to_scopes(self): from azure.cli.core.util import resource_to_scopes # resource converted to a scopes list self.assertEqual(resource_to_scopes('https://management.core.windows.net/'), ['https://management.core.windows.net//.default']) # resource with trailing slash self.assertEqual(resource_to_scopes('https://management.azure.com/'), ['https://management.azure.com//.default']) self.assertEqual(resource_to_scopes('https://datalake.azure.net/'), ['https://datalake.azure.net//.default']) # resource without trailing slash self.assertEqual(resource_to_scopes('https://managedhsm.azure.com'), ['https://managedhsm.azure.com/.default'])
def _get_token(self, sdk_resource=None): """ :param sdk_resource: `resource` converted from Track 2 SDK's `scopes` """ # When called by # - Track 1 SDK, use `resource` specified by CLI # - Track 2 SDK, use `sdk_resource` specified by SDK and ignore `resource` specified by CLI token_resource = sdk_resource or self._resource external_tenant_tokens = None try: scheme, token, token_entry = self._token_retriever(token_resource) if self._external_tenant_token_retriever: external_tenant_tokens = self._external_tenant_token_retriever(token_resource) except CLIError as err: if in_cloud_console(): AdalAuthentication._log_hostname() raise err except adal.AdalError as err: if in_cloud_console(): AdalAuthentication._log_hostname() adal_error_handler(err, scopes=resource_to_scopes(token_resource)) except requests.exceptions.SSLError as err: from .util import SSLERROR_TEMPLATE raise CLIError(SSLERROR_TEMPLATE.format(str(err))) except requests.exceptions.ConnectionError as err: raise CLIError('Please ensure you have network connection. Error detail: ' + str(err)) # scheme: str. The token scheme. Should always be 'Bearer'. # token: str. The raw access token. # token_entry: dict. The full token entry. # external_tenant_tokens: [(scheme: str, token: str, token_entry: dict), ...] return scheme, token, token_entry, external_tenant_tokens
def _get_mgmt_service_client(cli_ctx, client_type, subscription_bound=True, subscription_id=None, api_version=None, base_url_bound=True, resource=None, sdk_profile=None, aux_subscriptions=None, aux_tenants=None, **kwargs): from azure.cli.core._profile import Profile from azure.cli.core.util import resource_to_scopes logger.debug('Getting management service client client_type=%s', client_type.__name__) resource = resource or cli_ctx.cloud.endpoints.active_directory_resource_id profile = Profile(cli_ctx=cli_ctx) cred, subscription_id, _ = profile.get_login_credentials( subscription_id=subscription_id, resource=resource, aux_subscriptions=aux_subscriptions, aux_tenants=aux_tenants) client_kwargs = {} if base_url_bound: client_kwargs = {'base_url': cli_ctx.cloud.endpoints.resource_manager} if api_version: client_kwargs['api_version'] = api_version if sdk_profile: client_kwargs['profile'] = sdk_profile if kwargs: client_kwargs.update(kwargs) if is_track2(client_type): client_kwargs.update(_prepare_client_kwargs_track2(cli_ctx)) client_kwargs['credential_scopes'] = resource_to_scopes(resource) if subscription_bound: client = client_type(cred, subscription_id, **client_kwargs) else: client = client_type(cred, **client_kwargs) if not is_track2(client): configure_common_settings(cli_ctx, client) return client, subscription_id
def _prepare_mgmt_client_kwargs_track2(cli_ctx, cred): """Prepare kwargs for Track 2 SDK mgmt client.""" client_kwargs = _prepare_client_kwargs_track2(cli_ctx) from azure.cli.core.util import resource_to_scopes # Track 2 SDK maintains `scopes` and passes `scopes` to get_token. scopes = resource_to_scopes( cli_ctx.cloud.endpoints.active_directory_resource_id) client_kwargs['credential_scopes'] = scopes # Track 2 currently lacks the ability to take external credentials. # https://github.com/Azure/azure-sdk-for-python/issues/8313 # As a temporary workaround, manually add external tokens to 'x-ms-authorization-auxiliary' header. # https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/authenticate-multi-tenant if getattr(cred, "_external_tenant_token_retriever", None): *_, external_tenant_tokens = cred.get_all_tokens(*scopes) # Hard-code scheme to 'Bearer' as _BearerTokenCredentialPolicyBase._update_headers does. client_kwargs['headers']['x-ms-authorization-auxiliary'] = \ ', '.join("Bearer {}".format(t[1]) for t in external_tenant_tokens) return client_kwargs