diff --git a/middleware/kubernetes/handler.go b/middleware/kubernetes/handler.go index 1e41e9ebf..871605ef9 100644 --- a/middleware/kubernetes/handler.go +++ b/middleware/kubernetes/handler.go @@ -21,8 +21,7 @@ func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M m := new(dns.Msg) m.SetReply(r) m.Authoritative, m.RecursionAvailable, m.Compress = true, true, true - // Check that query matches one of the zones served by this middleware, - // otherwise delegate to the next in the pipeline. + zone := middleware.Zones(k.Zones).Matches(state.Name()) if zone == "" { if k.Fallthrough { diff --git a/middleware/kubernetes/handler_test.go b/middleware/kubernetes/handler_test.go index a68401250..b00f5382e 100644 --- a/middleware/kubernetes/handler_test.go +++ b/middleware/kubernetes/handler_test.go @@ -1,7 +1,6 @@ package kubernetes import ( - "net" "sort" "testing" @@ -13,7 +12,7 @@ import ( "k8s.io/client-go/1.5/pkg/api" ) -var dnsTestCases = map[string](*test.Case){ +var dnsTestCases = map[string](test.Case){ "A Service": { Qname: "svc1.testns.svc.cluster.local.", Qtype: dns.TypeA, Rcode: dns.RcodeSuccess, @@ -84,7 +83,7 @@ var dnsTestCases = map[string](*test.Case){ }, } -var podModeDisabledCases = map[string](*test.Case){ +var podModeDisabledCases = map[string](test.Case){ "A Record Pod mode = Case 1": { Qname: "10-240-0-1.podns.pod.cluster.local.", Qtype: dns.TypeA, @@ -107,7 +106,7 @@ var podModeDisabledCases = map[string](*test.Case){ }, } -var podModeInsecureCases = map[string](*test.Case){ +var podModeInsecureCases = map[string](test.Case){ "A Record Pod mode = Case 1": { Qname: "10-240-0-1.podns.pod.cluster.local.", Qtype: dns.TypeA, @@ -126,7 +125,7 @@ var podModeInsecureCases = map[string](*test.Case){ }, } -var podModeVerifiedCases = map[string](*test.Case){ +var podModeVerifiedCases = map[string](test.Case){ "A Record Pod mode = Case 1": { Qname: "10-240-0-1.podns.pod.cluster.local.", Qtype: dns.TypeA, @@ -149,9 +148,7 @@ var podModeVerifiedCases = map[string](*test.Case){ func TestServeDNS(t *testing.T) { k := Kubernetes{Zones: []string{"cluster.local."}} - _, cidr, _ := net.ParseCIDR("10.0.0.0/8") - k.ReverseCidrs = []net.IPNet{*cidr} k.APIConn = &APIConnServeTest{} k.interfaceAddrsFunc = localPodIP k.Next = test.NextHandler(dns.RcodeSuccess, nil) @@ -170,7 +167,7 @@ func TestServeDNS(t *testing.T) { runServeDNSTests(ctx, t, podModeVerifiedCases, k) } -func runServeDNSTests(ctx context.Context, t *testing.T, dnsTestCases map[string](*test.Case), k Kubernetes) { +func runServeDNSTests(ctx context.Context, t *testing.T, dnsTestCases map[string](test.Case), k Kubernetes) { for testname, tc := range dnsTestCases { r := tc.Msg() @@ -208,21 +205,18 @@ func runServeDNSTests(ctx context.Context, t *testing.T, dnsTestCases map[string sort.Sort(test.RRSet(resp.Answer)) sort.Sort(test.RRSet(resp.Ns)) sort.Sort(test.RRSet(resp.Extra)) - sort.Sort(test.RRSet(tc.Answer)) - sort.Sort(test.RRSet(tc.Ns)) - sort.Sort(test.RRSet(tc.Extra)) - if !test.Header(t, *tc, resp) { + if !test.Header(t, tc, resp) { t.Logf("%v Received:\n %v\n", testname, resp) continue } - if !test.Section(t, *tc, test.Answer, resp.Answer) { + if !test.Section(t, tc, test.Answer, resp.Answer) { t.Logf("%v Received:\n %v\n", testname, resp) } - if !test.Section(t, *tc, test.Ns, resp.Ns) { + if !test.Section(t, tc, test.Ns, resp.Ns) { t.Logf("%v Received:\n %v\n", testname, resp) } - if !test.Section(t, *tc, test.Extra, resp.Extra) { + if !test.Section(t, tc, test.Extra, resp.Extra) { t.Logf("%v Received:\n %v\n", testname, resp) } } diff --git a/middleware/kubernetes/kubernetes.go b/middleware/kubernetes/kubernetes.go index fef8ee0b7..b9ea683ff 100644 --- a/middleware/kubernetes/kubernetes.go +++ b/middleware/kubernetes/kubernetes.go @@ -44,7 +44,6 @@ type Kubernetes struct { LabelSelector *unversionedapi.LabelSelector Selector *labels.Selector PodMode string - ReverseCidrs []net.IPNet Fallthrough bool primaryZoneIndex int @@ -297,7 +296,6 @@ func (k *Kubernetes) Records(name string, exact bool) ([]msg.Service, error) { // just this name. This is used when find matches when completing SRV lookups // for instance. func (k *Kubernetes) Entries(r recordRequest) ([]msg.Service, error) { - // Abort if the namespace does not contain a wildcard, and namespace is not published per CoreFile // Case where namespace contains a wildcard is handled in Get(...) method. if (!wildcard(r.namespace)) && (len(k.Namespaces) > 0) && (!dnsstrings.StringInSlice(r.namespace, k.Namespaces)) { diff --git a/middleware/kubernetes/reverse_test.go b/middleware/kubernetes/reverse_test.go new file mode 100644 index 000000000..4de3e0a96 --- /dev/null +++ b/middleware/kubernetes/reverse_test.go @@ -0,0 +1,140 @@ +package kubernetes + +import ( + "sort" + "testing" + + "github.com/coredns/coredns/middleware/pkg/dnsrecorder" + "github.com/coredns/coredns/middleware/test" + + "github.com/miekg/dns" + "golang.org/x/net/context" + "k8s.io/client-go/1.5/pkg/api" +) + +type APIConnReverseTest struct{} + +func (APIConnReverseTest) Run() { return } +func (APIConnReverseTest) Stop() error { return nil } +func (APIConnReverseTest) PodIndex(string) []interface{} { return nil } + +func (APIConnReverseTest) ServiceList() []*api.Service { + svcs := []*api.Service{ + { + ObjectMeta: api.ObjectMeta{ + Name: "svc1", + Namespace: "testns", + }, + Spec: api.ServiceSpec{ + ClusterIP: "192.168.1.100", + Ports: []api.ServicePort{{ + Name: "http", + Protocol: "tcp", + Port: 80, + }}, + }, + }, + } + return svcs +} + +func (APIConnReverseTest) EndpointsList() api.EndpointsList { + return api.EndpointsList{ + Items: []api.Endpoints{ + { + Subsets: []api.EndpointSubset{ + { + Addresses: []api.EndpointAddress{ + { + IP: "10.0.0.100", + Hostname: "ep1a", + }, + }, + Ports: []api.EndpointPort{ + { + Port: 80, + Protocol: "tcp", + Name: "http", + }, + }, + }, + }, + ObjectMeta: api.ObjectMeta{ + Name: "svc1", + Namespace: "testns", + }, + }, + }, + } +} + +func (APIConnReverseTest) GetNodeByName(name string) (api.Node, error) { + return api.Node{ + ObjectMeta: api.ObjectMeta{ + Name: "test.node.foo.bar", + }, + }, nil +} + +func TestReverse(t *testing.T) { + + k := Kubernetes{Zones: []string{"cluster.local.", "0.10.in-addr.arpa."}} + k.interfaceAddrsFunc = localPodIP + k.APIConn = &APIConnReverseTest{} + + tests := []test.Case{ + { + Qname: "100.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, + Rcode: dns.RcodeSuccess, + Answer: []dns.RR{ + test.PTR("100.0.0.10.in-addr.arpa. 303 IN PTR ep1a.svc1.testns.svc.cluster.local."), + }, + }, + { + Qname: "101.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, + Rcode: dns.RcodeSuccess, + Ns: []dns.RR{ + test.SOA("0.10.in-addr.arpa. 300 IN SOA ns.dns.0.10.in-addr.arpa. hostmaster.0.10.in-addr.arpa. 1502782828 7200 1800 86400 60"), + }, + }, + } + + ctx := context.TODO() + for i, tc := range tests { + r := tc.Msg() + + w := dnsrecorder.New(&test.ResponseWriter{}) + + _, err := k.ServeDNS(ctx, w, r) + if err != tc.Error { + t.Errorf("Test %d: expected no error, got %v", i, err) + return + } + if tc.Error != nil { + continue + } + + resp := w.Msg + if resp == nil { + t.Fatalf("Test %d: got nil message and no error for: %s %d", i, r.Question[0].Name, r.Question[0].Qtype) + } + + sort.Sort(test.RRSet(resp.Answer)) + sort.Sort(test.RRSet(resp.Ns)) + sort.Sort(test.RRSet(resp.Extra)) + + if !test.Header(t, tc, resp) { + t.Logf("Test %d, received: %v", i, resp) + continue + } + if !test.Section(t, tc, test.Answer, resp.Answer) { + t.Logf("Test %d, received: %v", i, resp) + } + if !test.Section(t, tc, test.Ns, resp.Ns) { + t.Logf("Test %d, received: %v", i, resp) + } + if !test.Section(t, tc, test.Extra, resp.Extra) { + t.Logf("Test %d, received: %v", i, resp) + } + } +}