]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
API: Remove ENTs when "replacing" new records 6647/head
authorChris Hofstaedtler <chris.hofstaedtler@deduktiva.com>
Tue, 22 May 2018 11:44:56 +0000 (13:44 +0200)
committerChris Hofstaedtler <chris.hofstaedtler@deduktiva.com>
Tue, 22 May 2018 11:44:56 +0000 (13:44 +0200)
pdns/ws-auth.cc
regression-tests.api/test_Zones.py

index 63214bddb7bc80dd78ffd12991d2e407ec4f0f96..e4462a6c4bb836ed0f7ae7754f847e0033251f7e 100644 (file)
@@ -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.");
           }
index a4a3ffcadb0c2769016d0685faab2428dfc5864c..1a8da0ae47e4cec363b3b12a0624f758acb738cb 100644 (file)
@@ -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 = {