From: Jonathan Eenkhoorn Date: Thu, 12 Dec 2019 09:36:23 +0000 (+0100) Subject: Make a combination of delete and replace for rrset possible X-Git-Tag: rec-4.4.0-beta1~38^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e732e9ccd474d6a5e602f1a80b6d7132975482ab;p=thirdparty%2Fpdns.git Make a combination of delete and replace for rrset possible --- diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 85d64d7752..18e5024eb5 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1965,7 +1965,7 @@ static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) { di.backend->getDomainMetadataOne(zonename, "SOA-EDIT", soa_edit_kind); bool soa_edit_done = false; - set> seen; + set> seen; for (const auto& rrset : rrsets.array_items()) { string changetype = toUpper(stringFromJson(rrset, "changetype")); @@ -1977,11 +1977,11 @@ static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) { throw ApiException("RRset "+qname.toString()+" IN "+stringFromJson(rrset, "type")+": unknown type given"); } - if(seen.count({qname, qtype})) + if(seen.count({qname, qtype, changetype})) { - throw ApiException("Duplicate RRset "+qname.toString()+" IN "+qtype.getName()); + throw ApiException("Duplicate RRset "+qname.toString()+" IN "+qtype.getName()+" with changetype: "+changetype); } - seen.insert({qname, qtype}); + seen.insert({qname, qtype, changetype}); if (changetype == "DELETE") { // delete all matching qname/qtype RRs (and, implicitly comments). diff --git a/pdns/ws-auth.hh b/pdns/ws-auth.hh index e42ec43baa..a8ffe17adc 100644 --- a/pdns/ws-auth.hh +++ b/pdns/ws-auth.hh @@ -22,6 +22,7 @@ #ifndef WS_HH #define WS_HH #include +#include #include #include #include diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index c7fbe2758b..77f2441047 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -1184,6 +1184,35 @@ $ORIGIN %NAME% data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() self.assertIsNone(get_rrset(data, name, 'NS')) + def test_zone_rr_update_rrset_combine_replace_and_delete(self): + name, payload, zone = self.create_zone() + rrset1 = { + 'changetype': 'delete', + 'name': 'sub.' + name, + 'type': 'CNAME', + } + rrset2 = { + 'changetype': 'replace', + 'name': 'sub.' + name, + 'type': 'CNAME', + 'ttl': 500, + 'records': [ + { + "content": "www.example.org.", + "disabled": False + } + ] + } + payload = {'rrsets': [rrset1, rrset2]} + r = self.session.patch( + self.url("/api/v1/servers/localhost/zones/" + name), + data=json.dumps(payload), + headers={'content-type': 'application/json'}) + self.assert_success(r) + # verify that (only) the new record is there + data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + self.assertEquals(get_rrset(data, 'sub.' + name, 'CNAME')['records'], rrset2['records']) + def test_zone_disable_reenable(self): # This also tests that SOA-EDIT-API works. name, payload, zone = self.create_zone(soa_edit_api='EPOCH')