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
Exemple #2
0
    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
Exemple #4
0
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