From 2b0e3a4bf0ee47cb623cc8b3afcdce7e17ca722b Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Sat, 25 Sep 2021 11:08:18 +0200 Subject: [PATCH] bundles/powerdns: use only public ips or those attached to physical interfaces to create dns records --- bundles/powerdns/metadata.py | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/bundles/powerdns/metadata.py b/bundles/powerdns/metadata.py index 2cd0e53..24afe7c 100644 --- a/bundles/powerdns/metadata.py +++ b/bundles/powerdns/metadata.py @@ -1,3 +1,5 @@ +from ipaddress import ip_address, IPv4Address + from bundlewrap.metadata import atomic defaults = { @@ -131,10 +133,31 @@ def generate_dns_entries_for_nodes(metadata): if not ip6 and not ip.is_private: ip6 = ip - # We're doing this once again to get the nodes which only have - # private ips. if not ip4 and found_ips['ipv4']: - ip4 = sorted(found_ips['ipv4'])[0] + # This node apparently does not have a public IPv4 address. + # We now manually iterate over that nodes interfaces to get + # a IPv4 address which is tied to a physical interface. + # Note we can't use resolve_identifier() here, because we + # only want physical interfaces. + for interface, config in rnode.metadata.get('interfaces', {}).items(): + if not ( + interface.startswith('bond') or + interface.startswith('br') or + interface.startswith('eno') or + interface.startswith('enp') or + interface.startswith('eth') or + interface == 'default' # dummy nodes use these + ): + continue + + for ip in sorted(config.get('ips', set())): + if '/' in ip: + addr = ip_address(ip.split('/')[0]) + else: + addr = ip_address(ip) + + if not ip4 and isinstance(addr, IPv4Address): + ip4 = addr if ip4: results.add('{} IN A {}'.format(dns_name, ip4))