-
Notifications
You must be signed in to change notification settings - Fork 379
/
capabilities.go
188 lines (147 loc) · 5.7 KB
/
capabilities.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
//go:generate stringer -type=Capability
package providers
import (
"log"
)
// Capability is a bitmasked set of "features" that a provider supports. Only use constants from this package.
type Capability uint32
const (
// Keep this list sorted.
// If you add something here, you probably want to also add it to
// pkg/normalize/validate.go checkProviderCapabilities() or
// somewhere near there.
// CanAutoDNSSEC indicates that the provider can automatically handle DNSSEC,
// so folks can ask for that.
CanAutoDNSSEC Capability = iota
// CanConcur indicates the provider can be used concurrently. Can()
// indicates that it has been tested and shown to work concurrently.
// Cannot() indicates it has not been tested OR it has been shown to not
// work when used concurrently. The default is Cannot().
CanConcur
// CanGetZones indicates the provider supports the get-zones subcommand.
CanGetZones
// CanUseAKAMAICDN indicates the provider support the specific AKAMAICDN records that only the Akamai EdgeDns provider supports
CanUseAKAMAICDN
// CanUseAlias indicates the provider support ALIAS records (or flattened CNAMES). Up to the provider to translate them to the appropriate record type.
CanUseAlias
// CanUseAzureAlias indicates the provider support the specific Azure_ALIAS records that only the Azure provider supports
CanUseAzureAlias
// CanUseCAA indicates the provider can handle CAA records
CanUseCAA
// CanUseDHCID indicates the provider can handle DHCID records
CanUseDHCID
// CanUseDNAME indicates the provider can handle DNAME records
CanUseDNAME
// CanUseDS indicates that the provider can handle DS record types. This
// implies CanUseDSForChildren without specifying the latter explicitly.
CanUseDS
// CanUseDSForChildren indicates the provider can handle DS record types, but
// only for children records, not at the root of the zone.
CanUseDSForChildren
// CanUseHTTPS indicates the provider can handle HTTPS records
CanUseHTTPS
// CanUseLOC indicates whether service provider handles LOC records
CanUseLOC
// CanUseNAPTR indicates the provider can handle NAPTR records
CanUseNAPTR
// CanUsePTR indicates the provider can handle PTR records
CanUsePTR
// CanUseRoute53Alias indicates the provider support the specific R53_ALIAS records that only the Route53 provider supports
CanUseRoute53Alias
// CanUseSOA indicates the provider supports full management of a zone's SOA record
CanUseSOA
// CanUseSRV indicates the provider can handle SRV records
CanUseSRV
// CanUseSSHFP indicates the provider can handle SSHFP records
CanUseSSHFP
// CanUseSVCB indicates the provider can handle SVCB records
CanUseSVCB
// CanUseTLSA indicates the provider can handle TLSA records
CanUseTLSA
// CanUseDNSKEY indicates that the provider can handle DNSKEY records
CanUseDNSKEY
// DocCreateDomains means provider can add domains with the `dnscontrol create-domains` command
DocCreateDomains
// DocDualHost means provider allows full management of apex NS records, so we can safely dual-host with anothe provider
DocDualHost
// DocOfficiallySupported means it is actively used and maintained by stack exchange
DocOfficiallySupported
)
var providerCapabilities = map[string]map[Capability]bool{}
// ProviderHasCapability returns true if provider has capability.
func ProviderHasCapability(pType string, cap Capability) bool {
if providerCapabilities[pType] == nil {
return false
}
return providerCapabilities[pType][cap]
}
// DocumentationNote is a way for providers to give more detail about what features they support.
type DocumentationNote struct {
HasFeature bool
Unimplemented bool
Comment string
Link string
}
// DocumentationNotes is a full list of notes for a single provider
type DocumentationNotes map[Capability]*DocumentationNote
// ProviderMetadata is a common interface for DocumentationNotes and Capability to be used interchangeably
type ProviderMetadata interface{}
// Notes is a collection of all documentation notes, keyed by provider type
var Notes = map[string]DocumentationNotes{}
func unwrapProviderCapabilities(pName string, meta []ProviderMetadata) {
if providerCapabilities[pName] == nil {
providerCapabilities[pName] = map[Capability]bool{}
}
for _, pm := range meta {
switch x := pm.(type) {
case Capability:
providerCapabilities[pName][x] = true
case DocumentationNotes:
if Notes[pName] == nil {
Notes[pName] = DocumentationNotes{}
}
for k, v := range x {
Notes[pName][k] = v
providerCapabilities[pName][k] = v.HasFeature
}
default:
log.Fatalf("Unrecognized ProviderMetadata type: %T", pm)
}
}
}
// Can is a small helper for concisely creating Documentation Notes
// comments are variadic for easy ommission. First is comment, second is link, the rest are ignored.
func Can(comments ...string) *DocumentationNote {
n := &DocumentationNote{
HasFeature: true,
}
n.addStrings(comments)
return n
}
// Cannot is a small helper for concisely creating Documentation Notes
// comments are variadic for easy ommission. First is comment, second is link, the rest are ignored.
func Cannot(comments ...string) *DocumentationNote {
n := &DocumentationNote{
HasFeature: false,
}
n.addStrings(comments)
return n
}
// Unimplemented is a small helper for concisely creating Documentation Notes
// comments are variadic for easy ommission. First is comment, second is link, the rest are ignored.
func Unimplemented(comments ...string) *DocumentationNote {
n := &DocumentationNote{
HasFeature: false,
Unimplemented: true,
}
n.addStrings(comments)
return n
}
func (n *DocumentationNote) addStrings(comments []string) {
if len(comments) > 0 {
n.Comment = comments[0]
}
if len(comments) > 1 {
n.Link = comments[1]
}
}