]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
New DNSBackend entry points for views support.
authorPeter van Dijk <peter.van.dijk@powerdns.com>
Fri, 28 Mar 2025 06:04:35 +0000 (07:04 +0100)
committerMiod Vallat <miod.vallat@powerdns.com>
Mon, 26 May 2025 09:23:23 +0000 (11:23 +0200)
pdns/dnsbackend.hh
pdns/ueberbackend.cc
pdns/ueberbackend.hh

index 99d03776f757eafb519b688088b02d2c5e7e382c..a57e76a03be5ebaf0abac09e54ac05adf69285bf 100644 (file)
@@ -163,6 +163,7 @@ public:
     CAP_DIRECT = 1 << 2, // Backend supports direct commands
     CAP_LIST = 1 << 3, // Backend supports record enumeration
     CAP_CREATE = 1 << 4, // Backend supports domain creation
+    CAP_VIEWS = 1 << 5, // Backend supports views
   };
 
   virtual unsigned int getCapabilities() = 0;
@@ -479,6 +480,34 @@ public:
     return false;
   }
 
+  virtual void viewList(vector<string>& /* result */)
+  {
+  }
+
+  virtual void viewListZones(const string& /* view */, vector<ZoneName>& /* result */)
+  {
+  }
+
+  virtual bool viewAddZone(const string& /* view */, const ZoneName& /* zone */)
+  {
+    return false;
+  }
+
+  virtual bool viewDelZone(const string& /* view */, const ZoneName& /* zone */)
+  {
+    return false;
+  }
+
+  virtual bool networkSet(const Netmask& /* net */, std::string& /* tag */)
+  {
+    return false;
+  }
+
+  virtual bool networkList(vector<pair<Netmask, string>>& /* networks */)
+  {
+    return false;
+  }
+
   //! Returns whether backend operations have caused files to be created.
   virtual bool hasCreatedLocalFiles() const
   {
index c5b795ecb4e84f442f2f9a5750e8d26a313ee32f..655e7a59360768ae79924ff74fc4d4d72a118a92 100644 (file)
@@ -122,6 +122,10 @@ void UeberBackend::go()
 bool UeberBackend::getDomainInfo(const ZoneName& domain, DomainInfo& domainInfo, bool getSerial)
 {
   for (auto& backend : backends) {
+    // Do not risk passing variant zones to variant-unaware backends.
+    if (domain.hasVariant() && (backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
     if (backend->getDomainInfo(domain, domainInfo, getSerial)) {
       return true;
     }
@@ -132,6 +136,10 @@ bool UeberBackend::getDomainInfo(const ZoneName& domain, DomainInfo& domainInfo,
 bool UeberBackend::createDomain(const ZoneName& domain, const DomainInfo::DomainKind kind, const vector<ComboAddress>& primaries, const string& account)
 {
   for (auto& backend : backends) {
+    // Do not risk passing variant zones to variant-unaware backends.
+    if (domain.hasVariant() && (backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
     if (backend->createDomain(domain, kind, primaries, account)) {
       return true;
     }
@@ -153,6 +161,10 @@ bool UeberBackend::addDomainKey(const ZoneName& name, const DNSBackend::KeyData&
 {
   keyID = -1;
   for (auto& backend : backends) {
+    // Do not risk passing variant zones to variant-unaware backends.
+    if (name.hasVariant() && (backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
     if (backend->addDomainKey(name, key, keyID)) {
       return true;
     }
@@ -162,6 +174,10 @@ bool UeberBackend::addDomainKey(const ZoneName& name, const DNSBackend::KeyData&
 bool UeberBackend::getDomainKeys(const ZoneName& name, std::vector<DNSBackend::KeyData>& keys)
 {
   for (auto& backend : backends) {
+    // Do not risk passing variant zones to variant-unaware backends.
+    if (name.hasVariant() && (backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
     if (backend->getDomainKeys(name, keys)) {
       return true;
     }
@@ -172,6 +188,10 @@ bool UeberBackend::getDomainKeys(const ZoneName& name, std::vector<DNSBackend::K
 bool UeberBackend::getAllDomainMetadata(const ZoneName& name, std::map<std::string, std::vector<std::string>>& meta)
 {
   for (auto& backend : backends) {
+    // Do not risk passing variant zones to variant-unaware backends.
+    if (name.hasVariant() && (backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
     if (backend->getAllDomainMetadata(name, meta)) {
       return true;
     }
@@ -182,6 +202,10 @@ bool UeberBackend::getAllDomainMetadata(const ZoneName& name, std::map<std::stri
 bool UeberBackend::getDomainMetadata(const ZoneName& name, const std::string& kind, std::vector<std::string>& meta)
 {
   for (auto& backend : backends) {
+    // Do not risk passing variant zones to variant-unaware backends.
+    if (name.hasVariant() && (backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
     if (backend->getDomainMetadata(name, kind, meta)) {
       return true;
     }
@@ -203,6 +227,10 @@ bool UeberBackend::getDomainMetadata(const ZoneName& name, const std::string& ki
 bool UeberBackend::setDomainMetadata(const ZoneName& name, const std::string& kind, const std::vector<std::string>& meta)
 {
   for (auto& backend : backends) {
+    // Do not risk passing variant zones to variant-unaware backends.
+    if (name.hasVariant() && (backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
     if (backend->setDomainMetadata(name, kind, meta)) {
       return true;
     }
@@ -222,6 +250,10 @@ bool UeberBackend::setDomainMetadata(const ZoneName& name, const std::string& ki
 bool UeberBackend::activateDomainKey(const ZoneName& name, unsigned int keyID)
 {
   for (auto& backend : backends) {
+    // Do not risk passing variant zones to variant-unaware backends.
+    if (name.hasVariant() && (backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
     if (backend->activateDomainKey(name, keyID)) {
       return true;
     }
@@ -232,6 +264,10 @@ bool UeberBackend::activateDomainKey(const ZoneName& name, unsigned int keyID)
 bool UeberBackend::deactivateDomainKey(const ZoneName& name, unsigned int keyID)
 {
   for (auto& backend : backends) {
+    // Do not risk passing variant zones to variant-unaware backends.
+    if (name.hasVariant() && (backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
     if (backend->deactivateDomainKey(name, keyID)) {
       return true;
     }
@@ -242,6 +278,10 @@ bool UeberBackend::deactivateDomainKey(const ZoneName& name, unsigned int keyID)
 bool UeberBackend::publishDomainKey(const ZoneName& name, unsigned int keyID)
 {
   for (auto& backend : backends) {
+    // Do not risk passing variant zones to variant-unaware backends.
+    if (name.hasVariant() && (backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
     if (backend->publishDomainKey(name, keyID)) {
       return true;
     }
@@ -252,6 +292,10 @@ bool UeberBackend::publishDomainKey(const ZoneName& name, unsigned int keyID)
 bool UeberBackend::unpublishDomainKey(const ZoneName& name, unsigned int keyID)
 {
   for (auto& backend : backends) {
+    // Do not risk passing variant zones to variant-unaware backends.
+    if (name.hasVariant() && (backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
     if (backend->unpublishDomainKey(name, keyID)) {
       return true;
     }
@@ -262,6 +306,10 @@ bool UeberBackend::unpublishDomainKey(const ZoneName& name, unsigned int keyID)
 bool UeberBackend::removeDomainKey(const ZoneName& name, unsigned int keyID)
 {
   for (auto& backend : backends) {
+    // Do not risk passing variant zones to variant-unaware backends.
+    if (name.hasVariant() && (backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
     if (backend->removeDomainKey(name, keyID)) {
       return true;
     }
@@ -552,6 +600,10 @@ bool UeberBackend::getSOAUncached(const ZoneName& domain, SOAData& soaData)
   d_question.zoneId = -1;
 
   for (auto& backend : backends) {
+    // Do not risk passing variant zones to variant-unaware backends.
+    if (domain.hasVariant() && (backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
     if (backend->getSOA(domain, soaData)) {
       if (domain.operator const DNSName&() != soaData.qname) {
         throw PDNSException("getSOA() returned an SOA for the wrong zone. Question: '" + domain.toLogString() + "', answer: '" + soaData.qname.toLogString() + "'");
@@ -609,6 +661,10 @@ bool UeberBackend::autoPrimariesList(std::vector<AutoPrimary>& primaries)
 bool UeberBackend::autoPrimaryBackend(const string& ipAddr, const ZoneName& domain, const vector<DNSResourceRecord>& nsset, string* nameserver, string* account, DNSBackend** dnsBackend)
 {
   for (auto& backend : backends) {
+    // Do not risk passing variant zones to variant-unaware backends.
+    if (domain.hasVariant() && (backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
     if (backend->autoPrimaryBackend(ipAddr, domain, nsset, nameserver, account, dnsBackend)) {
       return true;
     }
@@ -682,6 +738,10 @@ void UeberBackend::addCache(const Question& question, vector<DNSZoneRecord>&& rr
 void UeberBackend::alsoNotifies(const ZoneName& domain, set<string>* ips)
 {
   for (auto& backend : backends) {
+    // Do not risk passing variant zones to variant-unaware backends.
+    if (domain.hasVariant() && (backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
     backend->alsoNotifies(domain, ips);
   }
 }
@@ -863,6 +923,78 @@ bool UeberBackend::deleteTSIGKey(const DNSName& name)
   return false;
 }
 
+void UeberBackend::viewList(vector<string>& result)
+{
+  for (auto& backend : backends) {
+    backend->viewList(result);
+  }
+}
+
+void UeberBackend::viewListZones(const string& view, vector<ZoneName>& result)
+{
+  for (auto& backend : backends) {
+    backend->viewListZones(view, result);
+  }
+}
+
+// FIXME: The logic in viewAddZone and viewDelZone causes view information to
+// be stored in the first views-capable backend, and could cause serious hair
+// pulling in setups with multiple views-capable backends (are we sure we
+// ever want to support that?)
+
+bool UeberBackend::viewAddZone(const string& view, const ZoneName& zone)
+{
+  for (auto& backend : backends) {
+    // Skip non-views-capable backends.
+    if ((backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
+    if (backend->viewAddZone(view, zone)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool UeberBackend::viewDelZone(const string& view, const ZoneName& zone)
+{
+  for (auto& backend : backends) {
+    // Skip non-views-capable backends.
+    if ((backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
+    if (backend->viewDelZone(view, zone)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool UeberBackend::networkSet(const Netmask& net, std::string& tag)
+{
+  for (auto& backend : backends) {
+    // Skip non-views-capable backends.
+    if ((backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
+    if (backend->networkSet(net, tag)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void UeberBackend::networkList(vector<pair<Netmask, string>>& networks)
+{
+  for (auto& backend : backends) {
+    // Skip non-views-capable backends.
+    if ((backend->getCapabilities() & DNSBackend::CAP_VIEWS) == 0) {
+      continue;
+    }
+    backend->networkList(networks);
+  }
+}
+
 // API Search
 //
 bool UeberBackend::searchRecords(const string& pattern, size_t maxResults, vector<DNSResourceRecord>& result)
index df21e07169ed1164d7f717c5bbf08b4118b9e2ed..ff1762e1b1e7e3efb87ddc150df8ee6d9ac64050 100644 (file)
@@ -134,6 +134,14 @@ public:
   bool getTSIGKeys(std::vector<struct TSIGKey>& keys);
   bool deleteTSIGKey(const DNSName& name);
 
+  void viewList(vector<string>& result);
+  void viewListZones(const string& view, vector<ZoneName>& result);
+  bool viewAddZone(const string& /* view */, const ZoneName& /* zone */);
+  bool viewDelZone(const string& /* view */, const ZoneName& /* zone */);
+
+  bool networkSet(const Netmask& net, std::string& tag);
+  void networkList(vector<pair<Netmask, string>>& networks);
+
   bool searchRecords(const string& pattern, vector<DNSResourceRecord>::size_type maxResults, vector<DNSResourceRecord>& result);
   bool searchComments(const string& pattern, size_t maxResults, vector<Comment>& result);