def _do_ssh_op(cmd, op_info, credentials_folder, op_call):
    # Get ssh_ip before getting public key to avoid getting "ResourceNotFound" exception after creating the keys
    op_info.ip = op_info.ip or ip_utils.get_ssh_ip(cmd, op_info.resource_group_name,
                                                   op_info.vm_name, op_info.use_private_ip)

    if not op_info.ip:
        if not op_info.use_private_ip:
            raise azclierror.ResourceNotFoundError(f"VM '{op_info.vm_name}' does not have a public "
                                                   "IP address to SSH to")

        raise azclierror.ResourceNotFoundError("Internal Error. Couldn't determine the IP address.")

    # If user provides local user, no credentials should be deleted.
    delete_keys = False
    delete_cert = False
    # If user provides a local user, use the provided credentials for authentication
    if not op_info.local_user:
        delete_cert = True
        op_info.public_key_file, op_info.private_key_file, delete_keys = \
            _check_or_create_public_private_files(op_info.public_key_file,
                                                  op_info.private_key_file,
                                                  credentials_folder,
                                                  op_info.ssh_client_folder)

        op_info.cert_file, op_info.local_user = _get_and_write_certificate(cmd, op_info.public_key_file,
                                                                           None, op_info.ssh_client_folder)

    op_call(op_info, delete_keys, delete_cert)
Exemple #2
0
def _do_ssh_op(cmd, op_info, op_call):
    # Get ssh_ip before getting public key to avoid getting "ResourceNotFound" exception after creating the keys
    if not op_info.is_arc():
        if op_info.ssh_proxy_folder:
            logger.warning("Target machine is not an Arc Server, --ssh-proxy-folder value will be ignored.")
        op_info.ip = op_info.ip or ip_utils.get_ssh_ip(cmd, op_info.resource_group_name,
                                                       op_info.vm_name, op_info.use_private_ip)
        if not op_info.ip:
            if not op_info.use_private_ip:
                raise azclierror.ResourceNotFoundError(f"VM '{op_info.vm_name}' does not have a public "
                                                       "IP address to SSH to")
            raise azclierror.ResourceNotFoundError("Internal Error. Couldn't determine the IP address.")

    # If user provides local user, no credentials should be deleted.
    delete_keys = False
    delete_cert = False
    cert_lifetime = None
    # If user provides a local user, use the provided credentials for authentication
    if not op_info.local_user:
        delete_cert = True
        op_info.public_key_file, op_info.private_key_file, delete_keys = \
            _check_or_create_public_private_files(op_info.public_key_file, op_info.private_key_file,
                                                  op_info.credentials_folder, op_info.ssh_client_folder)
        op_info.cert_file, op_info.local_user = _get_and_write_certificate(cmd, op_info.public_key_file,
                                                                           None, op_info.ssh_client_folder)
        if op_info.is_arc():
            # pylint: disable=broad-except
            try:
                cert_lifetime = ssh_utils.get_certificate_lifetime(op_info.cert_file,
                                                                   op_info.ssh_client_folder).total_seconds()
            except Exception as e:
                logger.warning("Couldn't determine certificate expiration. Error: %s", str(e))

    try:
        if op_info.is_arc():
            op_info.proxy_path = connectivity_utils.get_client_side_proxy(op_info.ssh_proxy_folder)
            op_info.relay_info = connectivity_utils.get_relay_information(cmd, op_info.resource_group_name,
                                                                          op_info.vm_name, cert_lifetime)
    except Exception as e:
        if delete_keys or delete_cert:
            logger.debug("An error occured before operation concluded. Deleting generated keys: %s %s %s",
                         op_info.private_key_file + ', ' if delete_keys else "",
                         op_info.public_key_file + ', ' if delete_keys else "",
                         op_info.cert_file if delete_cert else "")
            ssh_utils.do_cleanup(delete_keys, delete_cert, op_info.cert_file,
                                 op_info.private_key_file, op_info.public_key_file)
        raise e

    op_call(op_info, delete_keys, delete_cert)
def _do_ssh_op(cmd, resource_group, vm_name, ssh_ip, public_key_file,
               private_key_file, use_private_ip, op_call):
    _assert_args(resource_group, vm_name, ssh_ip)
    public_key_file, private_key_file = _check_or_create_public_private_files(
        public_key_file, private_key_file)
    ssh_ip = ssh_ip or ip_utils.get_ssh_ip(cmd, resource_group, vm_name,
                                           use_private_ip)

    if not ssh_ip:
        if not use_private_ip:
            raise azclierror.ResourceNotFoundError(
                f"VM '{vm_name}' does not have a public IP address to SSH to")

        raise azclierror.ResourceNotFoundError(
            f"VM '{vm_name}' does not have a public or private IP address to SSH to"
        )

    cert_file, username = _get_and_write_certificate(cmd, public_key_file,
                                                     None)
    op_call(ssh_ip, username, cert_file, private_key_file)
def _do_ssh_op(cmd, resource_group, vm_name, ssh_ip, public_key_file, private_key_file, use_private_ip,
               username, cert_file, credentials_folder, op_call):
    # Get ssh_ip before getting public key to avoid getting "ResourceNotFound" exception after creating the keys
    ssh_ip = ssh_ip or ip_utils.get_ssh_ip(cmd, resource_group, vm_name, use_private_ip)

    if not ssh_ip:
        if not use_private_ip:
            raise azclierror.ResourceNotFoundError(f"VM '{vm_name}' does not have a public IP address to SSH to")

        raise azclierror.ResourceNotFoundError(f"VM '{vm_name}' does not have a public or private IP address to SSH to")

    # If user provides local user, no credentials should be deleted.
    delete_keys = False
    delete_cert = False
    # If user provides a local user, use the provided credentials for authentication
    if not username:
        delete_cert = True
        public_key_file, private_key_file, delete_keys = _check_or_create_public_private_files(public_key_file,
                                                                                               private_key_file,
                                                                                               credentials_folder)
        cert_file, username = _get_and_write_certificate(cmd, public_key_file, None)

    op_call(ssh_ip, username, cert_file, private_key_file, delete_keys, delete_cert)
Exemple #5
0
def _decide_resource_type(cmd, op_info):
    # If the user provides an IP address the target will be treated as an Azure VM even if it is an
    # Arc Server. Which just means that the Connectivity Proxy won't be used to establish connection.
    is_arc_server = False
    is_azure_vm = False

    if op_info.ip:
        is_azure_vm = True
        vm = None

    elif op_info.resource_type:
        if op_info.resource_type.lower() == "microsoft.hybridcompute":
            arc, arc_error, is_arc_server = _check_if_arc_server(cmd, op_info.resource_group_name, op_info.vm_name)
            if not is_arc_server:
                colorama.init()
                if isinstance(arc_error, ResourceNotFoundError):
                    raise azclierror.ResourceNotFoundError(f"The resource {op_info.vm_name} in the resource group "
                                                           f"{op_info.resource_group_name} was not found.",
                                                           const.RECOMMENDATION_RESOURCE_NOT_FOUND)
                raise azclierror.BadRequestError("Unable to determine that the target machine is an Arc Server. "
                                                 f"Error:\n{str(arc_error)}", const.RECOMMENDATION_RESOURCE_NOT_FOUND)

        elif op_info.resource_type.lower() == "microsoft.compute":
            vm, vm_error, is_azure_vm = _check_if_azure_vm(cmd, op_info.resource_group_name, op_info.vm_name)
            if not is_azure_vm:
                colorama.init()
                if isinstance(vm_error, ResourceNotFoundError):
                    raise azclierror.ResourceNotFoundError(f"The resource {op_info.vm_name} in the resource group "
                                                           f"{op_info.resource_group_name} was not found.",
                                                           const.RECOMMENDATION_RESOURCE_NOT_FOUND)
                raise azclierror.BadRequestError("Unable to determine that the target machine is an Azure VM. "
                                                 f"Error:\n{str(vm_error)}", const.RECOMMENDATION_RESOURCE_NOT_FOUND)

    else:
        vm, vm_error, is_azure_vm = _check_if_azure_vm(cmd, op_info.resource_group_name, op_info.vm_name)
        arc, arc_error, is_arc_server = _check_if_arc_server(cmd, op_info.resource_group_name, op_info.vm_name)

        if is_azure_vm and is_arc_server:
            colorama.init()
            raise azclierror.BadRequestError(f"{op_info.resource_group_name} has Azure VM and Arc Server with the "
                                             f"same name: {op_info.vm_name}.",
                                             colorama.Fore.YELLOW + "Please provide a --resource-type." +
                                             colorama.Style.RESET_ALL)
        if not is_azure_vm and not is_arc_server:
            colorama.init()
            if isinstance(arc_error, ResourceNotFoundError) and isinstance(vm_error, ResourceNotFoundError):
                raise azclierror.ResourceNotFoundError(f"The resource {op_info.vm_name} in the resource group "
                                                       f"{op_info.resource_group_name} was not found. ",
                                                       const.RECOMMENDATION_RESOURCE_NOT_FOUND)
            raise azclierror.BadRequestError("Unable to determine the target machine type as Azure VM or "
                                             f"Arc Server. Errors:\n{str(arc_error)}\n{str(vm_error)}",
                                             const.RECOMMENDATION_RESOURCE_NOT_FOUND)

    # Note: We are not able to determine the os of the target if the user only provides an IP address.
    os_type = None
    if is_azure_vm and vm and vm.storage_profile and vm.storage_profile.os_disk and vm.storage_profile.os_disk.os_type:
        os_type = vm.storage_profile.os_disk.os_type

    if is_arc_server and arc and arc.properties and arc.properties and arc.properties.os_name:
        os_type = arc.properties.os_name

    if os_type:
        telemetry.add_extension_event('ssh', {'Context.Default.AzureCLI.TargetOSType': os_type})

    # Note 2: This is a temporary check while AAD login is not enabled for Windows.
    if os_type and os_type.lower() == 'windows' and not op_info.local_user:
        colorama.init()
        raise azclierror.RequiredArgumentMissingError("SSH Login using AAD credentials is not currently supported "
                                                      "for Windows.",
                                                      colorama.Fore.YELLOW + "Please provide --local-user." +
                                                      colorama.Style.RESET_ALL)

    target_resource_type = "Microsoft.Compute"
    if is_arc_server:
        target_resource_type = "Microsoft.HybridCompute"
    telemetry.add_extension_event('ssh', {'Context.Default.AzureCLI.TargetResourceType': target_resource_type})

    return target_resource_type