Handle floating ips in multi-node-known-hosts

Nodes (and ansible) don't know about floating ips because they are
external. However, they are valid interfaces over which nodes might talk
to each other- especially if we're re-using the inventory generated for
the jobs.

Start off by grabbing all of the addresses from nodepool, if they exist.
Then do the loop for finding the addresses we want. Then collapse
that list with set and do a pass to create the actual list of hosts and
keys needed.

Change-Id: I748fae1c86d7bb9333dc251991308282858811a4
This commit is contained in:
Monty Taylor 2017-09-06 16:31:15 -05:00
parent 19f5dd08b1
commit 5cdacdfbf4
No known key found for this signature in database
GPG Key ID: 7BAE94BC7141A594

View File

@ -37,6 +37,14 @@ def main():
public_keys = [x for x in this.keys() if public_keys = [x for x in this.keys() if
x.startswith('ansible_ssh_host_key')] x.startswith('ansible_ssh_host_key')]
addresses = [this['ansible_host']]
nodepool = this.get('nodepool', {})
for nodepool_address in (
'interface_ip', 'public_ipv4', 'private_ipv4', 'public_ipv6'):
address = nodepool.get(nodepool_address)
if address:
addresses.append(address)
for iface in this.get('ansible_interfaces', []): for iface in this.get('ansible_interfaces', []):
iface_key = 'ansible_{}'.format(iface.replace('-', '_')) iface_key = 'ansible_{}'.format(iface.replace('-', '_'))
ipv4 = this[iface_key].get('ipv4') ipv4 = this[iface_key].get('ipv4')
@ -45,31 +53,32 @@ def main():
ipv6 = this[iface_key].get('ipv6') ipv6 = this[iface_key].get('ipv6')
if not isinstance(ipv6, list): if not isinstance(ipv6, list):
ipv6 = [ipv6] ipv6 = [ipv6]
addresses = [x['address'] for x in ipv4 if x and not addresses += [x['address'] for x in ipv4 if x and not
x['address'].startswith('127.')] x['address'].startswith('127.')]
addresses += [y['address'] for y in ipv6 if y and not addresses += [y['address'] for y in ipv6 if y and not
y['scope'] == 'host'] y['scope'] == 'host']
addresses += [this['ansible_hostname']] addresses += [this['ansible_hostname']]
for addr in addresses:
for key in public_keys: for addr in set(addresses):
if key.endswith('rsa_public'): for key in public_keys:
key_type = 'ssh-rsa' if key.endswith('rsa_public'):
elif key.endswith('ecdsa_public'): key_type = 'ssh-rsa'
# XXX This will not work with > 256 bit ecdsa keys elif key.endswith('ecdsa_public'):
# until https://github.com/ansible/ansible/issues/28325 # XXX This will not work with > 256 bit ecdsa keys
# is fixed. We're using the proposed scheme in case it # until https://github.com/ansible/ansible/issues/28325
# does merge as-is, but it may need to be updated if # is fixed. We're using the proposed scheme in case it
# the patch is changed as well. # does merge as-is, but it may need to be updated if
key_type = this.get('{}_type'.format(key), # the patch is changed as well.
'ecdsa-sha2-nistp256') key_type = this.get('{}_type'.format(key),
elif key.endswith('ed25519_public'): 'ecdsa-sha2-nistp256')
key_type = 'ssh-ed25519' elif key.endswith('ed25519_public'):
else: key_type = 'ssh-ed25519'
continue else:
known_hosts.add( continue
'{addr} {key_type} {key}'.format(addr=addr, known_hosts.add(
key_type=key_type, '{addr} {key_type} {key}'.format(addr=addr,
key=this[key])) key_type=key_type,
key=this[key]))
ret = { ret = {
'ansible_facts': { 'ansible_facts': {