]> granicus.if.org Git - pdns/commitdiff
bind-add-zone: add bind zones using pdns_control
authorPavel Boldin <boldin.pavel@gmail.com>
Sun, 18 Aug 2013 04:26:42 +0000 (08:26 +0400)
committerPavel Boldin <boldin.pavel@gmail.com>
Tue, 10 Sep 2013 20:19:09 +0000 (00:19 +0400)
Add pdns_control for loading new zones without reloading named.conf.
Zone is added but not loaded, you should do it manually, by querying
something. Beware of cache, it is better to purge it before.

pdns/backends/bind/bindbackend2.cc
pdns/backends/bind/bindbackend2.hh
pdns/responsestats.cc
regression-tests/add-zone/command [new file with mode: 0755]
regression-tests/add-zone/description [new file with mode: 0644]
regression-tests/add-zone/expected_result [new file with mode: 0644]
regression-tests/addzone.com [new file with mode: 0644]

index ccaa2d2fb8a5ce4174cbfb5d761644f5b81c616c..36da7ce0d65b718c330b0599c9a46b5b4c688507 100644 (file)
@@ -531,6 +531,36 @@ string Bind2Backend::DLListRejectsHandler(const vector<string>&parts, Utility::p
   return ret.str();
 }
 
+string Bind2Backend::DLAddDomainHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+  if(parts.size() < 3)
+    return "Not enough arguments";
+
+  string domainname = canonic(parts[1]);
+  const string &filename = parts[2];
+
+  if(getState()->name_id_map.count(domainname))
+    return "Already loaded";
+
+  Bind2Backend bb2;
+  BB2DomainInfo& bbd = bb2.createDomain(domainname, filename);
+
+  bbd.d_filename=filename;
+  bbd.d_checknow=true;
+  bbd.d_loaded=true;
+  bbd.d_lastcheck=0;
+  bbd.d_status="parsing into memory";
+          
+  {
+    Lock l(&s_state_lock);
+    s_state->name_id_map[bbd.d_name]=bbd.d_id;
+  }
+
+  L<<Logger::Warning<<"Zone "<<domainname<< " loaded"<<endl;
+
+  return "Loaded zone " + domainname + " from " + filename;
+}
+
 Bind2Backend::Bind2Backend(const string &suffix, bool loadZones)
 {
   setArgPrefix("bind"+suffix);
@@ -555,6 +585,7 @@ Bind2Backend::Bind2Backend(const string &suffix, bool loadZones)
   dl->registerFunc("BIND-RELOAD-NOW", &DLReloadNowHandler, "bindbackend: reload domains", "<domains>");
   dl->registerFunc("BIND-DOMAIN-STATUS", &DLDomStatusHandler, "bindbackend: list status of all domains", "[domains]");
   dl->registerFunc("BIND-LIST-REJECTS", &DLListRejectsHandler, "bindbackend: list rejected domains");
+  dl->registerFunc("BIND-ADD-ZONE", &DLAddDomainHandler, "bindbackend: add zone", "<domain> <filename>");
 }
 
 Bind2Backend::~Bind2Backend()
@@ -654,9 +685,9 @@ void Bind2Backend::doEmptyNonTerminals(shared_ptr<State> stage, int id, bool nse
 
 void Bind2Backend::loadConfig(string* status)
 {
-  // Interference with createSlaveDomain()
+  // Interference with createDomain()
   Lock l(&s_state_lock);
-  
+
   static int domain_id=1;
 
   shared_ptr<State> staging = shared_ptr<State>(new State);
@@ -1300,11 +1331,32 @@ bool Bind2Backend::superMasterBackend(const string &ip, const string &domain, co
   return true;
 }
 
-bool Bind2Backend::createSlaveDomain(const string &ip, const string &domain, const string &account)
+BB2DomainInfo &Bind2Backend::createDomain(const string &domain, const string &filename)
 {
   // Interference with loadConfig(), use locking
   Lock l(&s_state_lock);
 
+  int newid=1;
+  // Find a free zone id nr.  
+  
+  if (!s_state->id_zone_map.empty()) {
+    id_zone_map_t::reverse_iterator i = s_state->id_zone_map.rbegin();
+    newid = i->second.d_id + 1;
+  }
+  
+  BB2DomainInfo &bbd = s_state->id_zone_map[newid];
+
+  bbd.d_id = newid;
+  bbd.d_records = shared_ptr<recordstorage_t >(new recordstorage_t);
+  bbd.d_name = domain;
+  bbd.setCheckInterval(getArgAsNum("check-interval"));
+  bbd.d_filename = filename;
+
+  return bbd;
+}
+
+bool Bind2Backend::createSlaveDomain(const string &ip, const string &domain, const string &account)
+{
   string filename = getArg("supermaster-destdir")+'/'+domain;
   
   L << Logger::Warning << d_logprefix
@@ -1326,25 +1378,15 @@ bool Bind2Backend::createSlaveDomain(const string &ip, const string &domain, con
   c_of << "};" << endl;
   c_of.close();
 
-  int newid=1;
-  // Find a free zone id nr.  
-  
-  if (!s_state->id_zone_map.empty()) {
-    id_zone_map_t::reverse_iterator i = s_state->id_zone_map.rbegin();
-    newid = i->second.d_id + 1;
-  }
-  
-  BB2DomainInfo &bbd = s_state->id_zone_map[newid];
+  BB2DomainInfo &bbd = createDomain(canonic(domain), filename);
 
-  bbd.d_id = newid;
-  bbd.d_records = shared_ptr<recordstorage_t >(new recordstorage_t);
-  bbd.d_name = domain;
-  bbd.setCheckInterval(getArgAsNum("check-interval"));
   bbd.d_masters.push_back(ip);
-  bbd.d_filename = filename;
-
-  s_state->name_id_map[domain] = bbd.d_id;
   
+  {
+    Lock l(&s_state_lock);
+    s_state->name_id_map[bbd.d_name] = bbd.d_id;
+  }
+
   return true;
 }
 
index 9880dccbd4a6a098f646a52525b1a661f3a9b216..3a7cfadace880b119ad20cc3dca6f8cc3d54fd60 100644 (file)
@@ -181,7 +181,8 @@ public:
   // for supermaster support
   bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db);
   bool createSlaveDomain(const string &ip, const string &domain, const string &account);
-  
+
+
 private:
   void setupDNSSEC();
   shared_ptr<SSQLite3> d_dnssecdb;
@@ -229,6 +230,8 @@ private:
 
   set<string> alsoNotify; //!< this is used to store the also-notify list of interested peers.
 
+  BB2DomainInfo& createDomain(const string &domain, const string &filename);
+
   int d_transaction_id;
   string d_transaction_tmpname;
 
@@ -241,6 +244,7 @@ private:
   static string DLDomStatusHandler(const vector<string>&parts, Utility::pid_t ppid);
   static string DLListRejectsHandler(const vector<string>&parts, Utility::pid_t ppid);
   static string DLReloadNowHandler(const vector<string>&parts, Utility::pid_t ppid);
+  static string DLAddDomainHandler(const vector<string>&parts, Utility::pid_t ppid);
   static void fixupAuth(shared_ptr<recordstorage_t> records);
   static void doEmptyNonTerminals(shared_ptr<State> stage, int id, bool nsec3zone, NSEC3PARAMRecordContent ns3pr);
   void loadConfig(string *status=0);
index 2d9c287a730a44e261de0a852b03547f0987afbc..92bf8899d09117f93c6a062fe112c1c24682b219 100644 (file)
@@ -52,4 +52,4 @@ map<uint16_t, uint64_t> ResponseStats::getSizeResponseCounts()
     ret[iter->first]=iter->second;
   }
   return ret;
-}
\ No newline at end of file
+}
diff --git a/regression-tests/add-zone/command b/regression-tests/add-zone/command
new file mode 100755 (executable)
index 0000000..bffa60e
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh
+cleandig ns1.addzone.com A
+cleandig ns1.test.com A
+sleep 2
+../pdns/pdns_control --config-dir=. bind-add-zone addzone.com addzone.com
+../pdns/pdns_control --config-dir=. purge addzone.com
+sleep 2
+../pdns/pdns_control --config-dir=. bind-add-zone addzone.com addzone.com
+sleep 2
+cleandig ns1.addzone.com A
+sleep 2
+cleandig ns1.addzone.com A
+cleandig ns1.test.com A
diff --git a/regression-tests/add-zone/description b/regression-tests/add-zone/description
new file mode 100644 (file)
index 0000000..863d5df
--- /dev/null
@@ -0,0 +1,2 @@
+Test whether bind-add-zone is actually adding zone and does not ruin
+other zones.
diff --git a/regression-tests/add-zone/expected_result b/regression-tests/add-zone/expected_result
new file mode 100644 (file)
index 0000000..e531b86
--- /dev/null
@@ -0,0 +1,42 @@
+1      .       IN      NS      518400  a.root-servers.net.
+1      .       IN      NS      518400  b.root-servers.net.
+1      .       IN      NS      518400  c.root-servers.net.
+1      .       IN      NS      518400  d.root-servers.net.
+1      .       IN      NS      518400  e.root-servers.net.
+1      .       IN      NS      518400  f.root-servers.net.
+1      .       IN      NS      518400  g.root-servers.net.
+1      .       IN      NS      518400  h.root-servers.net.
+1      .       IN      NS      518400  i.root-servers.net.
+1      .       IN      NS      518400  j.root-servers.net.
+1      .       IN      NS      518400  k.root-servers.net.
+1      .       IN      NS      518400  l.root-servers.net.
+1      .       IN      NS      518400  m.root-servers.net.
+2      a.root-servers.net.     IN      A       3600000 198.41.0.4
+2      b.root-servers.net.     IN      A       3600000 192.228.79.201
+2      c.root-servers.net.     IN      A       3600000 192.33.4.12
+2      d.root-servers.net.     IN      A       3600000 199.7.91.13
+2      e.root-servers.net.     IN      A       3600000 192.203.230.10
+2      f.root-servers.net.     IN      A       3600000 192.5.5.241
+2      g.root-servers.net.     IN      A       3600000 192.112.36.4
+2      h.root-servers.net.     IN      A       3600000 128.63.2.53
+2      i.root-servers.net.     IN      A       3600000 192.36.148.17
+2      j.root-servers.net.     IN      A       3600000 192.58.128.30
+2      k.root-servers.net.     IN      A       3600000 193.0.14.129
+2      l.root-servers.net.     IN      A       3600000 198.32.64.12
+2      m.root-servers.net.     IN      A       3600000 202.12.27.33
+Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 0, opcode: 0
+Reply to question for qname='ns1.addzone.com.', qtype=A
+0      ns1.test.com.   IN      A       3600    1.1.1.1
+Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='ns1.test.com.', qtype=A
+Loaded zone addzone.com from addzone.com
+1
+Already loaded
+Rcode: 2, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='ns1.addzone.com.', qtype=A
+0      ns1.addzone.com.        IN      A       3600    1.1.1.5
+Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='ns1.addzone.com.', qtype=A
+0      ns1.test.com.   IN      A       3600    1.1.1.1
+Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='ns1.test.com.', qtype=A
diff --git a/regression-tests/addzone.com b/regression-tests/addzone.com
new file mode 100644 (file)
index 0000000..710bd33
--- /dev/null
@@ -0,0 +1,38 @@
+$TTL 3600
+$ORIGIN addzone.com.
+@              IN      SOA     ns1.addzone.com.        ahu.example.com. (  2005092501
+                       8H ; refresh
+                       2H ; retry
+                       1W ; expire
+                       1D ; default_ttl
+                       )
+
+@                      IN      NS      ns1
+@                      IN      NS      ns2
+@                      IN      MX      10      smtp-servers.example.com.
+@                      IN      MX      15      smtp-servers
+ns1                    IN      A       1.1.1.5
+ns2                    IN      A       2.2.2.2
+www                    IN      CNAME   server1
+server1                        IN      A       1.2.3.4
+                       IN      RP      ahu.ds9a.nl. counter
+*.test                 IN      CNAME   server1
+www.test               IN      A       4.3.2.1
+sub.test               IN      NS      ns-test.example.net
+enum                   IN      NAPTR 100 50 "u" "e2u+sip" "" testuser.domain.com.
+counter                        IN      A       1.1.1.5
+_ldap._tcp.dc          IN      SRV     0 100 389 server2.example.net.
+_double._tcp.dc                IN      SRV     0 100 389 server1
+_double._tcp.dc                IN      SRV     1 100 389 server1
+_root._tcp.dc          IN      SRV     0 0 0 .
+blah                   IN      NS      blah
+blah                   IN      A       192.168.6.1
+;images                        IN      URL     "http://www.ds9a.nl"
+;bert@auto.test.com.                   IN      MBOXFW  "bert@ds9a.nl"
+very-long-txt          IN      TXT     "A very long TXT record! boy you won't believe how long. A very long TXT record! boy you won't believe how long. A very long TXT record! boy you won't believe how long. A very long TXT record! boy you won't believe how long. A very long TXT record! boy you won't believe how long!"
+within-server          IN      CNAME   outpost.example.com.
+_underscore            IN      TXT     "underscores are terrible"
+b.c                    IN      A       5.6.7.8
+*.a.b.c                        IN      A       8.7.6.5
+aland          IN TXT "\195\133LAND ISLANDS"
+hightxt                IN      TXT     "v=spf1 mx ip4:78.46.192.210 â€“all"