Ejemplo n.º 1
0
    def test_get_raw_token(self, mock_get_token, mock_read_cred_file):
        some_token_type = 'Bearer'
        mock_read_cred_file.return_value = [Test_Profile.token_entry1]
        mock_get_token.return_value = (some_token_type, Test_Profile.raw_token1,
                                       Test_Profile.token_entry1)
        # setup
        storage_mock = {'subscriptions': None}
        profile = Profile(storage_mock, use_global_creds_cache=False)
        consolidated = Profile._normalize_properties(self.user1,
                                                     [self.subscription1],
                                                     False)
        profile._set_subscriptions(consolidated)
        # action
        creds, sub, tenant = profile.get_raw_token(resource='https://foo')

        # verify
        self.assertEqual(creds[0], self.token_entry1['tokenType'])
        self.assertEqual(creds[1], self.raw_token1)
        # the last in the tuple is the whole token entry which has several fields
        self.assertEqual(creds[2]['expiresOn'], self.token_entry1['expiresOn'])
        mock_get_token.assert_called_once_with(mock.ANY, self.user1, self.tenant_id,
                                               'https://foo')
        self.assertEqual(mock_get_token.call_count, 1)
        self.assertEqual(sub, '1')
        self.assertEqual(tenant, self.tenant_id)
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
def login(username=None, password=None, service_principal=None, tenant=None):
    '''Log in to access Azure subscriptions'''
    interactive = False

    if username:
        if not password:
            import getpass
            password = getpass.getpass('Password: '******'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)
    return list(subscriptions)
Ejemplo n.º 4
0
def _get_mgmt_service_client(client_type,
                             subscription_bound=True,
                             subscription_id=None,
                             api_version=None,
                             base_url_bound=True,
                             resource=CLOUD.endpoints.active_directory_resource_id,
                             **kwargs):
    logger.debug('Getting management service client client_type=%s', client_type.__name__)
    profile = Profile()
    cred, subscription_id, _ = profile.get_login_credentials(subscription_id=subscription_id,
                                                             resource=resource)
    client_kwargs = {}
    if base_url_bound:
        client_kwargs = {'base_url': CLOUD.endpoints.resource_manager}
    if api_version:
        client_kwargs['api_version'] = api_version
    if kwargs:
        client_kwargs.update(kwargs)

    if subscription_bound:
        client = client_type(cred, subscription_id, **client_kwargs)
    else:
        client = client_type(cred, **client_kwargs)

    configure_common_settings(client)

    return (client, subscription_id)
Ejemplo n.º 5
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,
                             **kwargs):
    from azure.cli.core._profile import Profile
    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)

    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 subscription_bound:
        client = client_type(cred, subscription_id, **client_kwargs)
    else:
        client = client_type(cred, **client_kwargs)

    configure_common_settings(cli_ctx, client)

    return client, subscription_id
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    def test_create_account_without_subscriptions_thru_common_tenant(self, mock_auth_context):
        mock_auth_context.acquire_token.return_value = self.token_entry1
        mock_auth_context.acquire_token_with_username_password.return_value = self.token_entry1
        tenant_object = mock.MagicMock()
        tenant_object.id = "foo-bar"
        tenant_object.tenant_id = self.tenant_id
        mock_arm_client = mock.MagicMock()
        mock_arm_client.subscriptions.list.return_value = []
        mock_arm_client.tenants.list.return_value = (x for x in [tenant_object])

        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/'

        # action
        result = profile.find_subscriptions_on_login(False,
                                                     '1234',
                                                     'my-secret',
                                                     False,
                                                     None,
                                                     allow_no_subscriptions=True,
                                                     subscription_finder=finder)

        # assert
        self.assertEqual(1, len(result))
        self.assertEqual(result[0]['id'], self.tenant_id)
        self.assertEqual(result[0]['state'], 'Enabled')
        self.assertEqual(result[0]['tenantId'], self.tenant_id)
        self.assertEqual(result[0]['name'], 'N/A(tenant level account)')
Ejemplo n.º 8
0
def batch_data_service_factory(cli_ctx, kwargs):
    import azure.batch.batch_service_client as batch
    import azure.batch.batch_auth as batchauth

    account_name = kwargs.pop('account_name', None)
    account_key = kwargs.pop('account_key', None)
    account_endpoint = kwargs.pop('account_endpoint', None)
    kwargs.pop('yes', None)

    credentials = None
    if not account_key:
        from azure.cli.core._profile import Profile
        profile = Profile(cli_ctx=cli_ctx)
        # in order to use AAD auth in cloud shell mode, we will use mgmt AAD token
        # instead of Batch AAD token to auth
        if in_cloud_console():
            resource = cli_ctx.cloud.endpoints.active_directory_resource_id
        else:
            resource = cli_ctx.cloud.endpoints.batch_resource_id
        credentials, _, _ = profile.get_login_credentials(resource=resource)
    else:
        credentials = batchauth.SharedKeyCredentials(account_name, account_key)
    if not (account_endpoint.startswith('https://') or
            account_endpoint.startswith('http://')):
        account_endpoint = 'https://' + account_endpoint
    return batch.BatchServiceClient(credentials, batch_url=account_endpoint.rstrip('/'))
Ejemplo n.º 9
0
def list_releases(target_name, target_resource_group):
    """
    Lists all the release definitions that are deployed to a given Azure container service.

    :param target_name: Name of the target Azure container service instance.
    :type target_name: String
    :param target_resource_group: Name of Azure container service's resource group.
    :type target_resource_group: String
    """
    profile = Profile()
    _, subscription_id, _ = profile.get_login_credentials()

    o_auth_token = _get_service_token()
    container_service_resource_id = CONTAINER_SERVICE_RESOURCE_URL.format(subscription_id=subscription_id, resource_group_name=target_resource_group, container_service_name=target_name)
    data = {
        'acsResourceId': container_service_resource_id
    }

    list_releases_url = SERVICE_URL.format(
        subscription_id=subscription_id) + '/listReleases?api-version=' + API_VERSION

    headers = {}
    headers['Authorization'] = o_auth_token
    headers['Content-Type'] = 'application/json; charset=utf-8'
    headers['x-ms-client-request-id'] = str(uuid.uuid1())
    req = requests.post(list_releases_url, data=json.dumps(data), headers=headers, timeout=600)
    while req.status_code == 202:  # Long-running operation
        time.sleep(10)
        req = requests.get(BASE_URL + req.headers['Location'], headers=headers, timeout=600)
    if req.status_code != 200:
        raise CLIError(
            'Server returned status code: ' + str(req.status_code) + '. Could not list releases: ' + req.text)
    json_request = req.json()
    return json_request
Ejemplo n.º 10
0
    def test_get_login_credentials(self, mock_get_token, mock_read_cred_file):
        some_token_type = 'Bearer'
        mock_read_cred_file.return_value = [Test_Profile.token_entry1]
        mock_get_token.return_value = (some_token_type, Test_Profile.raw_token1)
        #setup
        storage_mock = {'subscriptions': None}
        profile = Profile(storage_mock)
        consolidated = Profile._normalize_properties(self.user1,
                                                     [self.subscription1],
                                                     False,
                                                     ENV_DEFAULT)
        profile._set_subscriptions(consolidated)
        #action
        cred, subscription_id, _ = profile.get_login_credentials()

        #verify
        self.assertEqual(subscription_id, '1')

        #verify the cred._tokenRetriever is a working lambda
        token_type, token = cred._token_retriever()
        self.assertEqual(token, self.raw_token1)
        self.assertEqual(some_token_type, token_type)
        self.assertEqual(mock_read_cred_file.call_count, 1)
        mock_get_token.assert_called_once_with(mock.ANY, self.user1, self.tenant_id,
                                               'https://management.core.windows.net/')
        self.assertEqual(mock_get_token.call_count, 1)
Ejemplo n.º 11
0
    def setup_continuous_delivery(self, cli_ctx,
                                  resource_group_name, name, repo_url, branch, git_token,
                                  slot, cd_app_type_details, cd_project_url, cd_create_account, location,
                                  test, private_repo_username, private_repo_password, webapp_list):
        """
        This method sets up CD for an Azure Web App thru Team Services
        """

        # Gather information about the Azure connection
        profile = Profile(cli_ctx=cli_ctx)
        subscription = profile.get_subscription()
        user = profile.get_current_account_user()
        cred, _, _ = profile.get_login_credentials(subscription_id=None)

        cd_manager = ContinuousDeliveryManager(self._update_progress)

        # Generate an Azure token with the VSTS resource app id
        auth_token = profile.get_access_token_for_resource(user, None, cd_manager.get_vsts_app_id())

        cd_manager.set_repository_info(repo_url, branch, git_token, private_repo_username, private_repo_password)
        cd_manager.set_azure_web_info(resource_group_name, name, cred, subscription['id'],
                                      subscription['name'], subscription['tenantId'], location)
        vsts_cd_status = cd_manager.setup_continuous_delivery(slot, cd_app_type_details, cd_project_url,
                                                              cd_create_account, auth_token, test, webapp_list)
        return vsts_cd_status
Ejemplo n.º 12
0
def login_account(cmd, client, resource_group_name, account_name, shared_key_auth=False, show=False):
    account = client.get(resource_group_name=resource_group_name,
                         account_name=account_name)
    cmd.cli_ctx.config.set_value('batch', 'account', account.name)
    cmd.cli_ctx.config.set_value('batch', 'endpoint',
                                 'https://{}/'.format(account.account_endpoint))

    if shared_key_auth:
        keys = client.get_keys(resource_group_name=resource_group_name,
                               account_name=account_name)
        cmd.cli_ctx.config.set_value('batch', 'auth_mode', 'shared_key')
        cmd.cli_ctx.config.set_value('batch', 'access_key', keys.primary)
        if show:
            return {
                'account': account.name,
                'endpoint': 'https://{}/'.format(account.account_endpoint),
                'primaryKey': keys.primary,
                'secondaryKey': keys.secondary
            }
    else:
        cmd.cli_ctx.config.set_value('batch', 'auth_mode', 'aad')
        if show:
            resource = cmd.cli_ctx.cloud.endpoints.batch_resource_id
            profile = Profile(cli_ctx=cmd.cli_ctx)
            creds, subscription, tenant = profile.get_raw_token(resource=resource)
            return {
                'tokenType': creds[0],
                'accessToken': creds[1],
                'expiresOn': creds[2]['expiresOn'],
                'subscription': subscription,
                'tenant': tenant,
                'resource': resource
            }
Ejemplo n.º 13
0
def login(username=None, password=None, service_principal=None, tenant=None):
    '''Log in to access Azure subscriptions'''
    interactive = False

    if username:
        if not password:
            import getpass
            password = getpass.getpass('Password: '******'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
Ejemplo n.º 14
0
def _arm_get_resource_by_name(cli_ctx, resource_name, resource_type):
    """Returns the ARM resource in the current subscription with resource_name.
    :param str resource_name: The name of resource
    :param str resource_type: The type of resource
    """
    result = get_resources_in_subscription(cli_ctx, resource_type)
    elements = [item for item in result if item.name.lower() == resource_name.lower()]

    if not elements:
        from azure.cli.core._profile import Profile
        profile = Profile(cli_ctx=cli_ctx)
        message = "The resource with name '{}' and type '{}' could not be found".format(
            resource_name, resource_type)
        try:
            subscription = profile.get_subscription()
            raise CLIError("{} in subscription '{} ({})'.".format(message, subscription['name'], subscription['id']))
        except (KeyError, TypeError):
            raise CLIError("{} in the current subscription.".format(message))

    elif len(elements) == 1:
        return elements[0]
    else:
        raise CLIError(
            "More than one resources with type '{}' are found with name '{}'.".format(
                resource_type, resource_name))
Ejemplo n.º 15
0
def _graph_client_factory(**_):
    from azure.cli.core._profile import Profile
    profile = Profile()
    cred, _, tenant_id = profile.get_login_credentials(True)
    client = GraphRbacManagementClient(cred, tenant_id)
    configure_common_settings(client)
    return client
Ejemplo n.º 16
0
def _mock_get_mgmt_service_client(client_type,
                                  subscription_bound=True,
                                  subscription_id=None,
                                  api_version=None,
                                  base_url_bound=None,
                                  resource=CLOUD.endpoints.active_directory_resource_id,
                                  **kwargs):
    # version of _get_mgmt_service_client to use when recording or playing tests
    profile = Profile()
    cred, subscription_id, _ = profile.get_login_credentials(subscription_id=subscription_id,
                                                             resource=resource)
    client_kwargs = {}

    if base_url_bound:
        client_kwargs = {'base_url': CLOUD.endpoints.resource_manager}
    if api_version:
        client_kwargs['api_version'] = api_version
    if kwargs:
        client_kwargs.update(kwargs)

    if subscription_bound:
        client = client_type(cred, subscription_id, **client_kwargs)
    else:
        client = client_type(cred, **client_kwargs)

    client = _debug.change_ssl_cert_verification(client)

    client.config.add_user_agent("AZURECLI/TEST/{}".format(core_version))

    return (client, subscription_id)
Ejemplo n.º 17
0
def create_bot_json(cmd, client, resource_group_name, resource_name, app_password=None, raw_bot_properties=None):
    if not raw_bot_properties:
        raw_bot_properties = client.bots.get(
            resource_group_name=resource_group_name,
            resource_name=resource_name
        )
    if not app_password:
        site_name = get_bot_site_name(raw_bot_properties.properties.endpoint)
        app_settings = get_app_settings(
            cmd=cmd,
            resource_group_name=resource_group_name,
            name=site_name
        )
        app_password = [item['value'] for item in app_settings if item['name'] == 'MicrosoftAppPassword'][0]

    profile = Profile(cli_ctx=cmd.cli_ctx)
    return {
        'type': 'abs',
        'id': raw_bot_properties.name,
        'name': raw_bot_properties.properties.display_name,
        'appId': raw_bot_properties.properties.msa_app_id,
        'appPassword': app_password,
        'endpoint': raw_bot_properties.properties.endpoint,
        'resourceGroup': str(resource_group_name),
        'tenantId': profile.get_subscription(subscription=client.config.subscription_id)['tenantId'],
        'subscriptionId': client.config.subscription_id
    }
Ejemplo n.º 18
0
def validate_lab_vm_list(namespace):
    """ Validates parameters for lab vm list and updates namespace. """
    collection = [namespace.filters, namespace.all, namespace.claimable]
    if _any(collection) and not _single(collection):
        raise CLIError("usage error: [--filters FILTER | --all | --claimable]")

    # Retrieve all the vms of the lab
    if namespace.all:
        namespace.filters = None
    # Retrieve all the vms claimable by user
    elif namespace.claimable:
        namespace.filters = 'properties/allowClaim'
    # Default to retrieving users vms only
    else:
        # Find out owner object id
        if not namespace.object_id:
            from azure.cli.core._profile import Profile, CLOUD
            from azure.graphrbac.models import GraphErrorException
            profile = Profile()
            cred, _, tenant_id = profile.get_login_credentials(
                resource=CLOUD.endpoints.active_directory_graph_resource_id)
            graph_client = GraphRbacManagementClient(cred,
                                                     tenant_id,
                                                     base_url=CLOUD.endpoints.active_directory_graph_resource_id)
            subscription = profile.get_subscription()
            try:
                object_id = _get_current_user_object_id(graph_client)
            except GraphErrorException:
                object_id = _get_object_id(graph_client, subscription=subscription)

        namespace.filters = "Properties/ownerObjectId eq '{}'".format(object_id)
def loganalytics_data_plane_client(cli_ctx, _):
    """Initialize Log Analytics data client for use with CLI."""
    from .vendored_sdks.loganalytics import LogAnalyticsDataClient
    from azure.cli.core._profile import Profile
    profile = Profile(cli_ctx=cli_ctx)
    cred, _, _ = profile.get_login_credentials(
        resource="https://api.loganalytics.io")
    return LogAnalyticsDataClient(cred)
Ejemplo n.º 20
0
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)
Ejemplo n.º 21
0
def _get_subscription_id_from_subscription(cli_ctx, subscription):  # pylint: disable=inconsistent-return-statements
    profile = Profile(cli_ctx=cli_ctx)
    subscriptions_list = profile.load_cached_subscriptions()
    for sub in subscriptions_list:
        if sub['id'] == subscription or sub['name'] == subscription:
            return sub['id']
    from azure.cli.core.util import CLIError
    raise CLIError("Subscription not found in the current context.")
Ejemplo n.º 22
0
def show_subscription(subscription=None, show_auth_for_sdk=None):
    import json
    profile = Profile()
    if not show_auth_for_sdk:
        return profile.get_subscription(subscription)

    # sdk-auth file should be in json format all the time, hence the print
    print(json.dumps(profile.get_sp_auth_info(subscription), indent=2))
Ejemplo n.º 23
0
def logout(username=None):
    """Log out to remove access to Azure subscriptions"""
    if _in_cloud_console():
        raise CLIError(_CLOUD_CONSOLE_ERR_TEMPLATE.format('logout'))

    profile = Profile()
    if not username:
        username = profile.get_current_account_user()
    profile.logout(username)
Ejemplo n.º 24
0
def logout(cmd, username=None):
    """Log out to remove access to Azure subscriptions"""
    if in_cloud_console():
        logger.warning(_CLOUD_CONSOLE_LOGOUT_WARNING)

    profile = Profile(cli_ctx=cmd.cli_ctx)
    if not username:
        username = profile.get_current_account_user()
    profile.logout(username)
Ejemplo n.º 25
0
def login(cmd, username=None, password=None, service_principal=None, tenant=None, allow_no_subscriptions=False,
          identity=False, use_device_code=False):
    """Log in to access Azure subscriptions"""
    from adal.adal_error import AdalError
    import requests

    # quick argument usage check
    if any([password, service_principal, tenant, allow_no_subscriptions]) and identity:
        raise CLIError("usage error: '--identity' is not applicable with other arguments")
    if any([password, service_principal, username, identity]) and use_device_code:
        raise CLIError("usage error: '--use-device-code' is not applicable with other arguments")

    interactive = False

    profile = Profile(cli_ctx=cmd.cli_ctx, async_persist=False)

    if identity:
        if in_cloud_console():
            return profile.find_subscriptions_in_cloud_console()
        return profile.find_subscriptions_in_vm_with_msi(username)
    elif in_cloud_console():  # tell users they might not need login
        logger.warning(_CLOUD_CONSOLE_LOGIN_WARNING)

    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,
            use_device_code=use_device_code,
            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
Ejemplo n.º 26
0
def create_keyvault(client, resource_group_name, vault_name, location=None, #pylint:disable=too-many-arguments
                    sku=SkuName.standard.value,
                    enabled_for_deployment=None,
                    enabled_for_disk_encryption=None,
                    enabled_for_template_deployment=None,
                    no_self_perms=None,
                    tags=None):
    from azure.mgmt.keyvault.models import VaultCreateOrUpdateParameters
    from azure.cli.core._profile import Profile, CLOUD
    from azure.graphrbac.models import GraphErrorException
    profile = Profile()
    cred, _, tenant_id = profile.get_login_credentials(
        resource=CLOUD.endpoints.active_directory_graph_resource_id)
    graph_client = GraphRbacManagementClient(cred,
                                             tenant_id,
                                             base_url=CLOUD.endpoints.active_directory_graph_resource_id) # pylint: disable=line-too-long
    subscription = profile.get_subscription()
    if no_self_perms:
        access_policies = []
    else:
        permissions = Permissions(keys=[KeyPermissions.get,
                                        KeyPermissions.create,
                                        KeyPermissions.delete,
                                        KeyPermissions.list,
                                        KeyPermissions.update,
                                        KeyPermissions.import_enum,
                                        KeyPermissions.backup,
                                        KeyPermissions.restore],
                                  secrets=[SecretPermissions.all],
                                  certificates=[CertificatePermissions.all])
        try:
            object_id = _get_current_user_object_id(graph_client)
        except GraphErrorException:
            object_id = _get_object_id(graph_client, subscription=subscription)
        if not object_id:
            raise CLIError('Cannot create vault.\n'
                           'Unable to query active directory for information '\
                           'about the current user.\n'
                           'You may try the --no-self-perms flag to create a vault'\
                           ' without permissions.')
        access_policies = [AccessPolicyEntry(tenant_id=tenant_id,
                                             object_id=object_id,
                                             permissions=permissions)]
    properties = VaultProperties(tenant_id=tenant_id,
                                 sku=Sku(name=sku),
                                 access_policies=access_policies,
                                 vault_uri=None,
                                 enabled_for_deployment=enabled_for_deployment,
                                 enabled_for_disk_encryption=enabled_for_disk_encryption,
                                 enabled_for_template_deployment=enabled_for_template_deployment)
    parameters = VaultCreateOrUpdateParameters(location=location,
                                               tags=tags,
                                               properties=properties)
    return client.create_or_update(resource_group_name=resource_group_name,
                                   vault_name=vault_name,
                                   parameters=parameters)
Ejemplo n.º 27
0
def logout(username=None):
    """Log out to remove access to Azure subscriptions"""
    if in_cloud_console():
        logger.warning(_CLOUD_CONSOLE_WARNING_TEMPLATE, 'logout')
        return

    profile = Profile()
    if not username:
        username = profile.get_current_account_user()
    profile.logout(username)
def applicationinsights_data_plane_client(cli_ctx, _, subscription=None):
    """Initialize Log Analytics data client for use with CLI."""
    from .vendored_sdks.applicationinsights import ApplicationInsightsDataClient
    from azure.cli.core._profile import Profile
    profile = Profile(cli_ctx=cli_ctx)
    cred, _, _ = profile.get_login_credentials(
        resource="https://api.applicationinsights.io",
        subscription_id=subscription
    )
    return ApplicationInsightsDataClient(cred)
Ejemplo n.º 29
0
def cf_dls_filesystem(account_name):
    from azure.datalake.store import core
    profile = Profile()
    subscription_id = None
    cred, subscription_id, _ = profile.get_login_credentials(
        subscription_id=subscription_id,
        resource=CLOUD.endpoints.active_directory_data_lake_resource_id)
    return core.AzureDLFileSystem(
        token=cred,
        store_name=account_name,
        url_suffix=CLOUD.suffixes.azure_datalake_store_file_system_endpoint)
Ejemplo n.º 30
0
def _graph_client_factory(cli_ctx, **_):
    from azure.cli.core._profile import Profile
    from azure.cli.core.commands.client_factory import configure_common_settings
    from azure.graphrbac import GraphRbacManagementClient
    profile = Profile(cli_ctx=cli_ctx)
    cred, _, tenant_id = profile.get_login_credentials(
        resource=cli_ctx.cloud.endpoints.active_directory_graph_resource_id)
    client = GraphRbacManagementClient(cred, tenant_id,
                                       base_url=cli_ctx.cloud.endpoints.active_directory_graph_resource_id)
    configure_common_settings(cli_ctx, client)
    return client
Ejemplo n.º 31
0
def _get_subscription_id():
    _, sub_id, _ = Profile().get_login_credentials(subscription_id=None)
    return sub_id
Ejemplo n.º 32
0
 def get_token(server, resource, scope):  # pylint: disable=unused-argument
     return Profile(cli_ctx=cli_ctx).get_login_credentials(resource)[0]._token_retriever()  # pylint: disable=protected-access
Ejemplo n.º 33
0
 def test_create_token_cache(self, mock_read_file):
     mock_read_file.return_value = []
     profile = Profile(use_global_creds_cache=False)
     cache = profile._creds_cache.adal_token_cache
     self.assertFalse(cache.read_items())
     self.assertTrue(mock_read_file.called)
Ejemplo n.º 34
0
def _get_profile():
    from azure.cli.core._profile import Profile
    return Profile()
Ejemplo n.º 35
0
    def _initialize_session(self):
        """
        Creates a session using available authentication type.

        Auth priority:
        1. Token Auth
        2. Tenant Auth
        3. Azure CLI Auth

        """

        # Only run once
        if self.credentials is not None:
            return

        tenant_auth_variables = [
            constants.ENV_TENANT_ID, constants.ENV_SUB_ID,
            constants.ENV_CLIENT_ID, constants.ENV_CLIENT_SECRET
        ]

        token_auth_variables = [
            constants.ENV_ACCESS_TOKEN, constants.ENV_SUB_ID
        ]

        msi_auth_variables = [
            constants.ENV_USE_MSI, constants.ENV_SUB_ID
        ]

        if self.authorization_file:
            self.credentials, self.subscription_id = self.load_auth_file(self.authorization_file)
            self.log.info("Creating session with authorization file")

        elif all(k in os.environ for k in token_auth_variables):
            # Token authentication
            self.credentials = BasicTokenAuthentication(
                token={
                    'access_token': os.environ[constants.ENV_ACCESS_TOKEN]
                })
            self.subscription_id = os.environ[constants.ENV_SUB_ID]
            self.log.info("Creating session with Token Authentication")
            self._is_token_auth = True

        elif all(k in os.environ for k in tenant_auth_variables):
            # Tenant (service principal) authentication
            self.credentials = ServicePrincipalCredentials(
                client_id=os.environ[constants.ENV_CLIENT_ID],
                secret=os.environ[constants.ENV_CLIENT_SECRET],
                tenant=os.environ[constants.ENV_TENANT_ID],
                resource=self.resource_namespace)
            self.subscription_id = os.environ[constants.ENV_SUB_ID]
            self.tenant_id = os.environ[constants.ENV_TENANT_ID]
            self.log.info("Creating session with Service Principal Authentication")

        elif all(k in os.environ for k in msi_auth_variables):
            # MSI authentication
            if constants.ENV_CLIENT_ID in os.environ:
                self.credentials = MSIAuthentication(
                    client_id=os.environ[constants.ENV_CLIENT_ID],
                    resource=self.resource_namespace)
            else:
                self.credentials = MSIAuthentication(
                    resource=self.resource_namespace)

            self.subscription_id = os.environ[constants.ENV_SUB_ID]
            self.log.info("Creating session with MSI Authentication")
        else:
            # Azure CLI authentication
            self._is_cli_auth = True
            (self.credentials,
             self.subscription_id,
             self.tenant_id) = Profile().get_login_credentials(
                resource=self.resource_namespace)
            self.log.info("Creating session with Azure CLI Authentication")

        # Let provided id parameter override everything else
        if self.subscription_id_override is not None:
            self.subscription_id = self.subscription_id_override

        self.log.info("Session using Subscription ID: %s" % self.subscription_id)

        if self.credentials is None:
            self.log.error('Unable to locate credentials for Azure session.')
Ejemplo n.º 36
0
def create_keyvault(
        client,
        resource_group_name,
        vault_name,
        location=None,  #pylint:disable=too-many-arguments
        sku=SkuName.standard.value,
        enabled_for_deployment=None,
        enabled_for_disk_encryption=None,
        enabled_for_template_deployment=None,
        no_self_perms=None,
        tags=None):
    from azure.mgmt.keyvault.models import VaultCreateOrUpdateParameters
    from azure.cli.core._profile import Profile, CLOUD
    from azure.graphrbac.models import GraphErrorException
    profile = Profile()
    cred, _, tenant_id = profile.get_login_credentials(
        resource=CLOUD.endpoints.active_directory_graph_resource_id)
    graph_client = GraphRbacManagementClient(cred,
                                             tenant_id,
                                             base_url=CLOUD.endpoints.active_directory_graph_resource_id)  # pylint: disable=line-too-long
    subscription = profile.get_subscription()
    if no_self_perms:
        access_policies = []
    else:
        permissions = Permissions(keys=[
            KeyPermissions.get, KeyPermissions.create, KeyPermissions.delete,
            KeyPermissions.list, KeyPermissions.update,
            KeyPermissions.import_enum, KeyPermissions.backup,
            KeyPermissions.restore
        ],
                                  secrets=[SecretPermissions.all],
                                  certificates=[CertificatePermissions.all])
        try:
            object_id = _get_current_user_object_id(graph_client)
        except GraphErrorException:
            object_id = _get_object_id(graph_client, subscription=subscription)
        if not object_id:
            raise CLIError('Cannot create vault.\n'
                           'Unable to query active directory for information '\
                           'about the current user.\n'
                           'You may try the --no-self-perms flag to create a vault'\
                           ' without permissions.')
        access_policies = [
            AccessPolicyEntry(tenant_id=tenant_id,
                              object_id=object_id,
                              permissions=permissions)
        ]
    properties = VaultProperties(
        tenant_id=tenant_id,
        sku=Sku(name=sku),
        access_policies=access_policies,
        vault_uri=None,
        enabled_for_deployment=enabled_for_deployment,
        enabled_for_disk_encryption=enabled_for_disk_encryption,
        enabled_for_template_deployment=enabled_for_template_deployment)
    parameters = VaultCreateOrUpdateParameters(location=location,
                                               tags=tags,
                                               properties=properties)
    return client.create_or_update(resource_group_name=resource_group_name,
                                   vault_name=vault_name,
                                   parameters=parameters)
Ejemplo n.º 37
0
def account_clear():
    """Clear all stored subscriptions. To clear individual, use 'logout'"""
    profile = Profile()
    profile.logout_all()
Ejemplo n.º 38
0
def _get_aad_token_after_challenge(cli_ctx, token_params, login_server,
                                   only_refresh_token, repository,
                                   artifact_repository, permission,
                                   is_diagnostics_context):
    authurl = urlparse(token_params['realm'])
    authhost = urlunparse(
        (authurl[0], authurl[1], '/oauth2/exchange', '', '', ''))

    from azure.cli.core._profile import Profile
    profile = Profile(cli_ctx=cli_ctx)

    # this might be a cross tenant scenario, so pass subscription to get_raw_token
    subscription = get_subscription_id(cli_ctx)
    creds, _, tenant = profile.get_raw_token(subscription=subscription)

    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    content = {
        'grant_type': 'access_token',
        'service': token_params['service'],
        'tenant': tenant,
        'access_token': creds[1]
    }

    response = requests.post(authhost,
                             urlencode(content),
                             headers=headers,
                             verify=(not should_disable_connection_verify()))

    if response.status_code not in [200]:
        from ._errors import CONNECTIVITY_REFRESH_TOKEN_ERROR
        if is_diagnostics_context:
            return CONNECTIVITY_REFRESH_TOKEN_ERROR.format_error_message(
                login_server, response.status_code)
        raise CLIError(
            CONNECTIVITY_REFRESH_TOKEN_ERROR.format_error_message(
                login_server, response.status_code).get_error_message())

    refresh_token = loads(response.content.decode("utf-8"))["refresh_token"]
    if only_refresh_token:
        return refresh_token

    authhost = urlunparse(
        (authurl[0], authurl[1], '/oauth2/token', '', '', ''))

    if repository:
        scope = 'repository:{}:{}'.format(repository, permission)
    elif artifact_repository:
        scope = 'artifact-repository:{}:{}'.format(artifact_repository,
                                                   permission)
    else:
        # catalog only has * as permission, even for a read operation
        scope = 'registry:catalog:*'

    content = {
        'grant_type': 'refresh_token',
        'service': login_server,
        'scope': scope,
        'refresh_token': refresh_token
    }
    response = requests.post(authhost,
                             urlencode(content),
                             headers=headers,
                             verify=(not should_disable_connection_verify()))

    if response.status_code not in [200]:
        from ._errors import CONNECTIVITY_ACCESS_TOKEN_ERROR
        if is_diagnostics_context:
            return CONNECTIVITY_ACCESS_TOKEN_ERROR.format_error_message(
                login_server, response.status_code)
        raise CLIError(
            CONNECTIVITY_ACCESS_TOKEN_ERROR.format_error_message(
                login_server, response.status_code).get_error_message())

    return loads(response.content.decode("utf-8"))["access_token"]
Ejemplo n.º 39
0
def send_raw_request(
        cli_ctx,
        method,
        url,
        headers=None,
        uri_parameters=None,  # pylint: disable=too-many-locals,too-many-branches,too-many-statements
        body=None,
        skip_authorization_header=False,
        resource=None,
        output_file=None,
        generated_client_request_id_name='x-ms-client-request-id'):
    import uuid
    from requests import Session, Request
    from requests.structures import CaseInsensitiveDict

    result = CaseInsensitiveDict()
    for s in headers or []:
        try:
            temp = shell_safe_json_parse(s)
            result.update(temp)
        except CLIError:
            key, value = s.split('=', 1)
            result[key] = value
    headers = result

    # If Authorization header is already provided, don't bother with the token
    if 'Authorization' in headers:
        skip_authorization_header = True

    # Handle User-Agent
    agents = [get_az_user_agent()]

    # Borrow AZURE_HTTP_USER_AGENT from msrest
    # https://github.com/Azure/msrest-for-python/blob/4cc8bc84e96036f03b34716466230fb257e27b36/msrest/pipeline/universal.py#L70
    _ENV_ADDITIONAL_USER_AGENT = 'AZURE_HTTP_USER_AGENT'
    import os
    if _ENV_ADDITIONAL_USER_AGENT in os.environ:
        agents.append(os.environ[_ENV_ADDITIONAL_USER_AGENT])

    # Custom User-Agent provided as command argument
    if 'User-Agent' in headers:
        agents.append(headers['User-Agent'])
    headers['User-Agent'] = ' '.join(agents)

    if generated_client_request_id_name:
        headers[generated_client_request_id_name] = str(uuid.uuid4())

    # try to figure out the correct content type
    if body:
        try:
            _ = shell_safe_json_parse(body)
            if 'Content-Type' not in headers:
                headers['Content-Type'] = 'application/json'
        except Exception:  # pylint: disable=broad-except
            pass

    # add telemetry
    headers['CommandName'] = cli_ctx.data['command']
    if cli_ctx.data.get('safe_params'):
        headers['ParameterSetName'] = ' '.join(cli_ctx.data['safe_params'])

    result = {}
    for s in uri_parameters or []:
        try:
            temp = shell_safe_json_parse(s)
            result.update(temp)
        except CLIError:
            key, value = s.split('=', 1)
            result[key] = value
    uri_parameters = result or None

    endpoints = cli_ctx.cloud.endpoints
    # If url is an ARM resource ID, like /subscriptions/xxx/resourcegroups/xxx?api-version=2019-07-01,
    # default to Azure Resource Manager.
    # https://management.azure.com + /subscriptions/xxx/resourcegroups/xxx?api-version=2019-07-01
    if '://' not in url:
        url = endpoints.resource_manager.rstrip('/') + url

    # Replace common tokens with real values. It is for smooth experience if users copy and paste the url from
    # Azure Rest API doc
    from azure.cli.core._profile import Profile
    profile = Profile(cli_ctx=cli_ctx)
    if '{subscriptionId}' in url:
        url = url.replace(
            '{subscriptionId}', cli_ctx.data['subscription_id']
            or profile.get_subscription_id())

    # Prepare the Bearer token for `Authorization` header
    if not skip_authorization_header and url.lower().startswith('https://'):
        # Prepare `resource` for `get_raw_token`
        if not resource:
            # If url starts with ARM endpoint, like `https://management.azure.com/`,
            # use `active_directory_resource_id` for resource, like `https://management.core.windows.net/`.
            # This follows the same behavior as `azure.cli.core.commands.client_factory._get_mgmt_service_client`
            if url.lower().startswith(endpoints.resource_manager.rstrip('/')):
                resource = endpoints.active_directory_resource_id
            else:
                from azure.cli.core.cloud import CloudEndpointNotSetException
                for p in [x for x in dir(endpoints) if not x.startswith('_')]:
                    try:
                        value = getattr(endpoints, p)
                    except CloudEndpointNotSetException:
                        continue
                    if isinstance(value,
                                  six.string_types) and url.lower().startswith(
                                      value.lower()):
                        resource = value
                        break
        if resource:
            # Prepare `subscription` for `get_raw_token`
            # If this is an ARM request, try to extract subscription ID from the URL.
            # But there are APIs which don't require subscription ID, like /subscriptions, /tenants
            # TODO: In the future when multi-tenant subscription is supported, we won't be able to uniquely identify
            #   the token from subscription anymore.
            token_subscription = None
            if url.lower().startswith(endpoints.resource_manager.rstrip('/')):
                token_subscription = _extract_subscription_id(url)
            if token_subscription:
                logger.debug(
                    'Retrieving token for resource %s, subscription %s',
                    resource, token_subscription)
                token_info, _, _ = profile.get_raw_token(
                    resource, subscription=token_subscription)
            else:
                logger.debug('Retrieving token for resource %s', resource)
                token_info, _, _ = profile.get_raw_token(resource)
            token_type, token, _ = token_info
            headers = headers or {}
            headers['Authorization'] = '{} {}'.format(token_type, token)
        else:
            logger.warning(
                "Can't derive appropriate Azure AD resource from --url to acquire an access token. "
                "If access token is required, use --resource to specify the resource"
            )

    # https://requests.readthedocs.io/en/latest/user/advanced/#prepared-requests
    s = Session()
    req = Request(method=method,
                  url=url,
                  headers=headers,
                  params=uri_parameters,
                  data=body)
    prepped = s.prepare_request(req)

    # Merge environment settings into session
    settings = s.merge_environment_settings(
        prepped.url, {}, None, not should_disable_connection_verify(), None)
    _log_request(prepped)
    r = s.send(prepped, **settings)
    _log_response(r)

    if not r.ok:
        reason = r.reason
        if r.text:
            reason += '({})'.format(r.text)
        raise CLIError(reason)
    if output_file:
        with open(output_file, 'wb') as fd:
            for chunk in r.iter_content(chunk_size=128):
                fd.write(chunk)
    return r
Ejemplo n.º 40
0
 def get_token(server, resource, scope):  # pylint: disable=unused-argument
     return Profile(cli_ctx=cli_ctx).get_raw_token(resource)[0]
Ejemplo n.º 41
0
class MediaV2Client():
    """ Media V2 Client """
    def __init__(self, cli_ctx, resource_group_name, account_name):
        from azure.cli.core._profile import Profile
        self.profile = Profile(cli_ctx=cli_ctx)
        self._old_rp_api_version = '2015-10-01'
        self.v2_media_api_resource = cli_ctx.cloud.endpoints.media_resource_id
        self.api_endpoint = self._get_v2_api_endpoint(cli_ctx,
                                                      resource_group_name,
                                                      account_name)
        self.access_token = self._get_v2_access_token()

    def _get_v2_api_endpoint(self, cli_ctx, resource_group_name, account_name):
        from msrestazure.tools import resource_id
        from azure.cli.command_modules.ams._sdk_utils import (
            get_media_namespace, get_media_type)

        access_token = self.profile.get_raw_token()[0][2].get('accessToken')

        media_old_rp_url = resource_id(
            subscription=get_subscription_id(cli_ctx),
            resource_group=resource_group_name,
            namespace=get_media_namespace(),
            type=get_media_type(),
            name=account_name) + '?api-version={}'.format(
                self._old_rp_api_version)

        media_service_res = requests.get(
            cli_ctx.cloud.endpoints.resource_manager.rstrip('/') +
            media_old_rp_url,
            headers={'Authorization': 'Bearer {}'.format(access_token)})
        if not media_service_res.ok:
            err_info = 'Request to 2015-10-01 Media API failed.'
            res_text = json.loads(media_service_res.text)
            if res_text is not None and res_text.get('error') is not None:
                err_info = res_text.get('error').get('message')
            raise CLIError(err_info)

        media_service = media_service_res.json()
        api_endpoints = media_service.get('properties').get('apiEndpoints')
        api_endpoint = next(
            (x for x in api_endpoints if x.get('majorVersion') == '2'),
            api_endpoints[0])
        if not api_endpoint:
            raise CLIError('v2 Media API endpoint was not found.')
        return api_endpoint

    def _get_v2_access_token(self):
        # pylint: disable=protected-access
        access_token = self.profile.get_raw_token(
            resource=self.v2_media_api_resource)[0][2].get('accessToken')
        return access_token

    def set_mru(self, account_id, count, type):
        headers = {}
        headers['Authorization'] = 'Bearer {}'.format(self.access_token)
        headers['Content-Type'] = 'application/json;odata=verbose'
        headers['Accept'] = 'application/json;odata=verbose'

        url_request_template = "{}EncodingReservedUnitTypes(guid'{}')?api-version=2.19"
        response = requests.put(
            url_request_template.format(self.api_endpoint.get('endpoint'),
                                        account_id),
            headers=headers,
            data='{{"ReservedUnitType":{}, "CurrentReservedUnits":{}}}'.format(
                type, count))

        if not response.ok:
            err_info = 'No error information available'
            if json.loads(response.text) is not None and json.loads(
                    response.text).get('error') is not None:
                err_info = json.loads(
                    response.text).get('error').get('message').get('value')
            raise CLIError(
                'Request to EncodingReservedUnitTypes v2 API endpoint failed. '
                + err_info)

    def get_mru(self):
        headers = {}
        headers['Authorization'] = 'Bearer {}'.format(self.access_token)
        headers['Content-Type'] = 'application/json;odata=minimalmetadata'
        headers['Accept'] = 'application/json;odata=minimalmetadata'
        headers['Accept-Charset'] = 'UTF-8'

        url_request_template = '{}EncodingReservedUnitTypes?api-version=2.19'
        response = requests.get(url_request_template.format(
            self.api_endpoint.get('endpoint')),
                                headers=headers)
        if not response.ok:
            raise CLIError(
                'Request to EncodingReservedUnitTypes v2 API endpoint failed.')
        return response.json().get('value')[0]
Ejemplo n.º 42
0
def set_active_subscription(subscription):
    """Set the current subscription"""
    if not id:
        raise CLIError('Please provide subscription id or unique name.')
    profile = Profile()
    profile.set_active_subscription(subscription)
Ejemplo n.º 43
0
def acs_create(resource_group_name,
               deployment_name,
               name,
               ssh_key_value,
               dns_name_prefix=None,
               content_version=None,
               admin_username="******",
               agent_count="3",
               agent_vm_size="Standard_D2_v2",
               location=None,
               master_count="3",
               orchestrator_type="dcos",
               service_principal=None,
               client_secret=None,
               tags=None,
               custom_headers=None,
               raw=False,
               **operation_config):  #pylint: disable=too-many-locals
    """Create a new Acs.
    :param resource_group_name: The name of the resource group. The name
     is case insensitive.
    :type resource_group_name: str
    :param deployment_name: The name of the deployment.
    :type deployment_name: str
    :param dns_name_prefix: Sets the Domain name prefix for the cluster.
     The concatenation of the domain name and the regionalized DNS zone
     make up the fully qualified domain name associated with the public
     IP address.
    :type dns_name_prefix: str
    :param name: Resource name for the container service.
    :type name: str
    :param ssh_key_value: Configure all linux machines with the SSH RSA
     public key string.  Your key should include three parts, for example
    'ssh-rsa AAAAB...snip...UcyupgH azureuser@linuxvm
    :type ssh_key_value: str
    :param content_version: If included it must match the ContentVersion
     in the template.
    :type content_version: str
    :param admin_username: User name for the Linux Virtual Machines.
    :type admin_username: str
    :param agent_count: The number of agents for the cluster.  Note, for
     DC/OS clusters you will also get 1 or 2 public agents in addition to
     these seleted masters.
    :type agent_count: str
    :param agent_vm_size: The size of the Virtual Machine.
    :type agent_vm_size: str
    :param location: Location for VM resources.
    :type location: str
    :param master_count: The number of DC/OS masters for the cluster.
    :type master_count: str
    :param orchestrator_type: The type of orchestrator used to manage the
     applications on the cluster. Possible values include: 'dcos', 'swarm'
    :type orchestrator_type: str or :class:`orchestratorType
     <Default.models.orchestratorType>`
    :param service_principal: The service principal used for cluster authentication
     to Azure APIs. If not specified, it is created for you and stored in the
     ${HOME}/.azure directory.
    :type service_principal: str
    :param client_secret: The secret associated with the service principal. If
     --service-principal is specified, then secret should also be specified. If
     --service-principal is not specified, the secret is auto-generated for you
     and stored in ${HOME}/.azure/ directory.
    :param tags: Tags object.
    :type tags: object
    :param dict custom_headers: headers that will be added to the request
    :param bool raw: returns the direct response alongside the
     deserialized response
    :rtype:
    :class:`AzureOperationPoller<msrestazure.azure_operation.AzureOperationPoller>`
     instance that returns :class:`DeploymentExtended
     <Default.models.DeploymentExtended>`
    :rtype: :class:`ClientRawResponse<msrest.pipeline.ClientRawResponse>`
     if raw=true
    :raises: :class:`CloudError<msrestazure.azure_exceptions.CloudError>`
    """
    if not dns_name_prefix:
        # Use subscription id to provide uniqueness and prevent DNS name clashes
        _, subscription_id, _ = Profile().get_login_credentials(
            subscription_id=None)
        dns_name_prefix = '{}-{}-{}'.format(name, resource_group_name,
                                            subscription_id[0:6])

    register_providers()
    groups = _resource_client_factory().resource_groups
    # Just do the get, we don't need the result, it will error out if the group doesn't exist.
    groups.get(resource_group_name)

    if orchestrator_type == 'Kubernetes' or orchestrator_type == 'kubernetes':
        from azure.cli.command_modules.role.custom import _graph_client_factory
        # TODO: This really needs to be broken out and unit tested.
        client = _graph_client_factory()
        if not service_principal:
            # --service-principal not specified, try to load it from local disk
            principalObj = load_acs_service_principal()
            if principalObj:
                service_principal = principalObj.get('service_principal')
                client_secret = principalObj.get('client_secret')
                _validate_service_principal(client, service_principal)
            else:
                # Nothing to load, make one.
                if not client_secret:
                    client_secret = binascii.b2a_hex(
                        os.urandom(10)).decode('utf-8')
                salt = binascii.b2a_hex(os.urandom(3)).decode('utf-8')
                url = 'http://{}.{}.{}.cloudapp.azure.com'.format(
                    salt, dns_name_prefix, location)

                service_principal = _build_service_principal(
                    client, name, url, client_secret)
                logger.info('Created a service principal: %s',
                            service_principal)
                store_acs_service_principal(client_secret, service_principal)
            # Either way, update the role assignment, this fixes things if we fail part-way through
            _add_role_assignment('Owner', service_principal)
        else:
            # --service-principal specfied, validate --client-secret was too
            if not client_secret:
                raise CLIError(
                    '--client-secret is required if --service-principal is specified'
                )
            _validate_service_principal(client, service_principal)
        return _create_kubernetes(resource_group_name,
                                  deployment_name,
                                  dns_name_prefix,
                                  name,
                                  ssh_key_value,
                                  admin_username=admin_username,
                                  agent_count=agent_count,
                                  agent_vm_size=agent_vm_size,
                                  location=location,
                                  service_principal=service_principal,
                                  client_secret=client_secret)

    ops = get_mgmt_service_client(ACSClient).acs
    return ops.create_or_update(resource_group_name,
                                deployment_name,
                                dns_name_prefix,
                                name,
                                ssh_key_value,
                                content_version=content_version,
                                admin_username=admin_username,
                                agent_count=agent_count,
                                agent_vm_size=agent_vm_size,
                                location=location,
                                master_count=master_count,
                                orchestrator_type=orchestrator_type,
                                tags=tags,
                                custom_headers=custom_headers,
                                raw=raw,
                                operation_config=operation_config)
Ejemplo n.º 44
0
def load_subscriptions(all_clouds=False, refresh=False):
    profile = Profile()
    if refresh:
        subscriptions = profile.refresh_accounts()
    subscriptions = profile.load_cached_subscriptions(all_clouds)
    return subscriptions
Ejemplo n.º 45
0
def _get_data_credentials(cli_ctx, subscription_id=None):
    from azure.cli.core._profile import Profile
    profile = Profile(cli_ctx=cli_ctx)
    creds, _, _ = profile.get_login_credentials(subscription_id=subscription_id, resource="https://quantum.microsoft.com")
    return creds
Ejemplo n.º 46
0
def get_subscription_id(cli_ctx):
    from azure.cli.core._profile import Profile
    if not cli_ctx.data.get('subscription_id'):
        cli_ctx.data['subscription_id'] = Profile(
            cli_ctx=cli_ctx).get_subscription_id()
    return cli_ctx.data['subscription_id']
Ejemplo n.º 47
0
    def _authenticate(self):
        try:
            keyvault_client_id = self._auth_params.get('keyvault_client_id')
            keyvault_secret_id = self._auth_params.get('keyvault_secret_id')

            # If user provided KeyVault secret, we will pull auth params information from it
            if keyvault_secret_id:
                self._auth_params.update(
                    json.loads(
                        get_keyvault_secret(keyvault_client_id,
                                            keyvault_secret_id)))

            client_id = self._auth_params.get('client_id')
            client_secret = self._auth_params.get('client_secret')
            access_token = self._auth_params.get('access_token')
            tenant_id = self._auth_params.get('tenant_id')
            use_msi = self._auth_params.get('use_msi')
            subscription_id = self._auth_params.get('subscription_id')

            if access_token and subscription_id:
                log.info("Creating session with Token Authentication")
                self.subscription_id = subscription_id
                self.credentials = BasicTokenAuthentication(
                    token={'access_token': access_token})
                self._is_token_auth = True

            elif client_id and client_secret and tenant_id and subscription_id:
                log.info(
                    "Creating session with Service Principal Authentication")
                self.subscription_id = subscription_id
                self.credentials = ServicePrincipalCredentials(
                    client_id=client_id,
                    secret=client_secret,
                    tenant=tenant_id,
                    resource=self.resource_namespace)
                self.tenant_id = tenant_id

            elif use_msi and subscription_id:
                log.info("Creating session with MSI Authentication")
                self.subscription_id = subscription_id
                if client_id:
                    self.credentials = MSIAuthentication(
                        client_id=client_id, resource=self.resource_namespace)
                else:
                    self.credentials = MSIAuthentication(
                        resource=self.resource_namespace)

            elif self._auth_params.get('enable_cli_auth'):
                log.info("Creating session with Azure CLI Authentication")
                self._is_cli_auth = True
                (self.credentials, self.subscription_id,
                 self.tenant_id) = Profile().get_login_credentials(
                     resource=self.resource_namespace)
            log.info("Session using Subscription ID: %s" %
                     self.subscription_id)

        except AuthenticationError as e:
            log.error('Azure Authentication Failure\n'
                      'Error: {0}'.format(
                          json.dumps(e.inner_exception.error_response,
                                     indent=2)))
            sys.exit(1)
        except HTTPError as e:
            if keyvault_client_id and keyvault_secret_id:
                log.error(
                    'Azure Authentication Failure\n'
                    'Error: Cannot retrieve SP credentials from the Key Vault '
                    '(KV uses MSI to access) with client id: {0}'.format(
                        keyvault_client_id))
            elif use_msi:
                log.error(
                    'Azure Authentication Failure\n'
                    'Error: Could not authenticate using managed service identity {0}'
                    .format(client_id if client_id else '(system identity)'))
            else:
                log.error('Azure Authentication Failure: %s' % e.response)
            sys.exit(1)
        except CLIError as e:
            log.error(
                'Azure Authentication Failure\n'
                'Error: Could not authenticate with Azure CLI credentials: {0}'
                .format(e))
            sys.exit(1)
        except Exception as e:
            log.error('Azure Authentication Failure\n' 'Error: {0}'.format(e))
            sys.exit(1)
Ejemplo n.º 48
0
def fzf_customer(cmd, fzf_filter=None, no_default=False):
    """
    Use fzf to quickly filter and select your current customer.
    """
    from azure.cli.core._profile import Profile
    from azure.cli.core.api import load_subscriptions

    subscriptions = load_subscriptions(cmd.cli_ctx,
                                       all_clouds=False,
                                       refresh=False)
    if "AZ_FZF_CUSTOMER_SUBSCRIPTIONS" not in os.environ:
        raise CLIError('Specify the path to subscriptions.yml in '
                       'AZ_FZF_CUSTOMER_SUBSCRIPTIONS environment variable')

    subscriptions_yml_path = os.environ['AZ_FZF_CUSTOMER_SUBSCRIPTIONS']
    if not os.path.isfile(subscriptions_yml_path):
        raise CLIError('"%s" is not a file' % subscriptions_yml_path)

    customer_subscriptions = {}
    try:
        with open(subscriptions_yml_path) as subscriptions_yml:
            customer_subscriptions = yaml.safe_load(subscriptions_yml)
    except yaml.YAMLError as exc:
        error_msg = ""
        if hasattr(exc, 'problem_mark'):
            if exc.context != None:
                error_msg = ('  parser says\n' + str(exc.problem_mark) +
                             '\n  ' + str(exc.problem) + ' ' +
                             str(exc.context) +
                             '\nPlease correct data and retry.')
            else:
                error_msg = ('  parser says\n' + str(exc.problem_mark) +
                             '\n  ' + str(exc.problem) +
                             '\nPlease correct data and retry.')
        else:
            error_msg = ("Something went wrong while parsing yaml file")
        raise CLIError('Error parsing %s\n%s' %
                       (subscriptions_yml_path, error_msg))

    except OSError as exc:
        print()
        raise CLIError('Something went wrong while opening "%s": %s' %
                       (subscriptions_yml_path, exc))

    if not customer_subscriptions:
        raise CLIError('No subscriptions found in subscriptions.yml')

    headers = ["Customer", "Name", "ID"]
    subs_sorted = sorted(customer_subscriptions, key=lambda i: i["customer"])
    subs_list = [[sub["customer"], sub["name"], sub["id"]]
                 for sub in subs_sorted]
    result = _fzf(_fzf_table(subs_list, headers),
                  header_lines=2,
                  fzf_filter=fzf_filter)

    if result:
        subscription = result.split('|')[-2].strip()
        if not no_default:
            LOGGER.info('setting default customer')
            Profile(cli_ctx=cmd.cli_ctx).set_active_subscription(subscription)
        return next((s for s in subscriptions if s["id"] == subscription))

    return None
Ejemplo n.º 49
0
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,
                                      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 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
    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
                    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
Ejemplo n.º 50
0
 def test_endpoint_none(self):
     with self.assertRaises(CloudEndpointNotSetException):
         profile = Profile()
         profile.get_login_credentials()