From 87115f512cb9f9dc4e7821d9f88d523cebe2660f Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Thu, 24 Nov 2022 15:13:33 +1100 Subject: [PATCH] launch: add ssh keys to inventory When bringing up a new server, scan the ssh-keys of the remote IP and add them automatically to the inventory output. c.f. I4863425d5b784d0cdf118e1252414ca78fd24179 Change-Id: I2120fd476aa89e207ab76a1fc0faeeb5a0fb55ce --- launch/src/opendev_launch/dns.py | 6 ++++ launch/src/opendev_launch/ssh_knownhosts.py | 37 +++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 launch/src/opendev_launch/ssh_knownhosts.py diff --git a/launch/src/opendev_launch/dns.py b/launch/src/opendev_launch/dns.py index fd56019a69..2f6ca58267 100755 --- a/launch/src/opendev_launch/dns.py +++ b/launch/src/opendev_launch/dns.py @@ -21,6 +21,7 @@ import argparse from . import rax_rdns from .sshfp import sshfp_print_records +from .ssh_knownhosts import generate_known_hosts def get_href(server): @@ -70,6 +71,8 @@ def set_rax_reverse_dns(cloud, server, ip4, ip6): def print_inventory_yaml(server, ip4, ip6): + known_hosts = generate_known_hosts(ip4) + print("\n") print("Put the following into system-config:inventory/base/hosts.yaml") print("\n") @@ -82,6 +85,9 @@ def print_inventory_yaml(server, ip4, ip6): print(" public_v4: {ip4}".format(ip4=ip4)) if ip6: print(" public_v6: {ip6}".format(ip6=ip6)) + print(" host_keys:") + for (key, fingerprint) in known_hosts: + print(" - '%s %s'" % (key, fingerprint)) def main(): diff --git a/launch/src/opendev_launch/ssh_knownhosts.py b/launch/src/opendev_launch/ssh_knownhosts.py new file mode 100644 index 0000000000..246fe40af2 --- /dev/null +++ b/launch/src/opendev_launch/ssh_knownhosts.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 + +import argparse +import subprocess + +def generate_known_hosts(ip): + '''Given an IP address (hostname not in dns yet), scan and return + inventory known_hosts strings + ''' + + p = ['ssh-keyscan', ip] + s = subprocess.run(p, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE).stdout.decode('utf-8') + known_hosts = [] + for line in s.split('\n'): + if not line: + continue + if line.startswith('#'): + continue + _, key_type, fingerprint = line.split(' ') + known_hosts.append((key_type, fingerprint)) + + return known_hosts + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("ip", help="address to scan") + args = parser.parse_args() + + known_hosts = generate_known_hosts(args.ip) + for (host, fingerprint) in known_hosts: + print("%s %s" % (host, fingerprint)) + +if __name__ == '__main__': + main()