Exemple #1
0
def call_aladdin_service(query):
    version = str(parse_version(core_version))
    correlation_id = telemetry_core._session.correlation_id  # pylint: disable=protected-access
    subscription_id = telemetry_core._get_azure_subscription_id()  # pylint: disable=protected-access

    # Used for DDOS protection and rate limiting
    user_id = telemetry_core._get_user_azure_id()  # pylint: disable=protected-access
    hashed_user_id = hashlib.sha256(user_id.encode('utf-8')).hexdigest()

    context = {
        "versionNumber": version,
    }

    # Only pull in the contextual values if we have consent
    if telemetry_core.is_telemetry_enabled():
        context['correlationId'] = correlation_id

    if telemetry_core.is_telemetry_enabled() and subscription_id is not None:
        context['subscriptionId'] = subscription_id

    api_url = 'https://app.aladdin.microsoft.com/api/v1.0/examples'
    headers = {'Content-Type': 'application/json', 'X-UserId': hashed_user_id}

    response = requests.get(api_url,
                            params={
                                'query': query,
                                'clientType': 'AzureCli',
                                'context': json.dumps(context),
                                'commandOnly': True,
                                'numberOfExamples': 5
                            },
                            headers=headers)

    return response
Exemple #2
0
def call_aladdin_service(query):
    version = str(parse_version(core_version))
    correlation_id = telemetry_core._session.correlation_id  # pylint: disable=protected-access
    subscription_id = telemetry_core._get_azure_subscription_id()  # pylint: disable=protected-access

    context = {
        "versionNumber": version,
    }

    # Only pull in the contextual values if we have consent
    if telemetry_core.is_telemetry_enabled():
        context['correlationId'] = correlation_id

    if telemetry_core.is_telemetry_enabled() and subscription_id is not None:
        context['subscriptionId'] = subscription_id

    api_url = 'https://app.aladdin.microsoft.com/api/v1.0/examples'
    headers = {'Content-Type': 'application/json'}

    response = requests.get(api_url,
                            params={
                                'query': query,
                                'clientType': 'AzureCli',
                                'context': json.dumps(context)
                            },
                            headers=headers)

    return response
Exemple #3
0
def call_aladdin_service(query):
    correlation_id = telemetry_core._session.correlation_id  # pylint: disable=protected-access
    subscription_id = telemetry_core._get_azure_subscription_id()  # pylint: disable=protected-access
    version = str(parse_version(core_version))

    context = {
        "correlationId": "",
        "subscriptionId": "",
        "versionNumber": version
    }

    # Only pull in the other values if we have consent
    if telemetry_core.is_telemetry_enabled():
        context.update(correlationId=correlation_id,
                       subscriptionId=subscription_id)

    api_url = 'https://app.aladdin.microsoft.com/api/v1.0/examples'
    headers = {'Content-Type': 'application/json'}

    response = requests.get(api_url,
                            params={
                                'query': query,
                                'clientType': 'AzureCli',
                                'context': json.dumps(context),
                                'commandOnly': True,
                                'numberOfExamples': 5
                            },
                            headers=headers)

    return response
def get_recommend_from_api(command_list, type, top_num=5, error_info=None):  # pylint: disable=unused-argument
    '''query next command from web api'''
    import requests
    url = "https://cli-recommendation.azurewebsites.net/api/RecommendationService"

    user_id = telemetry._get_user_azure_id()  # pylint: disable=protected-access
    hashed_user_id = hashlib.sha256(user_id.encode('utf-8')).hexdigest()
    payload = {
        "command_list": json.dumps(command_list),
        "type": type,
        "top_num": top_num,
        'error_info': error_info,
        'cli_version': version,
        'user_id': hashed_user_id
    }

    correlation_id = telemetry._session.correlation_id
    subscription_id = telemetry._get_azure_subscription_id()
    if telemetry.is_telemetry_enabled():
        if correlation_id:
            payload['correlation_id'] = correlation_id
        if subscription_id:
            payload['subscription_id'] = subscription_id

    response = requests.post(url, json.dumps(payload))
    if response.status_code != 200:
        raise RecommendationError(
            "Failed to connect to '{}' with status code '{}' and reason '{}'".
            format(url, response.status_code, response.reason))

    recommends = []
    if 'data' in response.json():
        recommends = response.json()['data']

    return recommends
    def test_cloud_forbid_telemetry(self):
        from unittest import mock
        from azure.cli.core import telemetry
        from azure.cli.core.mock import DummyCli
        from knack.completion import ARGCOMPLETE_ENV_NAME

        az_cli = DummyCli()
        telemetry.set_application(az_cli, ARGCOMPLETE_ENV_NAME)
        # mock user turns off telemetry
        with mock.patch('knack.config.CLIConfig.getboolean', return_value=False):
            self.assertFalse(telemetry.is_telemetry_enabled())
        # mock user turns on telemetry
        with mock.patch('knack.config.CLIConfig.getboolean', return_value=True):
            self.assertTrue(telemetry.is_telemetry_enabled())
            # mock to add current cloud name in CLOUDS_FORBIDDING_TELEMETRY
            with mock.patch('azure.cli.core.cloud.CLOUDS_FORBIDDING_TELEMETRY', [az_cli.cloud.name]):
                self.assertFalse(telemetry.is_telemetry_enabled())
Exemple #6
0
def call_aladdin_service(command, parameters, version):
    _log_debug(
        'call_aladdin_service: version: "%s", command: "%s", parameters: "%s"',
        version, command, parameters)

    response = None

    correlation_id = telemetry._session.correlation_id  # pylint: disable=protected-access
    subscription_id = telemetry._get_azure_subscription_id()  # pylint: disable=protected-access
    is_telemetry_enabled = telemetry.is_telemetry_enabled()

    telemetry_context = {
        'correlationId': correlation_id,
        'subscriptionId': subscription_id
    }

    telemetry_context = {
        k: v
        for k, v in telemetry_context.items()
        if v is not None and is_telemetry_enabled
    }

    if not is_telemetry_enabled:
        _log_debug(TELEMETRY_IS_DISABLED_STR)
    else:
        _log_debug(TELEMETRY_IS_ENABLED_STR)

        if subscription_id is None:
            _log_debug(TELEMETRY_MISSING_SUBSCRIPTION_ID_STR)
        if correlation_id is None:
            _log_debug(TELEMETRY_MISSING_CORRELATION_ID_STR)

    context = {**telemetry_context, "versionNumber": version}

    query = {"command": command, "parameters": parameters}

    api_url = 'https://app.aladdin.microsoft.com/api/v1.0/suggestions'
    headers = {'Content-Type': 'application/json'}

    try:
        response = requests.get(api_url,
                                params={
                                    'query': json.dumps(query),
                                    'clientType': 'AzureCli',
                                    'context': json.dumps(context)
                                },
                                headers=headers)
    except RequestException as ex:
        _log_debug('requests.get() exception: %s', ex)

    return response
    def _set_aladdin_recommendations(self):
        """Set recommendations from aladdin service.
        Call the aladdin service API, parse the response and set the recommendations.
        """

        import hashlib
        import json
        import requests
        from requests import RequestException
        from http import HTTPStatus
        from azure.cli.core import __version__ as version

        api_url = 'https://app.aladdin.microsoft.com/api/v1.0/suggestions'
        correlation_id = telemetry._session.correlation_id  # pylint: disable=protected-access
        subscription_id = telemetry._get_azure_subscription_id()  # pylint: disable=protected-access
        # Used for DDOS protection and rate limiting
        user_id = telemetry._get_user_azure_id()  # pylint: disable=protected-access
        hashed_user_id = hashlib.sha256(user_id.encode('utf-8')).hexdigest()

        headers = {
            'Content-Type': 'application/json',
            'X-UserId': hashed_user_id
        }
        context = {
            'versionNumber': version,
            'errorType': self._get_error_type()
        }

        if telemetry.is_telemetry_enabled():
            if correlation_id:
                context['correlationId'] = correlation_id
            if subscription_id:
                context['subscriptionId'] = subscription_id

        parameters = [
            item for item in self.parameters
            if item not in ['--debug', '--verbose', '--only-show-errors']
        ]
        query = {"command": self.command, "parameters": ','.join(parameters)}

        response = None
        try:
            response = requests.get(api_url,
                                    params={
                                        'query': json.dumps(query),
                                        'clientType': 'AzureCli',
                                        'context': json.dumps(context)
                                    },
                                    headers=headers,
                                    timeout=1)
        except RequestException as ex:
            logger.debug('Recommendation requests.get() exception: %s', ex)
            telemetry.set_debug_info('AladdinRecommendationService',
                                     ex.__class__.__name__)

        recommendations = []
        if response and response.status_code == HTTPStatus.OK:
            for result in response.json():
                # parse the reponse and format the recommendation
                command, parameters, placeholders = result['command'],\
                    result['parameters'].split(','),\
                    result['placeholders'].split('♠')
                recommendation = 'az {} '.format(command)
                for parameter, placeholder in zip(parameters, placeholders):
                    recommendation += '{} {} '.format(parameter, placeholder)
                recommendations.append(recommendation.strip())

        self.aladdin_recommendations.extend(recommendations)
def _is_telemetry_enabled():
    from azure.cli.core.telemetry import is_telemetry_enabled
    return is_telemetry_enabled()
def recommend_recovery_options(version, command, parameters, extension):
    from timeit import default_timer as timer
    start_time = timer()
    elapsed_time = None

    result = []
    cmd_tbl = CommandTable.CMD_TBL
    _log_debug(
        'recommend_recovery_options: version: "%s", command: "%s", parameters: "%s", extension: "%s"',
        version, command, parameters, extension)

    # if the user doesn't agree to telemetry...
    if not telemetry.is_telemetry_enabled():
        _log_debug(TELEMETRY_MUST_BE_ENABLED_STR)
        return result

    # if the command is empty...
    if not command:
        # try to get the raw command field from telemetry.
        session = telemetry._session  # pylint: disable=protected-access
        # get the raw command parsed by the CommandInvoker object.
        command = session.raw_command
        if command:
            _log_debug(f'Setting command to [{command}] from telemtry.')

    def append(line):
        result.append(line)

    def unable_to_help(command):
        msg = UNABLE_TO_HELP_FMT_STR.format(command=command)
        append(msg)

    def show_recommendation_header(command):
        msg = RECOMMENDATION_HEADER_FMT_STR.format(command=command)
        append(style_message(msg))

    if extension:
        _log_debug('Detected extension. No action to perform.')
    if not command:
        _log_debug('Command is empty. No action to perform.')

    # if an extension is in-use or the command is empty...
    if extension or not command:
        return result

    # perform some rudimentary parsing to extract the parameters and command in a standard form
    command, parameters = normalize_and_sort_parameters(
        cmd_tbl, command, parameters)
    response = call_aladdin_service(command, parameters, version)

    # only show recommendations when we can contact the service.
    if response and response.status_code == HTTPStatus.OK:
        recommendations = get_recommendations_from_http_response(response)

        if recommendations:
            show_recommendation_header(command)

            for recommendation in recommendations:
                append(f"\t{recommendation}")
        # only prompt user to use "az find" for valid CLI commands
        # note: pylint has trouble resolving statically initialized variables, which is why
        # we need to disable the unsupported membership test rule
        elif any(cmd.startswith(command) for cmd in cmd_tbl.keys()):  # pylint: disable=unsupported-membership-test
            unable_to_help(command)

    elapsed_time = timer() - start_time
    _log_debug(
        'The overall time it took to process failure recovery recommendations was %.2fms.',
        elapsed_time * 1000)

    return result
def call_aladdin_service(command, parameters, version):
    logger.debug(
        'call_aladdin_service: version: "%s", command: "%s", parameters: "%s"',
        version, command, parameters)

    response = None

    time_to_get_user_info = Timer()

    with time_to_get_user_info:
        correlation_id = get_correlation_id()
        subscription_id = get_subscription_id()

    set_property(TelemetryProperty.TimeToRetrieveUserInfoMs,
                 time_to_get_user_info.elapsed_ms)

    is_telemetry_enabled = telemetry.is_telemetry_enabled()

    telemetry_context = {
        'correlationId': correlation_id,
        'subscriptionId': subscription_id
    }

    telemetry_context = {
        k: v
        for k, v in telemetry_context.items()
        if v is not None and is_telemetry_enabled
    }

    if not is_telemetry_enabled:
        logger.debug(TELEMETRY_IS_DISABLED_STR)
    else:
        logger.debug(TELEMETRY_IS_ENABLED_STR)

        if subscription_id is None:
            set_property(TelemetryProperty.NoSubscriptionId, True)
            logger.debug(TELEMETRY_MISSING_SUBSCRIPTION_ID_STR)
        if correlation_id is None:
            set_property(TelemetryProperty.NoCorrelationId, True)
            logger.debug(TELEMETRY_MISSING_CORRELATION_ID_STR)

    context = {**telemetry_context, "versionNumber": version}

    query = {"command": command, "parameters": parameters}

    api_url = 'https://app.aladdin.microsoft.com/api/v1.0/suggestions'
    headers = {'Content-Type': 'application/json'}

    try:
        round_trip_request_time = Timer()

        with round_trip_request_time:
            response = requests.get(api_url,
                                    params={
                                        'query': json.dumps(query),
                                        'clientType': 'AzureCli',
                                        'context': json.dumps(context),
                                        'extensionVersion': VERSION
                                    },
                                    headers=headers,
                                    timeout=(SERVICE_CONNECTION_TIMEOUT, None))

        set_property(TelemetryProperty.RoundTripRequestTimeMs,
                     round_trip_request_time.elapsed_ms)
    except RequestException as ex:
        if isinstance(ex, requests.Timeout):
            set_property(TelemetryProperty.RequestTimedOut, True)

        logger.debug('requests.get() exception: %s', ex)
        set_exception(
            exception=ex,
            fault_type=FaultType.RequestError.value,
            summary='HTTP Get Request to Aladdin suggestions endpoint failed.')

    return response
 def is_telemetry_enabled(self):
     return core_telemetry.is_telemetry_enabled()