mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-12-09 05:36:27 +08:00
## Summary This PR adds a new domain modifier `IGNORE_EXTERNAL_DNS()` that automatically detects and ignores DNS records managed by Kubernetes [external-dns](https://github.com/kubernetes-sigs/external-dns) controller. **Related Issue:** This addresses the feature request discussed in StackExchange/dnscontrol#935 (Idea: Ownership system), where @tlimoncelli indicated openness to accepting a PR for this functionality. ## Problem When running DNSControl alongside Kubernetes external-dns, users face a challenge: - **external-dns** dynamically creates DNS records based on Kubernetes Ingress/Service resources - Users cannot use `IGNORE()` because they cannot predict which record names external-dns will create - Using `NO_PURGE()` is too broad - it prevents DNSControl from cleaning up any orphaned records The fundamental issue is that `IGNORE()` requires static patterns known at config-time, but external-dns creates records dynamically at runtime. ## Solution `IGNORE_EXTERNAL_DNS()` solves this by detecting external-dns managed records at runtime: ```javascript D("example.com", REG_CHANGEME, DnsProvider(DSP_MY_PROVIDER), IGNORE_EXTERNAL_DNS(), // Automatically ignore external-dns managed records A("@", "1.2.3.4"), CNAME("www", "@") ); ``` ### How It Works external-dns uses a TXT record registry to track ownership. For each managed record, it creates a TXT record like: - `a-myapp.example.com` → TXT containing `heritage=external-dns,external-dns/owner=...` - `cname-api.example.com` → TXT containing `heritage=external-dns,external-dns/owner=...` This PR: 1. Scans existing TXT records for the `heritage=external-dns` marker 2. Parses the TXT record name prefix (e.g., `a-`, `cname-`) to determine the managed record type 3. Automatically adds those records to the ignore list during diff operations ## Changes | File | Purpose | |------|---------| | `models/domain.go` | Add `IgnoreExternalDNS` field to DomainConfig | | `pkg/js/helpers.js` | Add `IGNORE_EXTERNAL_DNS()` JavaScript helper | | `pkg/diff2/externaldns.go` | Core detection logic for external-dns TXT records | | `pkg/diff2/externaldns_test.go` | Unit tests for detection logic | | `pkg/diff2/handsoff.go` | Integrate external-dns detection into handsoff() | | `pkg/diff2/diff2.go` | Pass IgnoreExternalDNS flag to handsoff() | | `commands/types/dnscontrol.d.ts` | TypeScript definitions for IDE support | | `documentation/.../IGNORE_EXTERNAL_DNS.md` | User documentation | ## Design Philosophy This follows DNSControl's pattern of convenience builders (like `M365_BUILDER`, `SPF_BUILDER`, `DKIM_BUILDER`) that make complex operations simple. Just as those builders abstract away implementation details, `IGNORE_EXTERNAL_DNS()` abstracts away the complexity of detecting external-dns managed records. ## Testing All unit tests pass: ``` go test ./pkg/diff2/... -v # Tests detection logic go test ./pkg/js/... # Tests JS helpers go build ./... # Builds successfully ``` ## Caveats Documented - Only supports TXT registry (the default for external-dns) - Requires external-dns to use default naming conventions - May need updates if external-dns changes its registry format --------- Co-authored-by: Tom Limoncelli <6293917+tlimoncelli@users.noreply.github.com>
10 KiB
10 KiB
Table of contents
Getting Started
Language Reference
- JavaScript DSL
- Top Level Functions
- Domain Modifiers
- A
- AAAA
- ALIAS
- AUTODNSSEC_OFF
- AUTODNSSEC_ON
- CAA
- CAA_BUILDER
- CNAME
- DHCID
- DNAME
- DNSKEY
- DISABLE_IGNORE_SAFETY_CHECK
- DKIM_BUILDER
- DMARC_BUILDER
- DS
- DefaultTTL
- DnsProvider
- FRAME
- HTTPS
- IGNORE
- IGNORE_EXTERNAL_DNS
- IGNORE_NAME
- IGNORE_TARGET
- IMPORT_TRANSFORM
- IMPORT_TRANSFORM_STRIP
- INCLUDE
- LOC
- LOC_BUILDER_DD
- LOC_BUILDER_DMM_STR
- LOC_BUILDER_DMS_STR
- LOC_BUILDER_STR
- M365_BUILDER
- MX
- NAMESERVER
- NAMESERVER_TTL
- NAPTR
- NO_PURGE
- NS
- OPENPGPKEY
- PTR
- PURGE
- SMIMEA
- SOA
- SPF_BUILDER
- SRV
- SSHFP
- SVCB
- TLSA
- TXT
- URL
- URL301
- Service Provider specific
- AdGuard Home
- Akamai Edge Dns
- Amazon Route 53
- Azure DNS
- Cloudflare DNS
- ClouDNS
- PowerDNS
- Record Modifiers
- TTL
- Service Provider specific
- Amazon Route 53
- Why CNAME/MX/NS targets require a "dot"
Provider
- Supported providers
- AdGuard Home
- Akamai Edge DNS
- Amazon Route 53
- AutoDNS
- AXFR+DDNS
- Azure DNS
- Azure Private DNS
- BIND
- Bunny DNS
- CentralNic Reseller (CNR) - formerly RRPProxy
- Cloudflare
- ClouDNS
- CSC Global
- deSEC
- DigitalOcean
- DNS Made Easy
- DNSimple
- DNS-over-HTTPS
- DOMAINNAMESHOP
- Dynadot
- easyname
- Exoscale
- Fortigate
- Gandi_v5
- Gcore
- Google Cloud DNS
- Hetzner DNS API
- Hetzner DNS Console (legacy)
- HEXONET
- hosting.de
- Huawei Cloud DNS
- Hurricane Electric DNS
- Internet.bs
- INWX
- Joker
- Linode
- Loopia
- LuaDNS
- Mythic Beasts
- Namecheap
- Name.com
- Netcup
- Netlify
- NS1
- OpenSRS
- Oracle Cloud
- OVH
- Packetframe
- Porkbun
- PowerDNS
- Realtime Register
- RWTH DNS-Admin
- Sakura Cloud
- SoftLayer DNS
- TransIP
- Vercel
- Vultr
Commands
Advanced features
- Concurrency Verified
- CI/CD example for GitLab
- CLI variables
- Nameservers and Delegations
- Notifications
- Useful code tricks
- JSON Reports
- Dual Host
Developer info
- Code Style Guide
- Documentation Style Guide
- DNSControl is an opinionated system
- Writing new DNS providers
- Creating new DNS Resource Types (rtypes)
- Integration Tests
- Test a branch
- Unit Testing DNS Data
- Bug Triage Process
- Bring-Your-Own-Secrets for automated testing
- Debugging with dlv
- ALIAS Records
- TXT record testing
- DNS records ordering
- How to add a requested provider