In _load_tsig_key_settings, the OperationalError handler for the
View.objects.get(name=view_name) lookup called close_old_connections()
but should have exited the script instead. This is the initial startup
and if loading of settings fails, the script should simply exit.
Also contains some code cleaning
DNS names are case-insensitive (RFC 4343), but the catalog-zone
dispatch compared dname verbatim:
if dname == "catz" or dname == f"{nb_view.name}.catz":
dname is derived from qname.to_text(), which preserves the casing the
client sent. A query for CATZ, Public.catz, or any other mixed-case
variant failed the comparison and fell through to _get_zone_from_nb,
which returned None, so the request was denied instead of being served
as a catalog zone.
Lowercase both sides before comparing. Pass the lowercased name to
create_zone so catalog zones always get a canonical lowercase origin,
and pass the original dname to _get_zone_from_nb to leave the regular
zone-lookup behavior unchanged.
export_bind_zone_file diverged from the AXFR path in four ways, each a
bug:
- It iterated nb_zone.records.all(), including inactive records, whereas
the AXFR handler filtered Record.objects.filter(zone=nb_zone,
active=True). Exported zone files could contain stale/withdrawn
records.
- It passed record.ttl straight to rdataset.add(), crashing with a
TypeError when the NetBox DNS Record had no TTL set. The AXFR path
used 'ttl = record.ttl or nb_zone.default_ttl'.
- It had no TXT quoting logic, so TXT values containing spaces or
semicolons were mis-tokenized by dns.rdata.from_text (a ';' was
treated as the start of a comment). The AXFR path quotes and chunks
TXT values for exactly this reason.
- It appended a fresh rdataset to the node for every record instead of
merging records that share a name and type, producing duplicate
rdatasets and malformed zone files.
Extract build_dns_zone(nb_zone) in utils.py containing the corrected,
AXFR-proven record-building logic (active filter, TTL fallback, TXT
quoting/chunking, rdataset merging via rdatasets_dict). Rewrite
export_bind_zone_file to build the zone through build_dns_zone and then
write it. Rewrite request_handler._get_zone_from_nb to look up the
NetBox DNS Zone and delegate to build_dns_zone, keeping only the
DoesNotExist/OperationalError handling that is specific to the query
path.
Both code paths now produce identical zone data.
_getZoneFromNB was the only camelCase function in the codebase,
inconsistent with the snake_case convention used everywhere else.
Rename it and update its callers and the adjacent comment.
Pure rename, no behavior change.
The logging call passed the exception as a positional argument with no
%s placeholder in the format string:
LOGGER.error("Error parsing query: ", e)
Python's logging applies msg % args, which raised TypeError (not all
arguments converted during string formatting) inside logging.handleError.
The logging framework swallows that secondary error, so neither the
intended message nor the exception was ever recorded.
Use an f-string so the exception is actually rendered and logged.
Remove unneeded definition.
modified: MANIFEST.in
Correct path
new file: netbox_dns_bridge/migrations/__init__.py
Fixes missing migration.
new file: netbox_dns_bridge/management/__init__.py
new file: netbox_dns_bridge/management/commands/__init__.py
Just in case
Fix paths after restructuring
renamed: netbox_dns_bridge/management/commands/export-dns-zone.py -> netbox_dns_bridge/management/commands/dns-export-zone.py
renamed: netbox_dns_bridge/management/commands/export-all-dns-zones.py -> netbox_dns_bridge/management/commands/dns-export-zones.py
Unify command naming scheme
new file: netbox_dns_bridge/migrations/0001_initial.py
Adds the missing migration. Since the plugin was renamed this is also an opportunity to merge all changes into a single migration.
renamed: netbox_dns_bridge/service/transfer/catalog_zone_manager.py -> netbox_dns_bridge/catalog_zone_manager.py
renamed: netbox_dns_bridge/service/transfer/dns_server.py -> netbox_dns_bridge/dns_server.py
new file: netbox_dns_bridge/management/commands/dns-settings.py
modified: netbox_dns_bridge/management/commands/dns-transfer-endpoint.py
renamed: netbox_dns_bridge/service/transfer/request_handler.py -> netbox_dns_bridge/request_handler.py
deleted: netbox_dns_bridge/service/transfer/__init__.py
Another restructure to simplify code re-use. New command dns-settings added to allow setting of catalog zone serial.
This will be needed to migrate from previous versions.
new file: .gitignore
new file: LICENSE.md
new file: MANIFEST.in
new file: README.md
new file: pylint.conf
new file: pyproject.toml
new file: requirements.txt
new file: src/netbox_plugin_bind_provisioner/__init__.py
new file: src/netbox_plugin_bind_provisioner/management/commands/bind-transfer-endpoint.py