Warn if IGNORE() is unreliable for this provider (#3683)

This commit is contained in:
Tom Limoncelli 2025-07-30 20:41:49 -04:00 committed by GitHub
parent a9243aa554
commit 633196e328
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 100 additions and 51 deletions

View file

@ -1725,6 +1725,7 @@ func makeTests() []*TestGroup {
// IGNORE with changes
testgroup("IGNORE with modify",
not("NAMECHEAP"), // Will fail until converted to use diff2 module.
tc("Create some records",
a("foo", "1.1.1.1"),
a("foo", "10.10.10.10"),
@ -1876,6 +1877,7 @@ func makeTests() []*TestGroup {
// https://github.com/StackExchange/dnscontrol/issues/3227
testgroup("IGNORE w/change b3227",
not("NAMECHEAP"), // Will fail until converted to use diff2 module.
tc("Create some records",
a("testignore", "8.8.8.8"),
a("testdefined", "9.9.9.9"),

View file

@ -38,6 +38,19 @@ func (d *differCompat) IncrementalDiff(existing []*models.RecordConfig) (reportM
return nil, nil, nil, nil, 0, err
}
if len(d.dc.EnsureAbsent) != 0 {
reportMsgs = append(reportMsgs, "WARNING: This provider does not reliably support ENSURE_ABSENT")
}
if d.dc.KeepUnknown {
reportMsgs = append(reportMsgs, "WARNING: This provider does not reliably support NO_PURGE")
}
if len(d.dc.Unmanaged) != 0 {
reportMsgs = append(reportMsgs, "WARNING: This provider does not reliably support IGNORE() and friends")
}
if d.dc.UnmanagedUnsafe {
reportMsgs = append(reportMsgs, "WARNING: This provider does not reliably support DISABLE_IGNORE_SAFETY_CHECK")
}
for _, inst := range instructions {
cor := Correlation{}
switch inst.Type {

View file

@ -24,8 +24,9 @@ var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanAutoDNSSEC: providers.Can(),
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Unimplemented(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAKAMAICDN: providers.Can(),
providers.CanUseAlias: providers.Cannot(),
providers.CanUseCAA: providers.Can(),

View file

@ -28,6 +28,16 @@ const (
// CanGetZones indicates the provider supports the get-zones subcommand.
CanGetZones
// CanOnlyDiff1Features indicates the provider has not yet been upgraded to
// use the "diff2" differencing engine. Instead, it uses the the backwards
// compatibility mode. The diff2 engine is required to repliably provide
// IGNORE(), NO_PURGE, and other features.
// This capability is set automatically for the provider during the call to
// RegisterDomainServiceProviderType. It is set to Can() if we detect
// compatibility mode is in use. All other values (Unimplemented and Cannot)
// are equivalent.
CanOnlyDiff1Features
// CanUseAKAMAICDN indicates the provider support the specific AKAMAICDN records that only the Akamai EdgeDns provider supports
CanUseAKAMAICDN

View file

@ -11,33 +11,34 @@ func _() {
_ = x[CanAutoDNSSEC-0]
_ = x[CanConcur-1]
_ = x[CanGetZones-2]
_ = x[CanUseAKAMAICDN-3]
_ = x[CanUseAlias-4]
_ = x[CanUseAzureAlias-5]
_ = x[CanUseCAA-6]
_ = x[CanUseDHCID-7]
_ = x[CanUseDNAME-8]
_ = x[CanUseDS-9]
_ = x[CanUseDSForChildren-10]
_ = x[CanUseHTTPS-11]
_ = x[CanUseLOC-12]
_ = x[CanUseNAPTR-13]
_ = x[CanUsePTR-14]
_ = x[CanUseRoute53Alias-15]
_ = x[CanUseSOA-16]
_ = x[CanUseSRV-17]
_ = x[CanUseSSHFP-18]
_ = x[CanUseSVCB-19]
_ = x[CanUseTLSA-20]
_ = x[CanUseDNSKEY-21]
_ = x[DocCreateDomains-22]
_ = x[DocDualHost-23]
_ = x[DocOfficiallySupported-24]
_ = x[CanOnlyDiff1Features-3]
_ = x[CanUseAKAMAICDN-4]
_ = x[CanUseAlias-5]
_ = x[CanUseAzureAlias-6]
_ = x[CanUseCAA-7]
_ = x[CanUseDHCID-8]
_ = x[CanUseDNAME-9]
_ = x[CanUseDS-10]
_ = x[CanUseDSForChildren-11]
_ = x[CanUseHTTPS-12]
_ = x[CanUseLOC-13]
_ = x[CanUseNAPTR-14]
_ = x[CanUsePTR-15]
_ = x[CanUseRoute53Alias-16]
_ = x[CanUseSOA-17]
_ = x[CanUseSRV-18]
_ = x[CanUseSSHFP-19]
_ = x[CanUseSVCB-20]
_ = x[CanUseTLSA-21]
_ = x[CanUseDNSKEY-22]
_ = x[DocCreateDomains-23]
_ = x[DocDualHost-24]
_ = x[DocOfficiallySupported-25]
}
const _Capability_name = "CanAutoDNSSECCanConcurCanGetZonesCanUseAKAMAICDNCanUseAliasCanUseAzureAliasCanUseCAACanUseDHCIDCanUseDNAMECanUseDSCanUseDSForChildrenCanUseHTTPSCanUseLOCCanUseNAPTRCanUsePTRCanUseRoute53AliasCanUseSOACanUseSRVCanUseSSHFPCanUseSVCBCanUseTLSACanUseDNSKEYDocCreateDomainsDocDualHostDocOfficiallySupported"
const _Capability_name = "CanAutoDNSSECCanConcurCanGetZonesCanOnlyDiff1FeaturesCanUseAKAMAICDNCanUseAliasCanUseAzureAliasCanUseCAACanUseDHCIDCanUseDNAMECanUseDSCanUseDSForChildrenCanUseHTTPSCanUseLOCCanUseNAPTRCanUsePTRCanUseRoute53AliasCanUseSOACanUseSRVCanUseSSHFPCanUseSVCBCanUseTLSACanUseDNSKEYDocCreateDomainsDocDualHostDocOfficiallySupported"
var _Capability_index = [...]uint16{0, 13, 22, 33, 48, 59, 75, 84, 95, 106, 114, 133, 144, 153, 164, 173, 191, 200, 209, 220, 230, 240, 252, 268, 279, 301}
var _Capability_index = [...]uint16{0, 13, 22, 33, 53, 68, 79, 95, 104, 115, 126, 134, 153, 164, 173, 184, 193, 211, 220, 229, 240, 250, 260, 272, 288, 299, 321}
func (i Capability) String() string {
if i >= Capability(len(_Capability_index)-1) {

View file

@ -39,8 +39,9 @@ var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanAutoDNSSEC: providers.Can(),
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Can(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAlias: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDNAME: providers.Can(),

View file

@ -27,6 +27,7 @@ var features = providers.DocumentationNotes{
providers.CanAutoDNSSEC: providers.Unimplemented("Ask for this feature."),
providers.CanConcur: providers.Can(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.DocCreateDomains: providers.Can(),
providers.DocDualHost: providers.Can(),
providers.DocOfficiallySupported: providers.Cannot("Actively maintained provider module."),

View file

@ -27,8 +27,9 @@ type providerClient struct {
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Can(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseSRV: providers.Can(),
providers.DocOfficiallySupported: providers.Can(),

View file

@ -35,12 +35,13 @@ var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanAutoDNSSEC: providers.Can("deSEC always signs all records. When trying to disable, a notice is printed."),
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Can(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAlias: providers.Unimplemented("Apex aliasing is supported via new SVCB and HTTPS record types. For details, check the deSEC docs."),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Can(),
providers.CanUseDNSKEY: providers.Can(),
providers.CanUseDS: providers.Can(),
providers.CanUseHTTPS: providers.Can(),
providers.CanUseLOC: providers.Unimplemented(),
providers.CanUseNAPTR: providers.Can(),

View file

@ -73,8 +73,8 @@ retry:
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Can(),
providers.CanGetZones: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseSRV: providers.Can(),

View file

@ -24,8 +24,9 @@ var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanAutoDNSSEC: providers.Can(),
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Can(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAlias: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot(),

View file

@ -14,8 +14,9 @@ import (
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Unimplemented(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAlias: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot(),

View file

@ -25,9 +25,10 @@ type domainNameShopProvider struct {
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanAutoDNSSEC: providers.Cannot(), // Maybe there is support for it
providers.CanGetZones: providers.Unimplemented(), //
providers.CanAutoDNSSEC: providers.Cannot(), // Maybe there is support for it
providers.CanConcur: providers.Unimplemented(),
providers.CanGetZones: providers.Unimplemented(), //
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAlias: providers.Unimplemented("Needs custom implementation"), // Can possibly be implemented, needs further research
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Unimplemented(), // Seems to support but needs to be implemented

View file

@ -55,8 +55,9 @@ func NewExoscale(m map[string]string, metadata json.RawMessage) (providers.DNSSe
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanGetZones: providers.Unimplemented(),
providers.CanConcur: providers.Unimplemented(),
providers.CanGetZones: providers.Unimplemented(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAlias: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseLOC: providers.Cannot(),

View file

@ -15,8 +15,9 @@ var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanAutoDNSSEC: providers.Cannot(),
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Can(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAlias: providers.Cannot(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Can(),

View file

@ -21,8 +21,9 @@ type HXClient struct {
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanGetZones: providers.Unimplemented(),
providers.CanConcur: providers.Unimplemented(),
providers.CanGetZones: providers.Unimplemented(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAlias: providers.Cannot("Using ALIAS is possible through our extended DNS (X-DNS) service. Feel free to get in touch with us."),
providers.CanUseCAA: providers.Can(),
providers.CanUseLOC: providers.Unimplemented(),

View file

@ -20,8 +20,9 @@ var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanAutoDNSSEC: providers.Can(),
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Unimplemented(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAlias: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Can(),

View file

@ -91,8 +91,9 @@ func NewLinode(m map[string]string, metadata json.RawMessage) (providers.DNSServ
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Unimplemented(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseCAA: providers.Can("Linode doesn't support changing the CAA flag"),
providers.CanUseLOC: providers.Cannot(),
providers.DocDualHost: providers.Cannot(),

View file

@ -50,8 +50,9 @@ var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanAutoDNSSEC: providers.Cannot(),
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Unimplemented(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAKAMAICDN: providers.Cannot(),
providers.CanUseAlias: providers.Cannot(),
providers.CanUseAzureAlias: providers.Cannot(),

View file

@ -29,8 +29,9 @@ type namecheapProvider struct {
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Can(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(), // If you remove this, also update not() statements in integrationTest/integration_test.go
providers.CanUseAlias: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseLOC: providers.Cannot(),

View file

@ -23,8 +23,9 @@ type namedotcomProvider struct {
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Unimplemented(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAlias: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUsePTR: providers.Cannot("PTR records are not supported (See Link)", "https://www.name.com/support/articles/205188508-Reverse-DNS-records"),

View file

@ -13,8 +13,9 @@ import (
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanGetZones: providers.Cannot(),
providers.CanConcur: providers.Unimplemented(),
providers.CanGetZones: providers.Cannot(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUsePTR: providers.Cannot(),

View file

@ -16,8 +16,9 @@ var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanAutoDNSSEC: providers.Cannot(),
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Can(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAlias: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot(),

View file

@ -20,8 +20,9 @@ import (
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Unimplemented(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAlias: providers.Can(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Cannot(), // should be supported, but getting 500s in tests

View file

@ -42,8 +42,9 @@ func newPacketframe(m map[string]string, metadata json.RawMessage) (providers.DN
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanGetZones: providers.Unimplemented(),
providers.CanConcur: providers.Unimplemented(),
providers.CanGetZones: providers.Unimplemented(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),
providers.DocDualHost: providers.Cannot(),

View file

@ -70,6 +70,7 @@ func RegisterDomainServiceProviderType(name string, fns DspFuncs, pm ...Provider
log.Fatalf("Cannot register registrar type %q multiple times", name)
}
DNSProviderTypes[name] = fns
unwrapProviderCapabilities(name, pm)
}

View file

@ -17,8 +17,9 @@ var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanAutoDNSSEC: providers.Unimplemented("Supported by RWTH but not implemented yet."),
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Unimplemented(),
providers.CanGetZones: providers.Can(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseAlias: providers.Cannot(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDS: providers.Unimplemented("DS records are only supported at the apex and require a different API call that hasn't been implemented yet."),

View file

@ -25,10 +25,11 @@ type softlayerProvider struct {
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanGetZones: providers.Unimplemented(),
providers.CanConcur: providers.Unimplemented(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseSRV: providers.Can(),
providers.CanConcur: providers.Unimplemented(),
providers.CanGetZones: providers.Unimplemented(),
providers.CanOnlyDiff1Features: providers.Can(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseSRV: providers.Can(),
}
func init() {