From 4de11a5434ff6b8c9012e0cfccee9f485f38c356 Mon Sep 17 00:00:00 2001 From: Christian Hofstaedtler Date: Tue, 20 May 2014 17:22:53 +0200 Subject: [PATCH] API: create slave zones completely empty We should not insert a SOA record, as this would cause serving of NXDOMAIN until the domain has been slaved. Fixes #1425. --- modules/gmysqlbackend/gmysqlbackend.cc | 2 +- modules/goraclebackend/goraclebackend.cc | 2 +- modules/gpgsqlbackend/gpgsqlbackend.cc | 2 +- modules/gsqlite3backend/gsqlite3backend.cc | 2 +- pdns/ws-auth.cc | 2 +- regression-tests.api/test_Zones.py | 21 +++++++++++++++++++++ 6 files changed, 26 insertions(+), 5 deletions(-) diff --git a/modules/gmysqlbackend/gmysqlbackend.cc b/modules/gmysqlbackend/gmysqlbackend.cc index d156a9ab6..50abc5690 100644 --- a/modules/gmysqlbackend/gmysqlbackend.cc +++ b/modules/gmysqlbackend/gmysqlbackend.cc @@ -117,7 +117,7 @@ public: declare(suffix,"delete-tsig-key-query","", "delete from tsigkeys where name='%s'"); declare(suffix,"get-tsig-keys-query","", "select name,algorithm, secret from tsigkeys"); - declare(suffix, "get-all-domains-query", "Retrieve all domains", "select records.domain_id, records.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check from records, domains where records.domain_id=domains.id and records.type='SOA' and (records.disabled=0 OR %d)"); + declare(suffix, "get-all-domains-query", "Retrieve all domains", "select domains.id, domains.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check from domains LEFT JOIN records ON records.domain_id=domains.id AND records.type='SOA' AND records.name=domains.name WHERE records.disabled=0 OR %d"); declare(suffix, "list-comments-query", "", "SELECT domain_id,name,type,modified_at,account,comment FROM comments WHERE domain_id=%d"); declare(suffix, "insert-comment-query", "", "INSERT INTO comments (domain_id, name, type, modified_at, account, comment) VALUES (%d, '%s', '%s', %d, '%s', '%s')"); diff --git a/modules/goraclebackend/goraclebackend.cc b/modules/goraclebackend/goraclebackend.cc index bfcd10965..741dbe7a2 100644 --- a/modules/goraclebackend/goraclebackend.cc +++ b/modules/goraclebackend/goraclebackend.cc @@ -124,7 +124,7 @@ public: declare(suffix,"delete-tsig-key-query","", "delete from tsigkeys where name='%s'"); declare(suffix,"get-tsig-keys-query","", "select name,algorithm, secret from tsigkeys"); - declare(suffix, "get-all-domains-query", "Retrieve all domains", "select records.domain_id, records.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check from records, domains where records.domain_id=domains.id and records.type='SOA' and (records.disabled=0 OR 1=%d)"); + declare(suffix, "get-all-domains-query", "Retrieve all domains", "select domains.id, domains.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check from domains LEFT JOIN records ON records.domain_id=domains.id AND records.type='SOA' AND records.name=domains.name WHERE records.disabled=0 OR 1=%d"); declare(suffix, "list-comments-query", "", "SELECT domain_id,name,type,modified_at,account,\"comment\" FROM comments WHERE domain_id=%d"); declare(suffix, "insert-comment-query", "", "INSERT INTO comments (id, domain_id, name, type, modified_at, account, \"comment\") VALUES (comments_id_sequence.nextval, %d, '%s', '%s', %d, '%s', '%s')"); diff --git a/modules/gpgsqlbackend/gpgsqlbackend.cc b/modules/gpgsqlbackend/gpgsqlbackend.cc index 2041f8397..64b08f43a 100644 --- a/modules/gpgsqlbackend/gpgsqlbackend.cc +++ b/modules/gpgsqlbackend/gpgsqlbackend.cc @@ -113,7 +113,7 @@ public: declare(suffix,"delete-tsig-key-query","", "delete from tsigkeys where name='%s'"); declare(suffix,"get-tsig-keys-query","", "select name,algorithm, secret from tsigkeys"); - declare(suffix, "get-all-domains-query", "Retrieve all domains", "select records.domain_id, records.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check from records, domains where records.domain_id=domains.id and records.type='SOA' and (records.disabled=false OR %d::bool)"); + declare(suffix, "get-all-domains-query", "Retrieve all domains", "select domains.id, domains.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check from domains LEFT JOIN records ON records.domain_id=domains.id AND records.type='SOA' AND records.name=domains.name WHERE records.disabled=0 OR %d::bool"); declare(suffix, "list-comments-query", "", "SELECT domain_id,name,type,modified_at,account,comment FROM comments WHERE domain_id=%d"); declare(suffix, "insert-comment-query", "", "INSERT INTO comments (domain_id, name, type, modified_at, account, comment) VALUES (%d, E'%s', E'%s', %d, E'%s', E'%s')"); diff --git a/modules/gsqlite3backend/gsqlite3backend.cc b/modules/gsqlite3backend/gsqlite3backend.cc index 83ffea148..deb9b52b4 100644 --- a/modules/gsqlite3backend/gsqlite3backend.cc +++ b/modules/gsqlite3backend/gsqlite3backend.cc @@ -127,7 +127,7 @@ public: declare(suffix,"delete-tsig-key-query","", "delete from tsigkeys where name='%s'"); declare(suffix,"get-tsig-keys-query","", "select name,algorithm, secret from tsigkeys"); - declare(suffix, "get-all-domains-query", "Retrieve all domains", "select records.domain_id, records.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check from records, domains where records.domain_id=domains.id and records.type='SOA' and (records.disabled=0 OR %d)"); + declare(suffix, "get-all-domains-query", "Retrieve all domains", "select domains.id, domains.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check from domains LEFT JOIN records ON records.domain_id=domains.id AND records.type='SOA' AND records.name=domains.name WHERE records.disabled=0 OR %d"); declare(suffix, "list-comments-query", "", "SELECT domain_id,name,type,modified_at,account,comment FROM comments WHERE domain_id=%d"); declare(suffix, "insert-comment-query", "", "INSERT INTO comments (domain_id, name, type, modified_at, account, comment) VALUES (%d, '%s', '%s', %d, '%s', '%s')"); diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 2c5bb9673..4b120807e 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -523,7 +523,7 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) { rr.ttl = ::arg().asNum("default-ttl"); rr.priority = 0; - if (!have_soa) { + if (!have_soa && zonekind != DomainInfo::Slave) { // synthesize a SOA record so the zone "really" exists SOAData sd; diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 955bcdae7..988876c40 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -157,6 +157,27 @@ class AuthZones(ApiTestCase): for k in ('name', 'masters', 'kind'): self.assertIn(k, data) self.assertEquals(data[k], payload[k]) + print "payload:", payload + print "data:", data + # Because slave zones don't get a SOA, we need to test that they'll show up in the zone list. + r = self.session.get(self.url("/servers/localhost/zones")) + zonelist = r.json() + print "zonelist:", zonelist + self.assertIn(payload['name'], [zone['name'] for zone in zonelist]) + # Also test that fetching the zone works. + r = self.session.get(self.url("/servers/localhost/zones/" + data['id'])) + data = r.json() + print "zone (fetched):", data + for k in ('name', 'masters', 'kind'): + self.assertIn(k, data) + self.assertEquals(data[k], payload[k]) + self.assertEqual(data['serial'], 0) + self.assertEqual(data['records'], []) + + def test_delete_slave_zone(self): + payload, data = self.create_zone(kind='Slave', nameservers=None, masters=['127.0.0.2']) + r = self.session.delete(self.url("/servers/localhost/zones/" + data['id'])) + r.raise_for_status() def test_get_zone_with_symbols(self): payload, data = self.create_zone(name='foo/bar.'+unique_zone_name()) -- 2.40.0