mirror of
https://github.com/coredns/coredns.git
synced 2025-10-27 08:14:18 -04:00
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:
@@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
//go:generate go run directives_generate.go
|
//go:generate go run directives_generate.go
|
||||||
|
//go:generate go run owners_generate.go
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/coredns/coredns/coremain"
|
"github.com/coredns/coredns/coremain"
|
||||||
|
|||||||
1
go.mod
1
go.mod
@@ -74,6 +74,7 @@ require (
|
|||||||
gopkg.in/DataDog/dd-trace-go.v0 v0.6.1
|
gopkg.in/DataDog/dd-trace-go.v0 v0.6.1
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
gopkg.in/ini.v1 v1.42.0 // 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/api v0.0.0-20181204000039-89a74a8d264d
|
||||||
k8s.io/apimachinery v0.0.0-20181127025237-2b1284ed4c93
|
k8s.io/apimachinery v0.0.0-20181127025237-2b1284ed4c93
|
||||||
k8s.io/client-go v10.0.0+incompatible
|
k8s.io/client-go v10.0.0+incompatible
|
||||||
|
|||||||
91
owners_generate.go
Normal file
91
owners_generate.go
Normal 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
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ chaos [VERSION] [AUTHORS...]
|
|||||||
~~~
|
~~~
|
||||||
|
|
||||||
* **VERSION** is the version to return. Defaults to `CoreDNS-<version>`, if not set.
|
* **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
|
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
|
following zones: `version.bind`, `version.server`, `authors.bind`, `hostname.bind` and
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import (
|
|||||||
type Chaos struct {
|
type Chaos struct {
|
||||||
Next plugin.Handler
|
Next plugin.Handler
|
||||||
Version string
|
Version string
|
||||||
Authors map[string]struct{}
|
Authors []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServeDNS implements the plugin.Handler interface.
|
// 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}
|
hdr := dns.RR_Header{Name: state.QName(), Rrtype: dns.TypeTXT, Class: dns.ClassCHAOS, Ttl: 0}
|
||||||
switch state.Name() {
|
switch state.Name() {
|
||||||
default:
|
default:
|
||||||
return c.Next.ServeDNS(ctx, w, r)
|
return plugin.NextOrFailure(c.Name(), c.Next, ctx, w, r)
|
||||||
case "authors.bind.":
|
case "authors.bind.":
|
||||||
for a := range c.Authors {
|
for _, a := range c.Authors {
|
||||||
m.Answer = append(m.Answer, &dns.TXT{Hdr: hdr, Txt: []string{trim(a)}})
|
m.Answer = append(m.Answer, &dns.TXT{Hdr: hdr, Txt: []string{a}})
|
||||||
}
|
}
|
||||||
case "version.bind.", "version.server.":
|
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.":
|
case "hostname.bind.", "id.server.":
|
||||||
hostname, err := os.Hostname()
|
hostname, err := os.Hostname()
|
||||||
if err != nil {
|
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.
|
// Name implements the Handler interface.
|
||||||
func (c Chaos) Name() string { return "chaos" }
|
func (c Chaos) Name() string { return "chaos" }
|
||||||
|
|
||||||
func trim(s string) string {
|
|
||||||
if len(s) < 256 {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
return s[:255]
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
func TestChaos(t *testing.T) {
|
func TestChaos(t *testing.T) {
|
||||||
em := Chaos{
|
em := Chaos{
|
||||||
Version: version,
|
Version: version,
|
||||||
Authors: map[string]struct{}{"Miek Gieben": struct{}{}},
|
Authors: []string{"Miek Gieben"},
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
|
//go:generate go run owners_generate.go
|
||||||
|
|
||||||
package chaos
|
package chaos
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/coredns/coredns/core/dnsserver"
|
"github.com/coredns/coredns/core/dnsserver"
|
||||||
"github.com/coredns/coredns/plugin"
|
"github.com/coredns/coredns/plugin"
|
||||||
|
|
||||||
@@ -16,7 +20,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setup(c *caddy.Controller) error {
|
func setup(c *caddy.Controller) error {
|
||||||
version, authors, err := chaosParse(c)
|
version, authors, err := parse(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return plugin.Error("chaos", err)
|
return plugin.Error("chaos", err)
|
||||||
}
|
}
|
||||||
@@ -28,28 +32,42 @@ func setup(c *caddy.Controller) error {
|
|||||||
return nil
|
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().
|
// Set here so we pick up AppName and AppVersion that get set in coremain's init().
|
||||||
chaosVersion = caddy.AppName + "-" + caddy.AppVersion
|
chaosVersion = caddy.AppName + "-" + caddy.AppVersion
|
||||||
|
|
||||||
version := ""
|
version := ""
|
||||||
authors := make(map[string]struct{})
|
|
||||||
|
|
||||||
for c.Next() {
|
for c.Next() {
|
||||||
args := c.RemainingArgs()
|
args := c.RemainingArgs()
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return chaosVersion, nil, nil
|
return trim(chaosVersion), Owners, nil
|
||||||
}
|
}
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
return args[0], nil, nil
|
return trim(args[0]), Owners, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
version = args[0]
|
version = args[0]
|
||||||
|
authors := make(map[string]struct{})
|
||||||
for _, a := range args[1:] {
|
for _, a := range args[1:] {
|
||||||
authors[a] = struct{}{}
|
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
|
var chaosVersion string
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ func TestSetupChaos(t *testing.T) {
|
|||||||
input string
|
input string
|
||||||
shouldErr bool
|
shouldErr bool
|
||||||
expectedVersion string // expected version.
|
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.
|
expectedErrContent string // substring from the expected error. Empty for positive cases.
|
||||||
}{
|
}{
|
||||||
// positive
|
// positive
|
||||||
@@ -26,7 +26,7 @@ func TestSetupChaos(t *testing.T) {
|
|||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
c := caddy.NewTestController("dns", test.input)
|
c := caddy.NewTestController("dns", test.input)
|
||||||
version, authors, err := chaosParse(c)
|
version, authors, err := parse(c)
|
||||||
|
|
||||||
if test.shouldErr && err == nil {
|
if test.shouldErr && err == nil {
|
||||||
t.Errorf("Test %d: Expected error but found %s for input %s", i, err, test.input)
|
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 {
|
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 !test.shouldErr && authors != nil && test.expectedAuthor != "" {
|
||||||
if _, ok := authors[test.expectedAuthor]; !ok {
|
if authors[0] != test.expectedAuthor {
|
||||||
t.Errorf("Chaos not correctly set for input %s. Expected: '%s', actual: '%s'", test.input, test.expectedAuthor, "Miek Gieben")
|
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
4
plugin/chaos/zowners.go
Normal 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"}
|
||||||
Reference in New Issue
Block a user