From: Seena Fallah Date: Tue, 3 Feb 2026 17:13:39 +0000 (+0100) Subject: auth: add default-soa-edit-api setting for API zone creation X-Git-Tag: rec-5.5.0-alpha0~35^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F16807%2Fhead;p=thirdparty%2Fpdns.git auth: add default-soa-edit-api setting for API zone creation Add a configurable default-soa-edit-api setting that sets the SOA-EDIT-API metadata for zones created via the API when the zone creation request does not include the soa_edit_api field. Signed-off-by: Seena Fallah --- diff --git a/docs/settings.rst b/docs/settings.rst index b600683fc7..5f63f00c39 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -483,6 +483,22 @@ Use this soa-edit value for all signed zones if no :ref:`metadata-soa-edit` metadata value is set. Overrides :ref:`setting-default-soa-edit` +.. _setting-default-soa-edit-api: + +``default-soa-edit-api`` +------------------------ + +- String +- Default: DEFAULT + +.. versionadded:: 5.2.0 + +The default :ref:`metadata-soa-edit-api` metadata value for zones created via +the API when the zone creation request does not include the ``soa_edit_api`` field. +Set to empty string to disable automatic SOA serial updates via the API. + +See :ref:`metadata-soa-edit-api` for the list of possible values. + .. _setting-default-soa-mail: ``default-soa-mail`` diff --git a/pdns/auth-main.cc b/pdns/auth-main.cc index 44b3c5208c..e9a2294b5d 100644 --- a/pdns/auth-main.cc +++ b/pdns/auth-main.cc @@ -265,6 +265,7 @@ static void declareArguments() ::arg().set("default-soa-content", "Default SOA content") = "a.misconfigured.dns.server.invalid hostmaster.@ 0 10800 3600 604800 3600"; ::arg().set("default-soa-edit", "Default SOA-EDIT value") = ""; ::arg().set("default-soa-edit-signed", "Default SOA-EDIT value for signed zones") = ""; + ::arg().set("default-soa-edit-api", "Default SOA-EDIT-API value for new zones") = "DEFAULT"; ::arg().set("dnssec-key-cache-ttl", "Seconds to cache DNSSEC keys from the database") = "30"; ::arg().set("domain-metadata-cache-ttl", "Seconds to cache zone metadata from the database") = ""; ::arg().set("zone-metadata-cache-ttl", "Seconds to cache zone metadata from the database") = "60"; diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index fc00b560c7..310c2ea238 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -2094,7 +2094,10 @@ static void apiServerZonesPOST(HttpRequest* req, HttpResponse* resp) try { // will be overridden by updateDomainSettingsFromDocument, if given in document. - domainInfo.backend->setDomainMetadataOne(zonename, "SOA-EDIT-API", "DEFAULT"); + const string defaultSOAEditAPI = ::arg()["default-soa-edit-api"]; + if (!defaultSOAEditAPI.empty()) { + domainInfo.backend->setDomainMetadataOne(zonename, "SOA-EDIT-API", defaultSOAEditAPI); + } for (auto& resourceRecord : new_records) { resourceRecord.domain_id = static_cast(domainInfo.id); diff --git a/regression-tests.api/runtests.py b/regression-tests.api/runtests.py index 8fd736450c..3b6c751cc9 100755 --- a/regression-tests.api/runtests.py +++ b/regression-tests.api/runtests.py @@ -73,6 +73,7 @@ views AUTH_COMMON_TPL = """ module-dir=../regression-tests/modules default-soa-edit=INCEPTION-INCREMENT +default-soa-edit-api=EPOCH launch+=bind bind-config=bindbackend.conf loglevel=5 diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index bd1642257a..372b1cc671 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -275,9 +275,38 @@ class AuthZones(ZonesApiTestCase, AuthZonesHelperMixin): self.assertEqual(data['catalog'], "default-catalog.example.com.") def test_create_zone_default_soa_edit_api(self): + """Test that zones created without soa_edit_api get the configured default-soa-edit-api value.""" name, payload, data = self.create_zone() print(data) - self.assertEqual(data['soa_edit_api'], 'DEFAULT') + # default-soa-edit-api is set to EPOCH in the test config + self.assertEqual(data['soa_edit_api'], 'EPOCH') + + def test_create_zone_override_soa_edit_api(self): + """Test that explicitly setting soa_edit_api overrides the default.""" + name, payload, data = self.create_zone(soa_edit_api='SOA-EDIT-INCREASE') + print(data) + self.assertEqual(data['soa_edit_api'], 'SOA-EDIT-INCREASE') + + def test_create_zone_empty_soa_edit_api(self): + """Test that explicitly setting soa_edit_api to empty does not use default.""" + name, payload, data = self.create_zone(soa_edit_api='') + print(data) + self.assertEqual(data['soa_edit_api'], '') + + def test_update_zone_does_not_override_soa_edit_api(self): + """Test that updating a zone does not change existing soa_edit_api to default.""" + # Create zone with empty soa_edit_api + name, payload, data = self.create_zone(soa_edit_api='') + self.assertEqual(data['soa_edit_api'], '') + # Update zone without specifying soa_edit_api - it should remain empty + update_payload = { + 'kind': 'Master', + 'masters': ['192.0.2.1'] + } + self.put_zone(name, update_payload) + data = self.get_zone(name) + # Verify soa_edit_api was NOT changed to the default value + self.assertEqual(data['soa_edit_api'], '') def test_create_zone_exists(self): name, payload, data = self.create_zone() @@ -693,7 +722,8 @@ class AuthZones(ZonesApiTestCase, AuthZonesHelperMixin): Create a zone, then set and unset "dnssec", then check if the serial was increased after every step """ - name, payload, data = self.create_zone() + # Use soa_edit_api='DEFAULT' to get predictable INCEPTION-INCREMENT serials + name, payload, data = self.create_zone(soa_edit_api='DEFAULT') soa_serial = get_first_rec(data, name, 'SOA')['content'].split(' ')[2] self.assertEqual(soa_serial[-2:], '01')