diff options
Diffstat (limited to 'core/setup')
32 files changed, 0 insertions, 2728 deletions
diff --git a/core/setup/bindhost.go b/core/setup/bindhost.go deleted file mode 100644 index a3c07e5eb..000000000 --- a/core/setup/bindhost.go +++ /dev/null @@ -1,13 +0,0 @@ -package setup - -import "github.com/miekg/coredns/middleware" - -// BindHost sets the host to bind the listener to. -func BindHost(c *Controller) (middleware.Middleware, error) { - for c.Next() { - if !c.Args(&c.BindHost) { - return nil, c.ArgErr() - } - } - return nil, nil -} diff --git a/core/setup/cache.go b/core/setup/cache.go deleted file mode 100644 index f5a1cf0d9..000000000 --- a/core/setup/cache.go +++ /dev/null @@ -1,53 +0,0 @@ -package setup - -import ( - "strconv" - - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/middleware/cache" -) - -// Cache sets up the root file path of the server. -func Cache(c *Controller) (middleware.Middleware, error) { - ttl, zones, err := cacheParse(c) - if err != nil { - return nil, err - } - return func(next middleware.Handler) middleware.Handler { - return cache.NewCache(ttl, zones, next) - }, nil -} - -func cacheParse(c *Controller) (int, []string, error) { - var ( - err error - ttl int - ) - - for c.Next() { - if c.Val() == "cache" { - // cache [ttl] [zones..] - origins := c.ServerBlockHosts - args := c.RemainingArgs() - if len(args) > 0 { - origins = args - // first args may be just a number, then it is the ttl, if not it is a zone - t := origins[0] - ttl, err = strconv.Atoi(t) - if err == nil { - origins = origins[1:] - if len(origins) == 0 { - // There was *only* the ttl, revert back to server block - origins = c.ServerBlockHosts - } - } - } - - for i, _ := range origins { - origins[i] = middleware.Host(origins[i]).Normalize() - } - return ttl, origins, nil - } - } - return 0, nil, nil -} diff --git a/core/setup/chaos.go b/core/setup/chaos.go deleted file mode 100644 index 13103adf4..000000000 --- a/core/setup/chaos.go +++ /dev/null @@ -1,45 +0,0 @@ -package setup - -import ( - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/middleware/chaos" -) - -// Chaos configures a new Chaos middleware instance. -func Chaos(c *Controller) (middleware.Middleware, error) { - version, authors, err := chaosParse(c) - if err != nil { - return nil, err - } - - return func(next middleware.Handler) middleware.Handler { - return chaos.Chaos{ - Next: next, - Version: version, - Authors: authors, - } - }, nil -} - -func chaosParse(c *Controller) (string, map[string]bool, error) { - version := "" - authors := make(map[string]bool) - - for c.Next() { - args := c.RemainingArgs() - if len(args) == 0 { - return defaultVersion, nil, nil - } - if len(args) == 1 { - return args[0], nil, nil - } - version = args[0] - for _, a := range args[1:] { - authors[a] = true - } - return version, authors, nil - } - return version, authors, nil -} - -const defaultVersion = "CoreDNS" diff --git a/core/setup/chaos_test.go b/core/setup/chaos_test.go deleted file mode 100644 index 8431cecef..000000000 --- a/core/setup/chaos_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package setup - -import ( - "fmt" - "strings" - "testing" -) - -func TestChaos(t *testing.T) { - tests := []struct { - input string - shouldErr bool - expectedVersion string // expected version. - expectedAuthor string // expected author (string, although we get a map). - expectedErrContent string // substring from the expected error. Empty for positive cases. - }{ - // positive - { - `chaos`, false, defaultVersion, "", "", - }, - { - `chaos v2`, false, "v2", "", "", - }, - { - `chaos v3 "Miek Gieben"`, false, "v3", "Miek Gieben", "", - }, - { - fmt.Sprintf(`chaos { - %s - }`, defaultVersion), false, defaultVersion, "", "", - }, - } - - for i, test := range tests { - c := NewTestController(test.input) - version, authors, err := chaosParse(c) - - if test.shouldErr && err == nil { - t.Errorf("Test %d: Expected error but found %s for input %s", i, err, test.input) - } - - if err != nil { - if !test.shouldErr { - t.Errorf("Test %d: Expected no error but found one for input %s. Error was: %v", i, test.input, err) - } - - if !strings.Contains(err.Error(), test.expectedErrContent) { - t.Errorf("Test %d: Expected error to contain: %v, found error: %v, input: %s", i, test.expectedErrContent, err, test.input) - } - } - - if !test.shouldErr && version != test.expectedVersion { - t.Errorf("Chaos not correctly set for input %s. Expected: %s, actual: %s", 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") - } - } - } -} diff --git a/core/setup/controller.go b/core/setup/controller.go deleted file mode 100644 index 7f8da6721..000000000 --- a/core/setup/controller.go +++ /dev/null @@ -1,85 +0,0 @@ -package setup - -import ( - "fmt" - "strings" - - "golang.org/x/net/context" - - "github.com/miekg/coredns/core/parse" - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/server" - "github.com/miekg/dns" -) - -// Controller is given to the setup function of middlewares which -// gives them access to be able to read tokens and set config. Each -// virtualhost gets their own server config and dispenser. -type Controller struct { - *server.Config - parse.Dispenser - - // OncePerServerBlock is a function that executes f - // exactly once per server block, no matter how many - // hosts are associated with it. If it is the first - // time, the function f is executed immediately - // (not deferred) and may return an error which is - // returned by OncePerServerBlock. - OncePerServerBlock func(f func() error) error - - // ServerBlockIndex is the 0-based index of the - // server block as it appeared in the input. - ServerBlockIndex int - - // ServerBlockHostIndex is the 0-based index of this - // host as it appeared in the input at the head of the - // server block. - ServerBlockHostIndex int - - // ServerBlockHosts is a list of hosts that are - // associated with this server block. All these - // hosts, consequently, share the same tokens. - ServerBlockHosts []string - - // ServerBlockStorage is used by a directive's - // setup function to persist state between all - // the hosts on a server block. - ServerBlockStorage interface{} -} - -// NewTestController creates a new *Controller for -// the input specified, with a filename of "Testfile". -// The Config is bare, consisting only of a Root of cwd. -// -// Used primarily for testing but needs to be exported so -// add-ons can use this as a convenience. Does not initialize -// the server-block-related fields. -func NewTestController(input string) *Controller { - return &Controller{ - Config: &server.Config{ - Root: ".", - }, - Dispenser: parse.NewDispenser("Testfile", strings.NewReader(input)), - OncePerServerBlock: func(f func() error) error { - return f() - }, - } -} - -// EmptyNext is a no-op function that can be passed into -// middleware.Middleware functions so that the assignment -// to the Next field of the Handler can be tested. -// -// Used primarily for testing but needs to be exported so -// add-ons can use this as a convenience. -var EmptyNext = middleware.HandlerFunc(func(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { - return 0, nil -}) - -// SameNext does a pointer comparison between next1 and next2. -// -// Used primarily for testing but needs to be exported so -// add-ons can use this as a convenience. -func SameNext(next1, next2 middleware.Handler) bool { - return fmt.Sprintf("%v", next1) == fmt.Sprintf("%v", next2) -} diff --git a/core/setup/dnssec.go b/core/setup/dnssec.go deleted file mode 100644 index 39f34b66f..000000000 --- a/core/setup/dnssec.go +++ /dev/null @@ -1,80 +0,0 @@ -package setup - -import ( - "strings" - - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/middleware/dnssec" -) - -// Dnssec sets up the dnssec middleware. -func Dnssec(c *Controller) (middleware.Middleware, error) { - zones, keys, err := dnssecParse(c) - if err != nil { - return nil, err - } - - return func(next middleware.Handler) middleware.Handler { - return dnssec.NewDnssec(zones, keys, next) - }, nil -} - -func dnssecParse(c *Controller) ([]string, []*dnssec.DNSKEY, error) { - zones := []string{} - - keys := []*dnssec.DNSKEY{} - for c.Next() { - if c.Val() == "dnssec" { - // dnssec [zones...] - zones = c.ServerBlockHosts - args := c.RemainingArgs() - if len(args) > 0 { - zones = args - } - - for c.NextBlock() { - k, e := keyParse(c) - if e != nil { - return nil, nil, e - } - keys = append(keys, k...) - } - } - } - for i, _ := range zones { - zones[i] = middleware.Host(zones[i]).Normalize() - } - return zones, keys, nil -} - -func keyParse(c *Controller) ([]*dnssec.DNSKEY, error) { - keys := []*dnssec.DNSKEY{} - - what := c.Val() - if !c.NextArg() { - return nil, c.ArgErr() - } - value := c.Val() - switch what { - case "key": - if value == "file" { - ks := c.RemainingArgs() - for _, k := range ks { - base := k - // Kmiek.nl.+013+26205.key, handle .private or without extension: Kmiek.nl.+013+26205 - if strings.HasSuffix(k, ".key") { - base = k[:len(k)-4] - } - if strings.HasSuffix(k, ".private") { - base = k[:len(k)-8] - } - k, err := dnssec.ParseKeyFile(base+".key", base+".private") - if err != nil { - return nil, err - } - keys = append(keys, k) - } - } - } - return keys, nil -} diff --git a/core/setup/dnssec_test.go b/core/setup/dnssec_test.go deleted file mode 100644 index 364a363bd..000000000 --- a/core/setup/dnssec_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package setup - -import ( - "strings" - "testing" -) - -func TestDnssec(t *testing.T) { - tests := []struct { - input string - shouldErr bool - expectedZones []string - expectedKeys []string - expectedErrContent string - }{ - { - `dnssec`, false, nil, nil, "", - }, - { - `dnssec miek.nl`, false, []string{"miek.nl."}, nil, "", - }, - } - - for i, test := range tests { - c := NewTestController(test.input) - zones, keys, err := dnssecParse(c) - - if test.shouldErr && err == nil { - t.Errorf("Test %d: Expected error but found %s for input %s", i, err, test.input) - } - - if err != nil { - if !test.shouldErr { - t.Errorf("Test %d: Expected no error but found one for input %s. Error was: %v", i, test.input, err) - } - - if !strings.Contains(err.Error(), test.expectedErrContent) { - t.Errorf("Test %d: Expected error to contain: %v, found error: %v, input: %s", i, test.expectedErrContent, err, test.input) - } - } - if !test.shouldErr { - for i, z := range test.expectedZones { - if zones[i] != z { - t.Errorf("Dnssec not correctly set for input %s. Expected: %s, actual: %s", test.input, z, zones[i]) - } - } - for i, k := range test.expectedKeys { - if k != keys[i].K.Header().Name { - t.Errorf("Dnssec not correctly set for input %s. Expected: '%s', actual: '%s'", test.input, k, keys[i].K.Header().Name) - } - } - } - } -} diff --git a/core/setup/errors.go b/core/setup/errors.go deleted file mode 100644 index bf6b56f87..000000000 --- a/core/setup/errors.go +++ /dev/null @@ -1,124 +0,0 @@ -package setup - -import ( - "io" - "log" - "os" - - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/middleware/errors" - - "github.com/hashicorp/go-syslog" -) - -// Errors configures a new errors middleware instance. -func Errors(c *Controller) (middleware.Middleware, error) { - handler, err := errorsParse(c) - if err != nil { - return nil, err - } - - var writer io.Writer - - switch handler.LogFile { - case "visible": - handler.Debug = true - case "stdout": - writer = os.Stdout - case "stderr": - writer = os.Stderr - case "syslog": - writer, err = gsyslog.NewLogger(gsyslog.LOG_ERR, "LOCAL0", "coredns") - if err != nil { - return nil, err - } - default: - if handler.LogFile == "" { - writer = os.Stderr // default - break - } - - var file *os.File - file, err = os.OpenFile(handler.LogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) - if err != nil { - return nil, err - } - if handler.LogRoller != nil { - file.Close() - - handler.LogRoller.Filename = handler.LogFile - - writer = handler.LogRoller.GetLogWriter() - } else { - writer = file - } - } - handler.Log = log.New(writer, "", 0) - - return func(next middleware.Handler) middleware.Handler { - handler.Next = next - return handler - }, nil -} - -func errorsParse(c *Controller) (errors.ErrorHandler, error) { - handler := errors.ErrorHandler{} - - optionalBlock := func() (bool, error) { - var hadBlock bool - - for c.NextBlock() { - hadBlock = true - - what := c.Val() - if !c.NextArg() { - return hadBlock, c.ArgErr() - } - where := c.Val() - - if what == "log" { - if where == "visible" { - handler.Debug = true - } else { - handler.LogFile = where - if c.NextArg() { - if c.Val() == "{" { - c.IncrNest() - logRoller, err := parseRoller(c) - if err != nil { - return hadBlock, err - } - handler.LogRoller = logRoller - } - } - } - } - } - return hadBlock, nil - } - - for c.Next() { - // weird hack to avoid having the handler values overwritten. - if c.Val() == "}" { - continue - } - // Configuration may be in a block - hadBlock, err := optionalBlock() - if err != nil { - return handler, err - } - - // Otherwise, the only argument would be an error log file name or 'visible' - if !hadBlock { - if c.NextArg() { - if c.Val() == "visible" { - handler.Debug = true - } else { - handler.LogFile = c.Val() - } - } - } - } - - return handler, nil -} diff --git a/core/setup/errors_test.go b/core/setup/errors_test.go deleted file mode 100644 index 42f625f92..000000000 --- a/core/setup/errors_test.go +++ /dev/null @@ -1,127 +0,0 @@ -package setup - -import ( - "testing" - - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/middleware/errors" -) - -func TestErrors(t *testing.T) { - c := NewTestController(`errors`) - mid, err := Errors(c) - - if err != nil { - t.Errorf("Expected no errors, got: %v", err) - } - - if mid == nil { - t.Fatal("Expected middleware, was nil instead") - } - - handler := mid(EmptyNext) - myHandler, ok := handler.(errors.ErrorHandler) - if !ok { - t.Fatalf("Expected handler to be type ErrorHandler, got: %#v", handler) - } - - if myHandler.LogFile != "" { - t.Errorf("Expected '%s' as the default LogFile", "") - } - if myHandler.LogRoller != nil { - t.Errorf("Expected LogRoller to be nil, got: %v", *myHandler.LogRoller) - } - if !SameNext(myHandler.Next, EmptyNext) { - t.Error("'Next' field of handler was not set properly") - } -} - -func TestErrorsParse(t *testing.T) { - tests := []struct { - inputErrorsRules string - shouldErr bool - expectedErrorHandler errors.ErrorHandler - }{ - {`errors`, false, errors.ErrorHandler{ - LogFile: "", - }}, - {`errors errors.txt`, false, errors.ErrorHandler{ - LogFile: "errors.txt", - }}, - {`errors visible`, false, errors.ErrorHandler{ - LogFile: "", - Debug: true, - }}, - {`errors { log visible }`, false, errors.ErrorHandler{ - LogFile: "", - Debug: true, - }}, - {`errors { log errors.txt { size 2 age 10 keep 3 } }`, false, errors.ErrorHandler{ - LogFile: "errors.txt", - LogRoller: &middleware.LogRoller{ - MaxSize: 2, - MaxAge: 10, - MaxBackups: 3, - LocalTime: true, - }, - }}, - {`errors { log errors.txt { - size 3 - age 11 - keep 5 - } -}`, false, errors.ErrorHandler{ - LogFile: "errors.txt", - LogRoller: &middleware.LogRoller{ - MaxSize: 3, - MaxAge: 11, - MaxBackups: 5, - LocalTime: true, - }, - }}, - } - for i, test := range tests { - c := NewTestController(test.inputErrorsRules) - actualErrorsRule, err := errorsParse(c) - - if err == nil && test.shouldErr { - t.Errorf("Test %d didn't error, but it should have", i) - } else if err != nil && !test.shouldErr { - t.Errorf("Test %d errored, but it shouldn't have; got '%v'", i, err) - } - if actualErrorsRule.LogFile != test.expectedErrorHandler.LogFile { - t.Errorf("Test %d expected LogFile to be %s, but got %s", - i, test.expectedErrorHandler.LogFile, actualErrorsRule.LogFile) - } - if actualErrorsRule.Debug != test.expectedErrorHandler.Debug { - t.Errorf("Test %d expected Debug to be %v, but got %v", - i, test.expectedErrorHandler.Debug, actualErrorsRule.Debug) - } - if actualErrorsRule.LogRoller != nil && test.expectedErrorHandler.LogRoller == nil || actualErrorsRule.LogRoller == nil && test.expectedErrorHandler.LogRoller != nil { - t.Fatalf("Test %d expected LogRoller to be %v, but got %v", - i, test.expectedErrorHandler.LogRoller, actualErrorsRule.LogRoller) - } - if actualErrorsRule.LogRoller != nil && test.expectedErrorHandler.LogRoller != nil { - if actualErrorsRule.LogRoller.Filename != test.expectedErrorHandler.LogRoller.Filename { - t.Fatalf("Test %d expected LogRoller Filename to be %s, but got %s", - i, test.expectedErrorHandler.LogRoller.Filename, actualErrorsRule.LogRoller.Filename) - } - if actualErrorsRule.LogRoller.MaxAge != test.expectedErrorHandler.LogRoller.MaxAge { - t.Fatalf("Test %d expected LogRoller MaxAge to be %d, but got %d", - i, test.expectedErrorHandler.LogRoller.MaxAge, actualErrorsRule.LogRoller.MaxAge) - } - if actualErrorsRule.LogRoller.MaxBackups != test.expectedErrorHandler.LogRoller.MaxBackups { - t.Fatalf("Test %d expected LogRoller MaxBackups to be %d, but got %d", - i, test.expectedErrorHandler.LogRoller.MaxBackups, actualErrorsRule.LogRoller.MaxBackups) - } - if actualErrorsRule.LogRoller.MaxSize != test.expectedErrorHandler.LogRoller.MaxSize { - t.Fatalf("Test %d expected LogRoller MaxSize to be %d, but got %d", - i, test.expectedErrorHandler.LogRoller.MaxSize, actualErrorsRule.LogRoller.MaxSize) - } - if actualErrorsRule.LogRoller.LocalTime != test.expectedErrorHandler.LogRoller.LocalTime { - t.Fatalf("Test %d expected LogRoller LocalTime to be %t, but got %t", - i, test.expectedErrorHandler.LogRoller.LocalTime, actualErrorsRule.LogRoller.LocalTime) - } - } - } -} diff --git a/core/setup/etcd.go b/core/setup/etcd.go deleted file mode 100644 index b90297abd..000000000 --- a/core/setup/etcd.go +++ /dev/null @@ -1,197 +0,0 @@ -package setup - -import ( - "crypto/tls" - "crypto/x509" - "io/ioutil" - "net" - "net/http" - "time" - - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/middleware/etcd" - "github.com/miekg/coredns/middleware/proxy" - "github.com/miekg/coredns/singleflight" - - etcdc "github.com/coreos/etcd/client" - "golang.org/x/net/context" -) - -const defaultEndpoint = "http://localhost:2379" - -// Etcd sets up the etcd middleware. -func Etcd(c *Controller) (middleware.Middleware, error) { - etcd, stubzones, err := etcdParse(c) - if err != nil { - return nil, err - } - if stubzones { - c.Startup = append(c.Startup, func() error { - etcd.UpdateStubZones() - return nil - }) - } - - return func(next middleware.Handler) middleware.Handler { - etcd.Next = next - return etcd - }, nil -} - -func etcdParse(c *Controller) (*etcd.Etcd, bool, error) { - stub := make(map[string]proxy.Proxy) - etc := etcd.Etcd{ - Proxy: proxy.New([]string{"8.8.8.8:53", "8.8.4.4:53"}), - PathPrefix: "skydns", - Ctx: context.Background(), - Inflight: &singleflight.Group{}, - Stubmap: &stub, - } - var ( - client etcdc.KeysAPI - tlsCertFile = "" - tlsKeyFile = "" - tlsCAcertFile = "" - endpoints = []string{defaultEndpoint} - stubzones = false - ) - for c.Next() { - if c.Val() == "etcd" { - etc.Client = client - etc.Zones = c.RemainingArgs() - if len(etc.Zones) == 0 { - etc.Zones = c.ServerBlockHosts - } - middleware.Zones(etc.Zones).FullyQualify() - if c.NextBlock() { - // TODO(miek): 2 switches? - switch c.Val() { - case "stubzones": - stubzones = true - case "debug": - etc.Debug = true - case "path": - if !c.NextArg() { - return &etcd.Etcd{}, false, c.ArgErr() - } - etc.PathPrefix = c.Val() - case "endpoint": - args := c.RemainingArgs() - if len(args) == 0 { - return &etcd.Etcd{}, false, c.ArgErr() - } - endpoints = args - case "upstream": - args := c.RemainingArgs() - if len(args) == 0 { - return &etcd.Etcd{}, false, c.ArgErr() - } - for i := 0; i < len(args); i++ { - h, p, e := net.SplitHostPort(args[i]) - if e != nil && p == "" { - args[i] = h + ":53" - } - } - endpoints = args - etc.Proxy = proxy.New(args) - case "tls": // cert key cacertfile - args := c.RemainingArgs() - if len(args) != 3 { - return &etcd.Etcd{}, false, c.ArgErr() - } - tlsCertFile, tlsKeyFile, tlsCAcertFile = args[0], args[1], args[2] - } - for c.Next() { - switch c.Val() { - case "stubzones": - stubzones = true - case "debug": - etc.Debug = true - case "path": - if !c.NextArg() { - return &etcd.Etcd{}, false, c.ArgErr() - } - etc.PathPrefix = c.Val() - case "endpoint": - args := c.RemainingArgs() - if len(args) == 0 { - return &etcd.Etcd{}, false, c.ArgErr() - } - endpoints = args - case "upstream": - args := c.RemainingArgs() - if len(args) == 0 { - return &etcd.Etcd{}, false, c.ArgErr() - } - for i := 0; i < len(args); i++ { - h, p, e := net.SplitHostPort(args[i]) - if e != nil && p == "" { - args[i] = h + ":53" - } - } - etc.Proxy = proxy.New(args) - case "tls": // cert key cacertfile - args := c.RemainingArgs() - if len(args) != 3 { - return &etcd.Etcd{}, false, c.ArgErr() - } - tlsCertFile, tlsKeyFile, tlsCAcertFile = args[0], args[1], args[2] - } - } - } - client, err := newEtcdClient(endpoints, tlsCertFile, tlsKeyFile, tlsCAcertFile) - if err != nil { - return &etcd.Etcd{}, false, err - } - etc.Client = client - return &etc, stubzones, nil - } - } - return &etcd.Etcd{}, false, nil -} - -func newEtcdClient(endpoints []string, tlsCert, tlsKey, tlsCACert string) (etcdc.KeysAPI, error) { - etcdCfg := etcdc.Config{ - Endpoints: endpoints, - Transport: newHTTPSTransport(tlsCert, tlsKey, tlsCACert), - } - cli, err := etcdc.New(etcdCfg) - if err != nil { - return nil, err - } - return etcdc.NewKeysAPI(cli), nil -} - -func newHTTPSTransport(tlsCertFile, tlsKeyFile, tlsCACertFile string) etcdc.CancelableTransport { - var cc *tls.Config = nil - - if tlsCertFile != "" && tlsKeyFile != "" { - var rpool *x509.CertPool - if tlsCACertFile != "" { - if pemBytes, err := ioutil.ReadFile(tlsCACertFile); err == nil { - rpool = x509.NewCertPool() - rpool.AppendCertsFromPEM(pemBytes) - } - } - - if tlsCert, err := tls.LoadX509KeyPair(tlsCertFile, tlsKeyFile); err == nil { - cc = &tls.Config{ - RootCAs: rpool, - Certificates: []tls.Certificate{tlsCert}, - InsecureSkipVerify: true, - } - } - } - - tr := &http.Transport{ - Proxy: http.ProxyFromEnvironment, - Dial: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).Dial, - TLSHandshakeTimeout: 10 * time.Second, - TLSClientConfig: cc, - } - - return tr -} diff --git a/core/setup/file.go b/core/setup/file.go deleted file mode 100644 index a0b90c3ca..000000000 --- a/core/setup/file.go +++ /dev/null @@ -1,130 +0,0 @@ -package setup - -import ( - "fmt" - "net" - "os" - - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/middleware/file" -) - -// File sets up the file middleware. -func File(c *Controller) (middleware.Middleware, error) { - zones, err := fileParse(c) - if err != nil { - return nil, err - } - - // Add startup functions to notify the master(s). - for _, n := range zones.Names { - c.Startup = append(c.Startup, func() error { - zones.Z[n].StartupOnce.Do(func() { - if len(zones.Z[n].TransferTo) > 0 { - zones.Z[n].Notify() - } - zones.Z[n].Reload(nil) - }) - return nil - }) - } - - return func(next middleware.Handler) middleware.Handler { - return file.File{Next: next, Zones: zones} - }, nil - -} - -func fileParse(c *Controller) (file.Zones, error) { - z := make(map[string]*file.Zone) - names := []string{} - for c.Next() { - if c.Val() == "file" { - // file db.file [zones...] - if !c.NextArg() { - return file.Zones{}, c.ArgErr() - } - fileName := c.Val() - - origins := c.ServerBlockHosts - args := c.RemainingArgs() - if len(args) > 0 { - origins = args - } - - reader, err := os.Open(fileName) - if err != nil { - // bail out - return file.Zones{}, err - } - - for i, _ := range origins { - origins[i] = middleware.Host(origins[i]).Normalize() - zone, err := file.Parse(reader, origins[i], fileName) - if err == nil { - z[origins[i]] = zone - } else { - return file.Zones{}, err - } - names = append(names, origins[i]) - } - - noReload := false - for c.NextBlock() { - t, _, e := transferParse(c) - if e != nil { - return file.Zones{}, e - } - switch c.Val() { - case "no_reload": - noReload = true - } - // discard from, here, maybe check and show log when we do? - for _, origin := range origins { - if t != nil { - z[origin].TransferTo = append(z[origin].TransferTo, t...) - } - z[origin].NoReload = noReload - } - } - } - } - return file.Zones{Z: z, Names: names}, nil -} - -// transferParse parses transfer statements: 'transfer to [address...]'. -func transferParse(c *Controller) (tos, froms []string, err error) { - what := c.Val() - if !c.NextArg() { - return nil, nil, c.ArgErr() - } - value := c.Val() - switch what { - case "transfer": - if value == "to" { - tos = c.RemainingArgs() - for i, _ := range tos { - if tos[i] != "*" { - if x := net.ParseIP(tos[i]); x == nil { - return nil, nil, fmt.Errorf("must specify an IP addres: `%s'", tos[i]) - } - tos[i] = middleware.Addr(tos[i]).Normalize() - } - } - } - if value == "from" { - froms = c.RemainingArgs() - for i, _ := range froms { - if froms[i] != "*" { - if x := net.ParseIP(froms[i]); x == nil { - return nil, nil, fmt.Errorf("must specify an IP addres: `%s'", froms[i]) - } - froms[i] = middleware.Addr(froms[i]).Normalize() - } else { - return nil, nil, fmt.Errorf("can't use '*' in transfer from") - } - } - } - } - return -} diff --git a/core/setup/health.go b/core/setup/health.go deleted file mode 100644 index 542cb3260..000000000 --- a/core/setup/health.go +++ /dev/null @@ -1,34 +0,0 @@ -package setup - -import ( - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/middleware/health" -) - -func Health(c *Controller) (middleware.Middleware, error) { - addr, err := parseHealth(c) - if err != nil { - return nil, err - } - - h := &health.Health{Addr: addr} - c.Startup = append(c.Startup, h.Start) - c.Shutdown = append(c.Shutdown, h.Shutdown) - return nil, nil -} - -func parseHealth(c *Controller) (string, error) { - addr := "" - for c.Next() { - args := c.RemainingArgs() - - switch len(args) { - case 0: - case 1: - addr = args[0] - default: - return "", c.ArgErr() - } - } - return addr, nil -} diff --git a/core/setup/kubernetes.go b/core/setup/kubernetes.go deleted file mode 100644 index 7439a9f1b..000000000 --- a/core/setup/kubernetes.go +++ /dev/null @@ -1,135 +0,0 @@ -package setup - -import ( - "errors" - "fmt" - "log" - "strings" - "time" - - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/middleware/kubernetes" - "github.com/miekg/coredns/middleware/kubernetes/nametemplate" - unversionedapi "k8s.io/kubernetes/pkg/api/unversioned" -) - -const ( - defaultNameTemplate = "{service}.{namespace}.{zone}" - defaultResyncPeriod = 5 * time.Minute -) - -// Kubernetes sets up the kubernetes middleware. -func Kubernetes(c *Controller) (middleware.Middleware, error) { - kubernetes, err := kubernetesParse(c) - if err != nil { - return nil, err - } - - err = kubernetes.StartKubeCache() - if err != nil { - return nil, err - } - - return func(next middleware.Handler) middleware.Handler { - kubernetes.Next = next - return kubernetes - }, nil -} - -func kubernetesParse(c *Controller) (kubernetes.Kubernetes, error) { - var err error - template := defaultNameTemplate - - k8s := kubernetes.Kubernetes{ - ResyncPeriod: defaultResyncPeriod, - } - k8s.NameTemplate = new(nametemplate.NameTemplate) - k8s.NameTemplate.SetTemplate(template) - - // TODO: expose resync period in Corefile - - for c.Next() { - if c.Val() == "kubernetes" { - zones := c.RemainingArgs() - - if len(zones) == 0 { - k8s.Zones = c.ServerBlockHosts - log.Printf("[debug] Zones(from ServerBlockHosts): %v", zones) - } else { - // Normalize requested zones - k8s.Zones = kubernetes.NormalizeZoneList(zones) - } - - middleware.Zones(k8s.Zones).FullyQualify() - if k8s.Zones == nil || len(k8s.Zones) < 1 { - err = errors.New("Zone name must be provided for kubernetes middleware.") - log.Printf("[debug] %v\n", err) - return kubernetes.Kubernetes{}, err - } - - for c.NextBlock() { - switch c.Val() { - case "template": - args := c.RemainingArgs() - if len(args) != 0 { - template := strings.Join(args, "") - err = k8s.NameTemplate.SetTemplate(template) - if err != nil { - return kubernetes.Kubernetes{}, err - } - } else { - log.Printf("[debug] 'template' keyword provided without any template value.") - return kubernetes.Kubernetes{}, c.ArgErr() - } - case "namespaces": - args := c.RemainingArgs() - if len(args) != 0 { - k8s.Namespaces = append(k8s.Namespaces, args...) - } else { - log.Printf("[debug] 'namespaces' keyword provided without any namespace values.") - return kubernetes.Kubernetes{}, c.ArgErr() - } - case "endpoint": - args := c.RemainingArgs() - if len(args) != 0 { - k8s.APIEndpoint = args[0] - } else { - log.Printf("[debug] 'endpoint' keyword provided without any endpoint url value.") - return kubernetes.Kubernetes{}, c.ArgErr() - } - case "resyncperiod": - args := c.RemainingArgs() - if len(args) != 0 { - k8s.ResyncPeriod, err = time.ParseDuration(args[0]) - if err != nil { - err = errors.New(fmt.Sprintf("Unable to parse resync duration value. Value provided was '%v'. Example valid values: '15s', '5m', '1h'. Error was: %v", args[0], err)) - log.Printf("[ERROR] %v", err) - return kubernetes.Kubernetes{}, err - } - } else { - log.Printf("[debug] 'resyncperiod' keyword provided without any duration value.") - return kubernetes.Kubernetes{}, c.ArgErr() - } - case "labels": - args := c.RemainingArgs() - if len(args) != 0 { - labelSelectorString := strings.Join(args, " ") - k8s.LabelSelector, err = unversionedapi.ParseToLabelSelector(labelSelectorString) - if err != nil { - err = errors.New(fmt.Sprintf("Unable to parse label selector. Value provided was '%v'. Error was: %v", labelSelectorString, err)) - log.Printf("[ERROR] %v", err) - return kubernetes.Kubernetes{}, err - } - } else { - log.Printf("[debug] 'labels' keyword provided without any selector value.") - return kubernetes.Kubernetes{}, c.ArgErr() - } - } - } - return k8s, nil - } - } - err = errors.New("Kubernetes setup called without keyword 'kubernetes' in Corefile") - log.Printf("[ERROR] %v\n", err) - return kubernetes.Kubernetes{}, err -} diff --git a/core/setup/kubernetes_test.go b/core/setup/kubernetes_test.go deleted file mode 100644 index cf6ac9abc..000000000 --- a/core/setup/kubernetes_test.go +++ /dev/null @@ -1,389 +0,0 @@ -package setup - -import ( - "strings" - "testing" - "time" - - unversionedapi "k8s.io/kubernetes/pkg/api/unversioned" -) - -func TestKubernetesParse(t *testing.T) { - tests := []struct { - description string // Human-facing description of test case - input string // Corefile data as string - shouldErr bool // true if test case is exected to produce an error. - expectedErrContent string // substring from the expected error. Empty for positive cases. - expectedZoneCount int // expected count of defined zones. - expectedNTValid bool // NameTemplate to be initialized and valid - expectedNSCount int // expected count of namespaces. - expectedResyncPeriod time.Duration // expected resync period value - expectedLabelSelector string // expected label selector value - }{ - // positive - { - "kubernetes keyword with one zone", - `kubernetes coredns.local`, - false, - "", - 1, - true, - 0, - defaultResyncPeriod, - "", - }, - { - "kubernetes keyword with multiple zones", - `kubernetes coredns.local test.local`, - false, - "", - 2, - true, - 0, - defaultResyncPeriod, - "", - }, - { - "kubernetes keyword with zone and empty braces", - `kubernetes coredns.local { -}`, - false, - "", - 1, - true, - 0, - defaultResyncPeriod, - "", - }, - { - "endpoint keyword with url", - `kubernetes coredns.local { - endpoint http://localhost:9090 -}`, - false, - "", - 1, - true, - 0, - defaultResyncPeriod, - "", - }, - { - "template keyword with valid template", - `kubernetes coredns.local { - template {service}.{namespace}.{zone} -}`, - false, - "", - 1, - true, - 0, - defaultResyncPeriod, - "", - }, - { - "namespaces keyword with one namespace", - `kubernetes coredns.local { - namespaces demo -}`, - false, - "", - 1, - true, - 1, - defaultResyncPeriod, - "", - }, - { - "namespaces keyword with multiple namespaces", - `kubernetes coredns.local { - namespaces demo test -}`, - false, - "", - 1, - true, - 2, - defaultResyncPeriod, - "", - }, - { - "resync period in seconds", - `kubernetes coredns.local { - resyncperiod 30s -}`, - false, - "", - 1, - true, - 0, - 30 * time.Second, - "", - }, - { - "resync period in minutes", - `kubernetes coredns.local { - resyncperiod 15m -}`, - false, - "", - 1, - true, - 0, - 15 * time.Minute, - "", - }, - { - "basic label selector", - `kubernetes coredns.local { - labels environment=prod -}`, - false, - "", - 1, - true, - 0, - defaultResyncPeriod, - "environment=prod", - }, - { - "multi-label selector", - `kubernetes coredns.local { - labels environment in (production, staging, qa),application=nginx -}`, - false, - "", - 1, - true, - 0, - defaultResyncPeriod, - "application=nginx,environment in (production,qa,staging)", - }, - { - "fully specified valid config", - `kubernetes coredns.local test.local { - resyncperiod 15m - endpoint http://localhost:8080 - template {service}.{namespace}.{zone} - namespaces demo test - labels environment in (production, staging, qa),application=nginx -}`, - false, - "", - 2, - true, - 2, - 15 * time.Minute, - "application=nginx,environment in (production,qa,staging)", - }, - // negative - { - "no kubernetes keyword", - "", - true, - "Kubernetes setup called without keyword 'kubernetes' in Corefile", - -1, - false, - -1, - defaultResyncPeriod, - "", - }, - { - "kubernetes keyword without a zone", - `kubernetes`, - true, - "Zone name must be provided for kubernetes middleware", - -1, - true, - 0, - defaultResyncPeriod, - "", - }, - { - "endpoint keyword without an endpoint value", - `kubernetes coredns.local { - endpoint -}`, - true, - "Wrong argument count or unexpected line ending after 'endpoint'", - -1, - true, - -1, - defaultResyncPeriod, - "", - }, - { - "template keyword without a template value", - `kubernetes coredns.local { - template -}`, - true, - "Wrong argument count or unexpected line ending after 'template'", - -1, - false, - 0, - defaultResyncPeriod, - "", - }, - { - "template keyword with an invalid template value", - `kubernetes coredns.local { - template {namespace}.{zone} -}`, - true, - "Record name template does not pass NameTemplate validation", - -1, - false, - 0, - defaultResyncPeriod, - "", - }, - { - "namespace keyword without a namespace value", - `kubernetes coredns.local { - namespaces -}`, - true, - "Parse error: Wrong argument count or unexpected line ending after 'namespaces'", - -1, - true, - -1, - defaultResyncPeriod, - "", - }, - { - "resyncperiod keyword without a duration value", - `kubernetes coredns.local { - resyncperiod -}`, - true, - "Wrong argument count or unexpected line ending after 'resyncperiod'", - -1, - true, - 0, - 0 * time.Minute, - "", - }, - { - "resync period no units", - `kubernetes coredns.local { - resyncperiod 15 -}`, - true, - "Unable to parse resync duration value. Value provided was ", - -1, - true, - 0, - 0 * time.Second, - "", - }, - { - "resync period invalid", - `kubernetes coredns.local { - resyncperiod abc -}`, - true, - "Unable to parse resync duration value. Value provided was ", - -1, - true, - 0, - 0 * time.Second, - "", - }, - { - "labels with no selector value", - `kubernetes coredns.local { - labels -}`, - true, - "Wrong argument count or unexpected line ending after 'labels'", - -1, - true, - 0, - 0 * time.Second, - "", - }, - { - "labels with invalid selector value", - `kubernetes coredns.local { - labels environment in (production, qa -}`, - true, - "Unable to parse label selector. Value provided was", - -1, - true, - 0, - 0 * time.Second, - "", - }, - } - - t.Logf("Parser test cases count: %v", len(tests)) - for i, test := range tests { - c := NewTestController(test.input) - k8sController, err := kubernetesParse(c) - t.Logf("setup test: %2v -- %v\n", i, test.description) - //t.Logf("controller: %v\n", k8sController) - - if test.shouldErr && err == nil { - t.Errorf("Test %d: Expected error, but did not find error for input '%s'. Error was: '%v'", i, test.input, err) - } - - if err != nil { - if !test.shouldErr { - t.Errorf("Test %d: Expected no error but found one for input %s. Error was: %v", i, test.input, err) - continue - } - - if test.shouldErr && (len(test.expectedErrContent) < 1) { - t.Fatalf("Test %d: Test marked as expecting an error, but no expectedErrContent provided for input '%s'. Error was: '%v'", i, test.input, err) - } - - if test.shouldErr && (test.expectedZoneCount >= 0) { - t.Errorf("Test %d: Test marked as expecting an error, but provides value for expectedZoneCount!=-1 for input '%s'. Error was: '%v'", i, test.input, err) - } - - if !strings.Contains(err.Error(), test.expectedErrContent) { - t.Errorf("Test %d: Expected error to contain: %v, found error: %v, input: %s", i, test.expectedErrContent, err, test.input) - } - continue - } - - // No error was raised, so validate initialization of k8sController - // Zones - foundZoneCount := len(k8sController.Zones) - if foundZoneCount != test.expectedZoneCount { - t.Errorf("Test %d: Expected kubernetes controller to be initialized with %d zones, instead found %d zones: '%v' for input '%s'", i, test.expectedZoneCount, foundZoneCount, k8sController.Zones, test.input) - } - - // NameTemplate - if k8sController.NameTemplate == nil { - t.Errorf("Test %d: Expected kubernetes controller to be initialized with a NameTemplate. Instead found '%v' for input '%s'", i, k8sController.NameTemplate, test.input) - } else { - foundNTValid := k8sController.NameTemplate.IsValid() - if foundNTValid != test.expectedNTValid { - t.Errorf("Test %d: Expected NameTemplate validity to be '%v', instead found '%v' for input '%s'", i, test.expectedNTValid, foundNTValid, test.input) - } - } - - // Namespaces - foundNSCount := len(k8sController.Namespaces) - if foundNSCount != test.expectedNSCount { - t.Errorf("Test %d: Expected kubernetes controller to be initialized with %d namespaces. Instead found %d namespaces: '%v' for input '%s'", i, test.expectedNSCount, foundNSCount, k8sController.Namespaces, test.input) - } - - // ResyncPeriod - foundResyncPeriod := k8sController.ResyncPeriod - if foundResyncPeriod != test.expectedResyncPeriod { - t.Errorf("Test %d: Expected kubernetes controller to be initialized with resync period '%s'. Instead found period '%s' for input '%s'", i, test.expectedResyncPeriod, foundResyncPeriod, test.input) - } - - // Labels - if k8sController.LabelSelector != nil { - foundLabelSelectorString := unversionedapi.FormatLabelSelector(k8sController.LabelSelector) - if foundLabelSelectorString != test.expectedLabelSelector { - t.Errorf("Test %d: Expected kubernetes controller to be initialized with label selector '%s'. Instead found selector '%s' for input '%s'", i, test.expectedLabelSelector, foundLabelSelectorString, test.input) - } - } - } -} diff --git a/core/setup/loadbalance.go b/core/setup/loadbalance.go deleted file mode 100644 index 4b132489b..000000000 --- a/core/setup/loadbalance.go +++ /dev/null @@ -1,16 +0,0 @@ -package setup - -import ( - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/middleware/loadbalance" -) - -// Loadbalance sets up the root file path of the server. -func Loadbalance(c *Controller) (middleware.Middleware, error) { - for c.Next() { - // TODO(miek): block and option parsing - } - return func(next middleware.Handler) middleware.Handler { - return loadbalance.RoundRobin{Next: next} - }, nil -} diff --git a/core/setup/log.go b/core/setup/log.go deleted file mode 100644 index 1deca2565..000000000 --- a/core/setup/log.go +++ /dev/null @@ -1,131 +0,0 @@ -package setup - -import ( - "io" - "log" - "os" - - "github.com/hashicorp/go-syslog" - "github.com/miekg/coredns/middleware" - corednslog "github.com/miekg/coredns/middleware/log" - "github.com/miekg/coredns/server" - "github.com/miekg/dns" -) - -// Log sets up the logging middleware. -func Log(c *Controller) (middleware.Middleware, error) { - rules, err := logParse(c) - if err != nil { - return nil, err - } - - // Open the log files for writing when the server starts - c.Startup = append(c.Startup, func() error { - for i := 0; i < len(rules); i++ { - var err error - var writer io.Writer - - if rules[i].OutputFile == "stdout" { - writer = os.Stdout - } else if rules[i].OutputFile == "stderr" { - writer = os.Stderr - } else if rules[i].OutputFile == "syslog" { - writer, err = gsyslog.NewLogger(gsyslog.LOG_INFO, "LOCAL0", "coredns") - if err != nil { - return err - } - } else { - var file *os.File - file, err = os.OpenFile(rules[i].OutputFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) - if err != nil { - return err - } - if rules[i].Roller != nil { - file.Close() - rules[i].Roller.Filename = rules[i].OutputFile - writer = rules[i].Roller.GetLogWriter() - } else { - writer = file - } - } - - rules[i].Log = log.New(writer, "", 0) - } - - return nil - }) - - return func(next middleware.Handler) middleware.Handler { - return corednslog.Logger{Next: next, Rules: rules, ErrorFunc: server.DefaultErrorFunc} - }, nil -} - -func logParse(c *Controller) ([]corednslog.Rule, error) { - var rules []corednslog.Rule - - for c.Next() { - args := c.RemainingArgs() - - var logRoller *middleware.LogRoller - if c.NextBlock() { - if c.Val() == "rotate" { - if c.NextArg() { - if c.Val() == "{" { - var err error - logRoller, err = parseRoller(c) - if err != nil { - return nil, err - } - // This part doesn't allow having something after the rotate block - if c.Next() { - if c.Val() != "}" { - return nil, c.ArgErr() - } - } - } - } - } - } - if len(args) == 0 { - // Nothing specified; use defaults - rules = append(rules, corednslog.Rule{ - NameScope: ".", - OutputFile: corednslog.DefaultLogFilename, - Format: corednslog.DefaultLogFormat, - Roller: logRoller, - }) - } else if len(args) == 1 { - // Only an output file specified - rules = append(rules, corednslog.Rule{ - NameScope: ".", - OutputFile: args[0], - Format: corednslog.DefaultLogFormat, - Roller: logRoller, - }) - } else { - // Name scope, output file, and maybe a format specified - - format := corednslog.DefaultLogFormat - - if len(args) > 2 { - switch args[2] { - case "{common}": - format = corednslog.CommonLogFormat - case "{combined}": - format = corednslog.CombinedLogFormat - default: - format = args[2] - } - } - - rules = append(rules, corednslog.Rule{ - NameScope: dns.Fqdn(args[0]), - OutputFile: args[1], - Format: format, - Roller: logRoller, - }) - } - } - - return rules, nil -} diff --git a/core/setup/log_test.go b/core/setup/log_test.go deleted file mode 100644 index ad9cb7c3a..000000000 --- a/core/setup/log_test.go +++ /dev/null @@ -1,175 +0,0 @@ -package setup - -import ( - "testing" - - "github.com/miekg/coredns/middleware" - corednslog "github.com/miekg/coredns/middleware/log" -) - -func TestLog(t *testing.T) { - - c := NewTestController(`log`) - - mid, err := Log(c) - - if err != nil { - t.Errorf("Expected no errors, got: %v", err) - } - - if mid == nil { - t.Fatal("Expected middleware, was nil instead") - } - - handler := mid(EmptyNext) - myHandler, ok := handler.(corednslog.Logger) - - if !ok { - t.Fatalf("Expected handler to be type Logger, got: %#v", handler) - } - - if myHandler.Rules[0].NameScope != "." { - t.Errorf("Expected . as the default NameScope") - } - if myHandler.Rules[0].OutputFile != corednslog.DefaultLogFilename { - t.Errorf("Expected %s as the default OutputFile", corednslog.DefaultLogFilename) - } - if myHandler.Rules[0].Format != corednslog.DefaultLogFormat { - t.Errorf("Expected %s as the default Log Format", corednslog.DefaultLogFormat) - } - if myHandler.Rules[0].Roller != nil { - t.Errorf("Expected Roller to be nil, got: %v", *myHandler.Rules[0].Roller) - } - if !SameNext(myHandler.Next, EmptyNext) { - t.Error("'Next' field of handler was not set properly") - } - -} - -func TestLogParse(t *testing.T) { - tests := []struct { - inputLogRules string - shouldErr bool - expectedLogRules []corednslog.Rule - }{ - {`log`, false, []corednslog.Rule{{ - NameScope: ".", - OutputFile: corednslog.DefaultLogFilename, - Format: corednslog.DefaultLogFormat, - }}}, - {`log log.txt`, false, []corednslog.Rule{{ - NameScope: ".", - OutputFile: "log.txt", - Format: corednslog.DefaultLogFormat, - }}}, - {`log example.org log.txt`, false, []corednslog.Rule{{ - NameScope: "example.org.", - OutputFile: "log.txt", - Format: corednslog.DefaultLogFormat, - }}}, - {`log example.org. stdout`, false, []corednslog.Rule{{ - NameScope: "example.org.", - OutputFile: "stdout", - Format: corednslog.DefaultLogFormat, - }}}, - {`log example.org log.txt {common}`, false, []corednslog.Rule{{ - NameScope: "example.org.", - OutputFile: "log.txt", - Format: corednslog.CommonLogFormat, - }}}, - {`log example.org accesslog.txt {combined}`, false, []corednslog.Rule{{ - NameScope: "example.org.", - OutputFile: "accesslog.txt", - Format: corednslog.CombinedLogFormat, - }}}, - {`log example.org. log.txt - log example.net accesslog.txt {combined}`, false, []corednslog.Rule{{ - NameScope: "example.org.", - OutputFile: "log.txt", - Format: corednslog.DefaultLogFormat, - }, { - NameScope: "example.net.", - OutputFile: "accesslog.txt", - Format: corednslog.CombinedLogFormat, - }}}, - {`log example.org stdout {host} - log example.org log.txt {when}`, false, []corednslog.Rule{{ - NameScope: "example.org.", - OutputFile: "stdout", - Format: "{host}", - }, { - NameScope: "example.org.", - OutputFile: "log.txt", - Format: "{when}", - }}}, - {`log access.log { rotate { size 2 age 10 keep 3 } }`, false, []corednslog.Rule{{ - NameScope: ".", - OutputFile: "access.log", - Format: corednslog.DefaultLogFormat, - Roller: &middleware.LogRoller{ - MaxSize: 2, - MaxAge: 10, - MaxBackups: 3, - LocalTime: true, - }, - }}}, - } - for i, test := range tests { - c := NewTestController(test.inputLogRules) - actualLogRules, err := logParse(c) - - if err == nil && test.shouldErr { - t.Errorf("Test %d didn't error, but it should have", i) - } else if err != nil && !test.shouldErr { - t.Errorf("Test %d errored, but it shouldn't have; got '%v'", i, err) - } - if len(actualLogRules) != len(test.expectedLogRules) { - t.Fatalf("Test %d expected %d no of Log rules, but got %d ", - i, len(test.expectedLogRules), len(actualLogRules)) - } - for j, actualLogRule := range actualLogRules { - - if actualLogRule.NameScope != test.expectedLogRules[j].NameScope { - t.Errorf("Test %d expected %dth LogRule NameScope to be %s , but got %s", - i, j, test.expectedLogRules[j].NameScope, actualLogRule.NameScope) - } - - if actualLogRule.OutputFile != test.expectedLogRules[j].OutputFile { - t.Errorf("Test %d expected %dth LogRule OutputFile to be %s , but got %s", - i, j, test.expectedLogRules[j].OutputFile, actualLogRule.OutputFile) - } - - if actualLogRule.Format != test.expectedLogRules[j].Format { - t.Errorf("Test %d expected %dth LogRule Format to be %s , but got %s", - i, j, test.expectedLogRules[j].Format, actualLogRule.Format) - } - if actualLogRule.Roller != nil && test.expectedLogRules[j].Roller == nil || actualLogRule.Roller == nil && test.expectedLogRules[j].Roller != nil { - t.Fatalf("Test %d expected %dth LogRule Roller to be %v, but got %v", - i, j, test.expectedLogRules[j].Roller, actualLogRule.Roller) - } - if actualLogRule.Roller != nil && test.expectedLogRules[j].Roller != nil { - if actualLogRule.Roller.Filename != test.expectedLogRules[j].Roller.Filename { - t.Fatalf("Test %d expected %dth LogRule Roller Filename to be %s, but got %s", - i, j, test.expectedLogRules[j].Roller.Filename, actualLogRule.Roller.Filename) - } - if actualLogRule.Roller.MaxAge != test.expectedLogRules[j].Roller.MaxAge { - t.Fatalf("Test %d expected %dth LogRule Roller MaxAge to be %d, but got %d", - i, j, test.expectedLogRules[j].Roller.MaxAge, actualLogRule.Roller.MaxAge) - } - if actualLogRule.Roller.MaxBackups != test.expectedLogRules[j].Roller.MaxBackups { - t.Fatalf("Test %d expected %dth LogRule Roller MaxBackups to be %d, but got %d", - i, j, test.expectedLogRules[j].Roller.MaxBackups, actualLogRule.Roller.MaxBackups) - } - if actualLogRule.Roller.MaxSize != test.expectedLogRules[j].Roller.MaxSize { - t.Fatalf("Test %d expected %dth LogRule Roller MaxSize to be %d, but got %d", - i, j, test.expectedLogRules[j].Roller.MaxSize, actualLogRule.Roller.MaxSize) - } - if actualLogRule.Roller.LocalTime != test.expectedLogRules[j].Roller.LocalTime { - t.Fatalf("Test %d expected %dth LogRule Roller LocalTime to be %t, but got %t", - i, j, test.expectedLogRules[j].Roller.LocalTime, actualLogRule.Roller.LocalTime) - } - } - } - } - -} diff --git a/core/setup/metrics.go b/core/setup/metrics.go deleted file mode 100644 index e88d93c86..000000000 --- a/core/setup/metrics.go +++ /dev/null @@ -1,72 +0,0 @@ -package setup - -import ( - "sync" - - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/middleware/metrics" -) - -const addr = "localhost:9153" - -var metricsOnce sync.Once - -func Prometheus(c *Controller) (middleware.Middleware, error) { - m, err := parsePrometheus(c) - if err != nil { - return nil, err - } - - metricsOnce.Do(func() { - c.Startup = append(c.Startup, m.Start) - c.Shutdown = append(c.Shutdown, m.Shutdown) - }) - - return func(next middleware.Handler) middleware.Handler { - m.Next = next - return m - }, nil -} - -func parsePrometheus(c *Controller) (metrics.Metrics, error) { - var ( - met metrics.Metrics - err error - ) - - for c.Next() { - if len(met.ZoneNames) > 0 { - return metrics.Metrics{}, c.Err("metrics: can only have one metrics module per server") - } - met = metrics.Metrics{ZoneNames: c.ServerBlockHosts} - for i, _ := range met.ZoneNames { - met.ZoneNames[i] = middleware.Host(met.ZoneNames[i]).Normalize() - } - args := c.RemainingArgs() - - switch len(args) { - case 0: - case 1: - met.Addr = args[0] - default: - return metrics.Metrics{}, c.ArgErr() - } - for c.NextBlock() { - switch c.Val() { - case "address": - args = c.RemainingArgs() - if len(args) != 1 { - return metrics.Metrics{}, c.ArgErr() - } - met.Addr = args[0] - default: - return metrics.Metrics{}, c.Errf("metrics: unknown item: %s", c.Val()) - } - - } - } - if met.Addr == "" { - met.Addr = addr - } - return met, err -} diff --git a/core/setup/pprof.go b/core/setup/pprof.go deleted file mode 100644 index 125d2a9ef..000000000 --- a/core/setup/pprof.go +++ /dev/null @@ -1,33 +0,0 @@ -package setup - -import ( - "sync" - - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/middleware/pprof" -) - -var pprofOnce sync.Once - -// PProf returns a new instance of a pprof handler. It accepts no arguments or options. -func PProf(c *Controller) (middleware.Middleware, error) { - found := false - for c.Next() { - if found { - return nil, c.Err("pprof can only be specified once") - } - if len(c.RemainingArgs()) != 0 { - return nil, c.ArgErr() - } - if c.NextBlock() { - return nil, c.ArgErr() - } - found = true - } - handler := &pprof.Handler{} - pprofOnce.Do(func() { - c.Startup = append(c.Startup, handler.Start) - c.Shutdown = append(c.Shutdown, handler.Shutdown) - }) - return nil, nil -} diff --git a/core/setup/pprof_test.go b/core/setup/pprof_test.go deleted file mode 100644 index ac9375af7..000000000 --- a/core/setup/pprof_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package setup - -import "testing" - -func TestPProf(t *testing.T) { - tests := []struct { - input string - shouldErr bool - }{ - {`pprof`, false}, - {`pprof {}`, true}, - {`pprof /foo`, true}, - {`pprof { - a b - }`, true}, - {`pprof - pprof`, true}, - } - for i, test := range tests { - c := NewTestController(test.input) - _, err := PProf(c) - if test.shouldErr && err == nil { - t.Errorf("Test %v: Expected error but found nil", i) - } else if !test.shouldErr && err != nil { - t.Errorf("Test %v: Expected no error but found error: %v", i, err) - } - } -} diff --git a/core/setup/proxy.go b/core/setup/proxy.go deleted file mode 100644 index 6753d07ad..000000000 --- a/core/setup/proxy.go +++ /dev/null @@ -1,17 +0,0 @@ -package setup - -import ( - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/middleware/proxy" -) - -// Proxy configures a new Proxy middleware instance. -func Proxy(c *Controller) (middleware.Middleware, error) { - upstreams, err := proxy.NewStaticUpstreams(c.Dispenser) - if err != nil { - return nil, err - } - return func(next middleware.Handler) middleware.Handler { - return proxy.Proxy{Next: next, Client: proxy.Clients(), Upstreams: upstreams} - }, nil -} diff --git a/core/setup/rewrite.go b/core/setup/rewrite.go deleted file mode 100644 index 86bef2ca3..000000000 --- a/core/setup/rewrite.go +++ /dev/null @@ -1,109 +0,0 @@ -package setup - -import ( - "strconv" - "strings" - - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/middleware/rewrite" -) - -// Rewrite configures a new Rewrite middleware instance. -func Rewrite(c *Controller) (middleware.Middleware, error) { - rewrites, err := rewriteParse(c) - if err != nil { - return nil, err - } - - return func(next middleware.Handler) middleware.Handler { - return rewrite.Rewrite{ - Next: next, - Rules: rewrites, - } - }, nil -} - -func rewriteParse(c *Controller) ([]rewrite.Rule, error) { - var simpleRules []rewrite.Rule - var regexpRules []rewrite.Rule - - for c.Next() { - var rule rewrite.Rule - var err error - var base = "." - var pattern, to string - var status int - var ext []string - - args := c.RemainingArgs() - - var ifs []rewrite.If - - switch len(args) { - case 1: - base = args[0] - fallthrough - case 0: - for c.NextBlock() { - switch c.Val() { - case "r", "regexp": - if !c.NextArg() { - return nil, c.ArgErr() - } - pattern = c.Val() - case "to": - args1 := c.RemainingArgs() - if len(args1) == 0 { - return nil, c.ArgErr() - } - to = strings.Join(args1, " ") - case "ext": // TODO(miek): fix or remove - args1 := c.RemainingArgs() - if len(args1) == 0 { - return nil, c.ArgErr() - } - ext = args1 - case "if": - args1 := c.RemainingArgs() - if len(args1) != 3 { - return nil, c.ArgErr() - } - ifCond, err := rewrite.NewIf(args1[0], args1[1], args1[2]) - if err != nil { - return nil, err - } - ifs = append(ifs, ifCond) - case "status": // TODO(miek): fix or remove - if !c.NextArg() { - return nil, c.ArgErr() - } - status, _ = strconv.Atoi(c.Val()) - if status < 200 || (status > 299 && status < 400) || status > 499 { - return nil, c.Err("status must be 2xx or 4xx") - } - default: - return nil, c.ArgErr() - } - } - // ensure to or status is specified - if to == "" && status == 0 { - return nil, c.ArgErr() - } - // TODO(miek): complex rules - base, pattern, to, status, ext, ifs = base, pattern, to, status, ext, ifs - err = err - // if rule, err = rewrite.NewComplexRule(base, pattern, to, status, ext, ifs); err != nil { - // return nil, err - // } - regexpRules = append(regexpRules, rule) - - // the only unhandled case is 2 and above - default: - rule = rewrite.NewSimpleRule(args[0], strings.Join(args[1:], " ")) - simpleRules = append(simpleRules, rule) - } - } - - // put simple rules in front to avoid regexp computation for them - return append(simpleRules, regexpRules...), nil -} diff --git a/core/setup/rewrite_test.go b/core/setup/rewrite_test.go deleted file mode 100644 index 5345c4bf6..000000000 --- a/core/setup/rewrite_test.go +++ /dev/null @@ -1,234 +0,0 @@ -package setup - -/* -func TestRewrite(t *testing.T) { - c := NewTestController(`rewrite /from /to`) - - mid, err := Rewrite(c) - if err != nil { - t.Errorf("Expected no errors, but got: %v", err) - } - if mid == nil { - t.Fatal("Expected middleware, was nil instead") - } - - handler := mid(EmptyNext) - myHandler, ok := handler.(rewrite.Rewrite) - if !ok { - t.Fatalf("Expected handler to be type Rewrite, got: %#v", handler) - } - - if !SameNext(myHandler.Next, EmptyNext) { - t.Error("'Next' field of handler was not set properly") - } - - if len(myHandler.Rules) != 1 { - t.Errorf("Expected handler to have %d rule, has %d instead", 1, len(myHandler.Rules)) - } -} - -func TestRewriteParse(t *testing.T) { - simpleTests := []struct { - input string - shouldErr bool - expected []rewrite.Rule - }{ - {`rewrite /from /to`, false, []rewrite.Rule{ - rewrite.SimpleRule{From: "/from", To: "/to"}, - }}, - {`rewrite /from /to - rewrite a b`, false, []rewrite.Rule{ - rewrite.SimpleRule{From: "/from", To: "/to"}, - rewrite.SimpleRule{From: "a", To: "b"}, - }}, - {`rewrite a`, true, []rewrite.Rule{}}, - {`rewrite`, true, []rewrite.Rule{}}, - {`rewrite a b c`, false, []rewrite.Rule{ - rewrite.SimpleRule{From: "a", To: "b c"}, - }}, - } - - for i, test := range simpleTests { - c := NewTestController(test.input) - actual, err := rewriteParse(c) - - if err == nil && test.shouldErr { - t.Errorf("Test %d didn't error, but it should have", i) - } else if err != nil && !test.shouldErr { - t.Errorf("Test %d errored, but it shouldn't have; got '%v'", i, err) - } else if err != nil && test.shouldErr { - continue - } - - if len(actual) != len(test.expected) { - t.Fatalf("Test %d expected %d rules, but got %d", - i, len(test.expected), len(actual)) - } - - for j, e := range test.expected { - actualRule := actual[j].(rewrite.SimpleRule) - expectedRule := e.(rewrite.SimpleRule) - - if actualRule.From != expectedRule.From { - t.Errorf("Test %d, rule %d: Expected From=%s, got %s", - i, j, expectedRule.From, actualRule.From) - } - - if actualRule.To != expectedRule.To { - t.Errorf("Test %d, rule %d: Expected To=%s, got %s", - i, j, expectedRule.To, actualRule.To) - } - } - } - - regexpTests := []struct { - input string - shouldErr bool - expected []rewrite.Rule - }{ - {`rewrite { - r .* - to /to /index.php? - }`, false, []rewrite.Rule{ - &rewrite.ComplexRule{Base: "/", To: "/to /index.php?", Regexp: regexp.MustCompile(".*")}, - }}, - {`rewrite { - regexp .* - to /to - ext / html txt - }`, false, []rewrite.Rule{ - &rewrite.ComplexRule{Base: "/", To: "/to", Exts: []string{"/", "html", "txt"}, Regexp: regexp.MustCompile(".*")}, - }}, - {`rewrite /path { - r rr - to /dest - } - rewrite / { - regexp [a-z]+ - to /to /to2 - } - `, false, []rewrite.Rule{ - &rewrite.ComplexRule{Base: "/path", To: "/dest", Regexp: regexp.MustCompile("rr")}, - &rewrite.ComplexRule{Base: "/", To: "/to /to2", Regexp: regexp.MustCompile("[a-z]+")}, - }}, - {`rewrite { - r .* - }`, true, []rewrite.Rule{ - &rewrite.ComplexRule{}, - }}, - {`rewrite { - - }`, true, []rewrite.Rule{ - &rewrite.ComplexRule{}, - }}, - {`rewrite /`, true, []rewrite.Rule{ - &rewrite.ComplexRule{}, - }}, - {`rewrite { - to /to - if {path} is a - }`, false, []rewrite.Rule{ - &rewrite.ComplexRule{Base: "/", To: "/to", Ifs: []rewrite.If{{A: "{path}", Operator: "is", B: "a"}}}, - }}, - {`rewrite { - status 500 - }`, true, []rewrite.Rule{ - &rewrite.ComplexRule{}, - }}, - {`rewrite { - status 400 - }`, false, []rewrite.Rule{ - &rewrite.ComplexRule{Base: "/", Status: 400}, - }}, - {`rewrite { - to /to - status 400 - }`, false, []rewrite.Rule{ - &rewrite.ComplexRule{Base: "/", To: "/to", Status: 400}, - }}, - {`rewrite { - status 399 - }`, true, []rewrite.Rule{ - &rewrite.ComplexRule{}, - }}, - {`rewrite { - status 200 - }`, false, []rewrite.Rule{ - &rewrite.ComplexRule{Base: "/", Status: 200}, - }}, - {`rewrite { - to /to - status 200 - }`, false, []rewrite.Rule{ - &rewrite.ComplexRule{Base: "/", To: "/to", Status: 200}, - }}, - {`rewrite { - status 199 - }`, true, []rewrite.Rule{ - &rewrite.ComplexRule{}, - }}, - {`rewrite { - status 0 - }`, true, []rewrite.Rule{ - &rewrite.ComplexRule{}, - }}, - {`rewrite { - to /to - status 0 - }`, true, []rewrite.Rule{ - &rewrite.ComplexRule{}, - }}, - } - - for i, test := range regexpTests { - c := NewTestController(test.input) - actual, err := rewriteParse(c) - - if err == nil && test.shouldErr { - t.Errorf("Test %d didn't error, but it should have", i) - } else if err != nil && !test.shouldErr { - t.Errorf("Test %d errored, but it shouldn't have; got '%v'", i, err) - } else if err != nil && test.shouldErr { - continue - } - - if len(actual) != len(test.expected) { - t.Fatalf("Test %d expected %d rules, but got %d", - i, len(test.expected), len(actual)) - } - - for j, e := range test.expected { - actualRule := actual[j].(*rewrite.ComplexRule) - expectedRule := e.(*rewrite.ComplexRule) - - if actualRule.Base != expectedRule.Base { - t.Errorf("Test %d, rule %d: Expected Base=%s, got %s", - i, j, expectedRule.Base, actualRule.Base) - } - - if actualRule.To != expectedRule.To { - t.Errorf("Test %d, rule %d: Expected To=%s, got %s", - i, j, expectedRule.To, actualRule.To) - } - - if fmt.Sprint(actualRule.Exts) != fmt.Sprint(expectedRule.Exts) { - t.Errorf("Test %d, rule %d: Expected Ext=%v, got %v", - i, j, expectedRule.To, actualRule.To) - } - - if actualRule.Regexp != nil { - if actualRule.String() != expectedRule.String() { - t.Errorf("Test %d, rule %d: Expected Pattern=%s, got %s", - i, j, expectedRule.String(), actualRule.String()) - } - } - - if fmt.Sprint(actualRule.Ifs) != fmt.Sprint(expectedRule.Ifs) { - t.Errorf("Test %d, rule %d: Expected Pattern=%s, got %s", - i, j, fmt.Sprint(expectedRule.Ifs), fmt.Sprint(actualRule.Ifs)) - } - - } - } -} -*/ diff --git a/core/setup/roller.go b/core/setup/roller.go deleted file mode 100644 index fd772cc47..000000000 --- a/core/setup/roller.go +++ /dev/null @@ -1,40 +0,0 @@ -package setup - -import ( - "strconv" - - "github.com/miekg/coredns/middleware" -) - -func parseRoller(c *Controller) (*middleware.LogRoller, error) { - var size, age, keep int - // This is kind of a hack to support nested blocks: - // As we are already in a block: either log or errors, - // c.nesting > 0 but, as soon as c meets a }, it thinks - // the block is over and return false for c.NextBlock. - for c.NextBlock() { - what := c.Val() - if !c.NextArg() { - return nil, c.ArgErr() - } - value := c.Val() - var err error - switch what { - case "size": - size, err = strconv.Atoi(value) - case "age": - age, err = strconv.Atoi(value) - case "keep": - keep, err = strconv.Atoi(value) - } - if err != nil { - return nil, err - } - } - return &middleware.LogRoller{ - MaxSize: size, - MaxAge: age, - MaxBackups: keep, - LocalTime: true, - }, nil -} diff --git a/core/setup/root.go b/core/setup/root.go deleted file mode 100644 index 0fce5f170..000000000 --- a/core/setup/root.go +++ /dev/null @@ -1,32 +0,0 @@ -package setup - -import ( - "log" - "os" - - "github.com/miekg/coredns/middleware" -) - -// Root sets up the root file path of the server. -func Root(c *Controller) (middleware.Middleware, error) { - for c.Next() { - if !c.NextArg() { - return nil, c.ArgErr() - } - c.Root = c.Val() - } - - // Check if root path exists - _, err := os.Stat(c.Root) - if err != nil { - if os.IsNotExist(err) { - // Allow this, because the folder might appear later. - // But make sure the user knows! - log.Printf("[WARNING] Root path does not exist: %s", c.Root) - } else { - return nil, c.Errf("Unable to access root path '%s': %v", c.Root, err) - } - } - - return nil, nil -} diff --git a/core/setup/root_test.go b/core/setup/root_test.go deleted file mode 100644 index 8b38e6d04..000000000 --- a/core/setup/root_test.go +++ /dev/null @@ -1,108 +0,0 @@ -package setup - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strings" - "testing" -) - -func TestRoot(t *testing.T) { - - // Predefined error substrings - parseErrContent := "Parse error:" - unableToAccessErrContent := "Unable to access root path" - - existingDirPath, err := getTempDirPath() - if err != nil { - t.Fatalf("BeforeTest: Failed to find an existing directory for testing! Error was: %v", err) - } - - nonExistingDir := filepath.Join(existingDirPath, "highly_unlikely_to_exist_dir") - - existingFile, err := ioutil.TempFile("", "root_test") - if err != nil { - t.Fatalf("BeforeTest: Failed to create temp file for testing! Error was: %v", err) - } - defer func() { - existingFile.Close() - os.Remove(existingFile.Name()) - }() - - inaccessiblePath := getInaccessiblePath(existingFile.Name()) - - tests := []struct { - input string - shouldErr bool - expectedRoot string // expected root, set to the controller. Empty for negative cases. - expectedErrContent string // substring from the expected error. Empty for positive cases. - }{ - // positive - { - fmt.Sprintf(`root %s`, nonExistingDir), false, nonExistingDir, "", - }, - { - fmt.Sprintf(`root %s`, existingDirPath), false, existingDirPath, "", - }, - // negative - { - `root `, true, "", parseErrContent, - }, - { - fmt.Sprintf(`root %s`, inaccessiblePath), true, "", unableToAccessErrContent, - }, - { - fmt.Sprintf(`root { - %s - }`, existingDirPath), true, "", parseErrContent, - }, - } - - for i, test := range tests { - c := NewTestController(test.input) - mid, err := Root(c) - - if test.shouldErr && err == nil { - t.Errorf("Test %d: Expected error but found %s for input %s", i, err, test.input) - } - - if err != nil { - if !test.shouldErr { - t.Errorf("Test %d: Expected no error but found one for input %s. Error was: %v", i, test.input, err) - } - - if !strings.Contains(err.Error(), test.expectedErrContent) { - t.Errorf("Test %d: Expected error to contain: %v, found error: %v, input: %s", i, test.expectedErrContent, err, test.input) - } - } - - // the Root method always returns a nil middleware - if mid != nil { - t.Errorf("Middware, returned from Root() was not nil: %v", mid) - } - - // check c.Root only if we are in a positive test. - if !test.shouldErr && test.expectedRoot != c.Root { - t.Errorf("Root not correctly set for input %s. Expected: %s, actual: %s", test.input, test.expectedRoot, c.Root) - } - } -} - -// getTempDirPath returnes the path to the system temp directory. If it does not exists - an error is returned. -func getTempDirPath() (string, error) { - tempDir := os.TempDir() - - _, err := os.Stat(tempDir) - if err != nil { - return "", err - } - - return tempDir, nil -} - -func getInaccessiblePath(file string) string { - // null byte in filename is not allowed on Windows AND unix - return filepath.Join("C:", "file\x00name") -} diff --git a/core/setup/secondary.go b/core/setup/secondary.go deleted file mode 100644 index e1f54a651..000000000 --- a/core/setup/secondary.go +++ /dev/null @@ -1,71 +0,0 @@ -package setup - -import ( - "github.com/miekg/coredns/middleware" - "github.com/miekg/coredns/middleware/file" - "github.com/miekg/coredns/middleware/secondary" -) - -// Secondary sets up the secondary middleware. -func Secondary(c *Controller) (middleware.Middleware, error) { - zones, err := secondaryParse(c) - if err != nil { - return nil, err - } - - // Add startup functions to retrieve the zone and keep it up to date. - for _, n := range zones.Names { - if len(zones.Z[n].TransferFrom) > 0 { - c.Startup = append(c.Startup, func() error { - zones.Z[n].StartupOnce.Do(func() { - zones.Z[n].TransferIn() - go func() { - zones.Z[n].Update() - }() - }) - return nil - }) - } - } - - return func(next middleware.Handler) middleware.Handler { - return secondary.Secondary{file.File{Next: next, Zones: zones}} - }, nil - -} - -func secondaryParse(c *Controller) (file.Zones, error) { - z := make(map[string]*file.Zone) - names := []string{} - for c.Next() { - if c.Val() == "secondary" { - // secondary [origin] - origins := c.ServerBlockHosts - args := c.RemainingArgs() - if len(args) > 0 { - origins = args - } - for i, _ := range origins { - origins[i] = middleware.Host(origins[i]).Normalize() - z[origins[i]] = file.NewZone(origins[i], "stdin") - names = append(names, origins[i]) - } - - for c.NextBlock() { - t, f, e := transferParse(c) - if e != nil { - return file.Zones{}, e - } - for _, origin := range origins { - if t != nil { - z[origin].TransferTo = append(z[origin].TransferTo, t...) - } - if f != nil { - z[origin].TransferFrom = append(z[origin].TransferFrom, f...) - } - } - } - } - } - return file.Zones{Z: z, Names: names}, nil -} diff --git a/core/setup/startupshutdown.go b/core/setup/startupshutdown.go deleted file mode 100644 index 1cf2c62e0..000000000 --- a/core/setup/startupshutdown.go +++ /dev/null @@ -1,64 +0,0 @@ -package setup - -import ( - "os" - "os/exec" - "strings" - - "github.com/miekg/coredns/middleware" -) - -// Startup registers a startup callback to execute during server start. -func Startup(c *Controller) (middleware.Middleware, error) { - return nil, registerCallback(c, &c.FirstStartup) -} - -// Shutdown registers a shutdown callback to execute during process exit. -func Shutdown(c *Controller) (middleware.Middleware, error) { - return nil, registerCallback(c, &c.Shutdown) -} - -// registerCallback registers a callback function to execute by -// using c to parse the line. It appends the callback function -// to the list of callback functions passed in by reference. -func registerCallback(c *Controller, list *[]func() error) error { - var funcs []func() error - - for c.Next() { - args := c.RemainingArgs() - if len(args) == 0 { - return c.ArgErr() - } - - nonblock := false - if len(args) > 1 && args[len(args)-1] == "&" { - // Run command in background; non-blocking - nonblock = true - args = args[:len(args)-1] - } - - command, args, err := middleware.SplitCommandAndArgs(strings.Join(args, " ")) - if err != nil { - return c.Err(err.Error()) - } - - fn := func() error { - cmd := exec.Command(command, args...) - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - - if nonblock { - return cmd.Start() - } - return cmd.Run() - } - - funcs = append(funcs, fn) - } - - return c.OncePerServerBlock(func() error { - *list = append(*list, funcs...) - return nil - }) -} diff --git a/core/setup/startupshutdown_test.go b/core/setup/startupshutdown_test.go deleted file mode 100644 index 871a64214..000000000 --- a/core/setup/startupshutdown_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package setup - -import ( - "os" - "path/filepath" - "strconv" - "testing" - "time" -) - -// The Startup function's tests are symmetrical to Shutdown tests, -// because the Startup and Shutdown functions share virtually the -// same functionality -func TestStartup(t *testing.T) { - tempDirPath, err := getTempDirPath() - if err != nil { - t.Fatalf("BeforeTest: Failed to find an existing directory for testing! Error was: %v", err) - } - - testDir := filepath.Join(tempDirPath, "temp_dir_for_testing_startupshutdown") - defer func() { - // clean up after non-blocking startup function quits - time.Sleep(500 * time.Millisecond) - os.RemoveAll(testDir) - }() - osSenitiveTestDir := filepath.FromSlash(testDir) - os.RemoveAll(osSenitiveTestDir) // start with a clean slate - - tests := []struct { - input string - shouldExecutionErr bool - shouldRemoveErr bool - }{ - // test case #0 tests proper functionality blocking commands - {"startup mkdir " + osSenitiveTestDir, false, false}, - - // test case #1 tests proper functionality of non-blocking commands - {"startup mkdir " + osSenitiveTestDir + " &", false, true}, - - // test case #2 tests handling of non-existent commands - {"startup " + strconv.Itoa(int(time.Now().UnixNano())), true, true}, - } - - for i, test := range tests { - c := NewTestController(test.input) - _, err = Startup(c) - if err != nil { - t.Errorf("Expected no errors, got: %v", err) - } - err = c.FirstStartup[0]() - if err != nil && !test.shouldExecutionErr { - t.Errorf("Test %d recieved an error of:\n%v", i, err) - } - err = os.Remove(osSenitiveTestDir) - if err != nil && !test.shouldRemoveErr { - t.Errorf("Test %d recieved an error of:\n%v", i, err) - } - } -} diff --git a/core/setup/testdata/blog/first_post.md b/core/setup/testdata/blog/first_post.md deleted file mode 100644 index f26583b75..000000000 --- a/core/setup/testdata/blog/first_post.md +++ /dev/null @@ -1 +0,0 @@ -# Test h1 diff --git a/core/setup/testdata/header.html b/core/setup/testdata/header.html deleted file mode 100644 index 9c96e0e37..000000000 --- a/core/setup/testdata/header.html +++ /dev/null @@ -1 +0,0 @@ -<h1>Header title</h1> diff --git a/core/setup/testdata/tpl_with_include.html b/core/setup/testdata/tpl_with_include.html deleted file mode 100644 index 95eeae0c8..000000000 --- a/core/setup/testdata/tpl_with_include.html +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<title>{{.Doc.title}}</title> -</head> -<body> -{{.Include "header.html"}} -{{.Doc.body}} -</body> -</html> |