Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rec api: add subtree option to the cache flush endpoint #6562

Merged
merged 4 commits into from
May 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pdns/recursordist/docs/http-api/endpoint-cache.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ Cache manipulation endpoint
:query server_id: The name of the server
:query domain: The domainname to flush for

.. versionadded:: 4.1.3

:query subtree: If set to `true`, also flush the whole subtree (default = `false`)

**Example Response:**

.. code-block:: json
Expand Down
7 changes: 4 additions & 3 deletions pdns/ws-recursor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -373,10 +373,11 @@ static void apiServerCacheFlush(HttpRequest* req, HttpResponse* resp) {
throw HttpMethodNotAllowedException();

DNSName canon = apiNameToDNSName(req->getvars["domain"]);
bool subtree = (req->getvars.count("subtree") > 0 && req->getvars["subtree"].compare("true") == 0);

int count = broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, canon, false));
count += broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, canon, false));
count += broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, canon, false));
int count = broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, canon, subtree));
count += broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, canon, subtree));
count += broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, canon, subtree));
resp->setBody(Json::object {
{ "count", count },
{ "result", "Flushed cache." }
Expand Down
2 changes: 2 additions & 0 deletions regression-tests.api/runtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ def run_check_call(cmd, *args, **kwargs):
'DAEMON': daemon,
'SQLITE_DB': SQLITE_DB,
'PDNSUTIL_CMD': ' '.join(PDNSUTIL_CMD),
'SDIG': sdig,
'DNSPORT': str(DNSPORT)
})

try:
Expand Down
27 changes: 26 additions & 1 deletion regression-tests.api/test_Cache.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from test_helper import ApiTestCase, is_auth, is_recursor
from test_helper import ApiTestCase, is_auth, is_recursor, sdig
import unittest


class Servers(ApiTestCase):
Expand All @@ -9,6 +10,30 @@ def test_flush(self):
data = r.json()
self.assertIn('count', data)

@unittest.skipIf(not is_recursor(), "Not applicable")
def test_flush_count(self):
sdig("ns1.example.com", 'A')
r = self.session.put(self.url("/api/v1/servers/localhost/cache/flush?domain=ns1.example.com."))
self.assert_success_json(r)
data = r.json()
self.assertIn('count', data)
self.assertEquals(1, data['count'])

@unittest.skipIf(not is_recursor(), "Not applicable")
def test_flush_subtree(self):
sdig("ns1.example.com", 'A')
sdig("ns2.example.com", 'A')
r = self.session.put(self.url("/api/v1/servers/localhost/cache/flush?domain=example.com.&subtree=false"))
self.assert_success_json(r)
data = r.json()
self.assertIn('count', data)
self.assertEquals(1, data['count'])
r = self.session.put(self.url("/api/v1/servers/localhost/cache/flush?domain=example.com.&subtree=true"))
self.assert_success_json(r)
data = r.json()
self.assertIn('count', data)
self.assertEquals(2, data['count'])

def test_flush_root(self):
r = self.session.put(self.url("/api/v1/servers/localhost/cache/flush?domain=."))
self.assert_success_json(r)
Expand Down
11 changes: 8 additions & 3 deletions regression-tests.api/test_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
else:
from urllib.parse import urljoin


DAEMON = os.environ.get('DAEMON', 'authoritative')
PDNSUTIL_CMD = os.environ.get('PDNSUTIL_CMD', 'NOT_SET BUT_THIS MIGHT_BE_A_LIST').split(' ')
SQLITE_DB = os.environ.get('SQLITE_DB', 'pdns.sqlite3')

SDIG = os.environ.get('SDIG', 'sdig')
DNSPORT = os.environ.get('DNSPORT', '53')

class ApiTestCase(unittest.TestCase):

Expand Down Expand Up @@ -86,7 +86,12 @@ def pdnsutil(subcommand, *args):
except subprocess.CalledProcessError as except_inst:
raise RuntimeError("pdnsutil %s %s failed: %s" % (command, args, except_inst.output.decode('ascii', errors='replace')))


def pdnsutil_rectify(zonename):
"""Run pdnsutil rectify-zone on the given zone."""
pdnsutil('rectify-zone', zonename)

def sdig(*args):
try:
return subprocess.check_call([SDIG, '127.0.0.1', str(DNSPORT)] + list(args))
except subprocess.CalledProcessError as except_inst:
raise RuntimeError("sdig %s %s failed: %s" % (command, args, except_inst.output.decode('ascii', errors='replace')))