Merge "Have nodepool scan as many ssh host keys as possible"
This commit is contained in:
commit
4a5a6edc10
@ -73,41 +73,79 @@ def nodescan(ip, port=22, timeout=60, gather_hostkeys=True):
|
||||
|
||||
keys = []
|
||||
key = None
|
||||
# First we wait for the sshd to be listening
|
||||
for count in iterate_timeout(
|
||||
timeout, exceptions.ConnectionTimeoutException,
|
||||
"connection to %s on port %s" % (ip, port)):
|
||||
sock = None
|
||||
t = None
|
||||
try:
|
||||
sock = socket.socket(family, socket.SOCK_STREAM)
|
||||
sock.settimeout(10)
|
||||
sock.connect(sockaddr)
|
||||
if gather_hostkeys:
|
||||
t = paramiko.transport.Transport(sock)
|
||||
t.start_client(timeout=timeout)
|
||||
key = t.get_remote_server_key()
|
||||
break
|
||||
except socket.error as e:
|
||||
if e.errno not in [errno.ECONNREFUSED, errno.EHOSTUNREACH, None]:
|
||||
log.exception(
|
||||
'Exception connecting to %s on port %s:' % (ip, port))
|
||||
except Exception as e:
|
||||
log.exception("ssh-keyscan failure: %s", e)
|
||||
except Exception:
|
||||
log.exception("ssh socket connection failure")
|
||||
finally:
|
||||
try:
|
||||
if t:
|
||||
t.close()
|
||||
except Exception as e:
|
||||
log.exception('Exception closing paramiko: %s', e)
|
||||
try:
|
||||
if sock:
|
||||
sock.close()
|
||||
except Exception as e:
|
||||
log.exception('Exception closing socket: %s', e)
|
||||
except Exception:
|
||||
log.exception('Exception closing socket')
|
||||
sock = None
|
||||
if gather_hostkeys:
|
||||
sock = None
|
||||
t = None
|
||||
key_index = 0
|
||||
# Now we gather hostkeys
|
||||
while key_index >= 0:
|
||||
try:
|
||||
sock = socket.socket(family, socket.SOCK_STREAM)
|
||||
# Do this early so that we don't trigger exceptions
|
||||
t = paramiko.transport.Transport(sock)
|
||||
opts = paramiko.transport.SecurityOptions(t)
|
||||
# We use each supported key type in turn to ensure we get
|
||||
# back that specific host key type.
|
||||
key_types = opts.key_types
|
||||
opts.key_types = [key_types[key_index]]
|
||||
key_index += 1
|
||||
if key_index >= len(key_types):
|
||||
key_index = -1
|
||||
|
||||
# Paramiko, at this time, seems to return only the ssh-rsa key, so
|
||||
# only the single key is placed into the list.
|
||||
if key:
|
||||
keys.append("%s %s" % (key.get_name(), key.get_base64()))
|
||||
sock.settimeout(10)
|
||||
sock.connect(sockaddr)
|
||||
t.start_client(timeout=timeout)
|
||||
key = t.get_remote_server_key()
|
||||
if key:
|
||||
keys.append("%s %s" % (key.get_name(), key.get_base64()))
|
||||
log.debug('Added ssh host key: %s', key.get_name())
|
||||
except paramiko.SSHException as e:
|
||||
msg = str(e)
|
||||
if 'no acceptable host key' not in msg:
|
||||
# We expect some host keys to not be valid when scanning
|
||||
# only log if the error isn't due to mismatched host key
|
||||
# types.
|
||||
log.exception("ssh-keyscan failure")
|
||||
except socket.error:
|
||||
log.exception(
|
||||
'Exception connecting to %s on port %s:' % (ip, port))
|
||||
except Exception:
|
||||
log.exception("ssh-keyscan failure")
|
||||
finally:
|
||||
try:
|
||||
if t:
|
||||
t.close()
|
||||
except Exception:
|
||||
log.exception('Exception closing paramiko')
|
||||
t = None
|
||||
try:
|
||||
if sock:
|
||||
sock.close()
|
||||
except Exception:
|
||||
log.exception('Exception closing socket')
|
||||
sock = None
|
||||
|
||||
return keys
|
||||
|
Loading…
Reference in New Issue
Block a user