def get_relay_information(cmd, resource_group, vm_name,
                          certificate_validity_in_seconds):
    from azext_ssh._client_factory import cf_endpoint
    client = cf_endpoint(cmd.cli_ctx)

    if not certificate_validity_in_seconds or \
       certificate_validity_in_seconds > consts.RELAY_INFO_MAXIMUM_DURATION_IN_SECONDS:
        certificate_validity_in_seconds = consts.RELAY_INFO_MAXIMUM_DURATION_IN_SECONDS

    try:
        t0 = time.time()
        result = client.list_credentials(
            resource_group_name=resource_group,
            machine_name=vm_name,
            endpoint_name="default",
            expiresin=certificate_validity_in_seconds)
        time_elapsed = time.time() - t0
        telemetry.add_extension_event(
            'ssh',
            {'Context.Default.AzureCLI.SSHListCredentialsTime': time_elapsed})
    except ResourceNotFoundError:
        logger.debug(
            "Default Endpoint couldn't be found. Trying to create Default Endpoint."
        )
        _create_default_endpoint(cmd, resource_group, vm_name, client)
        try:
            t0 = time.time()
            result = client.list_credentials(
                resource_group_name=resource_group,
                machine_name=vm_name,
                endpoint_name="default",
                expiresin=certificate_validity_in_seconds)
            time_elapsed = time.time() - t0
            telemetry.add_extension_event('ssh', {
                'Context.Default.AzureCLI.SSHListCredentialsTime':
                time_elapsed
            })
        except Exception as e:
            raise azclierror.ClientRequestError(
                f"Request for Azure Relay Information Failed:\n{str(e)}")
    except Exception as e:
        raise azclierror.ClientRequestError(
            f"Request for Azure Relay Information Failed:\n{str(e)}")
    return result
Exemple #2
0
def get_client_side_proxy(arc_proxy_folder):

    request_uri, install_location, older_version_location = _get_proxy_filename_and_url(
        arc_proxy_folder)
    install_dir = os.path.dirname(install_location)

    # Only download new proxy if it doesn't exist already
    if not os.path.isfile(install_location):
        t0 = time.time()
        # download the executable
        try:
            with urllib.request.urlopen(request_uri) as response:
                response_content = response.read()
                response.close()
        except Exception as e:
            raise azclierror.ClientRequestError(
                f"Failed to download client proxy executable from {request_uri}. "
                "Error: " + str(e)) from e
        time_elapsed = time.time() - t0

        proxy_data = {
            'Context.Default.AzureCLI.SSHProxyDownloadTime': time_elapsed,
            'Context.Default.AzureCLI.SSHProxyVersion':
            consts.CLIENT_PROXY_VERSION
        }
        telemetry.add_extension_event('ssh', proxy_data)

        # if directory doesn't exist, create it
        if not os.path.isdir(install_dir):
            file_utils.create_directory(
                install_dir,
                f"Failed to create client proxy directory '{install_dir}'. ")
        # if directory exists, delete any older versions of the proxy
        else:
            older_version_files = glob(older_version_location)
            for f in older_version_files:
                file_utils.delete_file(
                    f,
                    f"failed to delete older version file {f}",
                    warning=True)

        # write executable in the install location
        file_utils.write_to_file(install_location, 'wb', response_content,
                                 "Failed to create client proxy file. ")
        os.chmod(install_location,
                 os.stat(install_location).st_mode | stat.S_IXUSR)
        colorama.init()
        print(Fore.GREEN + f"SSH Client Proxy saved to {install_location}" +
              Style.RESET_ALL)

    return install_location
Exemple #3
0
def handle_exception(ex):  # pylint: disable=too-many-locals, too-many-statements, too-many-branches
    # For error code, follow guidelines at https://docs.python.org/2/library/sys.html#sys.exit,
    from jmespath.exceptions import JMESPathTypeError
    from msrestazure.azure_exceptions import CloudError
    from msrest.exceptions import HttpOperationError, ValidationError, ClientRequestError
    from azure.cli.core.azlogging import CommandLoggerContext
    from azure.common import AzureException
    from azure.core.exceptions import AzureError
    from requests.exceptions import SSLError, HTTPError
    import azure.cli.core.azclierror as azclierror
    import traceback

    logger.debug(
        "azure.cli.core.util.handle_exception is called with an exception:")
    # Print the traceback and exception message
    logger.debug(traceback.format_exc())

    with CommandLoggerContext(logger):
        error_msg = getattr(ex, 'message', str(ex))
        exit_code = 1

        if isinstance(ex, azclierror.AzCLIError):
            az_error = ex

        elif isinstance(ex, JMESPathTypeError):
            error_msg = "Invalid jmespath query supplied for `--query`: {}".format(
                error_msg)
            az_error = azclierror.InvalidArgumentValueError(error_msg)
            az_error.set_recommendation(QUERY_REFERENCE)

        elif isinstance(ex, SSLError):
            az_error = azclierror.AzureConnectionError(error_msg)
            az_error.set_recommendation(SSLERROR_TEMPLATE)

        elif isinstance(ex, CloudError):
            if extract_common_error_message(ex):
                error_msg = extract_common_error_message(ex)
            status_code = str(getattr(ex, 'status_code', 'Unknown Code'))
            AzCLIErrorType = get_error_type_by_status_code(status_code)
            az_error = AzCLIErrorType(error_msg)

        elif isinstance(ex, ValidationError):
            az_error = azclierror.ValidationError(error_msg)

        elif isinstance(ex, CLIError):
            # TODO: Fine-grained analysis here for Unknown error
            az_error = azclierror.UnknownError(error_msg)

        elif isinstance(ex, AzureError):
            if extract_common_error_message(ex):
                error_msg = extract_common_error_message(ex)
            AzCLIErrorType = get_error_type_by_azure_error(ex)
            az_error = AzCLIErrorType(error_msg)

        elif isinstance(ex, AzureException):
            if is_azure_connection_error(error_msg):
                az_error = azclierror.AzureConnectionError(error_msg)
            else:
                # TODO: Fine-grained analysis here for Unknown error
                az_error = azclierror.UnknownError(error_msg)

        elif isinstance(ex, ClientRequestError):
            if is_azure_connection_error(error_msg):
                az_error = azclierror.AzureConnectionError(error_msg)
            else:
                az_error = azclierror.ClientRequestError(error_msg)

        elif isinstance(ex, HttpOperationError):
            message, status_code = extract_http_operation_error(ex)
            if message:
                error_msg = message
            AzCLIErrorType = get_error_type_by_status_code(status_code)
            az_error = AzCLIErrorType(error_msg)

        elif isinstance(ex, HTTPError):
            status_code = str(
                getattr(ex.response, 'status_code', 'Unknown Code'))
            AzCLIErrorType = get_error_type_by_status_code(status_code)
            az_error = AzCLIErrorType(error_msg)

        elif isinstance(ex, KeyboardInterrupt):
            error_msg = 'Keyboard interrupt is captured.'
            az_error = azclierror.ManualInterrupt(error_msg)

        else:
            error_msg = "The command failed with an unexpected error. Here is the traceback:"
            az_error = azclierror.CLIInternalError(error_msg)
            az_error.set_exception_trace(ex)
            az_error.set_recommendation(
                "To open an issue, please run: 'az feedback'")

        if isinstance(az_error, azclierror.ResourceNotFoundError):
            exit_code = 3

        az_error.print_error()
        az_error.send_telemetry()

        return exit_code