]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add /api discovery endpoint 3495/head
authorChristian Hofstaedtler <christian.hofstaedtler@deduktiva.com>
Wed, 2 Mar 2016 12:44:26 +0000 (09:44 -0300)
committerChristian Hofstaedtler <christian.hofstaedtler@deduktiva.com>
Wed, 2 Mar 2016 12:44:26 +0000 (09:44 -0300)
Closes #3253.

docs/markdown/httpapi/api_spec.md
pdns/ws-api.cc
pdns/ws-api.hh
pdns/ws-auth.cc
pdns/ws-recursor.cc
regression-tests.api/test_Discovery.py [new file with mode: 0644]

index 2bf00b655fdf371db26a7367e276e61f156b9bd9..ebaa41aa1721f5fe56a7ef1a64ad1892106520ac 100644 (file)
@@ -96,6 +96,21 @@ Common Error Causes
 3. For requests that operate on a zone, the `zone_id` URL part was invalid. To get a valid `zone_id`, list the zones with the `/api/v1/servers/:server_id/zones` endpoint.
 
 
+URL: /api
+---------
+
+Version discovery endpoint.
+
+Allowed methods: `GET`
+
+    [
+      {
+        "url": "/api/v1",
+        "version": 1
+      }
+    ]
+
+
 URL: /api/v1
 ------------
 
@@ -103,7 +118,7 @@ Allowed methods: `GET`
 
     {
       "server_url": "/api/v1/servers{/server}",
-      "api_features": [],
+      "api_features": []
     }
 
 **TODO**:
index 12d3f7417c829cb9250871ce469028a877f21ce6..bf8f35e7edf9f26ed6eb275c908c7462331767cd 100644 (file)
@@ -91,6 +91,22 @@ static Json getServerDetail() {
   };
 }
 
+/* Return information about the supported API versions.
+ * The format of this MUST NEVER CHANGE at it's not versioned.
+ */
+void apiDiscovery(HttpRequest* req, HttpResponse* resp) {
+  if(req->method != "GET")
+    throw HttpMethodNotAllowedException();
+
+  Json version1 = Json::object {
+    { "version", 1 },
+    { "url", "/api/v1" }
+  };
+  Json doc = Json::array { version1 };
+
+  resp->setBody(doc);
+}
+
 void apiServer(HttpRequest* req, HttpResponse* resp) {
   if(req->method != "GET")
     throw HttpMethodNotAllowedException();
index 8c940769757b544147faab3904fb344396c6e224..e9dbbf5abc4338fa253e6c310b43364ae418e782 100644 (file)
@@ -25,6 +25,7 @@
 #include <map>
 #include "webserver.hh"
 
+void apiDiscovery(HttpRequest* req, HttpResponse* resp);
 void apiServer(HttpRequest* req, HttpResponse* resp);
 void apiServerDetail(HttpRequest* req, HttpResponse* resp);
 void apiServerConfig(HttpRequest* req, HttpResponse* resp);
index a3cf2fce028518e9951b16998d002c3a24082f53..c47505ddd26cbe9e60bd241cc967bf7fc7d546bf 100644 (file)
@@ -1211,6 +1211,7 @@ void AuthWebServer::webThread()
       d_ws->registerApiHandler("/api/v1/servers/localhost/zones", &apiServerZones);
       d_ws->registerApiHandler("/api/v1/servers/localhost", &apiServerDetail);
       d_ws->registerApiHandler("/api/v1/servers", &apiServer);
+      d_ws->registerApiHandler("/api", &apiDiscovery);
     }
     d_ws->registerWebHandler("/style.css", boost::bind(&AuthWebServer::cssfunction, this, _1, _2));
     d_ws->registerWebHandler("/", boost::bind(&AuthWebServer::indexfunction, this, _1, _2));
index 5b57957627dd15b07ace4c66e8fc2328b2008dcc..8eb17597f84b730ff97ebb2129fe142195e327ef 100644 (file)
@@ -426,6 +426,7 @@ RecursorWebServer::RecursorWebServer(FDMultiplexer* fdm)
   d_ws->registerApiHandler("/api/v1/servers/localhost/zones", &apiServerZones);
   d_ws->registerApiHandler("/api/v1/servers/localhost", &apiServerDetail);
   d_ws->registerApiHandler("/api/v1/servers", &apiServer);
+  d_ws->registerApiHandler("/api", &apiDiscovery);
 
   for(const auto& u : g_urlmap) 
     d_ws->registerWebHandler("/"+u.first, serveStuff);
diff --git a/regression-tests.api/test_Discovery.py b/regression-tests.api/test_Discovery.py
new file mode 100644 (file)
index 0000000..80d65ad
--- /dev/null
@@ -0,0 +1,10 @@
+from test_helper import ApiTestCase
+
+
+class DiscoveryTest(ApiTestCase):
+
+    def test_discovery(self):
+        r = self.session.get(self.url("/api"))
+        self.assert_success_json(r)
+        lst = r.json()
+        self.assertEquals(lst, [{'version': 1, 'url': '/api/v1'}])