From: Chris Hofstaedtler Date: Tue, 22 May 2018 11:44:56 +0000 (+0200) Subject: API: Remove ENTs when "replacing" new records X-Git-Tag: dnsdist-1.3.1~74^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=03b1cc2576499deaaf7c8a9b51f23d9ae5971f85;p=thirdparty%2Fpdns.git API: Remove ENTs when "replacing" new records --- diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 63214bddb7..e4462a6c4b 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1689,9 +1689,13 @@ static void patchZone(HttpRequest* req, HttpResponse* resp) { } if (replace_records) { + bool ent_present = false; di.backend->lookup(QType(QType::ANY), qname); DNSResourceRecord rr; while (di.backend->get(rr)) { + if (qtype.getCode() == 0) { + ent_present = true; + } if (qtype.getCode() == QType::CNAME && rr.qtype.getCode() != QType::CNAME) { throw ApiException("RRset "+qname.toString()+" IN "+qtype.getName()+": Conflicts with pre-existing non-CNAME RRset"); } else if (qtype.getCode() != QType::CNAME && rr.qtype.getCode() == QType::CNAME) { @@ -1699,6 +1703,12 @@ static void patchZone(HttpRequest* req, HttpResponse* resp) { } } + if (!new_records.empty() && ent_present) { + QType qt_ent{0}; + if (!di.backend->replaceRRSet(di.id, qname, qt_ent, new_records)) { + throw ApiException("Hosting backend does not support editing records."); + } + } if (!di.backend->replaceRRSet(di.id, qname, qtype, new_records)) { throw ApiException("Hosting backend does not support editing records."); } diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index a4a3ffcadb..1a8da0ae47 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -1526,6 +1526,41 @@ fred IN A 192.168.0.4 # should return zone, SOA, ns1, ns2, sub.sub A (but not the ENT) self.assertEquals(len(r.json()), 5) + def test_cname_at_ent_place(self): + name, payload, zone = self.create_zone(api_rectify=True) + rrset = { + 'changetype': 'replace', + 'name': 'sub2.sub1.' + name, + 'type': "A", + 'ttl': 3600, + 'records': [{ + 'content': "4.3.2.1", + 'disabled': False, + }], + } + payload = {'rrsets': [rrset]} + r = self.session.patch( + self.url("/api/v1/servers/localhost/zones/" + zone['id']), + data=json.dumps(payload), + headers={'content-type': 'application/json'}) + self.assertEquals(r.status_code, 204) + rrset = { + 'changetype': 'replace', + 'name': 'sub1.' + name, + 'type': "CNAME", + 'ttl': 3600, + 'records': [{ + 'content': "www.example.org.", + 'disabled': False, + }], + } + payload = {'rrsets': [rrset]} + r = self.session.patch( + self.url("/api/v1/servers/localhost/zones/" + zone['id']), + data=json.dumps(payload), + headers={'content-type': 'application/json'}) + self.assertEquals(r.status_code, 204) + def test_rrset_parameter_post_false(self): name = unique_zone_name() payload = {