diff --git a/bundles/nftables/metadata.py b/bundles/nftables/metadata.py index 08396ce..acfb166 100644 --- a/bundles/nftables/metadata.py +++ b/bundles/nftables/metadata.py @@ -78,7 +78,7 @@ def port_rules_to_nftables(metadata): if target in ('*', 'ipv4', 'ipv6'): ruleset.add(f'inet filter input {version_str} {port_str} accept {comment}') else: - resolved = repo.libs.tools.resolve_identifier(repo, target) + resolved = repo.libs.tools.resolve_identifier(repo, target, linklocal=True) for address in resolved['ipv4']: ruleset.add(f'inet filter input meta nfproto ipv4 {port_str} ip saddr {address} accept {comment}') diff --git a/bundles/powerdns/metadata.py b/bundles/powerdns/metadata.py index 90c06d4..db43cee 100644 --- a/bundles/powerdns/metadata.py +++ b/bundles/powerdns/metadata.py @@ -134,7 +134,7 @@ def generate_dns_entries_for_nodes(metadata): ip4 = None ip6 = None - found_ips = repo.libs.tools.resolve_identifier(repo, rnode.name) + found_ips = repo.libs.tools.resolve_identifier(repo, rnode.name, only_physical=True) for ip in sorted(found_ips['ipv4']): if not ip4 and not ip.is_private: ip4 = ip @@ -144,30 +144,10 @@ def generate_dns_entries_for_nodes(metadata): ip6 = ip if not ip4 and found_ips['ipv4']: - # 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 + # do it again, but do not filter out private addresses + for ip in sorted(found_ips['ipv4']): + if not ip4: + ip4 = ip if ip4: results.add('{} IN A {}'.format(dns_name, ip4)) diff --git a/libs/tools.py b/libs/tools.py index 40afde2..7a984df 100644 --- a/libs/tools.py +++ b/libs/tools.py @@ -5,7 +5,7 @@ from bundlewrap.utils.text import bold, red from bundlewrap.utils.ui import io -def resolve_identifier(repo, identifier): +def resolve_identifier(repo, identifier, linklocal=False, only_physical=False): """ Try to resolve an identifier (group or node). Return a set of ip addresses valid for this identifier. @@ -34,6 +34,15 @@ def resolve_identifier(repo, identifier): found_ips = set() for node in nodes: for interface, config in node.metadata.get('interfaces', {}).items(): + if only_physical and not ( + interface.startswith('bond') or + interface.startswith('br') or + interface.startswith('en') or + interface.startswith('et') or + interface == 'default' # dummy nodes use these + ): + continue + for ip in config.get('ips', set()): if '/' in ip: found_ips.add(ip_address(ip.split('/')[0])) @@ -54,6 +63,9 @@ def resolve_identifier(repo, identifier): } for ip in found_ips: + if ip.is_link_local and not linklocal: + continue + if isinstance(ip, IPv4Address): ip_dict['ipv4'].add(ip) else: