github.com/teknogeek/dnscontrol@v0.2.8/providers/capabilities.go (about) 1 package providers 2 3 import ( 4 "log" 5 ) 6 7 // Capability is a bitmasked set of "features" that a provider supports. Only use constants from this package. 8 type Capability uint32 9 10 const ( 11 // If you add something to this list, you probably want to add it to pkg/normalize/validate.go checkProviderCapabilities() or somewhere near there. 12 13 // CanUseAlias indicates the provider support ALIAS records (or flattened CNAMES). Up to the provider to translate them to the appropriate record type. 14 CanUseAlias Capability = iota 15 16 // CanUseCAA indicates the provider can handle CAA records 17 CanUseCAA 18 19 // CanUsePTR indicates the provider can handle PTR records 20 CanUsePTR 21 22 // CanUseSRV indicates the provider can handle SRV records 23 CanUseSRV 24 25 // CanUseTLSA indicates the provider can handle TLSA records 26 CanUseTLSA 27 28 // CanUseTXTMulti indicates the provider can handle TXT records with multiple strings 29 CanUseTXTMulti 30 31 // CantUseNOPURGE indicates NO_PURGE is broken for this provider. To make it 32 // work would require complex emulation of an incremental update mechanism, 33 // so it is easier to simply mark this feature as not working for this 34 // provider. 35 CantUseNOPURGE 36 37 // DocOfficiallySupported means it is actively used and maintained by stack exchange 38 DocOfficiallySupported 39 // DocDualHost means provider allows full management of apex NS records, so we can safely dual-host with anothe provider 40 DocDualHost 41 // DocCreateDomains means provider can add domains with the `dnscontrol create-domains` command 42 DocCreateDomains 43 44 // CanUseRoute53Alias indicates the provider support the specific R53_ALIAS records that only the Route53 provider supports 45 CanUseRoute53Alias 46 ) 47 48 var providerCapabilities = map[string]map[Capability]bool{} 49 50 // ProviderHasCabability returns true if provider has capability. 51 func ProviderHasCabability(pType string, cap Capability) bool { 52 if providerCapabilities[pType] == nil { 53 return false 54 } 55 return providerCapabilities[pType][cap] 56 } 57 58 // DocumentationNote is a way for providers to give more detail about what features they support. 59 type DocumentationNote struct { 60 HasFeature bool 61 Unimplemented bool 62 Comment string 63 Link string 64 } 65 66 // DocumentationNotes is a full list of notes for a single provider 67 type DocumentationNotes map[Capability]*DocumentationNote 68 69 // ProviderMetadata is a common interface for DocumentationNotes and Capability to be used interchangably 70 type ProviderMetadata interface{} 71 72 // Notes is a collection of all documentation notes, keyed by provider type 73 var Notes = map[string]DocumentationNotes{} 74 75 func unwrapProviderCapabilities(pName string, meta []ProviderMetadata) { 76 if providerCapabilities[pName] == nil { 77 providerCapabilities[pName] = map[Capability]bool{} 78 } 79 for _, pm := range meta { 80 switch x := pm.(type) { 81 case Capability: 82 providerCapabilities[pName][x] = true 83 case DocumentationNotes: 84 if Notes[pName] == nil { 85 Notes[pName] = DocumentationNotes{} 86 } 87 for k, v := range x { 88 Notes[pName][k] = v 89 providerCapabilities[pName][k] = v.HasFeature 90 } 91 default: 92 log.Fatalf("Unrecognized ProviderMetadata type: %T", pm) 93 } 94 95 } 96 } 97 98 // Can is a small helper for concisely creating Documentation Notes 99 // comments are variadic for easy ommission. First is comment, second is link, the rest are ignored. 100 func Can(comments ...string) *DocumentationNote { 101 n := &DocumentationNote{ 102 HasFeature: true, 103 } 104 n.addStrings(comments) 105 return n 106 } 107 108 // Cannot is a small helper for concisely creating Documentation Notes 109 // comments are variadic for easy ommission. First is comment, second is link, the rest are ignored. 110 func Cannot(comments ...string) *DocumentationNote { 111 n := &DocumentationNote{ 112 HasFeature: false, 113 } 114 n.addStrings(comments) 115 return n 116 } 117 118 // Unimplemented is a small helper for concisely creating Documentation Notes 119 // comments are variadic for easy ommission. First is comment, second is link, the rest are ignored. 120 func Unimplemented(comments ...string) *DocumentationNote { 121 n := &DocumentationNote{ 122 HasFeature: false, 123 Unimplemented: true, 124 } 125 n.addStrings(comments) 126 return n 127 } 128 129 func (n *DocumentationNote) addStrings(comments []string) { 130 if len(comments) > 0 { 131 n.Comment = comments[0] 132 } 133 if len(comments) > 1 { 134 n.Link = comments[1] 135 } 136 }