]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
auth /zones/example.com.?rrset_name=www.example.com.&rrset_type=A 11389/head
authorPeter van Dijk <peter.van.dijk@powerdns.com>
Thu, 3 Mar 2022 10:42:58 +0000 (11:42 +0100)
committerPeter van Dijk <peter.van.dijk@powerdns.com>
Fri, 11 Mar 2022 09:50:37 +0000 (10:50 +0100)
docs/http-api/swagger/authoritative-api-swagger.yaml
pdns/ws-auth.cc
regression-tests.api/test_Zones.py

index 17a85031e21136e39a9f9505c828f7bf3ae2b482..709a7f0ec76e52b284c3a45223592e518b443bc8 100644 (file)
@@ -188,6 +188,14 @@ paths:
           description: '“true” (default) or “false”, whether to include the “rrsets” in the response Zone object.'
           type: boolean
           default: true
+        - name: rrset_name
+          in: query
+          description: Limit output to RRsets for this name.
+          type: string
+        - name: rrset_type
+          in: query
+          description: Limit output to the RRset of this type. Can only be used together with rrset_name.
+          type: string
       responses:
         '200':
           description: A Zone
index a22117af452e24cf39c975adf7695d40d15c6afd..1aeee96d9e0b2807c71448d425cd6a9a5c1890b0 100644 (file)
@@ -402,7 +402,17 @@ static void fillZone(UeberBackend& B, const DNSName& zonename, HttpResponse* res
     // load all records + sort
     {
       DNSResourceRecord rr;
-      di.backend->list(zonename, di.id, true); // incl. disabled
+      if (req->getvars.count("rrset_name") == 0) {
+        di.backend->list(zonename, di.id, true); // incl. disabled
+      } else {
+        QType qt;
+        if (req->getvars.count("rrset_type") == 0) {
+          qt = QType::ANY;
+        } else {
+          qt = req->getvars["rrset_type"];
+        }
+        di.backend->lookup(qt, DNSName(req->getvars["rrset_name"]), di.id);
+      }
       while(di.backend->get(rr)) {
         if (!rr.qtype.getCode())
           continue; // skip empty non-terminals
index bd12e81bc83daca294a3645011449fe4be6aca22..d9291f5c2db9cc19b3a9a1eea8867bf33ba9c6c1 100644 (file)
@@ -1,5 +1,6 @@
 from __future__ import print_function
 import json
+import operator
 import time
 import unittest
 from copy import deepcopy
@@ -731,6 +732,97 @@ class AuthZones(ApiTestCase, AuthZonesHelperMixin):
             self.assertIn(k, data)
         self.assertEqual(data['name'], 'example.com.')
 
+    def test_get_zone_rrset(self):
+        rz = self.session.get(self.url("/api/v1/servers/localhost/zones"))
+        domains = rz.json()
+        example_com = [domain for domain in domains if domain['name'] == u'example.com.'][0]
+
+        # verify single record from name that has a single record
+        r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + example_com['id'] + "?rrset_name=host-18000.example.com."))
+        self.assert_success_json(r)
+        data = r.json()
+        for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial', 'rrsets'):
+            self.assertIn(k, data)
+        self.assertEqual(data['rrsets'],
+            [
+                {
+                    'comments': [],
+                    'name': 'host-18000.example.com.',
+                    'records':
+                    [
+                        {
+                            'content': '192.168.1.80',
+                            'disabled': False
+                        }
+                    ],
+                    'ttl': 120,
+                    'type': 'A'
+                }
+            ]
+        )
+
+        # verify two RRsets from a name that has two types with one record each
+        powerdnssec_org = [domain for domain in domains if domain['name'] == u'powerdnssec.org.'][0]
+        r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + powerdnssec_org['id'] + "?rrset_name=localhost.powerdnssec.org."))
+        self.assert_success_json(r)
+        data = r.json()
+        for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial', 'rrsets'):
+            self.assertIn(k, data)
+        self.assertEqual(sorted(data['rrsets'], key=operator.itemgetter('type')),
+            [
+                {
+                    'comments': [],
+                    'name': 'localhost.powerdnssec.org.',
+                    'records':
+                    [
+                        {
+                            'content': '127.0.0.1',
+                            'disabled': False
+                        }
+                    ],
+                    'ttl': 3600,
+                    'type': 'A'
+                },
+                {
+                    'comments': [],
+                    'name': 'localhost.powerdnssec.org.',
+                    'records':
+                    [
+                        {
+                            'content': '::1',
+                            'disabled': False
+                        }
+                    ],
+                    'ttl': 3600,
+                    'type': 'AAAA'
+                },
+            ]
+        )
+
+        # verify one RRset with one record from a name that has two, then filtered by type
+        r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + powerdnssec_org['id'] + "?rrset_name=localhost.powerdnssec.org.&rrset_type=AAAA"))
+        self.assert_success_json(r)
+        data = r.json()
+        for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial', 'rrsets'):
+            self.assertIn(k, data)
+        self.assertEqual(data['rrsets'],
+            [
+                {
+                    'comments': [],
+                    'name': 'localhost.powerdnssec.org.',
+                    'records':
+                    [
+                        {
+                            'content': '::1',
+                            'disabled': False
+                        }
+                    ],
+                    'ttl': 3600,
+                    'type': 'AAAA'
+                }
+            ]
+        )
+
     def test_import_zone_broken(self):
         payload = {
             'name': 'powerdns-broken.com',