mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-02-22 14:43:01 +08:00
Create a dynamic provider features matrix (#201)
* adding simple provider feature matrix generator * filling out matrix * clean output * dead code * explanatory text * explanatory text * typo * move stuff around * clean * editing
This commit is contained in:
parent
6ce221df49
commit
3a90435357
21 changed files with 765 additions and 79 deletions
137
build/generate/featureMatrix.go
Normal file
137
build/generate/featureMatrix.go
Normal file
|
@ -0,0 +1,137 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"sort"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/providers"
|
||||
_ "github.com/StackExchange/dnscontrol/providers/_all"
|
||||
)
|
||||
|
||||
func generateFeatureMatrix() error {
|
||||
allNames := map[string]bool{}
|
||||
for n := range providers.RegistrarTypes {
|
||||
allNames[n] = true
|
||||
}
|
||||
for n := range providers.DNSProviderTypes {
|
||||
allNames[n] = true
|
||||
}
|
||||
providerTypes := []string{}
|
||||
for n := range allNames {
|
||||
providerTypes = append(providerTypes, n)
|
||||
}
|
||||
sort.Strings(providerTypes)
|
||||
matrix := &FeatureMatrix{
|
||||
Providers: map[string]FeatureMap{},
|
||||
Features: []FeatureDef{
|
||||
{"Official Support", "This means the provider is actively used at Stack Exchange, bugs are more likely to be fixed, and failing integration tests will block a release. See below for details"},
|
||||
{"Registrar", "The provider has registrar capabilities to set nameservers for zones"},
|
||||
{"DNS Provider", "Can manage and serve DNS zones"},
|
||||
{"ALIAS", "Provider supports some kind of ALIAS, ANAME or flattened CNAME record type"},
|
||||
{"SRV", "Driver has explicitly implemented SRV record management"},
|
||||
{"PTR", "Provider supports adding PTR records for reverse lookup zones"},
|
||||
{"CAA", "Provider can manage CAA records"},
|
||||
|
||||
{"dual host", "This provider is recommended for use in 'dual hosting' scenarios. Usually this means the provider allows full control over the apex NS records"},
|
||||
{"create-domains", "This means the provider can automatically create domains that do not currently exist on your account. The 'dnscontrol create-domains' command will initialize any missing domains"},
|
||||
{"no_purge", "indicates you can use NO_PURGE macro to prevent deleting records not managed by dnscontrol. A few providers that generate the entire zone from scratch have a problem implementing this."},
|
||||
},
|
||||
}
|
||||
for _, p := range providerTypes {
|
||||
if p == "NONE" {
|
||||
continue
|
||||
}
|
||||
fm := FeatureMap{}
|
||||
notes := providers.Notes[p]
|
||||
if notes == nil {
|
||||
notes = providers.DocumentationNotes{}
|
||||
}
|
||||
setCap := func(name string, cap providers.Capability) {
|
||||
if notes[cap] != nil {
|
||||
fm[name] = notes[cap]
|
||||
return
|
||||
}
|
||||
fm.SetSimple(name, true, func() bool { return providers.ProviderHasCabability(p, cap) })
|
||||
}
|
||||
setDoc := func(name string, cap providers.Capability) {
|
||||
if notes[cap] != nil {
|
||||
fm[name] = notes[cap]
|
||||
}
|
||||
}
|
||||
setDoc("Official Support", providers.DocOfficiallySupported)
|
||||
fm.SetSimple("Registrar", false, func() bool { return providers.RegistrarTypes[p] != nil })
|
||||
fm.SetSimple("DNS Provider", false, func() bool { return providers.DNSProviderTypes[p] != nil })
|
||||
setCap("ALIAS", providers.CanUseAlias)
|
||||
setCap("SRV", providers.CanUseSRV)
|
||||
setCap("PTR", providers.CanUsePTR)
|
||||
setCap("CAA", providers.CanUseCAA)
|
||||
setDoc("dual host", providers.DocDualHost)
|
||||
setDoc("create-domains", providers.DocCreateDomains)
|
||||
|
||||
// no purge is a freaky double negative
|
||||
cap := providers.CantUseNOPURGE
|
||||
if notes[cap] != nil {
|
||||
fm["no_purge"] = notes[cap]
|
||||
} else {
|
||||
fm.SetSimple("no_purge", false, func() bool { return !providers.ProviderHasCabability(p, cap) })
|
||||
}
|
||||
matrix.Providers[p] = fm
|
||||
}
|
||||
buf := &bytes.Buffer{}
|
||||
err := tmpl.Execute(buf, matrix)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile("docs/_includes/matrix.html", buf.Bytes(), 0644)
|
||||
}
|
||||
|
||||
type FeatureDef struct {
|
||||
Name, Desc string
|
||||
}
|
||||
type FeatureMap map[string]*providers.DocumentationNote
|
||||
|
||||
func (fm FeatureMap) SetSimple(name string, unknownsAllowed bool, f func() bool) {
|
||||
if f() {
|
||||
fm[name] = &providers.DocumentationNote{HasFeature: true}
|
||||
} else if !unknownsAllowed {
|
||||
fm[name] = &providers.DocumentationNote{HasFeature: false}
|
||||
}
|
||||
}
|
||||
|
||||
type FeatureMatrix struct {
|
||||
Features []FeatureDef
|
||||
Providers map[string]FeatureMap
|
||||
}
|
||||
|
||||
var tmpl = template.Must(template.New("").Funcs(template.FuncMap{
|
||||
"safe": func(s string) template.HTML { return template.HTML(s) },
|
||||
}).Parse(`
|
||||
{% comment %}
|
||||
Matrix generated by build/generate/featureMatrix.go. DO NOT HAND EDIT!
|
||||
{% endcomment %}{{$providers := .Providers}}
|
||||
<table class="table-header-rotated">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
{{range $key,$val := $providers}}<th class="rotate"><div><span>{{$key}}</span></div></th>
|
||||
{{end -}}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .Features}}{{$name := .Name}}<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="{{.Desc}}">{{$name}}</th>
|
||||
{{range $pname, $features := $providers}}{{$f := index $features $name}}{{if $f -}}
|
||||
<td class="{{if $f.HasFeature}}success{{else}}danger{{end}}"
|
||||
{{- if $f.Comment}} data-toggle="tooltip" data-container="body" data-placement="top" title="{{$f.Comment}}"{{end}}>
|
||||
<i class="fa {{if $f.Comment}}has-tooltip {{end}}
|
||||
{{- if $f.HasFeature}}fa-check text-success{{else}}fa-times text-danger{{end}}" aria-hidden="true"></i>
|
||||
</td>
|
||||
{{- else}}<td><i class="fa fa-minus dim"></i></td>{{end}}
|
||||
{{end -}}
|
||||
</tr>
|
||||
{{end -}}
|
||||
</tbody>
|
||||
</table>
|
||||
`))
|
|
@ -1,6 +1,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/mjibson/esc/embed"
|
||||
)
|
||||
|
||||
|
@ -14,4 +16,8 @@ func main() {
|
|||
Files: []string{`pkg/js/helpers.js`},
|
||||
}
|
||||
embed.Run(conf)
|
||||
|
||||
if err := generateFeatureMatrix(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
334
docs/_includes/matrix.html
Normal file
334
docs/_includes/matrix.html
Normal file
|
@ -0,0 +1,334 @@
|
|||
|
||||
{% comment %}
|
||||
Matrix generated by build/generate/featureMatrix.go. DO NOT HAND EDIT!
|
||||
{% endcomment %}
|
||||
<table class="table-header-rotated">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th class="rotate"><div><span>ACTIVEDIRECTORY_PS</span></div></th>
|
||||
<th class="rotate"><div><span>BIND</span></div></th>
|
||||
<th class="rotate"><div><span>CLOUDFLAREAPI</span></div></th>
|
||||
<th class="rotate"><div><span>DIGITALOCEAN</span></div></th>
|
||||
<th class="rotate"><div><span>DNSIMPLE</span></div></th>
|
||||
<th class="rotate"><div><span>GANDI</span></div></th>
|
||||
<th class="rotate"><div><span>GCLOUD</span></div></th>
|
||||
<th class="rotate"><div><span>NAMECHEAP</span></div></th>
|
||||
<th class="rotate"><div><span>NAMEDOTCOM</span></div></th>
|
||||
<th class="rotate"><div><span>NS1</span></div></th>
|
||||
<th class="rotate"><div><span>ROUTE53</span></div></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="This means the provider is actively used at stack exchange, and we offer a stronger guarantee it will work">Official Support</th>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="The provider has registrar capabilities to set nameservers for zones">Registrar</th>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Can manage and serve DNS zones">DNS Provider</th>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Provider supports some kind of ALIAS,ANAME or flattened CNAME record type">ALIAS</th>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success" data-toggle="tooltip" data-container="body" data-placement="top" title="CF automatically flattens CNAME records into A records dynamically">
|
||||
<i class="fa has-tooltip fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Driver has explicitly implemented SRV record management">SRV</th>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Provider supports adding PTR records for reverse lookup zones">PTR</th>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="danger" data-toggle="tooltip" data-container="body" data-placement="top" title="PTR records are not supported https://www.name.com/support/articles/205188508-Reverse-DNS-records (2017-05-08)">
|
||||
<i class="fa has-tooltip fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Provider can manage CAA records">CAA</th>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="This provider is recommended for use in 'dual hosting' scenarios. Usually this means the provider allows full control over the apex NS records">dual host</th>
|
||||
<td class="danger" data-toggle="tooltip" data-container="body" data-placement="top" title="This driver does not manage NS records, so should not be used for dual-host scenarios">
|
||||
<i class="fa has-tooltip fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger" data-toggle="tooltip" data-container="body" data-placement="top" title="Cloudflare will not work well in situations where it is not the only DNS server">
|
||||
<i class="fa has-tooltip fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="danger" data-toggle="tooltip" data-container="body" data-placement="top" title="DNSimple does not allow sufficient control over the apex NS records">
|
||||
<i class="fa has-tooltip fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="danger" data-toggle="tooltip" data-container="body" data-placement="top" title="Apex NS records not editable">
|
||||
<i class="fa has-tooltip fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="This means the provider can automatically create domains that do not currently exist on your account. The 'dnscontrol create-domains' command will initialize any missing domains">create-domains</th>
|
||||
<td class="danger" data-toggle="tooltip" data-container="body" data-placement="top" title="AD depends on the zone already existing on the dns server">
|
||||
<i class="fa has-tooltip fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success" data-toggle="tooltip" data-container="body" data-placement="top" title="Driver just maintains list of zone files. It should automatically add missing ones.">
|
||||
<i class="fa has-tooltip fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger" data-toggle="tooltip" data-container="body" data-placement="top" title="Can only manage domains registered through their service">
|
||||
<i class="fa has-tooltip fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger" data-toggle="tooltip" data-container="body" data-placement="top" title="Requires domain registered through their service">
|
||||
<i class="fa has-tooltip fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger" data-toggle="tooltip" data-container="body" data-placement="top" title="New domains require registration">
|
||||
<i class="fa has-tooltip fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="indicates you can use NO_PURGE macro to prevent deleting records not managed by dnscontrol. A few providers that generate the entire zone from scratch have a problem implementing this.">no_purge</th>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
|
@ -5,11 +5,11 @@
|
|||
crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r"
|
||||
crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<script src="https://code.jquery.com/jquery-2.1.4.min.js" integrity="sha384-R4/ztc4ZlRqWjqIuvf6RX5yb/v90qNGx6fS48N0tRxiGkqveZETq72KgDVJCp2TC"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://use.fontawesome.com/03614296b7.js"></script>
|
||||
<link rel="stylesheet" href="{{site.github.url}}/css/site.css">
|
||||
<link rel="stylesheet" href="{{site.github.url}}/css/syntax.css">
|
||||
|
||||
|
@ -45,9 +45,6 @@
|
|||
{{ content}}
|
||||
</div>
|
||||
|
||||
{% comment %} Live reload script. Dev mode only {% endcomment %} {% unless site.github %}
|
||||
<script>document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1"></' + 'script>')</script>
|
||||
{% endunless %}
|
||||
{% comment %} This script makes the examples collapse appropriately {% endcomment %}
|
||||
|
||||
<script>
|
||||
|
@ -56,6 +53,9 @@
|
|||
$(this).parent().next().collapse('toggle');
|
||||
$(this).toggleClass('expanded')
|
||||
});
|
||||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
|
|
@ -12,4 +12,65 @@
|
|||
|
||||
body {
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.table-header-rotated {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.table-header-rotated td {
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.table-header-rotated th {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.table-header-rotated td {
|
||||
text-align: center;
|
||||
padding: 10px 5px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.table-header-rotated th.rotate {
|
||||
height: 140px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.table-header-rotated th.rotate>div {
|
||||
-webkit-transform: translate(25px, 51px) rotate(315deg);
|
||||
-ms-transform: translate(25px, 51px) rotate(315deg);
|
||||
transform: translate(25px, 51px) rotate(315deg);
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.table-header-rotated th.rotate>div>span {
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.table-header-rotated th.row-header {
|
||||
padding: 0 10px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
.success {
|
||||
background-color: #dff0d8;
|
||||
}
|
||||
.warning {
|
||||
background-color: #faf2cc;
|
||||
}
|
||||
.danger {
|
||||
background-color: #f2dede;
|
||||
}
|
||||
.info {
|
||||
background-color: #d9edf7;
|
||||
}
|
||||
.fa {
|
||||
font-size: 150%;
|
||||
}
|
||||
.has-tooltip:before{
|
||||
text-decoration: underline;
|
||||
}
|
||||
.dim {
|
||||
color: #eeeeee
|
||||
}
|
|
@ -36,3 +36,4 @@ Dnscontrol is a platform for seamlessly managing your dns configuration across a
|
|||
### [Writing Providers]({{site.github.url}}/writing-providers)
|
||||
|
||||
### [Adding new DNS record types]({{site.github.url}}/adding-new-rtypes)
|
||||
|
||||
|
|
|
@ -16,17 +16,26 @@ layout: default
|
|||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<h2> Provider Features </h2>
|
||||
|
||||
<p>The table below shows various features supported, or not supported by DNSControl providers.
|
||||
Underlined items have tooltips for more detailed explanation. This table is automatically generated
|
||||
from metadata supplied by the provider when they register themselves inside dnscontrol.
|
||||
</p>
|
||||
<p>
|
||||
An empty space may indicate the feature is not supported by a provider, or it may simply mean
|
||||
the feature has not been investigated and implemented yet. If a feature you need is missing from
|
||||
a provider that supports it, we'd love your contribution to ensure it works correctly and add it to this matrix.
|
||||
</p>
|
||||
<p>If a feature is definitively not supported for whatever reason, we would also like a PR to clarify why it is not supported, and fill in this entire matrix.</p>
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
{% include matrix.html %}
|
||||
|
||||
|
||||
### Providers with "official support"
|
||||
|
||||
The following providers have official support:
|
||||
|
||||
* ACTIVEDIRECTORY_PS
|
||||
* BIND
|
||||
* CLOUDFLAREAPI
|
||||
* GCLOUD
|
||||
* NAMEDOTCOM
|
||||
* ROUTE53
|
||||
|
||||
Official support means:
|
||||
|
||||
* New releases will block if any of these providers do not pass integration tests.
|
||||
|
@ -50,10 +59,11 @@ provided to help community members support their code independently.
|
|||
|
||||
Maintainers of contributed providers:
|
||||
|
||||
* digital ocean @Deraen
|
||||
* dnsimple @aeden
|
||||
* digital ocean @Deraen
|
||||
* dnsimple @aeden
|
||||
* gandi @TomOnTime
|
||||
* namecheap @captncraig
|
||||
* ns1 @captncraig
|
||||
* OVH @Oprax
|
||||
|
||||
### Requested providers
|
||||
|
@ -62,7 +72,6 @@ We have received requests for the following providers. If you would like to cont
|
|||
code to support this provider, please re-open the issue. We'd be glad to help in any way.
|
||||
|
||||
<ul>
|
||||
<li>AWS R53 (DNS works. Request is to add Registrar support) (<a href="https://github.com/StackExchange/dnscontrol/issues/68">#68</a>)</li>
|
||||
<li>Azure (<a href="https://github.com/StackExchange/dnscontrol/issues/42">#42</a>)</li>
|
||||
<li>ClouDNS (<a href="https://github.com/StackExchange/dnscontrol/issues/114">#114</a>)</li>
|
||||
<li>Dyn (<a href="https://github.com/StackExchange/dnscontrol/issues/61">#61</a>)</li>
|
||||
|
@ -71,5 +80,4 @@ code to support this provider, please re-open the issue. We'd be glad to help in
|
|||
<li>Hurricane Electric (dns.he.net) (<a href="https://github.com/StackExchange/dnscontrol/issues/118">#118</a>)</li>
|
||||
<li>Linode (<a href="https://github.com/StackExchange/dnscontrol/issues/121">#121</a>)</li>
|
||||
<li>OVH (<a href="https://github.com/StackExchange/dnscontrol/issues/143">#143</a>)</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</ul>
|
2
main.go
2
main.go
|
@ -10,7 +10,7 @@ import (
|
|||
_ "github.com/StackExchange/dnscontrol/providers/_all"
|
||||
)
|
||||
|
||||
//go:generate go run build/generate/generate.go
|
||||
//go:generate go run build/generate/generate.go build/generate/featureMatrix.go
|
||||
|
||||
func main() {
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
|
|
|
@ -16,10 +16,20 @@ type adProvider struct {
|
|||
psLog string
|
||||
}
|
||||
|
||||
var docNotes = providers.DocumentationNotes{
|
||||
providers.DocDualHost: providers.Cannot("This driver does not manage NS records, so should not be used for dual-host scenarios"),
|
||||
providers.DocCreateDomains: providers.Cannot("AD depends on the zone already existing on the dns server"),
|
||||
providers.DocOfficiallySupported: providers.Can(),
|
||||
providers.CanUseAlias: providers.Cannot(),
|
||||
providers.CanUseSRV: providers.Cannot(),
|
||||
providers.CanUsePTR: providers.Cannot(),
|
||||
providers.CanUseCAA: providers.Cannot(),
|
||||
}
|
||||
|
||||
// Register with the dnscontrol system.
|
||||
// This establishes the name (all caps), and the function to call to initialize it.
|
||||
func init() {
|
||||
providers.RegisterDomainServiceProviderType("ACTIVEDIRECTORY_PS", newDNS)
|
||||
providers.RegisterDomainServiceProviderType("ACTIVEDIRECTORY_PS", newDNS, docNotes)
|
||||
}
|
||||
|
||||
func newDNS(config map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
|
||||
|
|
|
@ -30,6 +30,12 @@ import (
|
|||
"github.com/StackExchange/dnscontrol/providers/diff"
|
||||
)
|
||||
|
||||
var docNotes = providers.DocumentationNotes{
|
||||
providers.DocDualHost: providers.Can(),
|
||||
providers.DocCreateDomains: providers.Can("Driver just maintains list of zone files. It should automatically add missing ones."),
|
||||
providers.DocOfficiallySupported: providers.Can(),
|
||||
}
|
||||
|
||||
func initBind(config map[string]string, providermeta json.RawMessage) (providers.DNSServiceProvider, error) {
|
||||
// config -- the key/values from creds.json
|
||||
// meta -- the json blob from NewReq('name', 'TYPE', meta)
|
||||
|
@ -50,7 +56,8 @@ func initBind(config map[string]string, providermeta json.RawMessage) (providers
|
|||
}
|
||||
|
||||
func init() {
|
||||
providers.RegisterDomainServiceProviderType("BIND", initBind, providers.CanUsePTR, providers.CanUseSRV, providers.CanUseCAA, providers.CantUseNOPURGE)
|
||||
providers.RegisterDomainServiceProviderType("BIND", initBind, providers.CanUsePTR,
|
||||
providers.CanUseSRV, providers.CanUseCAA, providers.CantUseNOPURGE, docNotes)
|
||||
}
|
||||
|
||||
type SoaInfo struct {
|
||||
|
|
97
providers/capabilities.go
Normal file
97
providers/capabilities.go
Normal file
|
@ -0,0 +1,97 @@
|
|||
package providers
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//Capability is a bitmasked set of "features" that a provider supports. Only use constants from this package.
|
||||
type Capability uint32
|
||||
|
||||
const (
|
||||
// CanUseAlias indicates the provider support ALIAS records (or flattened CNAMES). Up to the provider to translate them to the appropriate record type.
|
||||
// If you add something to this list, you probably want to add it to pkg/normalize/validate.go checkProviderCapabilities() or somewhere near there.
|
||||
CanUseAlias Capability = iota
|
||||
// CanUsePTR indicates the provider can handle PTR records
|
||||
CanUsePTR
|
||||
// CanUseSRV indicates the provider can handle SRV records
|
||||
CanUseSRV
|
||||
// CanUseCAA indicates the provider can handle CAA records
|
||||
CanUseCAA
|
||||
// CantUseNOPURGE indicates NO_PURGE is broken for this provider. To make it
|
||||
// work would require complex emulation of an incremental update mechanism,
|
||||
// so it is easier to simply mark this feature as not working for this
|
||||
// provider.
|
||||
CantUseNOPURGE
|
||||
|
||||
// DocOfficiallySupported means it is actively used and maintained by stack exchange
|
||||
DocOfficiallySupported
|
||||
// DocDualHost means provider allows full management of apex NS records, so we can safely dual-host with anothe provider
|
||||
DocDualHost
|
||||
// DocCreateDomains means provider can add domains with the `dnscontrol create-domains` command
|
||||
DocCreateDomains
|
||||
)
|
||||
|
||||
var providerCapabilities = map[string]map[Capability]bool{}
|
||||
|
||||
func ProviderHasCabability(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
|
||||
Comment 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 interchangably
|
||||
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) {
|
||||
for _, pm := range meta {
|
||||
switch x := pm.(type) {
|
||||
case Capability:
|
||||
if providerCapabilities[pName] == nil {
|
||||
providerCapabilities[pName] = map[Capability]bool{}
|
||||
}
|
||||
providerCapabilities[pName][x] = true
|
||||
case DocumentationNotes:
|
||||
if Notes[pName] == nil {
|
||||
Notes[pName] = DocumentationNotes{}
|
||||
}
|
||||
for k, v := range x {
|
||||
Notes[pName][k] = v
|
||||
}
|
||||
default:
|
||||
log.Fatalf("Unrecognized ProviderMetadata type: %T", pm)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Can is a small helper for concisely creating Documentation Notes
|
||||
// comments are variadic for easy ommission, so you generally should pass 0 or 1 only.
|
||||
func Can(comments ...string) *DocumentationNote {
|
||||
return &DocumentationNote{
|
||||
HasFeature: true,
|
||||
Comment: strings.Join(comments, " "),
|
||||
}
|
||||
}
|
||||
|
||||
// Cannot is a small helper for concisely creating Documentation Notes
|
||||
// comments are variadic for easy ommission, so you generally should pass 0 or 1 only.
|
||||
func Cannot(comments ...string) *DocumentationNote {
|
||||
return &DocumentationNote{
|
||||
HasFeature: false,
|
||||
Comment: strings.Join(comments, " "),
|
||||
}
|
||||
}
|
|
@ -33,8 +33,15 @@ Domain level metadata available:
|
|||
- ip_conversions
|
||||
*/
|
||||
|
||||
var docNotes = providers.DocumentationNotes{
|
||||
providers.DocDualHost: providers.Cannot("Cloudflare will not work well in situations where it is not the only DNS server"),
|
||||
providers.DocCreateDomains: providers.Can(),
|
||||
providers.DocOfficiallySupported: providers.Can(),
|
||||
providers.CanUseAlias: providers.Can("CF automatically flattens CNAME records into A records dynamically"),
|
||||
}
|
||||
|
||||
func init() {
|
||||
providers.RegisterDomainServiceProviderType("CLOUDFLAREAPI", newCloudflare, providers.CanUseSRV, providers.CanUseAlias)
|
||||
providers.RegisterDomainServiceProviderType("CLOUDFLAREAPI", newCloudflare, providers.CanUseSRV, providers.CanUseAlias, docNotes)
|
||||
providers.RegisterCustomRecordType("CF_REDIRECT", "CLOUDFLAREAPI", "")
|
||||
providers.RegisterCustomRecordType("CF_TEMP_REDIRECT", "CLOUDFLAREAPI", "")
|
||||
}
|
||||
|
|
|
@ -60,8 +60,13 @@ func newDo(m map[string]string, metadata json.RawMessage) (providers.DNSServiceP
|
|||
return api, nil
|
||||
}
|
||||
|
||||
var docNotes = providers.DocumentationNotes{
|
||||
providers.DocCreateDomains: providers.Can(),
|
||||
providers.DocOfficiallySupported: providers.Cannot(),
|
||||
}
|
||||
|
||||
func init() {
|
||||
providers.RegisterDomainServiceProviderType("DIGITALOCEAN", newDo, providers.CanUseSRV)
|
||||
providers.RegisterDomainServiceProviderType("DIGITALOCEAN", newDo, providers.CanUseSRV, docNotes)
|
||||
}
|
||||
|
||||
func (api *DoApi) EnsureDomainExists(domain string) error {
|
||||
|
|
|
@ -15,6 +15,17 @@ import (
|
|||
dnsimpleapi "github.com/dnsimple/dnsimple-go/dnsimple"
|
||||
)
|
||||
|
||||
var docNotes = providers.DocumentationNotes{
|
||||
providers.DocDualHost: providers.Cannot("DNSimple does not allow sufficient control over the apex NS records"),
|
||||
providers.DocCreateDomains: providers.Cannot(),
|
||||
providers.DocOfficiallySupported: providers.Cannot(),
|
||||
}
|
||||
|
||||
func init() {
|
||||
providers.RegisterRegistrarType("DNSIMPLE", newReg)
|
||||
providers.RegisterDomainServiceProviderType("DNSIMPLE", newDsp, providers.CanUsePTR, docNotes)
|
||||
}
|
||||
|
||||
const stateRegistered = "registered"
|
||||
|
||||
var defaultNameServerNames = []string{
|
||||
|
@ -313,11 +324,6 @@ func newProvider(m map[string]string, metadata json.RawMessage) (*DnsimpleApi, e
|
|||
return api, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
providers.RegisterRegistrarType("DNSIMPLE", newReg)
|
||||
providers.RegisterDomainServiceProviderType("DNSIMPLE", newDsp, providers.CanUsePTR)
|
||||
}
|
||||
|
||||
// remove all non-dnsimple NS records from our desired state.
|
||||
// if any are found, print a warning
|
||||
func removeOtherNS(dc *models.DomainConfig) {
|
||||
|
|
|
@ -25,6 +25,16 @@ Info required in `creds.json`:
|
|||
|
||||
*/
|
||||
|
||||
var docNotes = providers.DocumentationNotes{
|
||||
providers.DocCreateDomains: providers.Cannot("Can only manage domains registered through their service"),
|
||||
providers.DocOfficiallySupported: providers.Cannot(),
|
||||
}
|
||||
|
||||
func init() {
|
||||
providers.RegisterDomainServiceProviderType("GANDI", newGandi, providers.CanUsePTR,
|
||||
providers.CanUseSRV, docNotes, providers.CantUseNOPURGE)
|
||||
}
|
||||
|
||||
type GandiApi struct {
|
||||
ApiKey string
|
||||
domainIndex map[string]int64 // Map of domainname to index
|
||||
|
@ -145,7 +155,3 @@ func newGandi(m map[string]string, metadata json.RawMessage) (providers.DNSServi
|
|||
|
||||
return api, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
providers.RegisterDomainServiceProviderType("GANDI", newGandi, providers.CanUsePTR, providers.CanUseSRV)
|
||||
}
|
||||
|
|
|
@ -14,8 +14,14 @@ import (
|
|||
"github.com/StackExchange/dnscontrol/providers/diff"
|
||||
)
|
||||
|
||||
var docNotes = providers.DocumentationNotes{
|
||||
providers.DocDualHost: providers.Can(),
|
||||
providers.DocCreateDomains: providers.Can(),
|
||||
providers.DocOfficiallySupported: providers.Can(),
|
||||
}
|
||||
|
||||
func init() {
|
||||
providers.RegisterDomainServiceProviderType("GCLOUD", New, providers.CanUsePTR, providers.CanUseSRV, providers.CanUseCAA)
|
||||
providers.RegisterDomainServiceProviderType("GCLOUD", New, providers.CanUsePTR, providers.CanUseSRV, providers.CanUseCAA, docNotes)
|
||||
}
|
||||
|
||||
type gcloud struct {
|
||||
|
|
|
@ -16,8 +16,13 @@ type Namecheap struct {
|
|||
client *nc.Client
|
||||
}
|
||||
|
||||
var docNotes = providers.DocumentationNotes{
|
||||
providers.DocCreateDomains: providers.Cannot("Requires domain registered through their service"),
|
||||
providers.DocOfficiallySupported: providers.Cannot(),
|
||||
}
|
||||
|
||||
func init() {
|
||||
providers.RegisterRegistrarType("NAMECHEAP", newReg)
|
||||
providers.RegisterRegistrarType("NAMECHEAP", newReg, docNotes)
|
||||
// NOTE(tlim): If in the future the DNS Service Provider is implemented,
|
||||
// most likely it will require providers.CantUseNOPURGE.
|
||||
}
|
||||
|
|
|
@ -19,6 +19,13 @@ type nameDotCom struct {
|
|||
APIKey string `json:"apikey"`
|
||||
}
|
||||
|
||||
var docNotes = providers.DocumentationNotes{
|
||||
providers.DocDualHost: providers.Cannot("Apex NS records not editable"),
|
||||
providers.DocCreateDomains: providers.Cannot("New domains require registration"),
|
||||
providers.DocOfficiallySupported: providers.Can(),
|
||||
providers.CanUsePTR: providers.Cannot("PTR records are not supported https://www.name.com/support/articles/205188508-Reverse-DNS-records (2017-05-08)"),
|
||||
}
|
||||
|
||||
func newReg(conf map[string]string) (providers.Registrar, error) {
|
||||
return newProvider(conf)
|
||||
}
|
||||
|
@ -41,8 +48,7 @@ func newProvider(conf map[string]string) (*nameDotCom, error) {
|
|||
|
||||
func init() {
|
||||
providers.RegisterRegistrarType("NAMEDOTCOM", newReg)
|
||||
providers.RegisterDomainServiceProviderType("NAMEDOTCOM", newDsp, providers.CanUseAlias, providers.CanUseSRV)
|
||||
// PTR records are not supported https://www.name.com/support/articles/205188508-Reverse-DNS-records (2017-05-08)
|
||||
providers.RegisterDomainServiceProviderType("NAMEDOTCOM", newDsp, providers.CanUseAlias, providers.CanUseSRV, docNotes)
|
||||
}
|
||||
|
||||
///
|
||||
|
|
|
@ -18,8 +18,14 @@ import (
|
|||
"gopkg.in/ns1/ns1-go.v2/rest/model/dns"
|
||||
)
|
||||
|
||||
var docNotes = providers.DocumentationNotes{
|
||||
providers.DocCreateDomains: providers.Cannot(),
|
||||
providers.DocOfficiallySupported: providers.Cannot(),
|
||||
providers.DocDualHost: providers.Can(),
|
||||
}
|
||||
|
||||
func init() {
|
||||
providers.RegisterDomainServiceProviderType("NS1", newProvider)
|
||||
providers.RegisterDomainServiceProviderType("NS1", newProvider, docNotes)
|
||||
}
|
||||
|
||||
type nsone struct {
|
||||
|
|
|
@ -28,61 +28,33 @@ type DomainCreator interface {
|
|||
//RegistrarInitializer is a function to create a registrar. Function will be passed the unprocessed json payload from the configuration file for the given provider.
|
||||
type RegistrarInitializer func(map[string]string) (Registrar, error)
|
||||
|
||||
var registrarTypes = map[string]RegistrarInitializer{}
|
||||
var RegistrarTypes = map[string]RegistrarInitializer{}
|
||||
|
||||
//DspInitializer is a function to create a DNS service provider. Function will be passed the unprocessed json payload from the configuration file for the given provider.
|
||||
type DspInitializer func(map[string]string, json.RawMessage) (DNSServiceProvider, error)
|
||||
|
||||
var dspTypes = map[string]DspInitializer{}
|
||||
var dspCapabilities = map[string]Capability{}
|
||||
|
||||
//Capability is a bitmasked set of "features" that a provider supports. Only use constants from this package.
|
||||
type Capability uint32
|
||||
|
||||
const (
|
||||
// CanUseAlias indicates the provider support ALIAS records (or flattened CNAMES). Up to the provider to translate them to the appropriate record type.
|
||||
// If you add something to this list, you probably want to add it to pkg/normalize/validate.go checkProviderCapabilities() or somewhere near there.
|
||||
CanUseAlias Capability = 1 << iota
|
||||
// CanUsePTR indicates the provider can handle PTR records
|
||||
CanUsePTR
|
||||
// CanUseSRV indicates the provider can handle SRV records
|
||||
CanUseSRV
|
||||
// CanUseCAA indicates the provider can handle CAA records
|
||||
CanUseCAA
|
||||
// CantUseNOPURGE indicates NO_PURGE is broken for this provider. To make it
|
||||
// work would require complex emulation of an incremental update mechanism,
|
||||
// so it is easier to simply mark this feature as not working for this
|
||||
// provider.
|
||||
CantUseNOPURGE
|
||||
)
|
||||
|
||||
func ProviderHasCabability(pType string, cap Capability) bool {
|
||||
return dspCapabilities[pType]&cap != 0
|
||||
}
|
||||
var DNSProviderTypes = map[string]DspInitializer{}
|
||||
|
||||
//RegisterRegistrarType adds a registrar type to the registry by providing a suitable initialization function.
|
||||
func RegisterRegistrarType(name string, init RegistrarInitializer) {
|
||||
if _, ok := registrarTypes[name]; ok {
|
||||
func RegisterRegistrarType(name string, init RegistrarInitializer, pm ...ProviderMetadata) {
|
||||
if _, ok := RegistrarTypes[name]; ok {
|
||||
log.Fatalf("Cannot register registrar type %s multiple times", name)
|
||||
}
|
||||
registrarTypes[name] = init
|
||||
RegistrarTypes[name] = init
|
||||
unwrapProviderCapabilities(name, pm)
|
||||
}
|
||||
|
||||
//RegisterDomainServiceProviderType adds a dsp to the registry with the given initialization function.
|
||||
func RegisterDomainServiceProviderType(name string, init DspInitializer, caps ...Capability) {
|
||||
if _, ok := dspTypes[name]; ok {
|
||||
func RegisterDomainServiceProviderType(name string, init DspInitializer, pm ...ProviderMetadata) {
|
||||
if _, ok := DNSProviderTypes[name]; ok {
|
||||
log.Fatalf("Cannot register registrar type %s multiple times", name)
|
||||
}
|
||||
var abilities Capability
|
||||
for _, c := range caps {
|
||||
abilities |= c
|
||||
}
|
||||
dspTypes[name] = init
|
||||
dspCapabilities[name] = abilities
|
||||
DNSProviderTypes[name] = init
|
||||
unwrapProviderCapabilities(name, pm)
|
||||
}
|
||||
|
||||
func createRegistrar(rType string, config map[string]string) (Registrar, error) {
|
||||
initer, ok := registrarTypes[rType]
|
||||
initer, ok := RegistrarTypes[rType]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Registrar type %s not declared.", rType)
|
||||
}
|
||||
|
@ -90,7 +62,7 @@ func createRegistrar(rType string, config map[string]string) (Registrar, error)
|
|||
}
|
||||
|
||||
func CreateDNSProvider(dType string, config map[string]string, meta json.RawMessage) (DNSServiceProvider, error) {
|
||||
initer, ok := dspTypes[dType]
|
||||
initer, ok := DNSProviderTypes[dType]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("DSP type %s not declared", dType)
|
||||
}
|
||||
|
|
|
@ -56,8 +56,14 @@ func newRoute53(m map[string]string, metadata json.RawMessage) (*route53Provider
|
|||
return api, nil
|
||||
}
|
||||
|
||||
var docNotes = providers.DocumentationNotes{
|
||||
providers.DocDualHost: providers.Can(),
|
||||
providers.DocCreateDomains: providers.Can(),
|
||||
providers.DocOfficiallySupported: providers.Can(),
|
||||
}
|
||||
|
||||
func init() {
|
||||
providers.RegisterDomainServiceProviderType("ROUTE53", newRoute53Dsp, providers.CanUsePTR, providers.CanUseSRV, providers.CanUseCAA)
|
||||
providers.RegisterDomainServiceProviderType("ROUTE53", newRoute53Dsp, providers.CanUsePTR, providers.CanUseSRV, providers.CanUseCAA, docNotes)
|
||||
providers.RegisterRegistrarType("ROUTE53", newRoute53Reg)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue