diff --git a/build/generate/featureMatrix.go b/build/generate/featureMatrix.go new file mode 100644 index 000000000..d0e16b04f --- /dev/null +++ b/build/generate/featureMatrix.go @@ -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}} +
+ {{range $key,$val := $providers}} | {{$key}} |
+ {{end -}}
+ |
---|---|---|
{{$name}} | + {{range $pname, $features := $providers}}{{$f := index $features $name}}{{if $f -}} ++ + | + {{- else}}{{end}} + {{end -}} + |
+ | ACTIVEDIRECTORY_PS |
+ BIND |
+ CLOUDFLAREAPI |
+ DIGITALOCEAN |
+ DNSIMPLE |
+ GANDI |
+ GCLOUD |
+ NAMECHEAP |
+ NAMEDOTCOM |
+ NS1 |
+ ROUTE53 |
+
---|---|---|---|---|---|---|---|---|---|---|---|
Official Support | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | +
Registrar | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | +
DNS Provider | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | +
ALIAS | ++ + | ++ | + + | ++ | + | + | + | + | + + | ++ | + |
SRV | ++ + | ++ + | ++ + | ++ + | ++ | + + | ++ + | ++ | + + | ++ | + + | +
PTR | ++ + | ++ + | ++ | + | + + | ++ + | ++ + | ++ | + + | ++ | + + | +
CAA | ++ + | ++ + | ++ | + | + | + | + + | ++ | + | + | + + | +
dual host | ++ + | ++ + | ++ + | ++ | + + | ++ | + + | ++ | + + | ++ + | ++ + | +
create-domains | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | +
no_purge | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | +