NO_PURGE prevents changing record types
If I have a record created as an A record (foo in this example):
// Providers:
var REG_NONE = NewRegistrar('none', 'NONE'); // No registrar.
var DNS_BIND = NewDnsProvider('bind', 'BIND'); // ISC BIND.
var DNS_AD = NewDnsProvider("ad", "ACTIVEDIRECTORY_PS");
// Domains:
D("xwis.priv", REG_NONE, DnsProvider(DNS_BIND), DnsProvider(DNS_AD), NO_PURGE,
// ...
A('foo', '192.168.1.2'),
// ...
)
When I try to change the record to a CNAME with NO_PURGE turned on:
// Providers:
var REG_NONE = NewRegistrar('none', 'NONE'); // No registrar.
var DNS_BIND = NewDnsProvider('bind', 'BIND'); // ISC BIND.
var DNS_AD = NewDnsProvider("ad", "ACTIVEDIRECTORY_PS");
// Domains:
D("xwis.priv", REG_NONE, DnsProvider(DNS_BIND), DnsProvider(DNS_AD), NO_PURGE,
// ...
A('bar', '192.168.1.2'),
CNAME('foo', 'bar.xwis.priv.'),
// ...
)
Running dnscontrol preview warns that it won't delete the A record to make the CNAME because of NO_PURGE:
PS C:\dns> .\dnscontrol.exe preview --providers ad
******************** Domain: xwis.priv
----- Getting nameservers from: ad
----- Getting nameservers from: bind
----- DNS Provider: ad...2018/07/11 16:15:34 domains.go:38: WARNING: Active Directory only manages A and CNAME records.
Won't consider NS xwis.priv
2018/07/11 16:15:36 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:36 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:36 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:36 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:36 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:37 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:37 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:37 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:37 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:37 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:37 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:37 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:37 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:37 diff.go:78: Ignoring record domaindnszones A due to IGNORE
2018/07/11 16:15:37 diff.go:78: Ignoring record forestdnszones A due to IGNORE
2018/07/11 16:15:37 diff.go:96: Ignoring record set A foo.xwis.priv due to NO_PURGE
2 corrections
#1: CREATE record: bar A ttl(300) 192.168.1.2
#2: CREATE record: foo CNAME ttl(300) bar.xwis.priv.
----- DNS Provider: bind... (skipping)
----- Registrar: none... (skipping)
Done. 2 corrections.
Pushing the new config makes it seem like the CNAME was created:
PS C:\dns> .\dnscontrol.exe push --providers ad
******************** Domain: xwis.priv
----- Getting nameservers from: ad
----- Getting nameservers from: bind
----- DNS Provider: ad...2018/07/11 16:15:43 domains.go:38: WARNING: Active Directory only manages A and CNAME records.
Won't consider NS xwis.priv
2018/07/11 16:15:46 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:46 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:46 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:46 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:46 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:46 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:46 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:46 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:46 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:46 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:46 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:46 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:46 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:15:46 diff.go:78: Ignoring record domaindnszones A due to IGNORE
2018/07/11 16:15:46 diff.go:78: Ignoring record forestdnszones A due to IGNORE
2018/07/11 16:15:46 diff.go:96: Ignoring record set A foo.xwis.priv due to NO_PURGE
2 corrections
#1: CREATE record: bar A ttl(300) 192.168.1.2
SUCCESS!
#2: CREATE record: foo CNAME ttl(300) bar.xwis.priv.
SUCCESS!
----- DNS Provider: bind... (skipping)
----- Registrar: none... (skipping)
Done. 2 corrections.
However, the record remains an A record:

And running dnscontrol preview again indicates that it still wants to create the CNAME:
PS C:\dns> .\dnscontrol.exe preview --providers ad
******************** Domain: xwis.priv
----- Getting nameservers from: ad
----- Getting nameservers from: bind
----- DNS Provider: ad...2018/07/11 16:16:55 domains.go:38: WARNING: Active Directory only manages A and CNAME records.
Won't consider NS xwis.priv
2018/07/11 16:16:58 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:16:58 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:16:58 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:16:58 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:16:58 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:16:58 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:16:58 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:16:58 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:16:58 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:16:58 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:16:58 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:16:58 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:16:58 domains.go:180: Warning: Record of type SRV found in AD zone. Will be ignored.
2018/07/11 16:16:58 diff.go:78: Ignoring record domaindnszones A due to IGNORE
2018/07/11 16:16:58 diff.go:78: Ignoring record forestdnszones A due to IGNORE
2018/07/11 16:16:58 diff.go:96: Ignoring record set A foo.xwis.priv due to NO_PURGE
2 corrections
#1: CREATE record: foo CNAME ttl(300) bar.xwis.priv.
#2: MODIFY A xwis-noc.xwis.priv: (10.40.5.13 ttl=3600) -> (10.40.5.13 ttl=300)
----- DNS Provider: bind... (skipping)
----- Registrar: none... (skipping)
Done. 2 corrections.
Is there another mode similar to NO_PURGE that keeps records not in the dnsconfig.js manifest but tells dnscontrol it's ok to delete records explicitly listed in its manifest?
While I could create the bar entry as a CNAME to foo instead of the other way around, I wanted to do it this way to match other servers in our environment, this entry was initially configured differently than other services under our control before we started looking into dnscontrol.
Sorry, I meant to reply to this sooner, but must have slipped my mind.
The problem with "no purge" in this scenario is that the diff algorithm treats all "record sets" independently. A record set is identified by its type and label. So CNAME and A records with the same name are not really comparable by the current algorithm. There are a few providers (r53 I think) where we do try to handle the cname <-> A case specially because it needs to be handled a bit oddly in order to succeed in one or both directions I think.
But it is hard to infer intent from just the presence or absence of records in a no_purge scenario. CNAMEs and As are incompatible by definition, but other types may be able to coexist with the same name, and it may not be clear which are "managed" by dnscontrol and which are external and to be ignored.
It might make sense to have some annotation that says "make sure this record does not exist". The best analogue I have is in puppet where you can set up a file with ensure = absent to make sure it gets deleted. That feels a bit hacky to me, but semantically might be the right way to express what you want.
Another alternative I like much much less is adding a rule in the diff engine saying that CNAMEs are valid to be purged if another managed record exists for the same label. And possibly the opposite. I dislike special cases like that, because it only works on those specific record types, and feels pretty brittle to be honest. Also, people generally misunderstand CNAME semantics in general, and I do not really want to go doing magic cleaning up for you, lest people get even more confused.
No worries, we're going with a different domain setup so we won't have to worry about this.
I like the idea of being able to ensure a record of a specific type does not exist, I could see that being useful.
Hi @nlowe !
I know this bug has been around for many years but I have some good news. The tlim_corrector branch (with --diff2=true) should fix this bug. Would you be wiling to give that branch a test?
Also, the "ensure_absent" feature is easier to implement with the new diff2 algorithm. https://github.com/StackExchange/dnscontrol/issues/2064 should be completed soon. (the code is actually in the same branch, I just have to decided on what the command name will be, document it, etc.)
Hey @tlimoncelli!
I've actually switched employers and no longer have access to an environment where I'd be able to test this.
No worries.
Congrats on the new job! SpaceX sounds like a great place to work! (Do they use dnscontrol? :-) )