Releases: maxfield-allison/dnsweaver
Releases · maxfield-allison/dnsweaver
v1.0.0
Added
- Config Validation CLI:
--validateflag for pre-flight config checks with
structured error reporting (#71) - Graceful Shutdown: In-flight reconciliation tracking with clean provider
teardown (#69) - Structured Logging:
slog-based logging with JSON/text format and file
rotation support (#67) dnsweaver.hostnamesLabel: Comma-separated hostname declarations for
Docker containers (#96)- Dual-Stack DNS Guide: Deployment documentation for IPv4/IPv6 environments
- Source/Watcher Metrics: Prometheus instrumentation for source discovery and
watcher activity (#97)
Changed
- Pi-hole Config:
MODErenamed toACCESS_MODE;DNSWEAVER_SOURCE(singular)
deprecated in favor ofDNSWEAVER_SOURCES(plural) (#93) instance_idRestructured: Moved to top-level config field (#93)
Fixed
- Orphan Cleanup: Hostname-provider mapping tracked correctly during provider
switches (#51) - Startup Race: Events during initial reconciliation no longer lost (#55)
- Health Recovery: Health checker registered for recovered providers (#127)
- Pi-hole Default:
ACCESS_MODEdefaults toapiwhen not specified (#98)
Security
- Pre-v1.0 Security Audit: Comprehensive hardening including HTTP response
body limits, shell metacharacter validation, SSH credential handling, and input
sanitization (#36) - Code Review: Dead code removal, error handling improvements, naming
consistency (#94)
Testing
- Shared Test Harness: Mock infrastructure and helper utilities for provider
testing (#111) - Reconciler Edge Cases: Failure, behavior, and observability tests (#77)
- RFC 2136 Integration Tests: Full CRUD lifecycle testing (#130)
- Standardized Test Templates: Reusable integration testing frameworks (#136)
- Integration Tested: Verified against Technitium DNS and Cloudflare in
multi-provider E2E scenarios
Documentation
- Architecture Overview: System design and component interaction docs (#35)
- Multi-Instance Guide: Running multiple dnsweaver instances (#35)
- SSH Remote Management: dnsmasq provider SSH docs and secrets guide (#99)
- Test Case Matrix: Release checklist and test coverage mapping (#109)
- Provider Documentation: Accuracy corrections across all providers
Docker Images
docker pull ghcr.io/maxfield-allison/dnsweaver:v1.0.0
docker pull docker.io/maxamill/dnsweaver:v1.0.0v0.9.3
Fixed
- Source Registry:
dnsweaver.enabled=false(Docker) anddnsweaver.dev/enabled=false
(K8s) now opt out of ALL sources at the registry level, not just the dnsweaver native
source. Previously the traefik source still extracted hostnames from disabled workloads.
Fixes #75,
#152. - Helm Chart: Bumped appVersion to 0.9.3
Docker Images
docker pull ghcr.io/maxfield-allison/dnsweaver:v0.9.3
docker pull docker.io/maxamill/dnsweaver:v0.9.3v0.9.2
Fixed
- Critical Correctness (#148):
parseIntEnvreplaced withstrconv.Atoito prevent silent integer overflow on 32-bit platformsformatSRVKeyusesfmt.Sprintfinstead ofstring(rune(int))which produced Unicode characters instead of numeric keys- Thread-safe DNS record
Catalog— all public methods now protected bysync.Mutex - Enum validation for
log_level,log_format, anddocker_modeconfig fields RemoveHostnamenormalizes hostname before operations (RFC 1035)- A record validation rejects IPv6 addresses (must use AAAA)
GetExistingRecordsuses case-insensitive comparison per RFC 1035
- Concurrency & Safety (#149):
_FILEsecret read failure is now a hard error — no longer silently falls through to direct env var- Signal handler registered early (before initialization) so SIGINT/SIGTERM during startup triggers graceful shutdown
- Reconciliation concurrency guard —
TryLockprevents overlapping reconciliation from timer + events SetEnabled/SetDryRunuseatomic.Boolfor thread-safe access from concurrent goroutines- Mass deletion circuit breaker — orphan cleanup aborts if >50% of known hostnames would be deleted
- Kubernetes
AddEventHandlererrors now propagated (previously logged and silently dropped) sync.WaitGroupensures periodic reconciliation goroutine completes during shutdown
- Provider & Security Hardening (#150):
- dnsmasq
GetServer()usesnet.SplitHostPort— correct IPv6 address parsing - Domain matcher strips trailing dots before comparison for consistent matching
- Pi-hole v6 URL path values escaped with
url.PathEscapeto prevent injection - dnsmasq reload command validated against shell metacharacters
- SSH
RunWithSudopipes password via stdin instead ofecho(no/procexposure) - HTTP response bodies capped at 10 MB via
httputil.ReadBodyacross all providers
- dnsmasq
- Documentation Alignment (#151):
- Added dnsmasq provider example to
config.example.yml - Documented
_FILEsuffix support forTSIG_SECRETandSSH_PASSWORD - Fixed
DNSWEAVER_SOURCE(singular) →DNSWEAVER_SOURCES(plural) in K8s deployment docs - Documented Kubernetes source auto-registration behavior
record-typeannotation and K8s source doc consistently list A, AAAA, CNAME, SRV, TXT
- Added dnsmasq provider example to
- Helm Chart: Bumped appVersion to 0.9.2
Docker Images
docker pull ghcr.io/maxfield-allison/dnsweaver:v0.9.2
docker pull docker.io/maxamill/dnsweaver:v0.9.2v0.9.1
Fixed
- Documentation: Comprehensive documentation review and corrections
- Fixed incorrect env var
TLS_SKIP_VERIFY→INSECURE_SKIP_VERIFYin FAQ - Added
rfc2136to provider TYPE list in environment variable reference - Added missing per-instance env vars to reference:
MODE,EXCLUDE_DOMAINS_REGEX,
INSECURE_SKIP_VERIFY - Added
Operational Modespage (modes.md) to mkdocs navigation - Updated Go version from 1.24+ to 1.25+ in contributing guide
- Updated project structure in contributing guide (added
sources/,internal/kubernetes/,
pkg/workload/,pkg/sshutil/,providers/rfc2136/; removed obsoleteinternal/sources/) - Added 11 missing CHANGELOG version comparison links (v0.3.1–v0.7.0)
- Replaced internal IP
10.30.0.100with generic10.0.0.100in Kubernetes source docs
and annotations code comment - Fixed placeholder GitLab social link in mkdocs.yml
- Added
instance_idfield and RFC 2136 provider example to config.example.yml
- Fixed incorrect env var
- Helm Chart: Bumped chart version to 0.2.0 and appVersion to 0.9.1
Docker Images
docker pull ghcr.io/maxfield-allison/dnsweaver:v0.9.1
docker pull docker.io/maxamill/dnsweaver:v0.9.1v0.9.0
Added
- Kubernetes Platform Support: Full Kubernetes-native DNS management
- K8s watcher with informer-based event watching (#138) — real-time detection
of Ingress, IngressRoute (Traefik CRD), HTTPRoute (Gateway API), and Service resources - K8s source with annotation-driven configuration (#139) — hostnames, provider hints,
TTL, proxied, and metadata viadnsweaver.dev/*annotations - Deployment manifests: Helm chart, Kustomize base, and raw RBAC manifests (#140)
- Comprehensive Kubernetes deployment and source documentation
- Platform selector (
DNSWEAVER_PLATFORM) — run indocker,kubernetes, orbothmode
- K8s watcher with informer-based event watching (#138) — real-time detection
- Per-Record Metadata System (#141): Extensible key-value metadata on DNS records
Metadata map[string]stringfield onRecordandRecordHints(Phase 2)- Cloudflare per-record proxied control via
Record.Metadata["proxied"](Phase 3) - Source-level proxied field and
meta.*label parsing in dnsweaver source (Phase 4) - Metadata persistence in ownership TXT records (Phase 5)
- Metadata recovery from ownership TXT on startup for reconciliation (Phase 6)
- Workload Abstraction (#137): Platform-agnostic workload interface replacing
Docker-specific container/service types — enables multi-platform source support
Changed
- Cloudflare proxied default: Changed from
falsetotrueto match Cloudflare's
own default behavior — new records are proxied unless explicitly disabled
Fixed
- CI/CD: Bumped Go version in CI pipeline and Dockerfile to 1.25 to match
go.mod
Docker Images
docker pull ghcr.io/maxfield-allison/dnsweaver:v0.9.0
docker pull docker.io/maxamill/dnsweaver:v0.9.0v0.8.1
Fixed
- Cloudflare Provider: Fix JSON parsing failure on API responses — Cloudflare
changedmessagesfield from[]stringto[]object(matchingerrorsshape),
causingjson: cannot unmarshal object into Go struct fieldon every API call
Docker Images
docker pull ghcr.io/maxfield-allison/dnsweaver:v0.8.1
docker pull docker.io/maxamill/dnsweaver:v0.8.1v0.8.0
Added
- RFC 2136 Dynamic DNS Provider (#132): Industry-standard DNS update protocol support
- Works with BIND, Windows DNS, PowerDNS, Knot DNS, Technitium, and any RFC 2136-compliant server
- TSIG authentication with HMAC-SHA256/SHA512 support
- Catalog-based hostname enumeration via
_dnsweaver-catalog-N.<zone>TXT records - Per-record ownership verification via
_dnsweaver.<hostname>TXT records - Supports A, AAAA, CNAME, and SRV record types
- No AXFR required — catalog provides efficient O(n) enumeration
- Multi-Instance Coordination (#84): Instance-scoped ownership for shared DNS zones
- New
DNSWEAVER_INSTANCE_IDconfig (env var + YAML) identifies each instance - Ownership TXT records now carry instance ID:
heritage=dnsweaver,instance=<id> - Each instance only manages its own records — no cross-instance interference
- Orphan cleanup is instance-scoped: removing a service only cleans that instance's records
- Fully backward compatible: empty instance ID preserves legacy single-instance behavior
- Enables multiple dnsweaver deployments (e.g., per-node Docker, Pi clusters) sharing a zone
- New
Docker Images
docker pull ghcr.io/maxfield-allison/dnsweaver:v0.8.0
docker pull docker.io/maxamill/dnsweaver:v0.8.0v0.7.0
Added
- Pi-hole v6 API Support (#74): Full support for Pi-hole v6 REST API
- Automatic version detection probes Pi-hole to determine API version
- Session-based authentication with SID tokens for v6
- Supports
dns.hostsanddns.cnameRecordsconfig endpoints - New
API_VERSIONconfig option to override auto-detection (v5/v6/auto) - Maintains full backward compatibility with Pi-hole v5 legacy API
- Graceful Provider Initialization (#125): Resilient startup when providers are unavailable
- Providers that fail to connect at startup are retried in the background
- dnsweaver starts in "degraded" mode and becomes healthy once providers recover
- Configurable retry interval and max attempts
- Ping verification ensures provider connectivity before marking ready
- Shared SSH/SFTP Client Package (#120): New
pkg/sshutilfor remote provider operations- SSH client with connection pooling and keepalive
- SFTP-based FileSystem interface for remote file operations
- SSH exec-based CommandRunner for remote commands
- Configuration loading with Docker secrets support (
_FILEpattern) - Foundation for remote dnsmasq, BIND, and hosts-file providers
Fixed
- Pi-hole v6 version detection (#126): Use correct
/api/info/loginendpoint- Pi-hole v6 does not have
/api/infoendpoint (returns 404) - Changed to probe
/api/info/loginwhich is unauthenticated and confirms v6
- Pi-hole v6 does not have
- Pi-hole v6 List() returns 0 records (#103): Correct API response parsing
- Pi-hole v6
/api/config/dnsreturns hosts nested underconfig.dns, notconfig - Fixed parsing to handle
{ "config": { "dns": { "hosts": [...] } } }structure - Resolves "Item already present" errors when records already existed
- Pi-hole v6
Docker Images
docker pull ghcr.io/maxfield-allison/dnsweaver:v0.7.0
docker pull docker.io/maxamill/dnsweaver:v0.7.0v0.6.1
Docker Images
docker pull ghcr.io/maxfield-allison/dnsweaver:v0.6.1
docker pull docker.io/maxamill/dnsweaver:v0.6.1v0.6.0
Added
- MkDocs Documentation Site (#65): Comprehensive documentation with Material theme
- Full API reference, configuration guides, and provider documentation
- Searchable, mobile-friendly documentation hosted via GitHub Pages
- Includes examples, quickstart guides, and architecture overview
Changed
- License Change: MIT → BSL 1.1: Updated license to Business Source License 1.1
- Free for personal/homelab use, education, and small businesses
- Commercial license required for SaaS, embedded products, or larger organizations
- Converts to Apache 2.0 four years after each release
- See LICENSE file for full terms
- HTTP Client Consolidation (#92): Refactored HTTP client logic into shared
pkg/httputilpackage- All providers now use consistent HTTP client configuration
- Centralized TLS settings, timeouts, and error handling
- Added comprehensive test coverage for HTTP client behavior
- Providers use new factory pattern for cleaner initialization
Docker Images
docker pull ghcr.io/maxfield-allison/dnsweaver:v0.6.0
docker pull docker.io/maxamill/dnsweaver:v0.6.0