Paramiko: Is there a way to get the hostname from an SSHClient object?

Created on 30 Nov 2015  路  5Comments  路  Source: paramiko/paramiko

Hi,

in my app I pass around a few SSHClient instances inside some wrapper classes, and it would be useful (for debugging) to get the hostname where the client is connected to from the SSHClient object itself. Is there a way to do it?

Feature Needs patch

Most helpful comment

I want this feature. As it is now, when I pass my "SSHClient" instance around, I also have to pass a separate hostname argument with it. When a remote command fails, I want the exceptions that I raise to include the hostname in the error. Because a remote command could fail because the connection has been lost, running "hostname" at the time of the error doesn't work. It's not critical, but the addition of a static attribute to the SSHClient object seems like it would be a trivial addition.

EDIT: As a workaround, I just appended my own attribute to my SSHClient instance. Not my preferred solution as a future update could break this or cause unexpected behavior, even if unlikely:

def get_ssh_client(hostname):
    ssh = paramiko.SSHClient()
    ssh.remote_hostname = hostname
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname, timeout=10)
    return ssh

All 5 comments

This is really a mailing list question, not a bug, but it looks like librelist.com is down... so try IRC http://www.paramiko.org/contact.html

Librelist's site is up for me. That said, I can't remember the last time I got a Paramiko ML post - when the original maintainer lost the old mailing list prior to the handoff, I started over with the librelist, and naturally almost nobody subscribed :(


@kalidasya Glancing at the code I don't see that we actually store the info anywhere. The best you can do right now is to call client.get_transport().sock.getpeername() which tends to just get you the IP address that resolved for the hostname in question, not the hostname itself.

So for human-friendly debugging purposes, it'll definitely be easier to preserve the hostname you're giving Paramiko on your side of the code (this is what Fabric does, for example).

Gonna leave this open as a "why DON'T we do this?" though. Thanks!

@Russell-Jones: sorry, next time I will use IRC
@bitprophet : thanks for your investigation, I will store it on my side for now, but definitely +1 to do it in paramiko in the future!

I just run hostname on the remote computer and use the results. For example:

def get_hostname_by_ssh(host_ip):
    '''
    Make a connection to the remote system and get its hostname
    '''
    print('Checking out {}'.format(host_ip))
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(host_ip,
                username='user',
                password='password')
    _, stdout, _ = ssh.exec_command('hostname')
    hostname = stdout.read()
    ssh.close()
    if isinstance(hostname, bytes):
        hostname = hostname.decode('utf-8')
    print('Found {}'.format(hostname.strip()))
    return hostname.strip()

I want this feature. As it is now, when I pass my "SSHClient" instance around, I also have to pass a separate hostname argument with it. When a remote command fails, I want the exceptions that I raise to include the hostname in the error. Because a remote command could fail because the connection has been lost, running "hostname" at the time of the error doesn't work. It's not critical, but the addition of a static attribute to the SSHClient object seems like it would be a trivial addition.

EDIT: As a workaround, I just appended my own attribute to my SSHClient instance. Not my preferred solution as a future update could break this or cause unexpected behavior, even if unlikely:

def get_ssh_client(hostname):
    ssh = paramiko.SSHClient()
    ssh.remote_hostname = hostname
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname, timeout=10)
    return ssh
Was this page helpful?
0 / 5 - 0 ratings