github.com/philhug/dnscontrol@v0.2.4-0.20180625181521-921fa9849001/build/generate/featureMatrix.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "html/template" 6 "io/ioutil" 7 "sort" 8 9 "github.com/StackExchange/dnscontrol/providers" 10 _ "github.com/StackExchange/dnscontrol/providers/_all" 11 ) 12 13 func generateFeatureMatrix() error { 14 allNames := map[string]bool{} 15 for n := range providers.RegistrarTypes { 16 allNames[n] = true 17 } 18 for n := range providers.DNSProviderTypes { 19 allNames[n] = true 20 } 21 providerTypes := []string{} 22 for n := range allNames { 23 providerTypes = append(providerTypes, n) 24 } 25 sort.Strings(providerTypes) 26 matrix := &FeatureMatrix{ 27 Providers: map[string]FeatureMap{}, 28 Features: []FeatureDef{ 29 {"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"}, 30 {"DNS Provider", "Can manage and serve DNS zones"}, 31 {"Registrar", "The provider has registrar capabilities to set nameservers for zones"}, 32 {"ALIAS", "Provider supports some kind of ALIAS, ANAME or flattened CNAME record type"}, 33 {"CAA", "Provider can manage CAA records"}, 34 {"PTR", "Provider supports adding PTR records for reverse lookup zones"}, 35 {"SRV", "Driver has explicitly implemented SRV record management"}, 36 {"TLSA", "Provider can manage TLSA records"}, 37 {"TXTMulti", "Provider can manage TXT records with multiple strings"}, 38 {"R53_ALIAS", "Provider supports Route 53 limited ALIAS"}, 39 40 {"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"}, 41 {"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"}, 42 {"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."}, 43 }, 44 } 45 for _, p := range providerTypes { 46 if p == "NONE" { 47 continue 48 } 49 fm := FeatureMap{} 50 notes := providers.Notes[p] 51 if notes == nil { 52 notes = providers.DocumentationNotes{} 53 } 54 setCap := func(name string, cap providers.Capability) { 55 if notes[cap] != nil { 56 fm[name] = notes[cap] 57 return 58 } 59 fm.SetSimple(name, true, func() bool { return providers.ProviderHasCabability(p, cap) }) 60 } 61 setDoc := func(name string, cap providers.Capability, defaultNo bool) { 62 if notes[cap] != nil { 63 fm[name] = notes[cap] 64 } else if defaultNo { 65 fm[name] = &providers.DocumentationNote{ 66 HasFeature: false, 67 } 68 } 69 } 70 setDoc("Official Support", providers.DocOfficiallySupported, true) 71 fm.SetSimple("DNS Provider", false, func() bool { return providers.DNSProviderTypes[p] != nil }) 72 fm.SetSimple("Registrar", false, func() bool { return providers.RegistrarTypes[p] != nil }) 73 setCap("ALIAS", providers.CanUseAlias) 74 setCap("CAA", providers.CanUseCAA) 75 setCap("PTR", providers.CanUsePTR) 76 setCap("SRV", providers.CanUseSRV) 77 setCap("TLSA", providers.CanUseTLSA) 78 setCap("TXTMulti", providers.CanUseTXTMulti) 79 setCap("R53_ALIAS", providers.CanUseRoute53Alias) 80 setDoc("dual host", providers.DocDualHost, false) 81 setDoc("create-domains", providers.DocCreateDomains, true) 82 83 // no purge is a freaky double negative 84 cap := providers.CantUseNOPURGE 85 if notes[cap] != nil { 86 fm["no_purge"] = notes[cap] 87 } else { 88 fm.SetSimple("no_purge", false, func() bool { return !providers.ProviderHasCabability(p, cap) }) 89 } 90 matrix.Providers[p] = fm 91 } 92 buf := &bytes.Buffer{} 93 err := tmpl.Execute(buf, matrix) 94 if err != nil { 95 return err 96 } 97 return ioutil.WriteFile("docs/_includes/matrix.html", buf.Bytes(), 0644) 98 } 99 100 // FeatureDef describes features. 101 type FeatureDef struct { 102 Name, Desc string 103 } 104 105 // FeatureMap maps provider names to compliance documentation. 106 type FeatureMap map[string]*providers.DocumentationNote 107 108 // SetSimple configures a provider's setting in fm. 109 func (fm FeatureMap) SetSimple(name string, unknownsAllowed bool, f func() bool) { 110 if f() { 111 fm[name] = &providers.DocumentationNote{HasFeature: true} 112 } else if !unknownsAllowed { 113 fm[name] = &providers.DocumentationNote{HasFeature: false} 114 } 115 } 116 117 // FeatureMatrix describes features and which providers support it. 118 type FeatureMatrix struct { 119 Features []FeatureDef 120 Providers map[string]FeatureMap 121 } 122 123 var tmpl = template.Must(template.New("").Funcs(template.FuncMap{ 124 "safe": func(s string) template.HTML { return template.HTML(s) }, 125 }).Parse(` 126 {% comment %} 127 Matrix generated by build/generate/featureMatrix.go. DO NOT HAND EDIT! 128 {% endcomment %}{{$providers := .Providers}} 129 <table class="table-header-rotated"> 130 <thead> 131 <tr> 132 <th></th> 133 {{range $key,$val := $providers}}<th class="rotate"><div><span>{{$key}}</span></div></th> 134 {{end -}} 135 </tr> 136 </thead> 137 <tbody> 138 {{range .Features}}{{$name := .Name}}<tr> 139 <th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="{{.Desc}}">{{$name}}</th> 140 {{range $pname, $features := $providers}}{{$f := index $features $name}}{{if $f -}} 141 <td class="{{if $f.HasFeature}}success{{else if $f.Unimplemented}}info{{else}}danger{{end}}" 142 {{- if $f.Comment}} data-toggle="tooltip" data-container="body" data-placement="top" title="{{$f.Comment}}"{{end}}> 143 {{if $f.Link}}<a href="{{$f.Link}}">{{end}}<i class="fa {{if and $f.Comment (not $f.Unimplemented)}}has-tooltip {{end}} 144 {{- if $f.HasFeature}}fa-check text-success{{else if $f.Unimplemented}}fa-circle-o text-info{{else}}fa-times text-danger{{end}}" aria-hidden="true"></i>{{if $f.Link}}</a>{{end}} 145 </td> 146 {{- else}}<td><i class="fa fa-minus dim"></i></td>{{end}} 147 {{end -}} 148 </tr> 149 {{end -}} 150 </tbody> 151 </table> 152 `))