From fb7fcff982dc4f93d571eb993e4aa5f20620e101 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Mon, 7 Nov 2016 19:15:21 +0000 Subject: [PATCH] middleware/file|auto: Notifies and AXFR (#399) Be more explicit in the logs when a notify fails. New notify error message looks like: 2016/11/07 18:21:42 [ERROR] Notify for zone "example.org." was not accepted by "8.8.8.8:53": rcode was "SERVFAIL" Correctly pick up secondaries When multiple secondary are specified make sure they are picked up. Fixes #393 #398 --- middleware/auto/setup.go | 6 +++-- middleware/auto/setup_test.go | 30 ++++++++++++++++------- middleware/file/notify.go | 9 ++++--- middleware/kubernetes/controller.go | 38 ++++++++++++++--------------- 4 files changed, 50 insertions(+), 33 deletions(-) diff --git a/middleware/auto/setup.go b/middleware/auto/setup.go index a5e11186a..7681ea957 100644 --- a/middleware/auto/setup.go +++ b/middleware/auto/setup.go @@ -127,7 +127,7 @@ func autoParse(c *caddy.Controller) (Auto, error) { a.loader.template = rewriteToExpand(c.Val()) } - // template + // duration if c.NextArg() { i, err := strconv.Atoi(c.Val()) if err != nil { @@ -147,7 +147,9 @@ func autoParse(c *caddy.Controller) (Auto, error) { if e != nil { return a, e } - a.loader.transferTo = t + if t != nil { + a.loader.transferTo = append(a.loader.transferTo, t...) + } } } diff --git a/middleware/auto/setup_test.go b/middleware/auto/setup_test.go index 15790ead6..f0368ff6e 100644 --- a/middleware/auto/setup_test.go +++ b/middleware/auto/setup_test.go @@ -13,45 +13,53 @@ func TestAutoParse(t *testing.T) { expectedDirectory string expectedTempl string expectedRe string - expectedTo string + expectedTo []string }{ { `auto example.org { directory /tmp transfer to 127.0.0.1 }`, - false, "/tmp", "${1}", `db\.(.*)`, "127.0.0.1:53", + false, "/tmp", "${1}", `db\.(.*)`, []string{"127.0.0.1:53"}, }, { `auto { directory /tmp }`, - false, "/tmp", "${1}", `db\.(.*)`, "", + false, "/tmp", "${1}", `db\.(.*)`, nil, }, { `auto { directory /tmp (.*) bliep }`, - false, "/tmp", "bliep", `(.*)`, "", + false, "/tmp", "bliep", `(.*)`, nil, + }, + { + `auto { + directory /tmp (.*) bliep + transfer to 127.0.0.1 + transfer to 127.0.0.2 + }`, + false, "/tmp", "bliep", `(.*)`, []string{"127.0.0.1:53", "127.0.0.2:53"}, }, // errors { `auto example.org { directory }`, - true, "", "${1}", `db\.(.*)`, "", + true, "", "${1}", `db\.(.*)`, nil, }, { `auto example.org { directory /tmp * {1} }`, - true, "", "${1}", ``, "", + true, "", "${1}", ``, nil, }, { `auto example.org { directory /tmp .* {1} }`, - true, "", "${1}", ``, "", + true, "", "${1}", ``, nil, }, } @@ -73,8 +81,12 @@ func TestAutoParse(t *testing.T) { if a.loader.re.String() != test.expectedRe { t.Fatalf("Test %d expected %v, got %v", i, test.expectedRe, a.loader.re) } - if test.expectedTo != "" && a.loader.transferTo[0] != test.expectedTo { - t.Fatalf("Test %d expected %v, got %v", i, test.expectedTo, a.loader.transferTo[0]) + if test.expectedTo != nil { + for j, got := range a.loader.transferTo { + if got != test.expectedTo[j] { + t.Fatalf("Test %d expected %v, got %v", i, test.expectedTo[j], got) + } + } } } } diff --git a/middleware/file/notify.go b/middleware/file/notify.go index 3c6095a3b..1d198ceec 100644 --- a/middleware/file/notify.go +++ b/middleware/file/notify.go @@ -5,6 +5,7 @@ import ( "log" "github.com/miekg/coredns/middleware" + "github.com/miekg/coredns/middleware/pkg/rcode" "github.com/miekg/coredns/request" "github.com/miekg/dns" @@ -49,21 +50,23 @@ func notify(zone string, to []string) error { if err := notifyAddr(c, m, t); err != nil { log.Printf("[ERROR] " + err.Error()) } else { - log.Printf("[INFO] Sent notify for zone %s to %s", zone, t) + log.Printf("[INFO] Sent notify for zone %q to %q", zone, t) } } return nil } func notifyAddr(c *dns.Client, m *dns.Msg, s string) error { + code := dns.RcodeSuccess for i := 0; i < 3; i++ { ret, _, err := c.Exchange(m, s) if err != nil { continue } - if ret.Rcode == dns.RcodeSuccess || ret.Rcode == dns.RcodeNotImplemented { + code = ret.Rcode + if code == dns.RcodeSuccess { return nil } } - return fmt.Errorf("Failed to send notify for zone '%s' to '%s'", m.Question[0].Name, s) + return fmt.Errorf("Notify for zone %q was not accepted by %q: rcode was %q", m.Question[0].Name, s, rcode.ToString(code)) } diff --git a/middleware/kubernetes/controller.go b/middleware/kubernetes/controller.go index edf97c31b..e387b17fd 100644 --- a/middleware/kubernetes/controller.go +++ b/middleware/kubernetes/controller.go @@ -97,28 +97,28 @@ func serviceListFunc(c *kubernetes.Clientset, ns string, s *labels.Selector) fun } } -func v1ToApiFilter(in watch.Event) (out watch.Event, keep bool) { +func v1ToAPIFilter(in watch.Event) (out watch.Event, keep bool) { if in.Type == watch.Error { return in, true } switch v1Obj := in.Object.(type) { - case *v1.Service: - var apiObj api.Service - err := v1.Convert_v1_Service_To_api_Service(v1Obj, &apiObj, nil) - if err != nil { - log.Printf("[ERROR] Could not convert v1.Service: %s", err) - return in, true - } - return watch.Event{Type: in.Type, Object: &apiObj}, true - case *v1.Namespace: - var apiObj api.Namespace - err := v1.Convert_v1_Namespace_To_api_Namespace(v1Obj, &apiObj, nil) - if err != nil { - log.Printf("[ERROR] Could not convert v1.Namespace: %s", err) - return in, true - } - return watch.Event{Type: in.Type, Object: &apiObj}, true + case *v1.Service: + var apiObj api.Service + err := v1.Convert_v1_Service_To_api_Service(v1Obj, &apiObj, nil) + if err != nil { + log.Printf("[ERROR] Could not convert v1.Service: %s", err) + return in, true + } + return watch.Event{Type: in.Type, Object: &apiObj}, true + case *v1.Namespace: + var apiObj api.Namespace + err := v1.Convert_v1_Namespace_To_api_Namespace(v1Obj, &apiObj, nil) + if err != nil { + log.Printf("[ERROR] Could not convert v1.Namespace: %s", err) + return in, true + } + return watch.Event{Type: in.Type, Object: &apiObj}, true } log.Printf("[WARN] Unhandled v1 type in event: %v", in) @@ -134,7 +134,7 @@ func serviceWatchFunc(c *kubernetes.Clientset, ns string, s *labels.Selector) fu if err != nil { return nil, err } - return watch.Filter(w, v1ToApiFilter), nil + return watch.Filter(w, v1ToAPIFilter), nil } } @@ -165,7 +165,7 @@ func namespaceWatchFunc(c *kubernetes.Clientset, s *labels.Selector) func(option if err != nil { return nil, err } - return watch.Filter(w, v1ToApiFilter), nil + return watch.Filter(w, v1ToAPIFilter), nil } }