From: Bert Hubert Date: Thu, 15 Nov 2012 09:31:12 +0000 (+0000) Subject: improves json webserver in the auth server, plus compiles in the json helpers for... X-Git-Tag: auth-3.2-rc2~107 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e611a06c281a28a6acc7bb274b9c9a613efd48b1;p=pdns improves json webserver in the auth server, plus compiles in the json helpers for the recursor (which does not have it turned on in this commit) 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 --- diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 044d92cde..a70b27676 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -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= diff --git a/pdns/common_startup.cc b/pdns/common_startup.cc index 258e03eb0..1899e360e 100644 --- a/pdns/common_startup.cc +++ b/pdns/common_startup.cc @@ -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"); diff --git a/pdns/misc.cc b/pdns/misc.cc index 42b73b3c2..4739b6d96 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -777,3 +777,4 @@ bool stringfgets(FILE* fp, std::string& line) } while(!strchr(buffer, '\n')); return true; } + diff --git a/pdns/misc.hh b/pdns/misc.hh index e4e4cde2c..01993779b 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -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 diff --git a/pdns/ws.cc b/pdns/ws.cc index 426115dee..142232310 100644 --- a/pdns/ws.cc +++ b/pdns/ws.cc @@ -16,12 +16,15 @@ */ #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 #include @@ -239,40 +242,145 @@ string StatWebServer::jsonstat(const map &varmap, void *ptr, bool typedef map varmap_t; varmap_t ourvarmap=varmap; - if(ourvarmap.empty()) { - vector 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 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(time(0) - s_starttime); + } + else + value = lexical_cast(S.read(variable)); + + ret += '"'+ variable +"\": "+ value; + } + ret+="}"; + } + + if(command=="config") { + vector 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(S.read(variable)); + map object; + object["number"]=lexical_cast(number); + cerr<<"Flushed cache for '"<list(ourvarmap["zone"], sd.domain_id); + DNSResourceRecord rr; + + ret+="["; + map 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(rr.ttl); + object["priority"] = lexical_cast(rr.priority); + object["content"] = rr.content; + ret+=returnJSONObject(object); + } + + ret += "]"; + } + + + const char *kinds[]={"Master", "Slave", "Native"}; + if(command=="domains") { + UeberBackend B; + vector 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(di.serial)+", notified_serial: "+lexical_cast(di.notified_serial)+", last_check: "+lexical_cast(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(...) {