plugin/chaos: add default list of authors (#2737)

* plugin/chaos: add default list of authors

Add a owners_generate.go that generates a Owners variables for use in
the chaos plugin.

Add a default list of authors in the authors.bind CH zone. When doing a
query this now returns:

~~~ sh
% dig authors.bind TXT CH

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5456
;; flags: qr rd; QUERY: 1, ANSWER: 22, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;authors.bind.			CH	TXT

;; ANSWER SECTION:
authors.bind.		0	CH	TXT	"bradbeam"
authors.bind.		0	CH	TXT	"chrisohaver"
authors.bind.		0	CH	TXT	"dilyevsky"
authors.bind.		0	CH	TXT	"ekleiner"
authors.bind.		0	CH	TXT	"fastest963"
authors.bind.		0	CH	TXT	"fturib"
authors.bind.		0	CH	TXT	"greenpau"
authors.bind.		0	CH	TXT	"grobie"
authors.bind.		0	CH	TXT	"inigohu"
authors.bind.		0	CH	TXT	"isolus"
authors.bind.		0	CH	TXT	"johnbelamaric"
authors.bind.		0	CH	TXT	"miekg"
authors.bind.		0	CH	TXT	"nchrisdk"
authors.bind.		0	CH	TXT	"nitisht"
authors.bind.		0	CH	TXT	"pmoroney"
authors.bind.		0	CH	TXT	"rajansandeep"
authors.bind.		0	CH	TXT	"rdrozhdzh"
authors.bind.		0	CH	TXT	"rtreffer"
authors.bind.		0	CH	TXT	"stp-ip"
authors.bind.		0	CH	TXT	"superq"
authors.bind.		0	CH	TXT	"varyoo"
authors.bind.		0	CH	TXT	"yongtang"
~~~

This was hard to do previously as we didn't hardcode this in the source,
but now with OWNERS files we can just generate this list.

Privacy wise this isn't worse than being listed in OWNERS file in the
first place. And it's a nice hat tip to the people making CoreDNS
better.

Signed-off-by: Miek Gieben <miek@miek.nl>

* Sticklet bot comments

Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
Miek Gieben
2019-03-31 19:01:11 +01:00
committed by Yong Tang
parent 1e150674c5
commit 99c3d065bc
9 changed files with 136 additions and 28 deletions

View File

@@ -1,6 +1,7 @@
package main
//go:generate go run directives_generate.go
//go:generate go run owners_generate.go
import (
"github.com/coredns/coredns/coremain"

1
go.mod
View File

@@ -74,6 +74,7 @@ require (
gopkg.in/DataDog/dd-trace-go.v0 v0.6.1
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.42.0 // indirect
gopkg.in/yaml.v2 v2.2.2
k8s.io/api v0.0.0-20181204000039-89a74a8d264d
k8s.io/apimachinery v0.0.0-20181127025237-2b1284ed4c93
k8s.io/client-go v10.0.0+incompatible

91
owners_generate.go Normal file
View File

@@ -0,0 +1,91 @@
//+build ignore
// generates plugin/chaos/zowners.go.
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
"path"
"path/filepath"
"sort"
"gopkg.in/yaml.v2"
)
func main() {
o := map[string]struct{}{}
// top-level OWNERS file
o, err := owners("OWNERS", o)
if err != nil {
log.Fatal(err)
}
// each of the plugins, in case someone is not in the top-level one
err = filepath.Walk("plugin",
func(p string, i os.FileInfo, err error) error {
if err != nil {
return err
}
if i.IsDir() {
return nil
}
if path.Base(p) != "OWNERS" {
return nil
}
o, err = owners(p, o)
return err
})
// sort it and format it
list := []string{}
for k := range o {
list = append(list, k)
}
sort.Strings(list)
golist := `package chaos
// Owners are all GitHub handlers of all maintainers.
var Owners = []string{`
c := ", "
for i, a := range list {
if i == len(list)-1 {
c = "}"
}
golist += fmt.Sprintf("%q%s", a, c)
}
if err := ioutil.WriteFile("plugin/chaos/zowners.go", []byte(golist), 0644); err != nil {
log.Fatal(err)
}
return
}
// owners parses a owner file without knowning a whole lot about its structure.
func owners(path string, owners map[string]struct{}) (map[string]struct{}, error) {
file, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
c := yaml.MapSlice{}
err = yaml.Unmarshal(file, &c)
if err != nil {
return nil, err
}
for _, mi := range c {
key, ok := mi.Key.(string)
if !ok {
continue
}
if key == "approvers" {
for _, k := range mi.Value.([]interface{}) {
owners[k.(string)] = struct{}{}
}
}
}
return owners, nil
}

View File

@@ -16,7 +16,7 @@ chaos [VERSION] [AUTHORS...]
~~~
* **VERSION** is the version to return. Defaults to `CoreDNS-<version>`, if not set.
* **AUTHORS** is what authors to return. No default.
* **AUTHORS** is what authors to return. This defaults to all GitHub handles in the OWNERS files.
Note that you have to make sure that this plugin will get actual queries for the
following zones: `version.bind`, `version.server`, `authors.bind`, `hostname.bind` and

View File

@@ -16,7 +16,7 @@ import (
type Chaos struct {
Next plugin.Handler
Version string
Authors map[string]struct{}
Authors []string
}
// ServeDNS implements the plugin.Handler interface.
@@ -32,13 +32,13 @@ func (c Chaos) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (
hdr := dns.RR_Header{Name: state.QName(), Rrtype: dns.TypeTXT, Class: dns.ClassCHAOS, Ttl: 0}
switch state.Name() {
default:
return c.Next.ServeDNS(ctx, w, r)
return plugin.NextOrFailure(c.Name(), c.Next, ctx, w, r)
case "authors.bind.":
for a := range c.Authors {
m.Answer = append(m.Answer, &dns.TXT{Hdr: hdr, Txt: []string{trim(a)}})
for _, a := range c.Authors {
m.Answer = append(m.Answer, &dns.TXT{Hdr: hdr, Txt: []string{a}})
}
case "version.bind.", "version.server.":
m.Answer = []dns.RR{&dns.TXT{Hdr: hdr, Txt: []string{trim(c.Version)}}}
m.Answer = []dns.RR{&dns.TXT{Hdr: hdr, Txt: []string{c.Version}}}
case "hostname.bind.", "id.server.":
hostname, err := os.Hostname()
if err != nil {
@@ -52,10 +52,3 @@ func (c Chaos) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (
// Name implements the Handler interface.
func (c Chaos) Name() string { return "chaos" }
func trim(s string) string {
if len(s) < 256 {
return s
}
return s[:255]
}

View File

@@ -14,7 +14,7 @@ import (
func TestChaos(t *testing.T) {
em := Chaos{
Version: version,
Authors: map[string]struct{}{"Miek Gieben": struct{}{}},
Authors: []string{"Miek Gieben"},
}
tests := []struct {

View File

@@ -1,6 +1,10 @@
//go:generate go run owners_generate.go
package chaos
import (
"sort"
"github.com/coredns/coredns/core/dnsserver"
"github.com/coredns/coredns/plugin"
@@ -16,7 +20,7 @@ func init() {
}
func setup(c *caddy.Controller) error {
version, authors, err := chaosParse(c)
version, authors, err := parse(c)
if err != nil {
return plugin.Error("chaos", err)
}
@@ -28,28 +32,42 @@ func setup(c *caddy.Controller) error {
return nil
}
func chaosParse(c *caddy.Controller) (string, map[string]struct{}, error) {
func parse(c *caddy.Controller) (string, []string, error) {
// Set here so we pick up AppName and AppVersion that get set in coremain's init().
chaosVersion = caddy.AppName + "-" + caddy.AppVersion
version := ""
authors := make(map[string]struct{})
for c.Next() {
args := c.RemainingArgs()
if len(args) == 0 {
return chaosVersion, nil, nil
return trim(chaosVersion), Owners, nil
}
if len(args) == 1 {
return args[0], nil, nil
return trim(args[0]), Owners, nil
}
version = args[0]
authors := make(map[string]struct{})
for _, a := range args[1:] {
authors[a] = struct{}{}
}
return version, authors, nil
list := []string{}
for k := range authors {
k = trim(k) // limit size to 255 chars
list = append(list, k)
}
sort.Strings(list)
return version, list, nil
}
return version, authors, nil
return version, Owners, nil
}
func trim(s string) string {
if len(s) < 256 {
return s
}
return s[:255]
}
var chaosVersion string

View File

@@ -12,7 +12,7 @@ func TestSetupChaos(t *testing.T) {
input string
shouldErr bool
expectedVersion string // expected version.
expectedAuthor string // expected author (string, although we get a map).
expectedAuthor string // expected author (string, although we get a slice).
expectedErrContent string // substring from the expected error. Empty for positive cases.
}{
// positive
@@ -26,7 +26,7 @@ func TestSetupChaos(t *testing.T) {
for i, test := range tests {
c := caddy.NewTestController("dns", test.input)
version, authors, err := chaosParse(c)
version, authors, err := parse(c)
if test.shouldErr && err == nil {
t.Errorf("Test %d: Expected error but found %s for input %s", i, err, test.input)
@@ -43,11 +43,11 @@ func TestSetupChaos(t *testing.T) {
}
if !test.shouldErr && version != test.expectedVersion {
t.Errorf("Chaos not correctly set for input %s. Expected: %s, actual: %s", test.input, test.expectedVersion, version)
t.Errorf("Test %d: Chaos not correctly set for input %s. Expected: %s, actual: %s", i, test.input, test.expectedVersion, version)
}
if !test.shouldErr && authors != nil {
if _, ok := authors[test.expectedAuthor]; !ok {
t.Errorf("Chaos not correctly set for input %s. Expected: '%s', actual: '%s'", test.input, test.expectedAuthor, "Miek Gieben")
if !test.shouldErr && authors != nil && test.expectedAuthor != "" {
if authors[0] != test.expectedAuthor {
t.Errorf("Test %d: Chaos not correctly set for input %s. Expected: '%s', actual: '%s'", i, test.input, test.expectedAuthor, authors[0])
}
}
}

4
plugin/chaos/zowners.go Normal file
View File

@@ -0,0 +1,4 @@
package chaos
// Owners are all GitHub handlers of all maintainers.
var Owners = []string{"bradbeam", "chrisohaver", "dilyevsky", "ekleiner", "fastest963", "fturib", "greenpau", "grobie", "inigohu", "isolus", "johnbelamaric", "miekg", "nchrisdk", "nitisht", "pmoroney", "rajansandeep", "rdrozhdzh", "rtreffer", "stp-ip", "superq", "varyoo", "yongtang"}