Ignore A record only for dynamic DNS while updating others
A sub-domain foo.example.com has an A record (IPv4 address) set by a dynamic DNS client, static IPv6 (AAAA) managed by dnscontrol and TXT/SPF record also managed by dnscontrol.
Is there a way to tell dnscontrol to not touch the A record but update only the AAAA and TXT records? IGNORE_NAME and IGNORE_TARGET do not seem to do the trick.
It seems what's needed here is for IGNORE_TARGET to also support A type records (or any record type), not just CNAME. Are there technical reasons why the current implementation is limited to CNAME?
IGNORE_TARGET("foo.example.com", "A")
It only supports CNAMEs due to an overabundance of caution. The IGNORE*() code is a bit flakey so we started with just the one RTYPE needed at the time.
I'd gladly accept a PR that expands it to "A" records or all records. (Edit: I listed the wrong rtype originally)
As a temporary work-around, you could use a CNAME that points to a static AAAA record.
Tom
I'd like the A record to be ignored, that's the one managed by a dynamic DNS client. AAAA, TXT should all be managed by dnscontrol.
I stand corrected. I was thinking in reverse :)
@tlimoncelli 🙏 any chance we could prioritize improving this situation? it's important for those of us dealing with dynamic IP addresses. 🙏
Hi @timkgh . Sadly I won't have time to work on that kind of feature. My time is booked up with other projects for many months. This is a community-driven project. By that I mean that new features come from the community. I'd be glad to coach a volunteer.
I had another idea for a workaround: Have DNSControl ignore all records at that label. Use the native system for maintaining the A, TXT, and other records at that FQDN.
HTH, Tom
By native I assume just set the records straight up in the Cloudflare UI or whatever the DNS provider is?
Yet another idea is to wrap dnscontrol in a script that first fetches the current value for the A record and puts it in the dnsconfig.js file before it calls dnscontrol to apply the changes, in effect making it a nop. There's a slight chance of a race though.
By native I assume just set the records straight up in the Cloudflare UI or whatever the DNS provider is?
Yes, exactly.
I was thinking about this more. What you need is a change to IGNORE_NAME(), not IGNORE_TARGET().
This will get an error because we are ignoring "foo" and updating "foo":
D("example.com", REG,
IGNORE_NAME("foo"),
AAAA("foo", "2607:f8b0:4006:80b::200e"),
TXT("foo", "my text"),
)
The error will look something like:
integration_test.go:213: runTests: incdiff error: trying to update/add IGNORE_NAMEd record: foo TXT
Either that shouldn't be an error (which could be unsafe) or IGNORE_NAME() should accept an optional parameter that lets you specify which record types should be ignored. Something like IGNORE_NAME("foo", "AAAA,TXT")
Tom
Note to self: The current diff mechanism is made more complex by the IGNORE*() functions. We could simplify this with a different algorithm:
- There is a point where we have the "existing" and "desired" records. Existing is what records were downloaded via the API. Desired is what records were specified in the dnsconfig.js file.
- Query "existing" list for records that match all the
IGNORE_NAME()and `IGNORE_TARGET() patterns. Any matches should be added to desired list. - If "NO_PURGE" is set, add to "found" any records from "existing" that don't already exist. (This can be tricky: What do you do if the only difference is the TTL? I'd say... don't include the TTL in the comparison.)
- Now the diff algorithm can be greatly simplified. We don't have to deal with all the exceptions and edge-cases we were doing before.
The problem with this algorithm is that there is a race condition for the (few) providers that required changes on a label to include all the records on that label. For example, if you have three "A" records on "foo.example.com" and want to delete one of them, you do that with an API call such as "update foo.example.com with the 2 remaining A records". In that case, there is a chance that we might undo a change if it happens at the exact same time. I wouldn't worry about such changes as they are rare, but ... if you do something a million times, rare things happen.
Would the fix for
IGNORE_TARGETbe as easy as relaxing this check to allowArecords?
Yes. (and updating the integration tests)
I was thinking about this more. What you need is a change to
IGNORE_NAME(), notIGNORE_TARGET().
Ah I see. I finally realized IGNORE_TARGET is not what I want, I misunderstood what it did, it would have to match by the existing record IP address. It's IGNORE_NAME as you correctly pointed out.
@tlimoncelli Volunteering PR #1808, for dynamic DNS A record support.
Awesome work @bits01 😍
@tlimoncelli how often do you release new versions?
Releases aren't on a specific schedule. Would you be willing to build from master to test it out before I publish the release?
Releases aren't on a specific schedule. Would you be willing to build from master to test it out before I publish the release?
Just tried it on macOS and Cloudflare and it does exactly what I need 👍
great! I'll try to do an official release this week.