Элегантный способ проверить доступность SSH


Мне нужна программа Python, которую я использую, чтобы опросить удаленный сервер для подключения SSH и уведомить, когда он доступен. В настоящее время я делаю это с помощью paramiko; попытайтесь подключиться, если это не удастся, подождите и повторите попытку до тех пор, пока не будет достигнут успех или Макс повторит попытку. Это работает, но немного неуклюже. Кроме того, парамико, кажется, либо подключается, либо выдает ошибку, поэтому единственный способ, который я мог видеть, чтобы сделать это, был с блоком try/except, который плохой, плохой, плохой. Вот этот метод:

def check_ssh(self, ip, user, key_file, initial_wait=0, interval=0, retries=1):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    sleep(initial_wait)

    for x in range(retries):
        try:
            ssh.connect(ip, username=user, key_filename=key_file)
            return True
        except Exception, e:
            print e
            sleep(interval)
    return False

Должно быть более элегантное решение. чем это. Paramiko-моя библиотека SSH выбора, но я открыт для любых предложений здесь.

Чтобы уточнить, я хочу избежать использования try / except в качестве средства контроля нормального потока выполнения кода - он должен использоваться для обнаружения фактических ошибок, таких как плохой ключ хоста, недопустимый пользователь и т. д.

1 11

1 ответ:

Как упоминалось в комментарии frb, блок try ... except является хорошим подходом для проверки доступности конкретной службы. Однако вы не должны использовать блок "catch-all" except, а ограничивать его конкретными исключениями, которые возникают, если служба недоступна.

Согласно документации, paramiko.SSHClient.connect могут возникать различные исключения, в зависимости от проблемы, возникшей при подключении. Если вы хотите поймать все это, ваш блок try ... except будет выглядеть следующим образом:

try:
    ssh.connect(ip, username=user, key_filename=key_file)
    return True
except (BadHostKeyException, AuthenticationException, 
        SSHException, socket.error) as e:
    print e
    sleep(interval)

Если только a подмножество этих исключений имеет отношение к вашему случаю, поместите только те из них в кортеж после except.