]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
webserver: implement POST /../zones/<id>
authorChristian Hofstaedtler <christian@hofstaedtler.name>
Tue, 28 Jan 2014 09:26:07 +0000 (10:26 +0100)
committerChristian Hofstaedtler <christian@hofstaedtler.name>
Tue, 28 Jan 2014 20:12:21 +0000 (21:12 +0100)
Unify master/masters to masters on the way.

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

index 746d633bf35d36bfc3aab4cb2b1dedac904962ec..c03c483366474a2f4b5b767e770940e5f259ac51 100644 (file)
@@ -381,42 +381,6 @@ static string getZone(const string& zonename) {
   return makeStringFromDocument(doc);
 }
 
-static string createOrUpdateZone(const string& zonename, bool onlyCreate, rapidjson::Value& data) {
-  UeberBackend B;
-  DomainInfo di;
-
-  bool exists = B.getDomainInfo(zonename, di);
-  if(exists && onlyCreate)
-    return returnJSONError("Domain '"+zonename+"' already exists");
-
-  if(!exists) {
-    if(!B.createDomain(zonename))
-      return returnJSONError("Creating domain '"+zonename+"' failed");
-
-    if(!B.getDomainInfo(zonename, di))
-      return returnJSONError("Creating domain '"+zonename+"' failed: lookup of domain ID failed");
-
-    // create SOA record so zone "really" exists
-    DNSResourceRecord soa;
-    soa.qname = zonename;
-    soa.content = "1";
-    soa.qtype = "SOA";
-    soa.domain_id = di.id;
-    soa.auth = 0;
-    soa.ttl = ::arg().asNum( "default-ttl" );
-    soa.priority = 0;
-
-    di.backend->startTransaction(zonename, di.id);
-    di.backend->feedRecord(soa);
-    di.backend->commitTransaction();
-  }
-
-  di.backend->setKind(zonename, DomainInfo::stringToKind(stringFromJson(data, "kind")));
-  di.backend->setMaster(zonename, stringFromJson(data, "master"));
-
-  return getZone(zonename);
-}
-
 static void fillServerDetail(Value& out, Value::AllocatorType& allocator) {
   out.SetObject();
   out.AddMember("type", "Server", allocator);
@@ -494,7 +458,6 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) {
       throw ApiException("Zone name empty");
 
     string kind = stringFromJson(document, "kind");
-    string master = stringFromJson(document, "master", "");
 
     bool exists = B.getDomainInfo(zonename, di);
     if(exists)
@@ -504,6 +467,15 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) {
     if (!nameservers.IsArray() || nameservers.Size() == 0)
       throw ApiException("Need at least one nameserver");
 
+    string master;
+    const Value &masters = document["masters"];
+    if (masters.IsArray()) {
+      for (SizeType i = 0; i < masters.Size(); ++i) {
+        master += masters[i].GetString();
+        master += " ";
+      }
+    }
+
     // no going back after this
     if(!B.createDomain(zonename))
       throw ApiException("Creating domain '"+zonename+"' failed");
@@ -528,7 +500,7 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) {
     rr.priority = 0;
     rrset.push_back(rr);
 
-    for(SizeType i = 0; i < nameservers.Size(); ++i) {
+    for (SizeType i = 0; i < nameservers.Size(); ++i) {
       rr.content = nameservers[i].GetString();
       rr.qtype = "NS";
       rrset.push_back(rr);
@@ -541,8 +513,7 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) {
     di.backend->commitTransaction();
 
     di.backend->setKind(zonename, DomainInfo::stringToKind(kind));
-    if (!master.empty())
-      di.backend->setMaster(zonename, master);
+    di.backend->setMaster(zonename, master);
 
     resp->body = getZone(zonename);
     return;
@@ -585,6 +556,31 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) {
 static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) {
   string zonename = req->path_parameters["id"];
 
+  if(req->method == "PUT") {
+    // update domain settings
+    UeberBackend B;
+    DomainInfo di;
+    if(!B.getDomainInfo(zonename, di))
+      throw ApiException("Could not find domain '"+zonename+"'");
+
+    Document document;
+    parseJsonBody(req, document);
+
+    string master;
+    const Value &masters = document["masters"];
+    if (masters.IsArray()) {
+      for(SizeType i = 0; i < masters.Size(); ++i) {
+        master += masters[i].GetString();
+        master += " ";
+      }
+    }
+
+    di.backend->setKind(zonename, DomainInfo::stringToKind(stringFromJson(document, "kind")));
+    di.backend->setMaster(zonename, master);
+    resp->body = getZone(zonename);
+    return;
+  }
+
   if(req->method != "GET")
     throw HttpMethodNotAllowedException();
 
index fc438f1592eeb012bc7799ef5da80945d71d2385..816f71de96fa257cdf20592582a9e59bbcdde296 100644 (file)
@@ -64,3 +64,44 @@ class Servers(ApiTestCase):
         for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial'):
             self.assertIn(k, data)
         self.assertEquals(data['name'], 'example.com')
+
+    def test_UpdateZone(self):
+        # create
+        name = unique_zone_name()
+        payload = {
+            'name': name,
+            'kind': 'Native',
+            'nameservers': ['ns1.foo.com', 'ns2.foo.com']
+        }
+        r = self.session.post(
+            self.url("/servers/localhost/zones"),
+            data=json.dumps(payload),
+            headers={'content-type': 'application/json'})
+        self.assertSuccessJson(r)
+        # update, set as Master
+        payload = {
+            'kind': 'Master',
+            'masters': ['192.0.2.1','192.0.2.2']
+        }
+        r = self.session.put(
+            self.url("/servers/localhost/zones/" + name),
+            data=json.dumps(payload),
+            headers={'content-type': 'application/json'})
+        self.assertSuccessJson(r)
+        data = r.json()
+        for k in payload.keys():
+            self.assertIn(k, data)
+            self.assertEquals(data[k], payload[k])
+        # update, back to Native
+        payload = {
+            'kind': 'Native'
+        }
+        r = self.session.put(
+            self.url("/servers/localhost/zones/" + name),
+            data=json.dumps(payload),
+            headers={'content-type': 'application/json'})
+        self.assertSuccessJson(r)
+        data = r.json()
+        for k in payload.keys():
+            self.assertIn(k, data)
+            self.assertEquals(data[k], payload[k])