diff --git a/bundles/powerdns/items.py b/bundles/powerdns/items.py index 7328360..ddb8751 100644 --- a/bundles/powerdns/items.py +++ b/bundles/powerdns/items.py @@ -9,6 +9,10 @@ nameservers = set() for rnode in sorted(repo.nodes_in_group('dns')): nameservers.add(rnode.metadata.get('powerdns/my_hostname', rnode.metadata.get('hostname'))) +my_primary_servers = set() +for ips in node.metadata.get('powerdns/my_primary_servers', {}).values(): + my_primary_servers.update(ips) + directories = { '/etc/powerdns/pdns.d': { 'purge': True, @@ -36,7 +40,7 @@ files = { 'api_key': node.metadata.get('powerdns/api_key'), 'my_hostname': node.metadata.get('powerdns/my_hostname', node.metadata.get('hostname')), 'is_secondary': node.metadata.get('powerdns/is_secondary', False), - 'my_primary_servers': node.metadata.get('powerdns/my_primary_servers', set()), + 'my_primary_servers': my_primary_servers, 'my_secondary_servers': node.metadata.get('powerdns/my_secondary_servers', set()), }, 'needs': { @@ -167,3 +171,21 @@ if node.metadata.get('powerdns/features/pgsql', node.has_bundle('postgresql')): 'svc_systemd:pdns', }, } + + for hostname, ips in node.metadata.get('powerdns/my_primary_servers', {}).items(): + for ip in ips: + ip_name = ip.replace(':', '-') + actions[f'powerdns_ensure_{hostname}_{ip_name}_in_autoprimaries'] = { + 'command': 'psql -c "INSERT INTO supermasters (ip, nameserver, account) VALUES ' + f'(\'{ip}\', \'{hostname}\', \'admin\') ON CONFLICT ON CONSTRAINT ' + f'supermasters_pkey DO UPDATE SET nameserver = \'{hostname}\'" powerdns', + 'unless': f'bash -c "[ \"$(psql -tAqc "SELECT nameserver FROM supermasters WHERE ip = \'{ip}\'" powerdns)\" == \"{hostname}\" ]"', + 'triggers': { + 'action:powerdns_fix_primaries', + }, + } + + actions['powerdns_fix_primaries'] = { + 'command': f'psql -c "UPDATE domains SET master = \'{", ".join(sorted(my_primary_servers))}\'" powerdns', + 'triggered': True, + } diff --git a/bundles/powerdns/metadata.py b/bundles/powerdns/metadata.py index e93c7de..90c06d4 100644 --- a/bundles/powerdns/metadata.py +++ b/bundles/powerdns/metadata.py @@ -86,6 +86,8 @@ def get_ips_of_secondary_nameservers(metadata): ips = set() for rnode in repo.nodes_in_group('dns'): if rnode.metadata.get('powerdns/is_secondary', False): + if rnode.name == node.name: + raise BundleError(f'{node.name} cannot be its own secondary') for _, found_ips in repo.libs.tools.resolve_identifier(repo, rnode.name).items(): ips.update({str(ip) for ip in found_ips}) @@ -102,11 +104,15 @@ def get_ips_of_primary_nameservers(metadata): if not metadata.get('powerdns/is_secondary', False): return {} - ips = set() + ips = {} for rnode in repo.nodes_in_group('dns'): if not rnode.metadata.get('powerdns/is_secondary', False): + if rnode.name == node.name: + raise BundleError(f'{node.name} cannot be its own secondary') + hostname = rnode.metadata.get('hostname') + ips[hostname] = set() for _, found_ips in repo.libs.tools.resolve_identifier(repo, rnode.name).items(): - ips.update({str(ip) for ip in found_ips}) + ips[hostname].update({str(ip) for ip in found_ips}) return { 'powerdns': {