aboutsummaryrefslogtreecommitdiff
path: root/plugin/kubernetes/xfr_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/kubernetes/xfr_test.go')
-rw-r--r--plugin/kubernetes/xfr_test.go255
1 files changed, 76 insertions, 179 deletions
diff --git a/plugin/kubernetes/xfr_test.go b/plugin/kubernetes/xfr_test.go
index 1ada4f7aa..b5f13ad6e 100644
--- a/plugin/kubernetes/xfr_test.go
+++ b/plugin/kubernetes/xfr_test.go
@@ -1,229 +1,126 @@
package kubernetes
import (
- "context"
"strings"
"testing"
- "github.com/coredns/coredns/plugin/kubernetes/object"
- "github.com/coredns/coredns/plugin/pkg/dnstest"
- "github.com/coredns/coredns/plugin/test"
-
"github.com/miekg/dns"
)
-func TestKubernetesXFR(t *testing.T) {
+func TestKubernetesAXFR(t *testing.T) {
k := New([]string{"cluster.local."})
k.APIConn = &APIConnServeTest{}
- k.TransferTo = []string{"10.240.0.1:53"}
k.Namespaces = map[string]struct{}{"testns": {}}
- ctx := context.TODO()
- w := dnstest.NewMultiRecorder(&test.ResponseWriter{})
dnsmsg := &dns.Msg{}
dnsmsg.SetAxfr(k.Zones[0])
- _, err := k.ServeDNS(ctx, w, dnsmsg)
+ ch, err := k.Transfer(k.Zones[0], 0)
if err != nil {
t.Error(err)
}
+ validateAXFR(t, ch)
+}
- if len(w.Msgs) == 0 {
- t.Logf("%+v\n", w)
- t.Fatal("Did not get back a zone response")
- }
-
- if len(w.Msgs[0].Answer) == 0 {
- t.Logf("%+v\n", w)
- t.Fatal("Did not get back an answer")
- }
-
- // Ensure xfr starts with SOA
- if w.Msgs[0].Answer[0].Header().Rrtype != dns.TypeSOA {
- t.Error("Invalid XFR, does not start with SOA record")
- }
-
- // Ensure xfr starts with SOA
- // Last message is empty, so we need to go back one further
- if w.Msgs[len(w.Msgs)-2].Answer[len(w.Msgs[len(w.Msgs)-2].Answer)-1].Header().Rrtype != dns.TypeSOA {
- t.Error("Invalid XFR, does not end with SOA record")
- }
-
- testRRs := []dns.RR{}
- for _, tc := range dnsTestCases {
- if tc.Rcode != dns.RcodeSuccess {
- continue
- }
-
- for _, ans := range tc.Answer {
- // Exclude wildcard searches
- if strings.Contains(ans.Header().Name, "*") {
- continue
- }
-
- // Exclude TXT records
- if ans.Header().Rrtype == dns.TypeTXT {
- continue
- }
- testRRs = append(testRRs, ans)
- }
- }
-
- gotRRs := []dns.RR{}
- for _, resp := range w.Msgs {
- for _, ans := range resp.Answer {
- // Skip SOA records since these
- // test cases do not exist
- if ans.Header().Rrtype == dns.TypeSOA {
- continue
- }
-
- gotRRs = append(gotRRs, ans)
- }
-
- }
+func TestKubernetesIXFRFallback(t *testing.T) {
+ k := New([]string{"cluster.local."})
+ k.APIConn = &APIConnServeTest{}
+ k.Namespaces = map[string]struct{}{"testns": {}}
- diff := difference(testRRs, gotRRs)
- if len(diff) != 0 {
- t.Errorf("Got back %d records that do not exist in test cases, should be 0:", len(diff))
- for _, rec := range diff {
- t.Errorf("%+v", rec)
- }
- }
+ dnsmsg := &dns.Msg{}
+ dnsmsg.SetAxfr(k.Zones[0])
- diff = difference(gotRRs, testRRs)
- if len(diff) != 0 {
- t.Errorf("Found %d records we're missing, should be 0:", len(diff))
- for _, rec := range diff {
- t.Errorf("%+v", rec)
- }
+ ch, err := k.Transfer(k.Zones[0], 1)
+ if err != nil {
+ t.Error(err)
}
+ validateAXFR(t, ch)
}
-func TestKubernetesXFRNotAllowed(t *testing.T) {
+func TestKubernetesIXFRCurrent(t *testing.T) {
k := New([]string{"cluster.local."})
k.APIConn = &APIConnServeTest{}
- k.TransferTo = []string{"1.2.3.4:53"}
k.Namespaces = map[string]struct{}{"testns": {}}
- ctx := context.TODO()
- w := dnstest.NewMultiRecorder(&test.ResponseWriter{})
dnsmsg := &dns.Msg{}
dnsmsg.SetAxfr(k.Zones[0])
- _, err := k.ServeDNS(ctx, w, dnsmsg)
+ ch, err := k.Transfer(k.Zones[0], 3)
if err != nil {
t.Error(err)
}
- if len(w.Msgs) == 0 {
- t.Logf("%+v\n", w)
- t.Fatal("Did not get back a zone response")
+ var gotRRs []dns.RR
+ for rrs := range ch {
+ gotRRs = append(gotRRs, rrs...)
}
- if len(w.Msgs[0].Answer) != 0 {
- t.Logf("%+v\n", w)
- t.Fatal("Got an answer, should not have")
+ // ensure only one record is returned
+ if len(gotRRs) > 1 {
+ t.Errorf("Expected only one answer, got %d", len(gotRRs))
}
-}
-// difference shows what we're missing when comparing two RR slices
-func difference(testRRs []dns.RR, gotRRs []dns.RR) []dns.RR {
- expectedRRs := map[string]struct{}{}
- for _, rr := range testRRs {
- expectedRRs[rr.String()] = struct{}{}
+ // Ensure first record is a SOA
+ if gotRRs[0].Header().Rrtype != dns.TypeSOA {
+ t.Error("Invalid transfer response, does not start with SOA record")
}
-
- foundRRs := []dns.RR{}
- for _, rr := range gotRRs {
- if _, ok := expectedRRs[rr.String()]; !ok {
- foundRRs = append(foundRRs, rr)
- }
- }
- return foundRRs
}
-func TestEndpointsEquivalent(t *testing.T) {
- epA := object.Endpoints{
- Subsets: []object.EndpointSubset{{
- Addresses: []object.EndpointAddress{{IP: "1.2.3.4", Hostname: "foo"}},
- }},
- }
- epB := object.Endpoints{
- Subsets: []object.EndpointSubset{{
- Addresses: []object.EndpointAddress{{IP: "1.2.3.4", Hostname: "foo"}},
- }},
+func validateAXFR(t *testing.T, ch <-chan []dns.RR) {
+ xfr := []dns.RR{}
+ for rrs := range ch {
+ xfr = append(xfr, rrs...)
}
- epC := object.Endpoints{
- Subsets: []object.EndpointSubset{{
- Addresses: []object.EndpointAddress{{IP: "1.2.3.5", Hostname: "foo"}},
- }},
- }
- epD := object.Endpoints{
- Subsets: []object.EndpointSubset{{
- Addresses: []object.EndpointAddress{{IP: "1.2.3.5", Hostname: "foo"}},
- },
- {
- Addresses: []object.EndpointAddress{{IP: "1.2.2.2", Hostname: "foofoo"}},
- }},
- }
- epE := object.Endpoints{
- Subsets: []object.EndpointSubset{{
- Addresses: []object.EndpointAddress{{IP: "1.2.3.5", Hostname: "foo"}, {IP: "1.1.1.1"}},
- }},
- }
- epF := object.Endpoints{
- Subsets: []object.EndpointSubset{{
- Addresses: []object.EndpointAddress{{IP: "1.2.3.4", Hostname: "foofoo"}},
- }},
- }
- epG := object.Endpoints{
- Subsets: []object.EndpointSubset{{
- Addresses: []object.EndpointAddress{{IP: "1.2.3.4", Hostname: "foo"}},
- Ports: []object.EndpointPort{{Name: "http", Port: 80, Protocol: "TCP"}},
- }},
- }
- epH := object.Endpoints{
- Subsets: []object.EndpointSubset{{
- Addresses: []object.EndpointAddress{{IP: "1.2.3.4", Hostname: "foo"}},
- Ports: []object.EndpointPort{{Name: "newportname", Port: 80, Protocol: "TCP"}},
- }},
- }
- epI := object.Endpoints{
- Subsets: []object.EndpointSubset{{
- Addresses: []object.EndpointAddress{{IP: "1.2.3.4", Hostname: "foo"}},
- Ports: []object.EndpointPort{{Name: "http", Port: 8080, Protocol: "TCP"}},
- }},
- }
- epJ := object.Endpoints{
- Subsets: []object.EndpointSubset{{
- Addresses: []object.EndpointAddress{{IP: "1.2.3.4", Hostname: "foo"}},
- Ports: []object.EndpointPort{{Name: "http", Port: 80, Protocol: "UDP"}},
- }},
+ if xfr[0].Header().Rrtype != dns.TypeSOA {
+ t.Error("Invalid transfer response, does not start with SOA record")
}
- tests := []struct {
- equiv bool
- a *object.Endpoints
- b *object.Endpoints
- }{
- {true, &epA, &epB},
- {false, &epA, &epC},
- {false, &epA, &epD},
- {false, &epA, &epE},
- {false, &epA, &epF},
- {false, &epF, &epG},
- {false, &epG, &epH},
- {false, &epG, &epI},
- {false, &epG, &epJ},
+ zp := dns.NewZoneParser(strings.NewReader(expectedZone), "", "")
+ i := 0
+ for rr, ok := zp.Next(); ok; rr, ok = zp.Next() {
+ if !dns.IsDuplicate(rr, xfr[i]) {
+ t.Fatalf("Record %d, expected\n%v\n, got\n%v", i, rr, xfr[i])
+ }
+ i++
}
- for i, tc := range tests {
- if tc.equiv && !endpointsEquivalent(tc.a, tc.b) {
- t.Errorf("Test %d: expected endpoints to be equivalent and they are not.", i)
- }
- if !tc.equiv && endpointsEquivalent(tc.a, tc.b) {
- t.Errorf("Test %d: expected endpoints to be seen as different but they were not.", i)
- }
+ if err := zp.Err(); err != nil {
+ t.Fatal(err)
}
}
+
+const expectedZone = `
+cluster.local. 5 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 3 7200 1800 86400 5
+external.testns.svc.cluster.local. 5 IN CNAME ext.interwebs.test.
+external-to-service.testns.svc.cluster.local. 5 IN CNAME svc1.testns.svc.cluster.local.
+hdls1.testns.svc.cluster.local. 5 IN A 172.0.0.2
+172-0-0-2.hdls1.testns.svc.cluster.local. 5 IN A 172.0.0.2
+_http._tcp.hdls1.testns.svc.cluster.local. 5 IN SRV 0 16 80 172-0-0-2.hdls1.testns.svc.cluster.local.
+hdls1.testns.svc.cluster.local. 5 IN A 172.0.0.3
+172-0-0-3.hdls1.testns.svc.cluster.local. 5 IN A 172.0.0.3
+_http._tcp.hdls1.testns.svc.cluster.local. 5 IN SRV 0 16 80 172-0-0-3.hdls1.testns.svc.cluster.local.
+hdls1.testns.svc.cluster.local. 5 IN A 172.0.0.4
+dup-name.hdls1.testns.svc.cluster.local. 5 IN A 172.0.0.4
+_http._tcp.hdls1.testns.svc.cluster.local. 5 IN SRV 0 16 80 dup-name.hdls1.testns.svc.cluster.local.
+hdls1.testns.svc.cluster.local. 5 IN A 172.0.0.5
+dup-name.hdls1.testns.svc.cluster.local. 5 IN A 172.0.0.5
+_http._tcp.hdls1.testns.svc.cluster.local. 5 IN SRV 0 16 80 dup-name.hdls1.testns.svc.cluster.local.
+hdls1.testns.svc.cluster.local. 5 IN AAAA 5678:abcd::1
+5678-abcd--1.hdls1.testns.svc.cluster.local. 5 IN AAAA 5678:abcd::1
+_http._tcp.hdls1.testns.svc.cluster.local. 5 IN SRV 0 16 80 5678-abcd--1.hdls1.testns.svc.cluster.local.
+hdls1.testns.svc.cluster.local. 5 IN AAAA 5678:abcd::2
+5678-abcd--2.hdls1.testns.svc.cluster.local. 5 IN AAAA 5678:abcd::2
+_http._tcp.hdls1.testns.svc.cluster.local. 5 IN SRV 0 16 80 5678-abcd--2.hdls1.testns.svc.cluster.local.
+hdlsprtls.testns.svc.cluster.local. 5 IN A 172.0.0.20
+172-0-0-20.hdlsprtls.testns.svc.cluster.local. 5 IN A 172.0.0.20
+svc1.testns.svc.cluster.local. 5 IN A 10.0.0.1
+svc1.testns.svc.cluster.local. 5 IN SRV 0 100 80 svc1.testns.svc.cluster.local.
+_http._tcp.svc1.testns.svc.cluster.local. 5 IN SRV 0 100 80 svc1.testns.svc.cluster.local.
+svc6.testns.svc.cluster.local. 5 IN AAAA 1234:abcd::1
+svc6.testns.svc.cluster.local. 5 IN SRV 0 100 80 svc6.testns.svc.cluster.local.
+_http._tcp.svc6.testns.svc.cluster.local. 5 IN SRV 0 100 80 svc6.testns.svc.cluster.local.
+svcempty.testns.svc.cluster.local. 5 IN A 10.0.0.1
+svcempty.testns.svc.cluster.local. 5 IN SRV 0 100 80 svcempty.testns.svc.cluster.local.
+_http._tcp.svcempty.testns.svc.cluster.local. 5 IN SRV 0 100 80 svcempty.testns.svc.cluster.local.
+cluster.local. 5 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 3 7200 1800 86400 5
+`