]> granicus.if.org Git - pdns/commitdiff
webserver: implement statistics, fix config
authorChristian Hofstaedtler <christian@hofstaedtler.name>
Tue, 28 Jan 2014 21:02:25 +0000 (22:02 +0100)
committerChristian Hofstaedtler <christian@hofstaedtler.name>
Tue, 28 Jan 2014 21:49:38 +0000 (22:49 +0100)
Per the specification.

pdns/ws.cc
regression-tests.api/test_Servers.py

index e2777bc40d23fdfd8562ecaf8151974ca4b71093..4832da3006160632d76729d028d469fb459d742f 100644 (file)
@@ -420,25 +420,70 @@ static void apiServerConfig(HttpRequest* req, HttpResponse* resp) {
     throw HttpMethodNotAllowedException();
 
   vector<string> items = ::arg().list();
+  string value;
   Document doc;
   doc.SetArray();
-  BOOST_FOREACH(const string& var, items) {
-    Value kv, key, value;
-    kv.SetArray();
-    key.SetString(var.c_str(), var.length());
-    kv.PushBack(key, doc.GetAllocator());
-
-    if(var.find("password") != string::npos)
-      value="*****";
+  BOOST_FOREACH(const string& item, items) {
+    Value jitem;
+    jitem.SetObject();
+    jitem.AddMember("type", "ConfigSetting", doc.GetAllocator());
+
+    Value jname(item.c_str(), doc.GetAllocator());
+    jitem.AddMember("name", jname, doc.GetAllocator());
+
+    if(item.find("password") != string::npos)
+      value = "***";
     else
-      value.SetString(::arg()[var].c_str(), ::arg()[var].length(), doc.GetAllocator());
+      value = ::arg()[item];
 
-    kv.PushBack(value, doc.GetAllocator());
-    doc.PushBack(kv, doc.GetAllocator());
+    Value jvalue(value.c_str(), doc.GetAllocator());
+    jitem.AddMember("value", jvalue, doc.GetAllocator());
+
+    doc.PushBack(jitem, doc.GetAllocator());
   }
   resp->body = makeStringFromDocument(doc);
 }
 
+static void apiServerStatistics(HttpRequest* req, HttpResponse* resp) {
+  if(req->method != "GET")
+    throw HttpMethodNotAllowedException();
+
+  vector<string> items = S.getEntries();
+  string value;
+  Document doc;
+  doc.SetArray();
+  BOOST_FOREACH(const string& item, items) {
+    Value jitem;
+    jitem.SetObject();
+    jitem.AddMember("type", "StatisticItem", doc.GetAllocator());
+
+    Value jname(item.c_str(), doc.GetAllocator());
+    jitem.AddMember("name", jname, doc.GetAllocator());
+
+    value = lexical_cast<string>(S.read(item));
+
+    Value jvalue(value.c_str(), doc.GetAllocator());
+    jitem.AddMember("value", jvalue, doc.GetAllocator());
+
+    doc.PushBack(jitem, doc.GetAllocator());
+  }
+
+  // add uptime
+  // TODO: this is a hack. should we move this elsewhere?
+  {
+    Value jitem;
+    jitem.SetObject();
+    jitem.AddMember("type", "StatisticItem", doc.GetAllocator());
+    jitem.AddMember("name", "uptime", doc.GetAllocator());
+    value = lexical_cast<string>(time(0) - s_starttime);
+    Value jvalue(value.c_str(), doc.GetAllocator());
+    jitem.AddMember("value", jvalue, doc.GetAllocator());
+    doc.PushBack(jitem, doc.GetAllocator());
+  }
+
+  resp->body = makeStringFromDocument(doc);
+}
+
 static void apiServerSearchLog(HttpRequest* req, HttpResponse* resp) {
   if(req->method != "GET")
     throw HttpMethodNotAllowedException();
@@ -610,42 +655,7 @@ void StatWebServer::jsonstat(HttpRequest* req, HttpResponse* resp)
     req->parameters.erase("command");
   }
 
-  if(command=="get") {
-    if(req->parameters.empty()) {
-      vector<string> entries = S.getEntries();
-      BOOST_FOREACH(string& ent, entries) {
-        req->parameters[ent];
-      }
-      req->parameters["version"];
-      req->parameters["uptime"];
-    }
-
-    string variable, value;
-    
-    Document doc;
-    doc.SetObject();
-    for(varmap_t::const_iterator iter = req->parameters.begin(); iter != req->parameters.end() ; ++iter) {
-      variable = iter->first;
-      if(variable == "version") {
-        value = VERSION;
-      }
-      else if(variable == "uptime") {
-        value = lexical_cast<string>(time(0) - s_starttime);
-      }
-      else 
-        value = lexical_cast<string>(S.read(variable));
-      Value jval;
-      jval.SetString(value.c_str(), value.length(), doc.GetAllocator());
-      doc.AddMember(variable.c_str(), jval, doc.GetAllocator());
-    }
-    resp->body = makeStringFromDocument(doc);
-    return;
-  }
-  else if(command=="config") {
-    apiServerConfig(req, resp);
-    return;
-  }
-  else if(command == "flush-cache") {
+  if(command == "flush-cache") {
     extern PacketCache PC;
     int number; 
     if(req->parameters["domain"].empty())
@@ -865,6 +875,7 @@ void StatWebServer::launch()
     if(::arg().mustDo("experimental-json-interface")) {
       registerApiHandler("/servers/localhost/config", &apiServerConfig);
       registerApiHandler("/servers/localhost/search-log", &apiServerSearchLog);
+      registerApiHandler("/servers/localhost/statistics", &apiServerStatistics);
       registerApiHandler("/servers/localhost/zones/<id>", &apiServerZoneDetail);
       registerApiHandler("/servers/localhost/zones", &apiServerZones);
       registerApiHandler("/servers/localhost", &apiServerDetail);
index 561be5a49c8b8257e75cfb839893089ad91cd9ce..3895d87b5995477b326e5d9fd8cc68d55347b456 100644 (file)
@@ -29,6 +29,11 @@ class Servers(ApiTestCase):
     def test_ReadConfig(self):
         r = self.session.get(self.url("/servers/localhost/config"))
         self.assertSuccessJson(r)
-        data = dict(r.json())
-        self.assertIn('version', data)
-        print data
+        data = dict([(r['name'], r['value']) for r in r.json()])
+        self.assertIn('daemon', data)
+
+    def test_ReadStatistics(self):
+        r = self.session.get(self.url("/servers/localhost/statistics"))
+        self.assertSuccessJson(r)
+        data = dict([(r['name'], r['value']) for r in r.json()])
+        self.assertIn('uptime', data)