Пример #1
0
    def test_get_az_user_agent(self):
        from azure.cli.core._environment import _ENV_AZ_INSTALLER
        with mock.patch.dict('os.environ', {_ENV_AZ_INSTALLER: 'PIP'}):
            actual = get_az_user_agent()
            self.assertEqual(actual, 'AZURECLI/7.8.9 (PIP)')

        actual = get_az_user_agent()
        self.assertEqual(actual, 'AZURECLI/7.8.9')
Пример #2
0
def _get_basic_headers(params):
    import urllib3
    from azure.cli.core.util import (should_disable_connection_verify,
                                     get_az_user_agent)

    user_name, password = _get_site_credential(params.cmd.cli_ctx,
                                               params.resource_group_name,
                                               params.webapp_name, params.slot)

    if params.src_path:
        content_type = 'application/octet-stream'
    elif params.src_url:
        content_type = 'application/json'
    else:
        raise CLIError(
            'Unable to determine source location of the artifact being deployed'
        )

    headers = urllib3.util.make_headers(
        basic_auth='{0}:{1}'.format(user_name, password))
    headers['Cache-Control'] = 'no-cache'
    headers['User-Agent'] = get_az_user_agent()
    headers['Content-Type'] = content_type

    return headers
Пример #3
0
def configure_common_settings(cli_ctx, client):
    client = _debug.change_ssl_cert_verification(client)

    client.config.enable_http_logger = True

    client.config.add_user_agent(get_az_user_agent())

    try:
        command_ext_name = cli_ctx.data['command_extension_name']
        if command_ext_name:
            client.config.add_user_agent(
                "CliExtension/{}".format(command_ext_name))
    except KeyError:
        pass

    for header, value in cli_ctx.data['headers'].items():
        # We are working with the autorest team to expose the add_header functionality of the generated client to avoid
        # having to access private members
        client._client.add_header(header, value)  # pylint: disable=protected-access

    command_name_suffix = ';completer-request' if cli_ctx.data[
        'completer_active'] else ''
    # pylint: disable=protected-access
    client._client.add_header(
        'CommandName', "{}{}".format(cli_ctx.data['command'],
                                     command_name_suffix))
    if cli_ctx.data.get('safe_params'):
        client._client.add_header('ParameterSetName',
                                  ' '.join(cli_ctx.data['safe_params']))
    client.config.generate_client_request_id = 'x-ms-client-request-id' not in cli_ctx.data[
        'headers']
Пример #4
0
def configure_common_settings_track2(cli_ctx):
    client_kwargs = {}

    client_kwargs.update(_debug.change_ssl_cert_verification_track2())

    client_kwargs['logging_enable'] = True
    client_kwargs['user_agent'] = get_az_user_agent()

    try:
        command_ext_name = cli_ctx.data['command_extension_name']
        if command_ext_name:
            client_kwargs['user_agent'] += "CliExtension/{}".format(
                command_ext_name)
    except KeyError:
        pass

    headers = dict(cli_ctx.data['headers'])
    command_name_suffix = ';completer-request' if cli_ctx.data[
        'completer_active'] else ''
    headers['CommandName'] = "{}{}".format(cli_ctx.data['command'],
                                           command_name_suffix)
    if cli_ctx.data.get('safe_params'):
        headers['ParameterSetName'] = ' '.join(cli_ctx.data['safe_params'])
    client_kwargs['headers'] = headers

    if 'x-ms-client-request-id' in cli_ctx.data['headers']:
        client_kwargs['request_id'] = cli_ctx.data['headers'][
            'x-ms-client-request-id']

    return client_kwargs
Пример #5
0
    def _add_headers(request):
        agents = [request.headers['User-Agent'], get_az_user_agent()]
        request.headers['User-Agent'] = ' '.join(agents)

        try:
            request.headers.update(cli_ctx.data['headers'])
        except KeyError:
            pass
def _get_zip_deploy_headers(username, password, cmd_mock_client):
    from urllib3.util import make_headers
    from azure.cli.core.util import get_az_user_agent

    headers = make_headers(basic_auth='{0}:{1}'.format(username, password))
    headers['Content-Type'] = 'application/octet-stream'
    headers['Cache-Control'] = 'no-cache'
    headers['User-Agent'] = get_az_user_agent()
    headers['x-ms-client-request-id'] = cmd_mock_client.data['headers'][
        'x-ms-client-request-id']
    return headers
Пример #7
0
def _prepare_client_kwargs_track2(cli_ctx):
    """Prepare kwargs for Track 2 SDK client."""
    client_kwargs = {}

    # Prepare connection_verify to change SSL verification behavior, used by ConnectionConfiguration
    client_kwargs.update(_debug.change_ssl_cert_verification_track2())

    # Prepare User-Agent header, used by UserAgentPolicy
    client_kwargs['user_agent'] = get_az_user_agent()

    try:
        command_ext_name = cli_ctx.data['command_extension_name']
        if command_ext_name:
            client_kwargs['user_agent'] += "CliExtension/{}".format(
                command_ext_name)
    except KeyError:
        pass

    # Prepare custom headers, used by HeadersPolicy
    headers = dict(cli_ctx.data['headers'])

    # - Prepare CommandName header
    command_name_suffix = ';completer-request' if cli_ctx.data[
        'completer_active'] else ''
    headers['CommandName'] = "{}{}".format(cli_ctx.data['command'],
                                           command_name_suffix)

    # - Prepare ParameterSetName header
    if cli_ctx.data.get('safe_params'):
        headers['ParameterSetName'] = ' '.join(cli_ctx.data['safe_params'])

    client_kwargs['headers'] = headers

    # Prepare x-ms-client-request-id header, used by RequestIdPolicy
    if 'x-ms-client-request-id' in cli_ctx.data['headers']:
        client_kwargs['request_id'] = cli_ctx.data['headers'][
            'x-ms-client-request-id']

    # Replace NetworkTraceLoggingPolicy to redact 'Authorization' and 'x-ms-authorization-auxiliary' headers.
    #   NetworkTraceLoggingPolicy: log raw network trace, with all headers.
    from azure.cli.core.sdk.policies import SafeNetworkTraceLoggingPolicy
    client_kwargs['logging_policy'] = SafeNetworkTraceLoggingPolicy()

    # Disable ARMHttpLoggingPolicy.
    #   ARMHttpLoggingPolicy: Only log allowed information.
    from azure.core.pipeline.policies import SansIOHTTPPolicy
    client_kwargs['http_logging_policy'] = SansIOHTTPPolicy()

    return client_kwargs
Пример #8
0
def configure_common_settings(cli_ctx, client):
    client = _debug.change_ssl_cert_verification(client)

    client.config.enable_http_logger = True

    client.config.add_user_agent(get_az_user_agent())

    try:
        command_ext_name = cli_ctx.data['command_extension_name']
        if command_ext_name:
            client.config.add_user_agent(
                "CliExtension/{}".format(command_ext_name))
    except KeyError:
        pass

    # Prepare CommandName header
    command_name_suffix = ';completer-request' if cli_ctx.data[
        'completer_active'] else ''
    cli_ctx.data['headers']['CommandName'] = "{}{}".format(
        cli_ctx.data['command'], command_name_suffix)

    # Prepare ParameterSetName header
    if cli_ctx.data.get('safe_params'):
        cli_ctx.data['headers']['ParameterSetName'] = ' '.join(
            cli_ctx.data['safe_params'])

    # Prepare x-ms-client-request-id header
    client.config.generate_client_request_id = 'x-ms-client-request-id' not in cli_ctx.data[
        'headers']

    logger.debug("Adding custom headers to the client:")

    for header, value in cli_ctx.data['headers'].items():
        # msrest doesn't print custom headers in debug log, so CLI should do that
        logger.debug("    '%s': '%s'", header, value)
        # We are working with the autorest team to expose the add_header functionality of the generated client to avoid
        # having to access private members
        client._client.add_header(header, value)  # pylint: disable=protected-access
Пример #9
0
    def test_send_raw_requests(self, send_mock, get_raw_token_mock):
        if 'AZURE_HTTP_USER_AGENT' in os.environ:
            del os.environ[
                'AZURE_HTTP_USER_AGENT']  # Clear env var possibly added by DevOps

        return_val = mock.MagicMock()
        return_val.is_ok = True
        send_mock.return_value = return_val
        get_raw_token_mock.return_value = ("Bearer", "eyJ0eXAiOiJKV1",
                                           None), None, None

        cli_ctx = DummyCli()
        cli_ctx.data = {'command': 'rest', 'safe_params': ['method', 'uri']}
        test_arm_active_directory_resource_id = 'https://management.core.windows.net/'
        test_arm_endpoint = 'https://management.azure.com/'
        subscription_id = '00000001-0000-0000-0000-000000000000'
        arm_resource_id = '/subscriptions/{}/resourcegroups/02?api-version=2019-07-01'.format(
            subscription_id)
        full_arm_rest_url = test_arm_endpoint.rstrip('/') + arm_resource_id
        test_body = '{"b1": "v1"}'

        expected_header = {
            'User-Agent': get_az_user_agent(),
            'Accept-Encoding': 'gzip, deflate',
            'Accept': '*/*',
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'CommandName': 'rest',
            'ParameterSetName': 'method uri',
            'Content-Length': '12'
        }
        expected_header_with_auth = expected_header.copy()
        expected_header_with_auth['Authorization'] = 'Bearer eyJ0eXAiOiJKV1'

        # Test basic usage
        # Mock Put Blob https://docs.microsoft.com/en-us/rest/api/storageservices/put-blob
        # Authenticate with service SAS https://docs.microsoft.com/en-us/rest/api/storageservices/create-service-sas
        sas_token = ['sv=2019-02-02', '{"srt": "s"}', "{'ss': 'bf'}"]
        send_raw_request(
            cli_ctx,
            'PUT',
            'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30',
            uri_parameters=sas_token,
            body=test_body,
            generated_client_request_id_name=None)

        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args.args[1]
        self.assertEqual(request.method, 'PUT')
        self.assertEqual(
            request.url,
            'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30&sv=2019-02-02&srt=s&ss=bf'
        )
        self.assertEqual(request.body, '{"b1": "v1"}')
        # Verify no Authorization header
        self.assertDictEqual(dict(request.headers), expected_header)
        self.assertEqual(send_mock.call_args.kwargs["verify"],
                         not should_disable_connection_verify())

        # Test Authorization header is skipped
        send_raw_request(cli_ctx,
                         'GET',
                         full_arm_rest_url,
                         body=test_body,
                         skip_authorization_header=True,
                         generated_client_request_id_name=None)

        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args.args[1]
        self.assertDictEqual(dict(request.headers), expected_header)

        # Test Authorization header is already provided
        send_raw_request(cli_ctx,
                         'GET',
                         full_arm_rest_url,
                         body=test_body,
                         headers={'Authorization=Basic ABCDE'},
                         generated_client_request_id_name=None)

        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args.args[1]
        self.assertDictEqual(dict(request.headers), {
            **expected_header, 'Authorization': 'Basic ABCDE'
        })

        # Test Authorization header is auto appended
        send_raw_request(cli_ctx,
                         'GET',
                         full_arm_rest_url,
                         body=test_body,
                         generated_client_request_id_name=None)

        get_raw_token_mock.assert_called_with(
            mock.ANY,
            test_arm_active_directory_resource_id,
            subscription=subscription_id)
        request = send_mock.call_args.args[1]
        self.assertDictEqual(dict(request.headers), expected_header_with_auth)

        # Test ARM Subscriptions - List
        # https://docs.microsoft.com/en-us/rest/api/resources/subscriptions/list
        # /subscriptions?api-version=2020-01-01
        send_raw_request(cli_ctx,
                         'GET',
                         '/subscriptions?api-version=2020-01-01',
                         body=test_body,
                         generated_client_request_id_name=None)

        get_raw_token_mock.assert_called_with(
            mock.ANY, test_arm_active_directory_resource_id)
        request = send_mock.call_args.args[1]
        self.assertEqual(
            request.url,
            test_arm_endpoint.rstrip('/') +
            '/subscriptions?api-version=2020-01-01')
        self.assertDictEqual(dict(request.headers), expected_header_with_auth)

        # Test ARM Tenants - List
        # https://docs.microsoft.com/en-us/rest/api/resources/tenants/list
        # /tenants?api-version=2020-01-01
        send_raw_request(cli_ctx,
                         'GET',
                         '/tenants?api-version=2020-01-01',
                         body=test_body,
                         generated_client_request_id_name=None)

        get_raw_token_mock.assert_called_with(
            mock.ANY, test_arm_active_directory_resource_id)
        request = send_mock.call_args.args[1]
        self.assertEqual(
            request.url,
            test_arm_endpoint.rstrip('/') + '/tenants?api-version=2020-01-01')
        self.assertDictEqual(dict(request.headers), expected_header_with_auth)

        # Test ARM resource ID
        # /subscriptions/00000001-0000-0000-0000-000000000000/resourcegroups/02?api-version=2019-07-01
        send_raw_request(cli_ctx,
                         'GET',
                         arm_resource_id,
                         body=test_body,
                         generated_client_request_id_name=None)

        get_raw_token_mock.assert_called_with(
            mock.ANY,
            test_arm_active_directory_resource_id,
            subscription=subscription_id)
        request = send_mock.call_args.args[1]
        self.assertEqual(request.url, full_arm_rest_url)
        self.assertDictEqual(dict(request.headers), expected_header_with_auth)

        # Test full ARM URL
        # https://management.azure.com/subscriptions/00000001-0000-0000-0000-000000000000/resourcegroups/02?api-version=2019-07-01
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url)

        get_raw_token_mock.assert_called_with(
            mock.ANY,
            test_arm_active_directory_resource_id,
            subscription=subscription_id)
        request = send_mock.call_args.args[1]
        self.assertEqual(request.url, full_arm_rest_url)

        # Test full ARM URL with port
        # https://management.azure.com:443/subscriptions/00000001-0000-0000-0000-000000000000/resourcegroups/02?api-version=2019-07-01
        test_arm_endpoint_with_port = 'https://management.azure.com:443/'
        full_arm_rest_url_with_port = test_arm_endpoint_with_port.rstrip(
            '/') + arm_resource_id
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url_with_port)

        get_raw_token_mock.assert_called_with(
            mock.ANY,
            test_arm_active_directory_resource_id,
            subscription=subscription_id)
        request = send_mock.call_args.args[1]
        self.assertEqual(
            request.url,
            'https://management.azure.com:443/subscriptions/00000001-0000-0000-0000-000000000000/resourcegroups/02?api-version=2019-07-01'
        )

        # Test non-ARM APIs

        # Test AD Graph API https://graph.windows.net/
        url = 'https://graph.windows.net/00000002-0000-0000-0000-000000000000/applications/00000003-0000-0000-0000-000000000000?api-version=1.6'
        send_raw_request(cli_ctx,
                         'PATCH',
                         url,
                         body=test_body,
                         generated_client_request_id_name=None)
        get_raw_token_mock.assert_called_with(mock.ANY,
                                              'https://graph.windows.net/')
        request = send_mock.call_args.args[1]
        self.assertEqual(request.method, 'PATCH')
        self.assertEqual(request.url, url)

        # Test MS Graph API https://graph.microsoft.com/beta/appRoleAssignments/01
        url = 'https://graph.microsoft.com/beta/appRoleAssignments/01'
        send_raw_request(cli_ctx,
                         'PATCH',
                         url,
                         body=test_body,
                         generated_client_request_id_name=None)
        get_raw_token_mock.assert_called_with(mock.ANY,
                                              'https://graph.microsoft.com/')
        request = send_mock.call_args.args[1]
        self.assertEqual(request.method, 'PATCH')
        self.assertEqual(request.url, url)

        # Test custom case-insensitive User-Agent
        with mock.patch.dict('os.environ',
                             {'AZURE_HTTP_USER_AGENT': "env-ua"}):
            send_raw_request(cli_ctx,
                             'GET',
                             full_arm_rest_url,
                             headers={'user-agent=ARG-UA'})

            get_raw_token_mock.assert_called_with(
                mock.ANY,
                test_arm_active_directory_resource_id,
                subscription=subscription_id)
            request = send_mock.call_args.args[1]
            self.assertEqual(request.headers['User-Agent'],
                             get_az_user_agent() + ' env-ua ARG-UA')
Пример #10
0
def enable_one_deploy(cmd,
                      resource_group_name,
                      name,
                      src,
                      deploy_type=None,
                      is_async=None,
                      target_path=None,
                      timeout=None,
                      slot=None):
    import ntpath
    logger.info("Preparing for deployment")
    user_name, password = _get_site_credential(cmd.cli_ctx,
                                               resource_group_name, name, slot)

    try:
        scm_url = _get_scm_url(cmd, resource_group_name, name, slot)
    except ValueError:
        raise CLIError('Failed to fetch scm url for for app {}'.format(name))

    # Interpret deployment type from the file extension if the type parameter is not passed
    if deploy_type is None:
        fileName = ntpath.basename(src)
        fileExtension = fileName.split(".", 1)[1]
        if fileExtension in ('war', 'jar', 'zip', 'ear'):
            deploy_type = fileExtension
        elif fileExtension in ('sh', 'bat'):
            deploy_type = 'startup'
        else:
            deploy_type = 'static'

    logger.warning(
        "Deployment type: %s. To override deloyment type, please specify the --type parameter. Possible values: static, zip, war, jar, ear, startup",
        deploy_type)
    deploy_url = scm_url + '/api/publish?type=' + deploy_type

    if is_async is not None:
        deploy_url = deploy_url + '&async=true'

    if target_path is not None:
        deploy_url = deploy_url + '&path=' + target_path

    deployment_status_url = scm_url + '/api/deployments/latest'

    from azure.cli.core.util import (should_disable_connection_verify,
                                     get_az_user_agent)

    import urllib3
    authorization = urllib3.util.make_headers(
        basic_auth='{0}:{1}'.format(user_name, password))
    headers = authorization
    headers['Content-Type'] = 'application/octet-stream'
    headers['Cache-Control'] = 'no-cache'
    headers['User-Agent'] = get_az_user_agent()

    import requests
    import os

    # Read file content
    with open(os.path.realpath(os.path.expanduser(src)), 'rb') as fs:
        artifact_content = fs.read()
        logger.warning("Starting deployment...")
        res = requests.post(deploy_url,
                            data=artifact_content,
                            headers=headers,
                            verify=not should_disable_connection_verify())

    # check if an error occured during deployment
    if res.status_code == 400:
        raise CLIError("An error occured durng deployment: {}".format(
            res.text))

    # check if there's an ongoing process
    if res.status_code == 409:
        raise CLIError(
            "There may be an ongoing deployment or your app setting has WEBSITE_RUN_FROM_PACKAGE. "
            "Please track your deployment in {} and ensure the WEBSITE_RUN_FROM_PACKAGE app setting "
            "is removed.".format(deployment_status_url))

    # check the status of async deployment
    if res.status_code == 202:
        logger.warning("Asynchronous deployment request has been recieved")
        response = _check_zip_deployment_status(cmd, resource_group_name, name,
                                                deployment_status_url,
                                                authorization, timeout)
        return response

    return logger.warning("Deployment has completed successfully")