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)
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)
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