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')
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
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']
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
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
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
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
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')
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")