From ca1646d394793f760185debab01578b47a7acafe Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 23:02:47 +0200 Subject: [PATCH] bundles/powerdns: add support for zone transfers --- bundles/powerdns/files/pdns.conf | 15 +++++++++ bundles/powerdns/items.py | 2 ++ bundles/powerdns/metadata.py | 55 ++++++++++++++++++++++++++++++++ groups/features.py | 2 ++ nodes/gce/bind01.py | 4 +++ 5 files changed, 78 insertions(+) diff --git a/bundles/powerdns/files/pdns.conf b/bundles/powerdns/files/pdns.conf index 4b64c72..dc67064 100644 --- a/bundles/powerdns/files/pdns.conf +++ b/bundles/powerdns/files/pdns.conf @@ -16,3 +16,18 @@ security-poll-suffix= server-id=${node.name} default-ttl=86400 + +% if is_secondary: +# Primary server: ${my_primary_server['node']} +slave=yes +superslave=yes +allow-notify-from=${','.join(my_primary_server['ips'])} +% else: +allow-notify-from= +% endif + +% if node.metadata['powerdns'].get('my_secondary_servers'): +# This server is a primary server for the following nodes: +# ${', '.join(node.metadata['powerdns']['my_secondary_servers'])} +master=yes +% endif diff --git a/bundles/powerdns/items.py b/bundles/powerdns/items.py index 414290e..02d7f0e 100644 --- a/bundles/powerdns/items.py +++ b/bundles/powerdns/items.py @@ -53,6 +53,8 @@ files = { 'content_type': 'mako', 'context': { 'api_key': node.metadata['powerdns']['api_key'], + 'is_secondary': node.metadata['powerdns'].get('is_secondary', False), + 'my_primary_server': node.metadata['powerdns'].get('my_primary_server', {}), }, 'needs': { 'pkg_apt:pdns-server', diff --git a/bundles/powerdns/metadata.py b/bundles/powerdns/metadata.py index 4e18293..3c28c97 100644 --- a/bundles/powerdns/metadata.py +++ b/bundles/powerdns/metadata.py @@ -1,3 +1,5 @@ +from bundlewrap.exceptions import NoSuchGroup + defaults = { 'apt': { 'packages': { @@ -23,3 +25,56 @@ defaults = { }, }, } + + +@metadata_reactor +def get_ips_of_secondary_nameservers(metadata): + # Secondary Nameservers can't be a primary nameserver at the same + # time. Return early if this is a secondary server. + if metadata.get('powerdns/is_secondary', False): + return {} + + try: + nameservers = repo.nodes_in_group(metadata.get('powerdns/secondary_nameservers', '')) + except NoSuchGroup: + # This probably is no primary nameserver, either. Should be fine. + return {} + + nodes = set() + for rnode in nameservers: + if rnode.name == node.name: + # We can't be primary and secondary at the same time + continue + + nodes.add(rnode.name) + + return { + 'powerdns': { + 'my_secondary_servers': nodes, + }, + } + + +@metadata_reactor +def get_ips_of_primary_nameserver(metadata): + if not metadata.get('powerdns/is_secondary', False): + return {} + + ips = set() + for rnode in repo.nodes: + if not node.has_bundle('powerdns'): + continue + + if node.name in rnode.metadata.get('powerdns/my_secondary_servers', set()): + return { + 'powerdns': { + 'my_primary_server': { + 'ips': { + str(ip) for ip in repo.libs.tools.resolve_identifier(repo, rnode.name) + }, + 'node': rnode.name, + }, + }, + } + + return {} diff --git a/groups/features.py b/groups/features.py index 796369b..4605270 100644 --- a/groups/features.py +++ b/groups/features.py @@ -16,6 +16,8 @@ groups['dns'] = { 'bind': True, 'pgsql': True, }, + # Overridden in node metadata for primary server + 'is_secondary': True, }, }, } diff --git a/nodes/gce/bind01.py b/nodes/gce/bind01.py index e1f29ad..dc6ae76 100644 --- a/nodes/gce/bind01.py +++ b/nodes/gce/bind01.py @@ -31,6 +31,10 @@ nodes['gce.bind01'] = { }, }, }, + 'powerdns': { + 'is_secondary': False, + 'secondary_nameservers': 'dns', + }, 'vm': { 'cpu': 1, 'ram': 1,