Merge "Have nodepool scan as many ssh host keys as possible"

This commit is contained in:
Zuul 2020-11-06 19:14:53 +00:00 committed by Gerrit Code Review
commit 4a5a6edc10

View File

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