From: Christian Hofstaedtler Date: Tue, 28 Jan 2014 09:26:07 +0000 (+0100) Subject: webserver: implement POST /../zones/ X-Git-Tag: rec-3.6.0-rc1~213^2~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7c0ba3d20ff3a18e44b35ea22ddb7e18b0c0e904;p=thirdparty%2Fpdns.git webserver: implement POST /../zones/ Unify master/masters to masters on the way. --- diff --git a/pdns/ws.cc b/pdns/ws.cc index 746d633bf3..c03c483366 100644 --- a/pdns/ws.cc +++ b/pdns/ws.cc @@ -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(); diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index fc438f1592..816f71de96 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -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])