modified: certbot_dns_netbox/dns_netbox.py

Fix bug
This commit is contained in:
Sven Luthi committed 2026-10-28 12:34:22 +01:00
1 parent 927293869e
commit d702241782
2 files changed
+27 -14

No files matched your search

+26 -13
View File
@@ -148,9 +148,13 @@ class _NetboxDnsClient:
def update_txt_record(self, record_fqdn: str, validation: str) -> None: def update_txt_record(self, record_fqdn: str, validation: str) -> None:
"""Write the challenge token into one of the pre-provisioned records. """Write the challenge token into one of the pre-provisioned records.
Each challenge token claims its own record so that several tokens Records claimed earlier in this certbot run are skipped so that
for the same name (e.g. apex and wildcard on one certificate) stay several tokens for the same name (e.g. apex and wildcard on one
live simultaneously. certificate) stay live simultaneously. Among the remaining records,
the least recently updated one is chosen, according to the
timestamps NetBox keeps on the records themselves — that selection
needs no shared state, so separate certbot invocations for domains
sharing a record name still claim different records.
""" """
fqdn = self._fqdn(record_fqdn) fqdn = self._fqdn(record_fqdn)
records = self._get_txt_records(fqdn) records = self._get_txt_records(fqdn)
@@ -164,23 +168,32 @@ class _NetboxDnsClient:
) )
return return
existing = sorted( free = [
(record for record in records if not record.get("managed")), record
key=lambda record: record["id"], for record in records
) if not record.get("managed") and record["id"] not in self._claimed
free = [record for record in existing if record["id"] not in self._claimed] ]
if not free: if not free:
raise errors.PluginError( raise errors.PluginError(
f"Not enough TXT records for {record_fqdn} in view " f"Not enough TXT records for {record_fqdn} in view "
f"{search_view!r}: {len(existing)} record(s) exist, but all of " f"{search_view!r}: all existing records are already in use "
"them are already in use by this certificate request. Add " "by this certificate request. Add another TXT record with "
"another TXT record with the same name and rerun certbot." "the same name and rerun certbot."
) )
target = free[0] # least recently updated record first; ties break on the record id.
target = min(
free,
key=lambda record: (
record.get("last_updated") or "",
record["id"],
),
)
patch = {"id": target["id"], "value": validation} patch = {"id": target["id"], "value": validation}
if self._ttl: if self._ttl:
patch["ttl"] = self._ttl patch["ttl"] = self._ttl
self._nbapi.modify_dns_record(patch) self._nbapi.modify_dns_record(patch)
self._claimed.add(target["id"]) self._claimed.add(target["id"])
logger.info("Updated TXT record %s (id %s).", target["fqdn"], target["id"]) logger.info(
"Updated TXT record %s (id %s).", target["fqdn"], target["id"]
)
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "certbot-dns-netbox" name = "certbot-dns-netbox"
version = "1.0.1" version = "1.0.2"
description = "NetBox DNS (netbox-plugin-dns) DNS-01 authenticator plugin for Certbot" description = "NetBox DNS (netbox-plugin-dns) DNS-01 authenticator plugin for Certbot"
readme = "README.md" readme = "README.md"
requires-python = ">=3.9" requires-python = ">=3.9"