- Fix dnspython silently relativizing in-zone FQDN targets to '@' by
calling rdata.to_text(origin=origin, relativize=False); CoreDNS MySQL
requires absolute FQDNs in RDATA and was serving '.' for any CNAME/MX
pointing to the zone apex
- Reorder write_zone to delete stale records before inserting new ones
so a brief NXDOMAIN is preferred over briefly serving duplicate records
- Rework save-queue batch loop: keep batch open until queue is empty
rather than closing after a fixed timeout, so sequential DA zone pushes
accumulate into a single batch
- Add managed_by='directadmin' to _ensure_zone_exists for new and
legacy NULL rows
CoreDNS MySQL (cybercinch fork) expects '@' for zone-apex references in
record RDATA. Storing the full FQDN (e.g. 'ithome.net.nz.') caused CoreDNS
to strip the zone suffix and serve 'MX 0 .' / 'CNAME .' instead of the
correct apex target.
- Add _relativize_name(): converts zone FQDN → '@', in-zone subdomains →
relative label, external FQDNs left unchanged. Handles both already-
relativized output from dnspython ($ORIGIN present) and absolute FQDNs
when $ORIGIN is absent from the zone file.
- Replace _normalize_cname_data() with _relativize_name(); add
_normalize_mx_data(), _normalize_ns_data(), _normalize_srv_data() using
the same helper.
- _parse_zone_to_record_set() now normalizes MX, NS, SRV alongside CNAME.
- _ensure_zone_exists() sets managed_by='directadmin' on create and
back-fills NULL rows from pre-migration installs.
- Zone.managed_by changed to nullable=True to match ALTER TABLE migration
where existing rows have no value.
- schema/coredns_mysql.sql updated to reflect actual two-table schema with
managed_by column and migration comment.
- 11 new tests (130 total, all passing).
Migrate remaining session.query() calls in coredns_mysql.py to
select()/session.execute() style; update bulk delete to delete()
construct and count to func.count(); drop sessionmaker(bind=).
Update test fixtures and assertions to match.
Zero session.query() calls remaining across the entire codebase.
- Migrated from setuptools to Poetry; added pyproject.toml, poetry.lock,
poetry.toml and .python-version (Python 3.11.12)
- Built out full directdnsonly Python package with BIND and CoreDNS MySQL
backends, CherryPy REST API, persist-queue worker, and vyper-based config
- Auth credentials now read from config/env (app.auth_username/password)
rather than hardcoded; override via DADNS_APP_AUTH_PASSWORD env var
- Added Dockerfile.deepseek: Python 3.11 slim + BIND9 + Poetry install
- Rewrote docker-compose.yml for local dev stack (MySQL + dadns services)
- Added SQL schema, docker/ BIND configs, justfile, tests, and README
- Expanded .gitignore for Poetry/Python project artifacts