]> granicus.if.org Git - pdns/commitdiff
improves json webserver in the auth server, plus compiles in the json helpers for...
authorBert Hubert <bert.hubert@netherlabs.nl>
Thu, 15 Nov 2012 09:31:12 +0000 (09:31 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Thu, 15 Nov 2012 09:31:12 +0000 (09:31 +0000)
to turn on json webserver, set 'json-interface' in the configuration.

git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@2894 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/Makefile.am
pdns/common_startup.cc
pdns/misc.cc
pdns/misc.hh
pdns/ws.cc

index 044d92cde09562b5024705e1f4d26ccc97dae857..a70b27676b50ed758e75f6364a4c5497f74dda04 100644 (file)
@@ -64,7 +64,7 @@ aes/aestab.c aes/aestab.h aes/brg_endian.h aes/brg_types.h aes/dns_random.cc \
 randomhelper.cc namespaces.hh nsecrecords.cc base32.cc dbdnsseckeeper.cc dnssecinfra.cc \
 dnsseckeeper.hh dnssecinfra.hh base32.hh dns.cc dnssecsigner.cc polarrsakeyinfra.cc md5.cc \
 md5.hh signingpipe.cc signingpipe.hh dnslabeltext.cc lua-pdns.cc lua-auth.cc lua-auth.hh serialtweaker.cc \
-ednssubnet.cc ednssubnet.hh cachecleaner.hh
+ednssubnet.cc ednssubnet.hh cachecleaner.hh json.cc json.hh
 
 #
 pdns_server_LDFLAGS=@moduleobjects@ @modulelibs@ @DYNLINKFLAGS@ @LIBDL@ @THREADFLAGS@  $(BOOST_SERIALIZATION_LDFLAGS)  -rdynamic
@@ -239,7 +239,8 @@ base64.cc base64.hh zoneparser-tng.cc zoneparser-tng.hh rec_channel.cc rec_chann
 rec_channel_rec.cc selectmplexer.cc epollmplexer.cc sillyrecords.cc htimer.cc htimer.hh \
 aes/dns_random.cc aes/aescrypt.c aes/aeskey.c aes/aestab.c aes/aes_modes.c \
 lua-pdns.cc lua-pdns.hh lua-recursor.cc lua-recursor.hh randomhelper.cc  \
-recpacketcache.cc recpacketcache.hh dns.cc nsecrecords.cc base32.cc cachecleaner.hh
+recpacketcache.cc recpacketcache.hh dns.cc nsecrecords.cc base32.cc cachecleaner.hh json_ws.cc json_ws.hh \
+json.cc json.hh
 
 pdns_recursor_LDFLAGS= $(LUA_LIBS)
 pdns_recursor_LDADD=
index 258e03eb01312f3dd3b44daddca47b8ceebd929c..1899e360efe7b5e66137e3efa04fbd8271517c5b 100644 (file)
@@ -53,6 +53,7 @@ void declareArguments()
   ::arg().set("soa-serial-offset","Make sure that no SOA serial is less than this number")="0";
   
   ::arg().set("retrieval-threads", "Number of AXFR-retrieval threads for slave operation")="2";
+  ::arg().setSwitch("json-interface", "If the webserver should serve JSON data")="no";
 
   ::arg().setCmd("help","Provide a helpful message");
   ::arg().setCmd("version","Output version and compilation date");
index 42b73b3c2e3afe016cabe744a615cdc61c2703f2..4739b6d969e7bb6e2b95385eb2fef228bfcabfba 100644 (file)
@@ -777,3 +777,4 @@ bool stringfgets(FILE* fp, std::string& line)
   } while(!strchr(buffer, '\n'));
   return true;
 }
+
index e4e4cde2c15070f519f87460ef2414d43c7ae758..01993779b08079f0c2540084a5b30b4c3233d29a 100644 (file)
@@ -1,6 +1,6 @@
 /*
     PowerDNS Versatile Database Driven Nameserver
-    Copyright (C) 2002-2009  PowerDNS.COM BV
+    Copyright (C) 2002-2012  PowerDNS.COM BV
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2
@@ -449,5 +449,4 @@ replacing_insert(Index& i,const typename Index::value_type& x)
   return res;
 }
 
-
 #endif
index 426115dee13a194e1f79fba9be104f148ae46c5d..14223231060bbc249871a9d97b2356f1065c0386 100644 (file)
 */
 #include "utility.hh"
 #include "ws.hh"
+#include "json.hh"
 #include "webserver.hh"
 #include "logger.hh"
+#include "packetcache.hh"
 #include "statbag.hh"
 #include "misc.hh"
 #include "arguments.hh"
 #include "dns.hh"
+#include "ueberbackend.hh"
 #include <boost/format.hpp>
 #include <boost/foreach.hpp>
 
@@ -239,40 +242,145 @@ string StatWebServer::jsonstat(const map<string,string> &varmap, void *ptr, bool
 
   typedef map<string,string> varmap_t;
   varmap_t ourvarmap=varmap;
-  if(ourvarmap.empty()) {
-    vector<string> entries = S.getEntries();
-    BOOST_FOREACH(string& ent, entries) {
-      ourvarmap[ent];
-    }
-    ourvarmap["version"];
+  string callback;
+  string command;
+
+  if(ourvarmap.count("callback")) {
+    callback=ourvarmap["callback"];
+    ourvarmap.erase("callback");
+  }
+  
+  if(ourvarmap.count("command")) {
+    command=ourvarmap["command"];
+    ourvarmap.erase("command");
   }
+  
+  ourvarmap.erase("_");
+  if(!callback.empty())
+      ret += callback+"(";
+    
+  if(command=="get") {
+    if(ourvarmap.empty()) {
+      vector<string> entries = S.getEntries();
+      BOOST_FOREACH(string& ent, entries) {
+        ourvarmap[ent];
+      }
+      ourvarmap["version"];
+      ourvarmap["uptime"];
+    }
 
+    string variable, value;
+    
+    ret+="{";
+    for(varmap_t::const_iterator iter = ourvarmap.begin(); iter != ourvarmap.end() ; ++iter) {
+      if(iter != ourvarmap.begin())
+        ret += ",";
+      
+      variable = iter->first;
+      if(variable == "version") {
+        value = '"'+string(VERSION)+'"';
+      }
+      else if(variable == "uptime") {
+        value = lexical_cast<string>(time(0) - s_starttime);
+      }
+      else 
+        value = lexical_cast<string>(S.read(variable));
+      
+        ret += '"'+ variable +"\": "+ value;
+    }
+    ret+="}";
+  }
+  if(command=="config") {
+    vector<string> items = ::arg().list();
+    ret += "[";
+    bool first=1;
+    BOOST_FOREACH(const string& var, items) {
+      if(!first) ret+=",";
+      first=false;
+      ret += "[";
+      ret += "\""+var+"\", \"";
+      ret += ::arg()[var] + "\"";
+      ret += "]";
+    }
+    ret += "]";
+  }
 
-  string variable, value;
-  ret+="{";
-  for(varmap_t::const_iterator iter = ourvarmap.begin(); iter != ourvarmap.end() ; ++iter) {
-    if(iter != ourvarmap.begin())
-      ret += ",";
+  if(command == "flush-cache") {
+    extern PacketCache PC;
+    int number; 
+    if(ourvarmap["domain"].empty())
+      number = PC.purge();
+    else
+      number = PC.purge(ourvarmap["domain"]);
       
-    variable = iter->first;
-    if(variable == "version")
-      value = '"'+string(VERSION)+'"';
-    else 
-      value = lexical_cast<string>(S.read(variable));
+    map<string, string> object;
+    object["number"]=lexical_cast<string>(number);
+    cerr<<"Flushed cache for '"<<ourvarmap["domain"]<<"', cleaned "<<number<<" records"<<endl;
+    ret += returnJSONObject(object);
+  }
+  if(command=="get-zone") {
+    UeberBackend B;
+    SOAData sd;
+    sd.db= (DNSBackend*)-1;
+    B.getSOA(ourvarmap["zone"], sd);
+    sd.db->list(ourvarmap["zone"], sd.domain_id);
+    DNSResourceRecord rr;
+    
+    ret+="[";
+    map<string, string> object;
+    bool first=1;
+    while(sd.db->get(rr)) {
+      if(!first) ret += ", ";
+      first=false;
+      object.clear();
+      object["name"] = rr.qname;
+      object["type"] = rr.qtype.getName();
+      object["ttl"] = lexical_cast<string>(rr.ttl);
+      object["priority"] = lexical_cast<string>(rr.priority);
+      object["content"] = rr.content;
+      ret+=returnJSONObject(object);
+    }
+
+    ret += "]";
+  }
+
+  const char *kinds[]={"Master", "Slave", "Native"};
+  if(command=="domains") {
+    UeberBackend B;
+    vector<DomainInfo> domains;
+    B.getAllDomains(&domains);
+    ret += "{ domains: [ ";
+    bool first=true;
+    BOOST_FOREACH(DomainInfo& di, domains) {
+      if(!first) ret+=", ";
+      first=false;
       
-    ret += '"'+ variable +"\": "+ value;
+      ret += "{ name: \"";
+      ret += di.zone +"\", kind: \""+ kinds[di.kind]+"\", masters: \"";
+      BOOST_FOREACH(const string& master, di.masters) {
+        ret += master+ " ";
+      }
+      ret+="\", serial: "+lexical_cast<string>(di.serial)+", notified_serial: "+lexical_cast<string>(di.notified_serial)+", last_check: "+lexical_cast<string>(di.last_check);
+      ret+=" }";
+    }
+    ret+= "]}";
+  }
+  
+  if(!callback.empty()) {
+    ret += ");";
   }
-  ret+="}";
   return ret;
 }
 
 void StatWebServer::launch()
 {
   try {
-    
     d_ws->setCaller(this);
     d_ws->registerHandler("",&indexfunction);
-    d_ws->registerHandler("jsonstat", &jsonstat);
+    if(::arg().mustDo("json-interface"))
+      d_ws->registerHandler("jsonstat", &jsonstat);
     d_ws->go();
   }
   catch(...) {