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.
modified: netbox_dns_bridge/catalog_zone_manager.py
Fix wrong import in previous version and slight change to
meachanism to create catz member identifier.
modified: netbox_dns_bridge/request_handler.py
modified: netbox_dns_bridge/utils.py
Various little bug fixes. Analysed by AI but fixed by hand to ensure integrity.
modified: src/netbox_plugin_bind_provisioner/models.py
Remove the settings model from Netbox's Permission system as these values are for internal use of the plugin only.
new file: src/netbox_plugin_bind_provisioner/management/commands/export-all-dns-zones.py
new file: src/netbox_plugin_bind_provisioner/management/commands/export-dns-zone.py
new file: src/netbox_plugin_bind_provisioner/utils.py
Adds export commands for zones to bind zone files and bump version to v1.0.4