}
}
+static void apiServerSearchData(HttpRequest* req, HttpResponse* resp) {
+ if(req->method != "GET")
+ throw HttpMethodNotAllowedException();
+
+ string q = req->parameters["q"];
+ if (q.empty())
+ throw ApiException("Query q can't be blank");
+
+ Document doc;
+ doc.SetArray();
+
+ BOOST_FOREACH(const SyncRes::domainmap_t::value_type& val, *t_sstorage->domainmap) {
+ string zoneId = apiZoneNameToId(val.first);
+ if (pdns_ci_find(val.first, q) != string::npos) {
+ Value object;
+ object.SetObject();
+ object.AddMember("type", "zone", doc.GetAllocator());
+ Value jzoneId(zoneId.c_str(), doc.GetAllocator()); // copy
+ object.AddMember("zone_id", jzoneId, doc.GetAllocator());
+ Value jzoneName(val.first.c_str(), doc.GetAllocator()); // copy
+ object.AddMember("name", jzoneName, doc.GetAllocator());
+ doc.PushBack(object, doc.GetAllocator());
+ }
+
+ // if zone name is an exact match, don't bother with returning all records/comments in it
+ if (val.first == q) {
+ continue;
+ }
+
+ const SyncRes::AuthDomain& zone = val.second;
+
+ BOOST_FOREACH(const SyncRes::AuthDomain::records_t::value_type& rr, zone.d_records) {
+ if (pdns_ci_find(rr.qname, q) == string::npos && pdns_ci_find(rr.content, q) == string::npos)
+ continue;
+
+ Value object;
+ object.SetObject();
+ object.AddMember("type", "record", doc.GetAllocator());
+ Value jzoneId(zoneId.c_str(), doc.GetAllocator()); // copy
+ object.AddMember("zone_id", jzoneId, doc.GetAllocator());
+ Value jzoneName(val.first.c_str(), doc.GetAllocator()); // copy
+ object.AddMember("zone_name", jzoneName, doc.GetAllocator());
+ Value jname(rr.qname.c_str(), doc.GetAllocator()); // copy
+ object.AddMember("name", jname, doc.GetAllocator());
+ Value jcontent(rr.content.c_str(), doc.GetAllocator()); // copy
+ object.AddMember("content", jcontent, doc.GetAllocator());
+
+ doc.PushBack(object, doc.GetAllocator());
+ }
+ }
+ resp->setBody(doc);
+}
+
RecursorWebServer::RecursorWebServer(FDMultiplexer* fdm)
{
RecursorControlParser rcp; // inits
d_ws->registerApiHandler("/servers/localhost/config/allow-from", &apiServerConfigAllowFrom);
d_ws->registerApiHandler("/servers/localhost/config", &apiServerConfig);
d_ws->registerApiHandler("/servers/localhost/search-log", &apiServerSearchLog);
+ d_ws->registerApiHandler("/servers/localhost/search-data", &apiServerSearchData);
d_ws->registerApiHandler("/servers/localhost/statistics", &apiServerStatistics);
d_ws->registerApiHandler("/servers/localhost/zones/<id>", &apiServerZoneDetail);
d_ws->registerApiHandler("/servers/localhost/zones", &apiServerZones);
@unittest.skipIf(not isRecursor(), "Not applicable")
class RecursorZones(ApiTestCase):
- def test_CreateAuthZone(self):
+ def create_zone(self, name=None, kind=None, rd=False, servers=None):
+ if name is None:
+ name = unique_zone_name()
+ if servers is None:
+ servers = []
payload = {
- 'name': unique_zone_name(),
- 'kind': 'Native',
- 'recursion_desired': False
+ 'name': name,
+ 'kind': kind,
+ 'servers': servers,
+ 'recursion_desired': rd
}
r = self.session.post(
self.url("/servers/localhost/zones"),
data=json.dumps(payload),
headers={'content-type': 'application/json'})
self.assertSuccessJson(r)
- data = r.json()
+ return (payload, r.json())
+
+ def test_CreateAuthZone(self):
+ payload, data = self.create_zone(kind='Native')
# return values are normalized
payload['name'] += '.'
for k in payload.keys():
self.assertEquals(data[k], payload[k])
def test_CreateForwardedZone(self):
- payload = {
- 'name': unique_zone_name(),
- 'kind': 'Forwarded',
- 'servers': ['8.8.8.8'],
- 'recursion_desired': False
- }
- r = self.session.post(
- self.url("/servers/localhost/zones"),
- data=json.dumps(payload),
- headers={'content-type': 'application/json'})
- self.assertSuccessJson(r)
- data = r.json()
+ payload, data = self.create_zone(kind='Forwarded', rd=False, servers=['8.8.8.8'])
# return values are normalized
payload['servers'][0] += ':53'
payload['name'] += '.'
self.assertEquals(data[k], payload[k])
def test_CreateForwardedRDZone(self):
- payload = {
- 'name': 'google.com',
- 'kind': 'Forwarded',
- 'servers': ['8.8.8.8'],
- 'recursion_desired': True
- }
- r = self.session.post(
- self.url("/servers/localhost/zones"),
- data=json.dumps(payload),
- headers={'content-type': 'application/json'})
- self.assertSuccessJson(r)
- data = r.json()
+ payload, data = self.create_zone(name='google.com', kind='Forwarded', rd=True, servers=['8.8.8.8'])
# return values are normalized
payload['servers'][0] += ':53'
payload['name'] += '.'
self.assertEquals(data[k], payload[k])
def test_CreateAuthZoneWithSymbols(self):
- payload = {
- 'name': 'foo/bar.'+unique_zone_name(),
- 'kind': 'Native',
- 'recursion_desired': False
- }
- r = self.session.post(
- self.url("/servers/localhost/zones"),
- data=json.dumps(payload),
- headers={'content-type': 'application/json'})
- self.assertSuccessJson(r)
- data = r.json()
+ payload, data = self.create_zone(name='foo/bar.'+unique_zone_name(), kind='Native')
# return values are normalized
payload['name'] += '.'
expected_id = (payload['name'].replace('/', '=2F'))
self.assertEquals(data['id'], expected_id)
def test_RenameAuthZone(self):
- name = unique_zone_name()+'.'
- payload = {
- 'name': name,
- 'kind': 'Native',
- 'recursion_desired': False
- }
- r = self.session.post(
- self.url("/servers/localhost/zones"),
- data=json.dumps(payload),
- headers={'content-type': 'application/json'})
- self.assertSuccessJson(r)
+ payload, data = self.create_zone(kind='Native')
+ name = payload['name'] + '.'
# now rename it
payload = {
'name': 'renamed-'+name,
data = r.json()
for k in payload.keys():
self.assertEquals(data[k], payload[k])
+
+ def test_SearchRRExactZone(self):
+ name = unique_zone_name() + '.'
+ self.create_zone(name=name, kind='Native')
+ r = self.session.get(self.url("/servers/localhost/search-data?q=" + name))
+ self.assertSuccessJson(r)
+ print r.json()
+ self.assertEquals(r.json(), [{u'type': u'zone', u'name': name, u'zone_id': name}])
+
+ def test_SearchRRSubstring(self):
+ name = 'search-rr-zone.name'
+ self.create_zone(name=name, kind='Native')
+ r = self.session.get(self.url("/servers/localhost/search-data?q=rr-zone"))
+ self.assertSuccessJson(r)
+ print r.json()
+ # should return zone, SOA
+ self.assertEquals(len(r.json()), 2)