Skip to content

Commit 737c734

Browse files
committed
Add an API endpoint to get backend storage layout version for a given zone.
Signed-off-by: Miod Vallat <[email protected]>
1 parent 327b348 commit 737c734

File tree

4 files changed

+53
-1
lines changed

4 files changed

+53
-1
lines changed

.github/actions/spell-check/expect.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,6 +1339,7 @@ stickysidebar
13391339
Stillaway
13401340
Stirnimann
13411341
Stolte
1342+
storageversion
13421343
Storbeck
13431344
Storesund
13441345
stou

docs/http-api/swagger/authoritative-api-swagger.yaml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
swagger: '2.0'
22
info:
3-
version: "0.0.17"
3+
version: "0.0.18"
44
title: PowerDNS Authoritative HTTP API
55
license:
66
name: MIT
@@ -374,6 +374,19 @@ paths:
374374
type: string
375375
<<: *commonErrors
376376

377+
'/servers/{server_id}/zones/{zone_id}/storageversion':
378+
get:
379+
summary: 'Return the backend storage version used to store the zone data.'
380+
description: 'This returns a backend-dependent version information. Currently only supported by the LMDB backend.'
381+
tags:
382+
- zones
383+
responses:
384+
'200':
385+
description: Storage version number
386+
schema:
387+
$ref: '#/definitions/StorageVersion'
388+
<<: *commonErrors
389+
377390
'/servers/{server_id}/config':
378391
get:
379392
summary: 'Returns all ConfigSettings for a single server'
@@ -1611,3 +1624,10 @@ definitions:
16111624
items:
16121625
$ref: '#/definitions/Network'
16131626

1627+
StorageVersion:
1628+
title: StorageVersion
1629+
description: 'The version number of the backend storage for a zone'
1630+
properties:
1631+
storageversion:
1632+
type: number
1633+

pdns/ws-auth.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2403,6 +2403,24 @@ static void apiServerZoneRectify(HttpRequest* req, HttpResponse* resp)
24032403
resp->setSuccessResult("Rectified");
24042404
}
24052405

2406+
static void apiServerZoneStorageVersion(HttpRequest* req, HttpResponse* resp)
2407+
{
2408+
ZoneData zoneData{req};
2409+
2410+
auto version = zoneData.domainInfo.backend->getStorageLayoutVersion();
2411+
if (version < 0) {
2412+
throw ApiException("Storage layout version not available");
2413+
}
2414+
2415+
if (req->accept_json) {
2416+
resp->setJsonBody(Json::object{{"storageversion", version}});
2417+
}
2418+
else {
2419+
resp->headers["Content-Type"] = "text/plain; charset=us-ascii";
2420+
resp->body = std::to_string(version);
2421+
}
2422+
}
2423+
24062424
// Validate the "changetype" field of a Json patch record.
24072425
// Returns true if this is a replace operation, false if this is a delete
24082426
// operation.
@@ -3047,6 +3065,7 @@ void AuthWebServer::webThread()
30473065
d_ws->registerApiHandler("/api/v1/servers/localhost/zones/<id>/metadata", apiZoneMetadataPOST, "POST");
30483066
d_ws->registerApiHandler("/api/v1/servers/localhost/zones/<id>/notify", apiServerZoneNotify, "PUT");
30493067
d_ws->registerApiHandler("/api/v1/servers/localhost/zones/<id>/rectify", apiServerZoneRectify, "PUT");
3068+
d_ws->registerApiHandler("/api/v1/servers/localhost/zones/<id>/storageversion", apiServerZoneStorageVersion, "GET");
30503069
d_ws->registerApiHandler("/api/v1/servers/localhost/zones/<id>", apiServerZoneDetailGET, "GET");
30513070
d_ws->registerApiHandler("/api/v1/servers/localhost/zones/<id>", apiServerZoneDetailPATCH, "PATCH");
30523071
d_ws->registerApiHandler("/api/v1/servers/localhost/zones/<id>", apiServerZoneDetailPUT, "PUT");

regression-tests.api/test_Zones.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2711,6 +2711,18 @@ def test_underscore_names(self):
27112711
# check our record has appeared
27122712
self.assertEqual(get_rrset(data, rrset['name'], 'A')['records'], rrset['records'])
27132713

2714+
def test_storage_version(self):
2715+
name = unique_zone_name()
2716+
self.create_zone(name=name, kind='Native')
2717+
# Require a json answer to GET
2718+
self.session.headers['Content-Type'] = 'application/json'
2719+
r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name + "/storageversion"))
2720+
if is_auth_lmdb():
2721+
self.assertEqual(r.status_code, 200)
2722+
self.assertGreater(r.json()['storageversion'], 5)
2723+
else:
2724+
self.assertEqual(r.status_code, 422)
2725+
27142726
@unittest.skipIf(not is_auth(), "Not applicable")
27152727
class AuthRootZone(ZonesApiTestCase, AuthZonesHelperMixin):
27162728

0 commit comments

Comments
 (0)