From a08f483ac57c7e14a560eec95bb85c20dde5b078 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Tue, 13 Oct 2020 19:06:22 +0200 Subject: [PATCH 01/23] bundles/powerdns: introduce --- bundles/powerdns/metadata.py | 22 ++++++++++++++++++++++ data/powerdns/files/bind-zones | 1 + groups/features.py | 3 ++- 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 bundles/powerdns/metadata.py create mode 120000 data/powerdns/files/bind-zones diff --git a/bundles/powerdns/metadata.py b/bundles/powerdns/metadata.py new file mode 100644 index 0000000..dd33090 --- /dev/null +++ b/bundles/powerdns/metadata.py @@ -0,0 +1,22 @@ +defaults = { + 'apt': { + 'packages': { + 'pdns-server': {}, + 'pdns-tools': {}, + 'pdns-backend-bind': {}, + 'pdns-backend-pgsql': {}, + }, + }, + 'postgresql': { + 'users': { + 'powerdns': { + 'password': repo.vault.password_for('{} postgresql powerdns'.format(node.name)), + }, + }, + 'databases': { + 'powerdns': { + 'owner': 'powerdns', + }, + }, + }, +} diff --git a/data/powerdns/files/bind-zones b/data/powerdns/files/bind-zones new file mode 120000 index 0000000..0c1b4d8 --- /dev/null +++ b/data/powerdns/files/bind-zones @@ -0,0 +1 @@ +../../bind/files/zones \ No newline at end of file diff --git a/groups/features.py b/groups/features.py index c7c0c25..a468356 100644 --- a/groups/features.py +++ b/groups/features.py @@ -7,6 +7,7 @@ groups['webserver'] = { groups['dns'] = { 'bundles': { - 'bind', + 'postgresql', + 'powerdns', }, } From fa67bd13f4cfe26fd5be796eef09c48cb3d09ca6 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 13:19:44 +0200 Subject: [PATCH 02/23] bundles/powerdns: minimal pdns.conf --- bundles/powerdns/files/pdns.conf | 3 +++ bundles/powerdns/items.py | 13 +++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 bundles/powerdns/files/pdns.conf create mode 100644 bundles/powerdns/items.py diff --git a/bundles/powerdns/files/pdns.conf b/bundles/powerdns/files/pdns.conf new file mode 100644 index 0000000..4c2b1dc --- /dev/null +++ b/bundles/powerdns/files/pdns.conf @@ -0,0 +1,3 @@ +launch=bind,psql + +include-dir=/etc/powerdns/pdns.d diff --git a/bundles/powerdns/items.py b/bundles/powerdns/items.py new file mode 100644 index 0000000..30b64d6 --- /dev/null +++ b/bundles/powerdns/items.py @@ -0,0 +1,13 @@ +directories = { + '/etc/powerdns/pdns.d': { + 'purge': True, + }, +} + +files = { + '/etc/powerdns/pdns.conf': { + 'needs': { + 'pkg_apt:pdns-server', + }, + }, +} From df852e8ef973be08ac513cb34da738103e1c15bd Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 17:44:31 +0200 Subject: [PATCH 03/23] bundles/powerdns: more config, add bind backend --- bundles/powerdns/files/bind.conf | 2 + bundles/powerdns/files/named.conf | 6 ++ bundles/powerdns/files/pdns.conf | 17 +++++- bundles/powerdns/items.py | 92 ++++++++++++++++++++++++++++++- bundles/powerdns/metadata.py | 3 + groups/features.py | 7 +++ 6 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 bundles/powerdns/files/bind.conf create mode 100644 bundles/powerdns/files/named.conf diff --git a/bundles/powerdns/files/bind.conf b/bundles/powerdns/files/bind.conf new file mode 100644 index 0000000..01775c1 --- /dev/null +++ b/bundles/powerdns/files/bind.conf @@ -0,0 +1,2 @@ +launch+=bind +bind-config=/etc/powerdns/named.conf diff --git a/bundles/powerdns/files/named.conf b/bundles/powerdns/files/named.conf new file mode 100644 index 0000000..925e314 --- /dev/null +++ b/bundles/powerdns/files/named.conf @@ -0,0 +1,6 @@ +% for zone in sorted(zones): +zone "${zone}" { + file "/var/lib/powerdns/zones/${zone}"; + type native; +}; +% endfor diff --git a/bundles/powerdns/files/pdns.conf b/bundles/powerdns/files/pdns.conf index 4c2b1dc..5bb2c83 100644 --- a/bundles/powerdns/files/pdns.conf +++ b/bundles/powerdns/files/pdns.conf @@ -1,3 +1,16 @@ -launch=bind,psql - +launch= include-dir=/etc/powerdns/pdns.d + +api=yes +api-key=${api_key} +webserver=yes + +disable-syslog=yes +log-timestamp=no + +max-tcp-connections=500 +max-tcp-connections-per-client=10 + +security-poll-suffix= + +server-id=${node.name} diff --git a/bundles/powerdns/items.py b/bundles/powerdns/items.py index 30b64d6..45abff3 100644 --- a/bundles/powerdns/items.py +++ b/bundles/powerdns/items.py @@ -1,13 +1,103 @@ +from datetime import datetime +from os import listdir +from os.path import isfile, join +from subprocess import check_output + +zone_path = join(repo.path, 'data', 'powerdns', 'files', 'bind-zones') + +ZONE_HEADER = """ +; _ ____ _ _ _____ _ _ _ _ ____ +; / \\ / ___| | | |_ _| | | | \\ | |/ ___| +; / _ \\| | | |_| | | | | | | | \\| | | _ +; / ___ \\ |___| _ | | | | |_| | |\\ | |_| | +; /_/ \\_\\____|_| |_| |_| \\___/|_| \\_|\\____| +; +; --> Diese Datei wird von BundleWrap verwaltet! <-- + +$TTL 60 +@ IN SOA ns-1.kunbox.net. hostmaster.kunbox.net. ( + {serial} + 3600 + 3600 + 86400 + 300 + ) +@ IN NS bind01.gce.kunbox.net. + IN NS b.ns14.net. + IN NS c.ns14.net. + IN NS d.ns14.net. +""" + +default_attributes = { + 'needs': { + 'pkg_apt:pdns-server', + 'pkg_apt:pdns-backend-bind', + 'pkg_apt:pdns-backend-pgsql', + }, + 'triggers': { + 'svc_systemd:pdns:restart', + }, +} + directories = { '/etc/powerdns/pdns.d': { 'purge': True, + **default_attributes, }, + '/var/lib/powerdns/zones': { + 'purge': True, + **default_attributes + } } files = { '/etc/powerdns/pdns.conf': { + 'content_type': 'mako', + 'context': { + 'api_key': node.metadata['powerdns']['api_key'], + }, + **default_attributes, + }, +} + +svc_systemd = { + 'pdns': { 'needs': { - 'pkg_apt:pdns-server', + 'directory:', + 'file:', }, }, } + +if node.metadata['powerdns'].get('features', {}).get('bind', False): + primary_zones = set() + for zone in listdir(zone_path): + if not isfile(join(zone_path, zone)) or zone.startswith(".") or zone.startswith("_"): + continue + + try: + output = check_output(['git', 'log', '-1', '--pretty=%ci', join(zone_path, zone)]).decode('utf-8').strip() + serial = datetime.strptime(output, '%Y-%m-%d %H:%M:%S %z').strftime('%y%m%d%H%M') + except: + serial = datetime.now().strftime('%y%m%d0000') + + primary_zones.add(zone) + + files["/var/lib/powerdns/zones/{}".format(zone)] = { + 'content_type': 'mako', + 'context': { + 'header': ZONE_HEADER.format(serial=serial), + 'metadata_records': node.metadata.get('powerdns', {}).get('bind-zones', {}).get(zone, {}).get('records', []), + }, + 'source': 'bind-zones/{}'.format(zone), + **default_attributes + } + + files['/etc/powerdns/pdns.d/bind.conf'] = default_attributes + files['/etc/powerdns/named.conf'] = { + 'content_type': 'mako', + 'context': { + 'zones': primary_zones, + }, + **default_attributes + } diff --git a/bundles/powerdns/metadata.py b/bundles/powerdns/metadata.py index dd33090..4e18293 100644 --- a/bundles/powerdns/metadata.py +++ b/bundles/powerdns/metadata.py @@ -7,6 +7,9 @@ defaults = { 'pdns-backend-pgsql': {}, }, }, + 'powerdns': { + 'api_key': repo.vault.password_for('{} powerdns api'.format(node.name)), + }, 'postgresql': { 'users': { 'powerdns': { diff --git a/groups/features.py b/groups/features.py index a468356..1c5009e 100644 --- a/groups/features.py +++ b/groups/features.py @@ -10,4 +10,11 @@ groups['dns'] = { 'postgresql', 'powerdns', }, + 'metadata': { + 'powerdns': { + 'features': { + 'bind': True, + }, + }, + }, } From 72abcae3488dc5f414742e245b8e0da5e579b525 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 17:56:13 +0200 Subject: [PATCH 04/23] dns: ns-1.kunbox.net IN A 34.89.208.78 --- data/bind/files/zones/kunbox.net | 3 +++ 1 file changed, 3 insertions(+) diff --git a/data/bind/files/zones/kunbox.net b/data/bind/files/zones/kunbox.net index 94fa4e5..dd82109 100644 --- a/data/bind/files/zones/kunbox.net +++ b/data/bind/files/zones/kunbox.net @@ -14,6 +14,9 @@ mx0 IN A 94.130.52.224 IN AAAA 2a01:4f8:10b:2a5f::2 *.mx0 IN CNAME mx0 +; Nameservers +ns-1 IN A 34.89.208.78 + % for record in sorted(metadata_records): ${record} % endfor From a553e736d1d4f62877108e11946bca084b835751 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 17:59:46 +0200 Subject: [PATCH 05/23] bundles/powerdns: fix dependencies --- bundles/powerdns/items.py | 54 +++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/bundles/powerdns/items.py b/bundles/powerdns/items.py index 45abff3..2a2aeb2 100644 --- a/bundles/powerdns/items.py +++ b/bundles/powerdns/items.py @@ -28,25 +28,23 @@ $TTL 60 IN NS d.ns14.net. """ -default_attributes = { - 'needs': { - 'pkg_apt:pdns-server', - 'pkg_apt:pdns-backend-bind', - 'pkg_apt:pdns-backend-pgsql', - }, - 'triggers': { - 'svc_systemd:pdns:restart', - }, -} - directories = { '/etc/powerdns/pdns.d': { 'purge': True, - **default_attributes, + 'needs': { + 'pkg_apt:pdns-server', + 'pkg_apt:pdns-backend-bind', + 'pkg_apt:pdns-backend-pgsql', + }, + 'triggers': { + 'svc_systemd:pdns:restart', + }, }, '/var/lib/powerdns/zones': { 'purge': True, - **default_attributes + 'needs': { + 'pkg_apt:pdns-backend-bind', + }, } } @@ -56,7 +54,12 @@ files = { 'context': { 'api_key': node.metadata['powerdns']['api_key'], }, - **default_attributes, + 'needs': { + 'pkg_apt:pdns-server', + }, + 'triggers': { + 'svc_systemd:pdns:restart', + }, }, } @@ -65,6 +68,9 @@ svc_systemd = { 'needs': { 'directory:', 'file:', + 'pkg_apt:pdns-server', + 'pkg_apt:pdns-backend-bind', + 'pkg_apt:pdns-backend-pgsql', }, }, } @@ -90,14 +96,28 @@ if node.metadata['powerdns'].get('features', {}).get('bind', False): 'metadata_records': node.metadata.get('powerdns', {}).get('bind-zones', {}).get(zone, {}).get('records', []), }, 'source': 'bind-zones/{}'.format(zone), - **default_attributes + 'triggers': { + 'svc_systemd:pdns:reload', + }, } - files['/etc/powerdns/pdns.d/bind.conf'] = default_attributes + files['/etc/powerdns/pdns.d/bind.conf'] = { + 'needs': { + 'pkg_apt:pdns-backend-bind', + }, + 'triggers': { + 'svc_systemd:pdns:restart', + }, + } files['/etc/powerdns/named.conf'] = { 'content_type': 'mako', 'context': { 'zones': primary_zones, }, - **default_attributes + 'needs': { + 'pkg_apt:pdns-backend-bind', + }, + 'triggers': { + 'svc_systemd:pdns:reload', + }, } From 8acc0a7bb1b16400e2f8ccfc83909854ad28e46c Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 19:12:26 +0200 Subject: [PATCH 06/23] bundles/apt: make sure we have build-essential and git --- bundles/apt/items.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bundles/apt/items.py b/bundles/apt/items.py index 02cb8fb..3aba429 100644 --- a/bundles/apt/items.py +++ b/bundles/apt/items.py @@ -67,10 +67,12 @@ pkg_apt = { 'arping': {}, 'at': {}, + 'build-essential': {}, 'bzip2': {}, 'curl': {}, 'diffutils': {}, 'dnsutils': {}, + 'git': {}, 'grep': {}, 'gzip': {}, 'htop': {}, From 2c1a825b7dd536cbc3ff51d090e08d31b21763c1 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 19:14:15 +0200 Subject: [PATCH 07/23] bundles/apt: make sure we have python3-dev --- bundles/apt/items.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bundles/apt/items.py b/bundles/apt/items.py index 3aba429..1e2c416 100644 --- a/bundles/apt/items.py +++ b/bundles/apt/items.py @@ -90,6 +90,7 @@ pkg_apt = { 'netcat': {}, 'nmap': {}, 'python3': {}, + 'python3-dev': {}, 'python3-pip': {}, 'python3-virtualenv': {}, 'tar': {}, From d442ab399eee3d85aa7fa43efaad498c9c58a285 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 19:23:45 +0200 Subject: [PATCH 08/23] bundles/powerdns: support pgsql --- bundles/powerdns/files/pgsql.conf | 6 ++ bundles/powerdns/files/schema.pgsql.sql | 105 ++++++++++++++++++++++++ bundles/powerdns/items.py | 31 +++++++ groups/features.py | 1 + 4 files changed, 143 insertions(+) create mode 100644 bundles/powerdns/files/pgsql.conf create mode 100644 bundles/powerdns/files/schema.pgsql.sql diff --git a/bundles/powerdns/files/pgsql.conf b/bundles/powerdns/files/pgsql.conf new file mode 100644 index 0000000..293d286 --- /dev/null +++ b/bundles/powerdns/files/pgsql.conf @@ -0,0 +1,6 @@ +launch+=gpgsql +gpgsql-host=localhost +gpgsql-port=5432 +gpgsql-dbname=powerdns +gpgsql-user=powerdns +gpgsql-password=${password} diff --git a/bundles/powerdns/files/schema.pgsql.sql b/bundles/powerdns/files/schema.pgsql.sql new file mode 100644 index 0000000..9635168 --- /dev/null +++ b/bundles/powerdns/files/schema.pgsql.sql @@ -0,0 +1,105 @@ +-- 4.3 schema, https://doc.powerdns.com/authoritative/backends/generic-postgresql.html + +CREATE TABLE domains ( + id SERIAL PRIMARY KEY, + name VARCHAR(255) NOT NULL, + master VARCHAR(128) DEFAULT NULL, + last_check INT DEFAULT NULL, + type VARCHAR(6) NOT NULL, + notified_serial BIGINT DEFAULT NULL, + account VARCHAR(40) DEFAULT NULL, + CONSTRAINT c_lowercase_name CHECK (((name)::TEXT = LOWER((name)::TEXT))) +); + +CREATE UNIQUE INDEX name_index ON domains(name); + +ALTER TABLE domains OWNER TO ${user}; + +CREATE TABLE records ( + id BIGSERIAL PRIMARY KEY, + domain_id INT DEFAULT NULL, + name VARCHAR(255) DEFAULT NULL, + type VARCHAR(10) DEFAULT NULL, + content VARCHAR(65535) DEFAULT NULL, + ttl INT DEFAULT NULL, + prio INT DEFAULT NULL, + change_date INT DEFAULT NULL, + disabled BOOL DEFAULT 'f', + ordername VARCHAR(255), + auth BOOL DEFAULT 't', + CONSTRAINT domain_exists + FOREIGN KEY(domain_id) REFERENCES domains(id) + ON DELETE CASCADE, + CONSTRAINT c_lowercase_name CHECK (((name)::TEXT = LOWER((name)::TEXT))) +); + +CREATE INDEX rec_name_index ON records(name); +CREATE INDEX nametype_index ON records(name,type); +CREATE INDEX domain_id ON records(domain_id); +CREATE INDEX recordorder ON records (domain_id, ordername text_pattern_ops); + +ALTER TABLE records OWNER TO ${user}; + +CREATE TABLE supermasters ( + ip INET NOT NULL, + nameserver VARCHAR(255) NOT NULL, + account VARCHAR(40) NOT NULL, + PRIMARY KEY(ip, nameserver) +); + +ALTER TABLE supermasters OWNER TO ${user}; + +CREATE TABLE comments ( + id SERIAL PRIMARY KEY, + domain_id INT NOT NULL, + name VARCHAR(255) NOT NULL, + type VARCHAR(10) NOT NULL, + modified_at INT NOT NULL, + account VARCHAR(40) DEFAULT NULL, + comment VARCHAR(65535) NOT NULL, + CONSTRAINT domain_exists + FOREIGN KEY(domain_id) REFERENCES domains(id) + ON DELETE CASCADE, + CONSTRAINT c_lowercase_name CHECK (((name)::TEXT = LOWER((name)::TEXT))) +); + +CREATE INDEX comments_domain_id_idx ON comments (domain_id); +CREATE INDEX comments_name_type_idx ON comments (name, type); +CREATE INDEX comments_order_idx ON comments (domain_id, modified_at); + +ALTER TABLE comments OWNER TO ${user}; + +CREATE TABLE domainmetadata ( + id SERIAL PRIMARY KEY, + domain_id INT REFERENCES domains(id) ON DELETE CASCADE, + kind VARCHAR(32), + content TEXT +); + +CREATE INDEX domainidmetaindex ON domainmetadata(domain_id); + +ALTER TABLE domainmetadata OWNER TO ${user}; + +CREATE TABLE cryptokeys ( + id SERIAL PRIMARY KEY, + domain_id INT REFERENCES domains(id) ON DELETE CASCADE, + flags INT NOT NULL, + active BOOL, + content TEXT +); + +CREATE INDEX domainidindex ON cryptokeys(domain_id); +ALTER TABLE cryptokeys OWNER TO ${user}; + + +CREATE TABLE tsigkeys ( + id SERIAL PRIMARY KEY, + name VARCHAR(255), + algorithm VARCHAR(50), + secret VARCHAR(255), + CONSTRAINT c_lowercase_name CHECK (((name)::TEXT = LOWER((name)::TEXT))) +); + +CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm); + +ALTER TABLE tsigkeys OWNER TO ${user}; diff --git a/bundles/powerdns/items.py b/bundles/powerdns/items.py index 2a2aeb2..fe8bd8d 100644 --- a/bundles/powerdns/items.py +++ b/bundles/powerdns/items.py @@ -109,6 +109,7 @@ if node.metadata['powerdns'].get('features', {}).get('bind', False): 'svc_systemd:pdns:restart', }, } + files['/etc/powerdns/named.conf'] = { 'content_type': 'mako', 'context': { @@ -121,3 +122,33 @@ if node.metadata['powerdns'].get('features', {}).get('bind', False): 'svc_systemd:pdns:reload', }, } + +if node.metadata['powerdns'].get('features', {}).get('pgsql', False): + files['/etc/powerdns/pdns.d/pgsql.conf'] = { + 'content_type': 'mako', + 'context': { + 'password': node.metadata['postgresql']['users']['powerdns']['password'], + }, + 'needs': { + 'pkg_apt:pdns-backend-pgsql', + }, + 'triggers': { + 'svc_systemd:pdns:restart', + }, + } + + files['/etc/powerdns/schema.pgsql.sql'] = {} + + actions = { + 'powerdns_load_pgsql_schema': { + 'command': 'sudo -u postgres psql -d powerdns < /etc/powerdns/schema.pgsql.sql', + 'unless': 'sudo -u postgres psql -d powerdns -c "\dt" | grep domains 2>&1 >/dev/null', + 'needs': { + 'bundle:postgresql', + 'file:/etc/powerdns/schema.pgsql.sql', + }, + 'needed_by': { + 'svc_systemd:pdns', + }, + } + } diff --git a/groups/features.py b/groups/features.py index 1c5009e..796369b 100644 --- a/groups/features.py +++ b/groups/features.py @@ -14,6 +14,7 @@ groups['dns'] = { 'powerdns': { 'features': { 'bind': True, + 'pgsql': True, }, }, }, From 0533e4087ab2c3c137a5ce6eb72acbb3b617c6ed Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 19:24:40 +0200 Subject: [PATCH 09/23] bundles/postgresql: install dev packages --- bundles/postgresql/items.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bundles/postgresql/items.py b/bundles/postgresql/items.py index ff24ccd..7bbf141 100644 --- a/bundles/postgresql/items.py +++ b/bundles/postgresql/items.py @@ -1,6 +1,7 @@ pkg_apt = { 'postgresql-11': {}, 'postgresql-client-11': {}, + 'postgresql-server-dev-11': {}, } if node.has_bundle('zfs'): From 9bba18d13edaa6539d03686a7f7090724429beec Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 20:10:34 +0200 Subject: [PATCH 10/23] bundles/powerdnsadmin: introduce --- bundles/powerdnsadmin/files/config.py | 14 +++ .../powerdnsadmin/files/powerdnsadmin.service | 14 +++ bundles/powerdnsadmin/items.py | 87 +++++++++++++++++++ bundles/powerdnsadmin/metadata.py | 35 ++++++++ nodes/gce/bind01.py | 6 +- 5 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 bundles/powerdnsadmin/files/config.py create mode 100644 bundles/powerdnsadmin/files/powerdnsadmin.service create mode 100644 bundles/powerdnsadmin/items.py create mode 100644 bundles/powerdnsadmin/metadata.py diff --git a/bundles/powerdnsadmin/files/config.py b/bundles/powerdnsadmin/files/config.py new file mode 100644 index 0000000..53a70bb --- /dev/null +++ b/bundles/powerdnsadmin/files/config.py @@ -0,0 +1,14 @@ +SALT = '${repo.vault.decrypt('encrypt$gAAAAABfidFVqVEgWvlXgP-GSQUgVtcTxzoZx2G8VYWHaGKRpgaLDchlTRcKwqgvfG5orNpXt7aDd5i2aehi6cvIlxYNdL87twfVhDLBDho8j-Uz5Vga8-9cEzEZULl5pFCIcRlYUCKyEIOcdXSaLCM3p8pGjrh-O8_g49rbADKmLFoJx2vVTVs=')}' +SECRET_KEY = '${repo.vault.password_for('{} powerdnsadmin secret_key'.format(node.name))}' +BIND_ADDRESS = '127.0.0.1' +PORT = 9191 +OFFLINE_MODE = True + +SQLA_DB_USER = 'powerdnsadmin' +SQLA_DB_PASSWORD = '${node.metadata['postgresql']['users']['powerdnsadmin']['password']}' +SQLA_DB_HOST = '127.0.0.1' +SQLA_DB_NAME = 'powerdnsadmin' +SQLALCHEMY_TRACK_MODIFICATIONS = True +SQLALCHEMY_DATABASE_URI = 'postgresql://' + SQLA_DB_USER + ':' + SQLA_DB_PASSWORD + '@' + SQLA_DB_HOST + '/' + SQLA_DB_NAME + +SAML_ENABLED = False diff --git a/bundles/powerdnsadmin/files/powerdnsadmin.service b/bundles/powerdnsadmin/files/powerdnsadmin.service new file mode 100644 index 0000000..3f7eb31 --- /dev/null +++ b/bundles/powerdnsadmin/files/powerdnsadmin.service @@ -0,0 +1,14 @@ +[Unit] +Description=PowerDNS-Admin +After=network.target postgresql.service + +[Service] +User=powerdnsadmin +Group=powerdnsadmin +Environment=FLASK_CONF=/opt/powerdnsadmin/config.py +WorkingDirectory=/opt/powerdnsadmin/src +ExecStartPre=-/bin/chown powerdnsadmin:powerdnsadmin /opt/powerdnsadmin/src/powerdnsadmin/static +ExecStart=/opt/powerdnsadmin/venv/bin/gunicorn 'powerdnsadmin:create_app()' + +[Install] +WantedBy=multi-user.target diff --git a/bundles/powerdnsadmin/items.py b/bundles/powerdnsadmin/items.py new file mode 100644 index 0000000..2d1802b --- /dev/null +++ b/bundles/powerdnsadmin/items.py @@ -0,0 +1,87 @@ +assert node.has_bundle('nodejs') +assert node.has_bundle('postgresql') + +directories = { + '/opt/powerdnsadmin/src': {}, +} + +git_deploy = { + '/opt/powerdnsadmin/src': { + 'repo': 'https://github.com/ngoduykhanh/PowerDNS-Admin.git', + 'rev': 'master', + 'triggers': { + 'action:powerdnsadmin_install_deps', + 'action:powerdnsadmin_upgrade_database', + 'action:powerdnsadmin_compile_assets', + 'svc_systemd:powerdnsadmin:restart', + }, + }, +} + +files = { + '/opt/powerdnsadmin/config.py': { + 'content_type': 'mako', + }, + '/etc/systemd/system/powerdnsadmin.service': { + 'triggers': { + 'action:systemd-reload', + }, + }, +} + +actions = { + 'powerdnsadmin_create_virtualenv': { + 'command': '/usr/bin/python3 -m virtualenv -p python3 /opt/powerdnsadmin/venv/', + 'unless': 'test -d /opt/powerdnsadmin/venv/', + 'needs': { + 'directory:/opt/powerdnsadmin', # provided by bundle:users + }, + }, + 'powerdnsadmin_install_deps': { + 'triggered': True, + 'command': '/opt/powerdnsadmin/venv/bin/pip install -r /opt/powerdnsadmin/src/requirements.txt', + 'needs': { + 'action:powerdnsadmin_create_virtualenv', + 'pkg_apt:', + }, + }, + 'powerdnsadmin_install_deps': { + 'triggered': True, + 'command': '/opt/powerdnsadmin/venv/bin/pip install -r /opt/powerdnsadmin/src/requirements.txt', + 'needs': { + 'action:powerdnsadmin_create_virtualenv', + 'pkg_apt:', + }, + }, + 'powerdnsadmin_upgrade_database': { + 'triggered': True, + 'command': 'FLASK_CONF=/opt/powerdnsadmin/config.py FLASK_APP=/opt/powerdnsadmin/src/powerdnsadmin/__init__.py /opt/powerdnsadmin/venv/bin/flask db upgrade', + # TODO unless + 'needs': { + 'action:powerdnsadmin_install_deps', + 'bundle:postgresql', + 'pkg_apt:', + }, + }, + 'powerdnsadmin_compile_assets': { + 'triggered': True, + 'command': 'cd /opt/powerdnsadmin/src && yarn install --pure-lockfile && FLASK_APP=/opt/powerdnsadmin/src/powerdnsadmin/__init__.py /opt/powerdnsadmin/venv/bin/flask assets build', + 'needs': { + 'action:powerdnsadmin_install_deps', + 'pkg_apt:', + }, + }, +} + +svc_systemd = { + 'powerdnsadmin': { + 'needs': { + 'file:/opt/powerdnsadmin/config.py', + 'file:/etc/systemd/system/powerdnsadmin.service', + 'git_deploy:/opt/powerdnsadmin/src', + 'action:powerdnsadmin_install_deps', + 'action:powerdnsadmin_upgrade_database', + 'action:powerdnsadmin_compile_assets', + }, + }, +} diff --git a/bundles/powerdnsadmin/metadata.py b/bundles/powerdnsadmin/metadata.py new file mode 100644 index 0000000..aeb3562 --- /dev/null +++ b/bundles/powerdnsadmin/metadata.py @@ -0,0 +1,35 @@ +defaults = { + 'apt': { + 'packages': { + 'default-libmysqlclient-dev': {}, + 'libffi-dev': {}, + 'libldap2-dev': {}, + 'libsasl2-dev': {}, + 'libssl-dev': {}, + 'libxml2-dev': {}, + 'libxmlsec1-dev': {}, + 'libxslt1-dev': {}, + 'pkg-config': {}, + 'python3-psycopg2': {}, + 'python3-wheel': {}, + }, + }, + 'users': { + 'powerdnsadmin': { + 'home': '/opt/powerdnsadmin', + }, + }, + 'postgresql': { + 'users': { + 'powerdnsadmin': { + 'password': repo.vault.password_for('{} postgresql powerdnsadmin'.format(node.name)), + }, + }, + 'databases': { + 'powerdnsadmin': { + 'owner': 'powerdnsadmin', + }, + }, + }, + +} diff --git a/nodes/gce/bind01.py b/nodes/gce/bind01.py index abe38f3..cb99b5c 100644 --- a/nodes/gce/bind01.py +++ b/nodes/gce/bind01.py @@ -1,7 +1,11 @@ -# ns-3.kunbox.net +# ns-1.kunbox.net # Frankfurt, Germany nodes['gce.bind01'] = { + 'bundles': { + 'nodejs', + 'powerdnsadmin', + }, 'groups': { 'dns', }, From 155c93f739e21bac64558346cb653a52d5b2d435 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 20:10:55 +0200 Subject: [PATCH 11/23] bundles/powerdns: fix schema import for pgsql --- bundles/powerdns/items.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/powerdns/items.py b/bundles/powerdns/items.py index fe8bd8d..3f903a8 100644 --- a/bundles/powerdns/items.py +++ b/bundles/powerdns/items.py @@ -141,7 +141,7 @@ if node.metadata['powerdns'].get('features', {}).get('pgsql', False): actions = { 'powerdns_load_pgsql_schema': { - 'command': 'sudo -u postgres psql -d powerdns < /etc/powerdns/schema.pgsql.sql', + 'command': 'PGPASSWORD={pw} psql -h 127.0.0.1 -d powerdns -U powerdns -w < /etc/powerdns/schema.pgsql.sql'.format(pw=node.metadata['postgresql']['users']['powerdns']['password']), 'unless': 'sudo -u postgres psql -d powerdns -c "\dt" | grep domains 2>&1 >/dev/null', 'needs': { 'bundle:postgresql', From e5a7aad0e86ae3f6a04a2d8c9a582bedeb3b21fa Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 20:11:14 +0200 Subject: [PATCH 12/23] dns: fix missing "" for TXT records --- data/bind/files/zones/franzi.business | 10 +++++----- data/bind/files/zones/kunbox.net | 14 +++++++------- data/bind/files/zones/kunsmann.eu | 8 ++++---- data/bind/files/zones/trans-agenda.eu | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/data/bind/files/zones/franzi.business b/data/bind/files/zones/franzi.business index ce9b927..33ddf88 100644 --- a/data/bind/files/zones/franzi.business +++ b/data/bind/files/zones/franzi.business @@ -5,7 +5,7 @@ $ORIGIN franzi.business. @ IN A 94.130.52.224 IN AAAA 2a01:4f8:10b:2a5f::2 IN MX 10 mx0.kunbox.net. - IN TXT v=spf1 mx ~all + IN TXT "v=spf1 mx ~all" * IN A 94.130.52.224 IN AAAA 2a01:4f8:10b:2a5f::2 @@ -18,11 +18,11 @@ icinga IN A 165.232.42.173 sewfile IN A 116.203.205.248 IN AAAA 2a01:4f8:c0c:c71b::1 - IN TXT v=spf1 a mx ~all + IN TXT "v=spf1 a mx ~all" _matrix._tcp IN SRV 10 10 8448 matrix -2019._domainkey IN TXT v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwkg6UAcu3V98hal1UVf6yB0WT1CKDS0AK83CUlSP8bUwraPxkxK1nkQOUsmjbQs6a3FhdsKprMi32GeUaTVvZg81JIybPk3jNugfNWfSjs2TXPomYu+XD2pmmbR3cZlzC5NGR2nmBFt/P/S2ihPHj35KziiBIwK1TdvOi1M2+upCjK33Icco0ByCm0gJpD2O0cbqcBcUKqd6X440vYhNXH1ygp0e91P0iRnvS9sg6yD0xjD8kD6j/8GfxBY+9bpU3EvDoBgyJSbjw5b6PUVJbKMXzw1NIRNj0SXKs5BakjS8+7u62vR11IPCYRwy+yr0rDT0tNegM7gStIIgoTpOoQIDAQAB -_dmarc IN TXT v=DMARC1; p=none; rua=mailto:postmaster@kunsmann.eu; ruf=mailto:postmaster@kunsmann.eu; fo=0:d:s; adkim=r; aspf=r -_token._dnswl IN TXT gg3mbwjx9bbuo5osvhq7oz6bc881wcmc +2019._domainkey IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwkg6UAcu3V98hal1UVf6yB0WT1CKDS0AK83CUlSP8bUwraPxkxK1nkQOUsmjbQs6a3FhdsKprMi32GeUaTVvZg81JIybPk3jNugfNWfSjs2TXPomYu+XD2pmmbR3cZlzC5NGR2nmBFt/P/S2ihPHj35KziiBIwK1TdvOi1M2+upCjK33Icco0ByCm0gJpD2O0cbqcBcUKqd6X440vYhNXH1ygp0e91P0iRnvS9sg6yD0xjD8kD6j/8GfxBY+9bpU3EvDoBgyJSbjw5b6PUVJbKMXzw1NIRNj0SXKs5BakjS8+7u62vR11IPCYRwy+yr0rDT0tNegM7gStIIgoTpOoQIDAQAB" +_dmarc IN TXT "v=DMARC1; p=none; rua=mailto:postmaster@kunsmann.eu; ruf=mailto:postmaster@kunsmann.eu; fo=0:d:s; adkim=r; aspf=r" +_token._dnswl IN TXT "gg3mbwjx9bbuo5osvhq7oz6bc881wcmc" diff --git a/data/bind/files/zones/kunbox.net b/data/bind/files/zones/kunbox.net index dd82109..bae3e61 100644 --- a/data/bind/files/zones/kunbox.net +++ b/data/bind/files/zones/kunbox.net @@ -7,7 +7,7 @@ $ORIGIN kunbox.net. ; Needs to have a working Mail address, otherwise Telekom goes mimimi IN MX 10 mx0 - IN TXT v=spf1 mx ~all + IN TXT "v=spf1 mx ~all" ; Mail servers mx0 IN A 94.130.52.224 @@ -21,10 +21,10 @@ ns-1 IN A 34.89.208.78 ${record} % endfor -2019._domainkey IN TXT v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwkg6UAcu3V98hal1UVf6yB0WT1CKDS0AK83CUlSP8bUwraPxkxK1nkQOUsmjbQs6a3FhdsKprMi32GeUaTVvZg81JIybPk3jNugfNWfSjs2TXPomYu+XD2pmmbR3cZlzC5NGR2nmBFt/P/S2ihPHj35KziiBIwK1TdvOi1M2+upCjK33Icco0ByCm0gJpD2O0cbqcBcUKqd6X440vYhNXH1ygp0e91P0iRnvS9sg6yD0xjD8kD6j/8GfxBY+9bpU3EvDoBgyJSbjw5b6PUVJbKMXzw1NIRNj0SXKs5BakjS8+7u62vR11IPCYRwy+yr0rDT0tNegM7gStIIgoTpOoQIDAQAB -_dmarc IN TXT v=DMARC1; p=none; rua=mailto:postmaster@kunsmann.eu; ruf=mailto:postmaster@kunsmann.eu; fo=0:d:s; adkim=r; aspf=r -_token._dnswl IN TXT 6akc10htbgmg56e072w0w2n0wql4oezu +2019._domainkey IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwkg6UAcu3V98hal1UVf6yB0WT1CKDS0AK83CUlSP8bUwraPxkxK1nkQOUsmjbQs6a3FhdsKprMi32GeUaTVvZg81JIybPk3jNugfNWfSjs2TXPomYu+XD2pmmbR3cZlzC5NGR2nmBFt/P/S2ihPHj35KziiBIwK1TdvOi1M2+upCjK33Icco0ByCm0gJpD2O0cbqcBcUKqd6X440vYhNXH1ygp0e91P0iRnvS9sg6yD0xjD8kD6j/8GfxBY+9bpU3EvDoBgyJSbjw5b6PUVJbKMXzw1NIRNj0SXKs5BakjS8+7u62vR11IPCYRwy+yr0rDT0tNegM7gStIIgoTpOoQIDAQAB" +_dmarc IN TXT "v=DMARC1; p=none; rua=mailto:postmaster@kunsmann.eu; ruf=mailto:postmaster@kunsmann.eu; fo=0:d:s; adkim=r; aspf=r" +_token._dnswl IN TXT "6akc10htbgmg56e072w0w2n0wql4oezu" -f2k1.de._report._dmarc IN TXT v=DMARC1 -franzi.business._report._dmarc IN TXT v=DMARC1 -kunsmann.eu._report._dmarc IN TXT v=DMARC1 +f2k1.de._report._dmarc IN TXT "v=DMARC1" +franzi.business._report._dmarc IN TXT "v=DMARC1" +kunsmann.eu._report._dmarc IN TXT "v=DMARC1" diff --git a/data/bind/files/zones/kunsmann.eu b/data/bind/files/zones/kunsmann.eu index 009e53b..2e58da4 100644 --- a/data/bind/files/zones/kunsmann.eu +++ b/data/bind/files/zones/kunsmann.eu @@ -5,11 +5,11 @@ $ORIGIN kunsmann.eu. @ IN A 94.130.52.224 IN AAAA 2a01:4f8:10b:2a5f::2 IN MX 10 mx0.kunbox.net. - IN TXT v=spf1 a mx ~all + IN TXT "v=spf1 a mx ~all" * IN A 94.130.52.224 IN AAAA 2a01:4f8:10b:2a5f::2 -2019._domainkey IN TXT v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwkg6UAcu3V98hal1UVf6yB0WT1CKDS0AK83CUlSP8bUwraPxkxK1nkQOUsmjbQs6a3FhdsKprMi32GeUaTVvZg81JIybPk3jNugfNWfSjs2TXPomYu+XD2pmmbR3cZlzC5NGR2nmBFt/P/S2ihPHj35KziiBIwK1TdvOi1M2+upCjK33Icco0ByCm0gJpD2O0cbqcBcUKqd6X440vYhNXH1ygp0e91P0iRnvS9sg6yD0xjD8kD6j/8GfxBY+9bpU3EvDoBgyJSbjw5b6PUVJbKMXzw1NIRNj0SXKs5BakjS8+7u62vR11IPCYRwy+yr0rDT0tNegM7gStIIgoTpOoQIDAQAB -_dmarc IN TXT v=DMARC1; p=none; rua=mailto:postmaster@kunsmann.eu; ruf=mailto:postmaster@kunsmann.eu; fo=0:d:s; adkim=r; aspf=r -_token._dnswl IN TXT 5mx0rv9ru8s1zz4tf4xlt48osh09czmg +2019._domainkey IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwkg6UAcu3V98hal1UVf6yB0WT1CKDS0AK83CUlSP8bUwraPxkxK1nkQOUsmjbQs6a3FhdsKprMi32GeUaTVvZg81JIybPk3jNugfNWfSjs2TXPomYu+XD2pmmbR3cZlzC5NGR2nmBFt/P/S2ihPHj35KziiBIwK1TdvOi1M2+upCjK33Icco0ByCm0gJpD2O0cbqcBcUKqd6X440vYhNXH1ygp0e91P0iRnvS9sg6yD0xjD8kD6j/8GfxBY+9bpU3EvDoBgyJSbjw5b6PUVJbKMXzw1NIRNj0SXKs5BakjS8+7u62vR11IPCYRwy+yr0rDT0tNegM7gStIIgoTpOoQIDAQAB" +_dmarc IN TXT "v=DMARC1; p=none; rua=mailto:postmaster@kunsmann.eu; ruf=mailto:postmaster@kunsmann.eu; fo=0:d:s; adkim=r; aspf=r" +_token._dnswl IN TXT "5mx0rv9ru8s1zz4tf4xlt48osh09czmg" diff --git a/data/bind/files/zones/trans-agenda.eu b/data/bind/files/zones/trans-agenda.eu index 0da91a1..29c3787 100644 --- a/data/bind/files/zones/trans-agenda.eu +++ b/data/bind/files/zones/trans-agenda.eu @@ -3,7 +3,7 @@ ${header} $ORIGIN trans-agenda.eu. @ IN MX 10 mx0.kunbox.net. - IN TXT v=spf1 a mx ~all + IN TXT "v=spf1 a mx ~all" part.of.the IN A 94.130.52.224 part.of.the IN AAAA 2a01:4f8:10b:2a5f::2 From 0a115d2372ae552bf69c3a9d2efb0e398be97b1b Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 20:12:47 +0200 Subject: [PATCH 13/23] EOL bundles/bind --- bundles/bind/files/keys.conf | 6 - bundles/bind/files/named.conf.local | 30 ---- bundles/bind/files/named.conf.options | 3 - bundles/bind/items.py | 146 ------------------ bundles/bind/metadata.py | 72 --------- data/powerdns/files/bind-zones | 1 - .../files/bind-zones}/felix-kunsmann.de | 0 .../files/bind-zones}/franzi.business | 0 .../files/bind-zones}/kunbox.net | 0 .../files/bind-zones}/kunsmann.eu | 0 .../files/bind-zones}/trans-agenda.de | 0 .../files/bind-zones}/trans-agenda.eu | 0 12 files changed, 258 deletions(-) delete mode 100644 bundles/bind/files/keys.conf delete mode 100644 bundles/bind/files/named.conf.local delete mode 100644 bundles/bind/files/named.conf.options delete mode 100644 bundles/bind/items.py delete mode 100644 bundles/bind/metadata.py delete mode 120000 data/powerdns/files/bind-zones rename data/{bind/files/zones => powerdns/files/bind-zones}/felix-kunsmann.de (100%) rename data/{bind/files/zones => powerdns/files/bind-zones}/franzi.business (100%) rename data/{bind/files/zones => powerdns/files/bind-zones}/kunbox.net (100%) rename data/{bind/files/zones => powerdns/files/bind-zones}/kunsmann.eu (100%) rename data/{bind/files/zones => powerdns/files/bind-zones}/trans-agenda.de (100%) rename data/{bind/files/zones => powerdns/files/bind-zones}/trans-agenda.eu (100%) diff --git a/bundles/bind/files/keys.conf b/bundles/bind/files/keys.conf deleted file mode 100644 index faf4ce4..0000000 --- a/bundles/bind/files/keys.conf +++ /dev/null @@ -1,6 +0,0 @@ -% for key in keys: -key ${key['name']} { - algorithm ${key['algorithm']}; - secret "${key['secret']}"; -}; -% endfor diff --git a/bundles/bind/files/named.conf.local b/bundles/bind/files/named.conf.local deleted file mode 100644 index 5f5e826..0000000 --- a/bundles/bind/files/named.conf.local +++ /dev/null @@ -1,30 +0,0 @@ -include "/etc/bind/keys.conf"; - -% for zone in sorted(primary_zones): -zone "${zone}" IN { - type master; - file "/var/lib/bind/primary/${zone}"; -}; -% endfor - - -zone "10.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; - -zone "16.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; -zone "17.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; -zone "18.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; -zone "19.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; -zone "20.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; -zone "21.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; -zone "22.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; -zone "23.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; -zone "24.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; -zone "25.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; -zone "26.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; -zone "27.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; -zone "28.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; -zone "29.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; -zone "30.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; -zone "31.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; - -zone "168.192.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; diff --git a/bundles/bind/files/named.conf.options b/bundles/bind/files/named.conf.options deleted file mode 100644 index 1e9db6e..0000000 --- a/bundles/bind/files/named.conf.options +++ /dev/null @@ -1,3 +0,0 @@ -% for o in node.metadata.get('bind', {}).get('options', []): -<%include file="options/${o}"/> -% endfor diff --git a/bundles/bind/items.py b/bundles/bind/items.py deleted file mode 100644 index 958fffc..0000000 --- a/bundles/bind/items.py +++ /dev/null @@ -1,146 +0,0 @@ -from os import listdir -from os.path import isfile, join -from datetime import datetime -from subprocess import check_output - -ZONE_HEADER = """ -; _ ____ _ _ _____ _ _ _ _ ____ -; / \\ / ___| | | |_ _| | | | \\ | |/ ___| -; / _ \\| | | |_| | | | | | | | \\| | | _ -; / ___ \\ |___| _ | | | | |_| | |\\ | |_| | -; /_/ \\_\\____|_| |_| |_| \\___/|_| \\_|\\____| -; -; --> Diese Datei wird von BundleWrap verwaltet! <-- - -$TTL 60 -@ IN SOA ns-1.kunbox.net. hostmaster.kunbox.net. ( - {serial} - 3600 - 3600 - 86400 - 300 - ) -@ IN NS bind01.gce.kunbox.net. - IN NS b.ns14.net. - IN NS c.ns14.net. - IN NS d.ns14.net. -""" - -svc_systemd = { - 'bind9': { - 'needs': { - 'pkg_apt:bind9', - }, - }, -} - -pkg_apt = { - 'bind9': {}, -} - -directories = { - "/var/lib/bind/primary": { - 'group': 'bind', - 'needs': { - 'pkg_apt:bind9', - }, - 'owner': 'bind', - 'purge': True, - }, - "/var/log/named": { - 'group': 'bind', - 'needs': { - 'pkg_apt:bind9', - }, - 'owner': 'bind', - }, -} - -files = { - "/etc/bind/keys.conf": { - 'content_type': 'mako', - 'group': 'bind', - 'mode': '0440', - 'context': { - 'keys': node.metadata.get('bind', {}).get('keys', []), - }, - 'triggers': { - 'svc_systemd:bind9:reload', - }, - 'needs': { - 'pkg_apt:bind9', - }, - }, - "/etc/bind/named.conf.options": { - 'content_type': 'mako', - 'group': 'bind', - 'mode': '0440', - 'triggers': { - 'svc_systemd:bind9:reload', - }, - 'needs': { - 'pkg_apt:bind9', - }, - }, -} - -if node.metadata.get('bind', {}).get('rndc', ''): - files['/etc/bind/rndc.conf'] = { - 'mode': '0440', - 'source': 'rndc/{}'.format(node.metadata['bind']['rndc']), - 'content_type': 'mako', - 'triggers': { - 'svc_systemd:bind9:reload', - }, - } - -# this looks for zones either directly at data/bind/zones/ or in a subdirectory if so configured -zone_path = join( - repo.path, - 'data', 'bind', 'files', 'zones', - node.metadata.get('bind', {}).get('zone_path', ""), -) - -primary_zones = set() - -for zone in listdir(zone_path): - if not isfile(join(zone_path, zone)) or zone.startswith(".") or zone.startswith("_"): - continue - - output = check_output(['git', 'log', '-1', '--pretty=%ci', join(zone_path, zone)]).decode('utf-8').strip() - serial = datetime.strptime(output, '%Y-%m-%d %H:%M:%S %z').strftime('%y%m%d%H%M') - - primary_zones.add(zone) - - files["/var/lib/bind/primary/{}".format(zone)] = { - 'content_type': 'mako', - 'context': { - 'header': ZONE_HEADER.format(serial=serial), - 'metadata_records': node.metadata.get('bind', {}).get('zones_primary', {}).get(zone, {}).get('records', []), - }, - 'mode': '0444', - 'owner': 'bind', - 'source': 'zones/{}'.format(join(node.metadata.get('bind', {}).get('zone_path', ""), zone)), - 'triggers': { - 'svc_systemd:bind9:reload', - }, - 'needs': { - 'pkg_apt:bind9' - }, - } - -primary_zones.union(set(node.metadata.get('bind', {}).get('zones_primary', {}).keys())) - -files['/etc/bind/named.conf.local'] = { - 'content_type': 'mako', - 'context': { - 'primary_zones': list(primary_zones), - }, - 'group': 'bind', - 'triggers': { - 'svc_systemd:bind9:reload', - }, - 'needs': { - 'pkg_apt:bind9', - }, -} diff --git a/bundles/bind/metadata.py b/bundles/bind/metadata.py deleted file mode 100644 index a99c341..0000000 --- a/bundles/bind/metadata.py +++ /dev/null @@ -1,72 +0,0 @@ -from bundlewrap.metadata import atomic - - -defaults = { - 'icinga2_api': { - 'bind': { - 'services': { - 'BIND PROCESS': { - 'command_on_monitored_host': '/usr/lib/nagios/plugins/check_procs -C named -c 1:1', - }, - }, - }, - }, -} - -@metadata_reactor -def port_checks(metadata): - services = {} - - for interface in metadata.get('bind/listen', set()): - services[f'BIND PORT {interface}'] = { - 'check_command': 'tcp', - 'vars.tcp_address': metadata.get(f'interfaces/{interface}/ip_addresses')[0], - 'vars.tcp_port': 53, - } - - return { - 'icinga2_api': { - 'bind': { - 'services': services, - }, - }, - } - -@metadata_reactor -def generate_dns_entries_for_nodes(metadata): - results = set() - - for rnode in repo.nodes: - node_name_split = rnode.name.split('.') - node_name_split.reverse() - dns_name = '.'.join(node_name_split) - ip4 = None - ip6 = None - - # We only need this for GCE, because machines over there don't - # have a public ipv4 address. - if rnode.metadata.get('external_ipv4', None): - ip4 = rnode.metadata.get('external_ipv4') - - for iface, config in sorted(rnode.metadata.get('interfaces', {}).items()): - if not ip4 and 'ipv4' in config: - ip4 = sorted(config['ipv4'])[0] - - if not ip6 and 'ipv6' in config: - ip6 = sorted(config['ipv6'])[0] - - if ip4: - results.add('{} IN A {}'.format(dns_name, ip4)) - - if ip6: - results.add('{} IN AAAA {}'.format(dns_name, ip6)) - - return { - 'bind': { - 'zones_primary': { - 'kunbox.net': { - 'records': results, - }, - }, - }, - } diff --git a/data/powerdns/files/bind-zones b/data/powerdns/files/bind-zones deleted file mode 120000 index 0c1b4d8..0000000 --- a/data/powerdns/files/bind-zones +++ /dev/null @@ -1 +0,0 @@ -../../bind/files/zones \ No newline at end of file diff --git a/data/bind/files/zones/felix-kunsmann.de b/data/powerdns/files/bind-zones/felix-kunsmann.de similarity index 100% rename from data/bind/files/zones/felix-kunsmann.de rename to data/powerdns/files/bind-zones/felix-kunsmann.de diff --git a/data/bind/files/zones/franzi.business b/data/powerdns/files/bind-zones/franzi.business similarity index 100% rename from data/bind/files/zones/franzi.business rename to data/powerdns/files/bind-zones/franzi.business diff --git a/data/bind/files/zones/kunbox.net b/data/powerdns/files/bind-zones/kunbox.net similarity index 100% rename from data/bind/files/zones/kunbox.net rename to data/powerdns/files/bind-zones/kunbox.net diff --git a/data/bind/files/zones/kunsmann.eu b/data/powerdns/files/bind-zones/kunsmann.eu similarity index 100% rename from data/bind/files/zones/kunsmann.eu rename to data/powerdns/files/bind-zones/kunsmann.eu diff --git a/data/bind/files/zones/trans-agenda.de b/data/powerdns/files/bind-zones/trans-agenda.de similarity index 100% rename from data/bind/files/zones/trans-agenda.de rename to data/powerdns/files/bind-zones/trans-agenda.de diff --git a/data/bind/files/zones/trans-agenda.eu b/data/powerdns/files/bind-zones/trans-agenda.eu similarity index 100% rename from data/bind/files/zones/trans-agenda.eu rename to data/powerdns/files/bind-zones/trans-agenda.eu From 7c1c0f5e8010bee76fde30ceaee47c765e4c5daa Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 20:16:34 +0200 Subject: [PATCH 14/23] bundles/powerdns: increase default TTL to 1 day --- bundles/powerdns/files/pdns.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bundles/powerdns/files/pdns.conf b/bundles/powerdns/files/pdns.conf index 5bb2c83..4b64c72 100644 --- a/bundles/powerdns/files/pdns.conf +++ b/bundles/powerdns/files/pdns.conf @@ -14,3 +14,5 @@ max-tcp-connections-per-client=10 security-poll-suffix= server-id=${node.name} + +default-ttl=86400 From c5fc67660aa6f959d3add7dcea0153c50e6e1242 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 20:25:17 +0200 Subject: [PATCH 15/23] nodes/gce.bind01: add nginx for powerdnsadmin --- nodes/gce/bind01.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/nodes/gce/bind01.py b/nodes/gce/bind01.py index cb99b5c..e1f29ad 100644 --- a/nodes/gce/bind01.py +++ b/nodes/gce/bind01.py @@ -8,6 +8,7 @@ nodes['gce.bind01'] = { }, 'groups': { 'dns', + 'webserver', }, 'metadata': { 'interfaces': { @@ -19,6 +20,17 @@ nodes['gce.bind01'] = { }, }, 'external_ipv4': '34.89.208.78', + 'nginx': { + 'vhosts': { + 'ns-1.kunbox.net': { + 'proxy': { + '/': { + 'target': 'http://127.0.0.1:8000/', + }, + }, + }, + }, + }, 'vm': { 'cpu': 1, 'ram': 1, From 31cc74951bb9e21d90867f7369177e6c86633c21 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 20:40:05 +0200 Subject: [PATCH 16/23] bundles/powerdns: only reload pdns on zone changes, don't restart --- bundles/powerdns/items.py | 40 +++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/bundles/powerdns/items.py b/bundles/powerdns/items.py index 3f903a8..414290e 100644 --- a/bundles/powerdns/items.py +++ b/bundles/powerdns/items.py @@ -75,6 +75,16 @@ svc_systemd = { }, } +actions = { + 'powerdns_reload_zones': { + 'triggered': True, + 'command': 'pdns_control rediscover; pdns_control reload', + 'needs': { + 'svc_systemd:pdns', + }, + }, +} + if node.metadata['powerdns'].get('features', {}).get('bind', False): primary_zones = set() for zone in listdir(zone_path): @@ -97,7 +107,7 @@ if node.metadata['powerdns'].get('features', {}).get('bind', False): }, 'source': 'bind-zones/{}'.format(zone), 'triggers': { - 'svc_systemd:pdns:reload', + 'action:powerdns_reload_zones', }, } @@ -106,7 +116,7 @@ if node.metadata['powerdns'].get('features', {}).get('bind', False): 'pkg_apt:pdns-backend-bind', }, 'triggers': { - 'svc_systemd:pdns:restart', + 'action:powerdns_reload_zones', }, } @@ -119,7 +129,7 @@ if node.metadata['powerdns'].get('features', {}).get('bind', False): 'pkg_apt:pdns-backend-bind', }, 'triggers': { - 'svc_systemd:pdns:reload', + 'action:powerdns_reload_zones', }, } @@ -133,22 +143,20 @@ if node.metadata['powerdns'].get('features', {}).get('pgsql', False): 'pkg_apt:pdns-backend-pgsql', }, 'triggers': { - 'svc_systemd:pdns:restart', + 'action:powerdns_reload_zones', }, } files['/etc/powerdns/schema.pgsql.sql'] = {} - actions = { - 'powerdns_load_pgsql_schema': { - 'command': 'PGPASSWORD={pw} psql -h 127.0.0.1 -d powerdns -U powerdns -w < /etc/powerdns/schema.pgsql.sql'.format(pw=node.metadata['postgresql']['users']['powerdns']['password']), - 'unless': 'sudo -u postgres psql -d powerdns -c "\dt" | grep domains 2>&1 >/dev/null', - 'needs': { - 'bundle:postgresql', - 'file:/etc/powerdns/schema.pgsql.sql', - }, - 'needed_by': { - 'svc_systemd:pdns', - }, - } + actions['powerdns_load_pgsql_schema'] = { + 'command': 'PGPASSWORD={pw} psql -h 127.0.0.1 -d powerdns -U powerdns -w < /etc/powerdns/schema.pgsql.sql'.format(pw=node.metadata['postgresql']['users']['powerdns']['password']), + 'unless': 'sudo -u postgres psql -d powerdns -c "\dt" | grep domains 2>&1 >/dev/null', + 'needs': { + 'bundle:postgresql', + 'file:/etc/powerdns/schema.pgsql.sql', + }, + 'needed_by': { + 'svc_systemd:pdns', + }, } From f2073e72edd4fd5d50d3c27f7985fc35c803eaec Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 22:19:45 +0200 Subject: [PATCH 17/23] libs/tools: add resolve_identifier() --- libs/tools.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 libs/tools.py diff --git a/libs/tools.py b/libs/tools.py new file mode 100644 index 0000000..373f2f3 --- /dev/null +++ b/libs/tools.py @@ -0,0 +1,31 @@ +from bundlewrap.exceptions import NoSuchGroup, NoSuchNode +from ipaddress import ip_address + +def resolve_identifier(repo, identifier): + """ + Try to resolve an identifier (group or node). Return a set of ip + addresses valid for this identifier. + """ + try: + nodes = {repo.get_node(identifier)} + except NoSuchNode: + try: + nodes = repo.nodes_in_group(identifier) + except NoSuchGroup: + try: + return {ip_address(identifier)} + except: + return set() + + found_ips = set() + for node in nodes: + for interface, config in node.metadata.get('interfaces', {}).items(): + for ip in config.get('ipv4', set()): + found_ips.add(ip_address(ip)) + for ip in config.get('ipv4', set()): + found_ips.add(ip_address(ip)) + + if node.metadata.get('external_ipv4'): + found_ips.add(ip_address(node.metadata.get('external_ipv4'))) + + return found_ips From ca1646d394793f760185debab01578b47a7acafe Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Fri, 16 Oct 2020 23:02:47 +0200 Subject: [PATCH 18/23] 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, From 51e6d0534eb8f1de8faa5e4eecf350fdd515b939 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Sat, 17 Oct 2020 10:50:21 +0200 Subject: [PATCH 19/23] bundles/powerdns: fix Faults --- bundles/powerdns/items.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/powerdns/items.py b/bundles/powerdns/items.py index 02d7f0e..fd07b14 100644 --- a/bundles/powerdns/items.py +++ b/bundles/powerdns/items.py @@ -152,8 +152,8 @@ if node.metadata['powerdns'].get('features', {}).get('pgsql', False): files['/etc/powerdns/schema.pgsql.sql'] = {} actions['powerdns_load_pgsql_schema'] = { - 'command': 'PGPASSWORD={pw} psql -h 127.0.0.1 -d powerdns -U powerdns -w < /etc/powerdns/schema.pgsql.sql'.format(pw=node.metadata['postgresql']['users']['powerdns']['password']), - 'unless': 'sudo -u postgres psql -d powerdns -c "\dt" | grep domains 2>&1 >/dev/null', + 'command': node.metadata['postgresql']['users']['powerdns']['password'].format_into('PGPASSWORD={} psql -h 127.0.0.1 -d powerdns -U powerdns -w < /etc/powerdns/schema.pgsql.sql'), + 'unless': 'sudo -u postgres psql -d powerdns -c "\dt" | grep domains 2>&1 >/dev/null', 'needs': { 'bundle:postgresql', 'file:/etc/powerdns/schema.pgsql.sql', From 793220c0ec88c3b2c3eba0ad38cfd3165c7066cc Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Sat, 17 Oct 2020 12:56:17 +0200 Subject: [PATCH 20/23] bundles/powerdns: auto-generate zonefile header based on dns server nodes --- bundles/powerdns/files/pdns.conf | 13 ++++--------- bundles/powerdns/items.py | 9 ++++----- bundles/powerdns/metadata.py | 30 +++++++++++++----------------- nodes/a.ns14.net.py | 11 +++++++++++ nodes/b.ns14.net.py | 11 +++++++++++ nodes/c.ns14.net.py | 11 +++++++++++ nodes/d.ns14.net.py | 11 +++++++++++ nodes/gce/bind01.py | 1 + 8 files changed, 66 insertions(+), 31 deletions(-) create mode 100644 nodes/a.ns14.net.py create mode 100644 nodes/b.ns14.net.py create mode 100644 nodes/c.ns14.net.py create mode 100644 nodes/d.ns14.net.py diff --git a/bundles/powerdns/files/pdns.conf b/bundles/powerdns/files/pdns.conf index dc67064..3bdffcf 100644 --- a/bundles/powerdns/files/pdns.conf +++ b/bundles/powerdns/files/pdns.conf @@ -13,21 +13,16 @@ max-tcp-connections-per-client=10 security-poll-suffix= -server-id=${node.name} +server-id=${my_hostname} -default-ttl=86400 +default-ttl=60 % if is_secondary: -# Primary server: ${my_primary_server['node']} +# Primary servers: ${', '.join(sorted(my_primary_servers['nodes']))} slave=yes superslave=yes -allow-notify-from=${','.join(my_primary_server['ips'])} +allow-notify-from=${','.join(sorted(my_primary_servers['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 fd07b14..6fcf13a 100644 --- a/bundles/powerdns/items.py +++ b/bundles/powerdns/items.py @@ -22,11 +22,9 @@ $TTL 60 86400 300 ) -@ IN NS bind01.gce.kunbox.net. - IN NS b.ns14.net. - IN NS c.ns14.net. - IN NS d.ns14.net. """ +for rnode in sorted(repo.nodes_in_group('dns')): + ZONE_HEADER += '@ IN NS {}\n'.format(rnode.metadata.get('powerdns', {}).get('my_hostname', rnode.hostname)) directories = { '/etc/powerdns/pdns.d': { @@ -53,8 +51,9 @@ files = { 'content_type': 'mako', 'context': { 'api_key': node.metadata['powerdns']['api_key'], + 'my_hostname': node.metadata['powerdns'].get('my_hostname', node.name), 'is_secondary': node.metadata['powerdns'].get('is_secondary', False), - 'my_primary_server': node.metadata['powerdns'].get('my_primary_server', {}), + 'my_primary_servers': node.metadata['powerdns'].get('my_primary_servers', {}), }, 'needs': { 'pkg_apt:pdns-server', diff --git a/bundles/powerdns/metadata.py b/bundles/powerdns/metadata.py index 3c28c97..14c0370 100644 --- a/bundles/powerdns/metadata.py +++ b/bundles/powerdns/metadata.py @@ -28,29 +28,25 @@ 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. +def get_ips_of_primary_nameservers(metadata): + if not metadata.get('powerdns/is_secondary', False): return {} + ips = set() 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) + for rnode in repo.nodes_in_group('dns'): + if not rnode.metadata.get('powerdns/is_secondary', False): + ips.update({ + str(ip) for ip in repo.libs.tools.resolve_identifier(repo, rnode.name) + }) + nodes.add(rnode.name) return { 'powerdns': { - 'my_secondary_servers': nodes, + 'my_primary_servers': { + 'ips': ips, + 'nodes': nodes, + }, }, } diff --git a/nodes/a.ns14.net.py b/nodes/a.ns14.net.py new file mode 100644 index 0000000..db4d7c8 --- /dev/null +++ b/nodes/a.ns14.net.py @@ -0,0 +1,11 @@ +# This node is not actually part of this repository, it's a DNS server +# managed by AutoDNS. It needs a node file, because we're using that to +# auto-generate DNS configs. + +nodes['a.ns14.net'] = { + 'hostname': 'a.ns14.net', + 'dummy': True, + 'groups': { + 'dns', + }, +} diff --git a/nodes/b.ns14.net.py b/nodes/b.ns14.net.py new file mode 100644 index 0000000..c9ea427 --- /dev/null +++ b/nodes/b.ns14.net.py @@ -0,0 +1,11 @@ +# This node is not actually part of this repository, it's a DNS server +# managed by AutoDNS. It needs a node file, because we're using that to +# auto-generate DNS configs. + +nodes['b.ns14.net'] = { + 'hostname': 'b.ns14.net', + 'dummy': True, + 'groups': { + 'dns', + }, +} diff --git a/nodes/c.ns14.net.py b/nodes/c.ns14.net.py new file mode 100644 index 0000000..58b36c9 --- /dev/null +++ b/nodes/c.ns14.net.py @@ -0,0 +1,11 @@ +# This node is not actually part of this repository, it's a DNS server +# managed by AutoDNS. It needs a node file, because we're using that to +# auto-generate DNS configs. + +nodes['c.ns14.net'] = { + 'hostname': 'c.ns14.net', + 'dummy': True, + 'groups': { + 'dns', + }, +} diff --git a/nodes/d.ns14.net.py b/nodes/d.ns14.net.py new file mode 100644 index 0000000..728c644 --- /dev/null +++ b/nodes/d.ns14.net.py @@ -0,0 +1,11 @@ +# This node is not actually part of this repository, it's a DNS server +# managed by AutoDNS. It needs a node file, because we're using that to +# auto-generate DNS configs. + +nodes['d.ns14.net'] = { + 'hostname': 'd.ns14.net', + 'dummy': True, + 'groups': { + 'dns', + }, +} diff --git a/nodes/gce/bind01.py b/nodes/gce/bind01.py index dc6ae76..9c0230c 100644 --- a/nodes/gce/bind01.py +++ b/nodes/gce/bind01.py @@ -34,6 +34,7 @@ nodes['gce.bind01'] = { 'powerdns': { 'is_secondary': False, 'secondary_nameservers': 'dns', + 'my_hostname': 'ns-1.kunbox.net', }, 'vm': { 'cpu': 1, From 4d6b867bb3e14c06cbb04e9047a762b5d411b779 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Sat, 17 Oct 2020 12:57:35 +0200 Subject: [PATCH 21/23] bundles/powerdns: add metadata reactor for automatic node-dns-generation --- bundles/powerdns/metadata.py | 51 +++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/bundles/powerdns/metadata.py b/bundles/powerdns/metadata.py index 14c0370..1161c37 100644 --- a/bundles/powerdns/metadata.py +++ b/bundles/powerdns/metadata.py @@ -52,25 +52,40 @@ def get_ips_of_primary_nameservers(metadata): @metadata_reactor -def get_ips_of_primary_nameserver(metadata): - if not metadata.get('powerdns/is_secondary', False): - return {} +def generate_dns_entries_for_nodes(metadata): + results = set() - ips = set() for rnode in repo.nodes: - if not node.has_bundle('powerdns'): - continue + node_name_split = rnode.name.split('.') + node_name_split.reverse() + dns_name = '.'.join(node_name_split) + ip4 = None + ip6 = None - 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, - }, + # We only need this for GCE, because machines over there don't + # have a public ipv4 address. + if rnode.metadata.get('external_ipv4', None): + ip4 = rnode.metadata.get('external_ipv4') + + for iface, config in sorted(rnode.metadata.get('interfaces', {}).items()): + if not ip4 and 'ipv4' in config: + ip4 = sorted(config['ipv4'])[0] + + if not ip6 and 'ipv6' in config: + ip6 = sorted(config['ipv6'])[0] + + if ip4: + results.add('{} IN A {}'.format(dns_name, ip4)) + + if ip6: + results.add('{} IN AAAA {}'.format(dns_name, ip6)) + + return { + 'powerdns': { + 'bind-zones': { + 'kunbox.net': { + 'records': results, }, - } - - return {} + }, + }, + } From ae7c3220e034442ecc2fdf1034fa6b792657b686 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Sat, 17 Oct 2020 13:04:28 +0200 Subject: [PATCH 22/23] bundles/powerdns: fix NS records in zonefile header --- bundles/powerdns/items.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/powerdns/items.py b/bundles/powerdns/items.py index 6fcf13a..fef1d6e 100644 --- a/bundles/powerdns/items.py +++ b/bundles/powerdns/items.py @@ -24,7 +24,7 @@ $TTL 60 ) """ for rnode in sorted(repo.nodes_in_group('dns')): - ZONE_HEADER += '@ IN NS {}\n'.format(rnode.metadata.get('powerdns', {}).get('my_hostname', rnode.hostname)) + ZONE_HEADER += '@ IN NS {}.\n'.format(rnode.metadata.get('powerdns', {}).get('my_hostname', rnode.hostname)) directories = { '/etc/powerdns/pdns.d': { From ab4e1ac752a2d4f81496bda5ca3045a57a960599 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Sat, 17 Oct 2020 13:10:59 +0200 Subject: [PATCH 23/23] add __pycache__ to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2d22306..d1f7e7b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .secrets.cfg +__pycache__