aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml3
-rw-r--r--middleware/kubernetes/handler_test.go15
-rw-r--r--middleware/test/helpers.go19
-rw-r--r--test/kubernetes_test.go570
4 files changed, 506 insertions, 101 deletions
diff --git a/.travis.yml b/.travis.yml
index c55b23ab9..60410e045 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -25,7 +25,7 @@ env:
# IPv6 is needed by some of the CoreDNS test cases. The VM environment
# is needed to have access to sudo in the test environment. Sudo is
# needed to have docker in the test environment. Docker is needed to
-# launch a kubernetes instance in the test environment.
+# launch a Kubernetes instance in the test environment.
# (Dependencies are fun! :) )
before_install:
- cat /proc/net/if_inet6
@@ -51,5 +51,6 @@ before_script:
script:
- make TEST_TYPE=$TEST_TYPE travis
+
after_success:
- bash <(curl -s https://codecov.io/bash)
diff --git a/middleware/kubernetes/handler_test.go b/middleware/kubernetes/handler_test.go
index 292ffdf3a..d5345215d 100644
--- a/middleware/kubernetes/handler_test.go
+++ b/middleware/kubernetes/handler_test.go
@@ -235,19 +235,8 @@ func runServeDNSTests(ctx context.Context, t *testing.T, dnsTestCases map[string
}
// Before sorting, make sure that CNAMES do not appear after their target records
- for i, c := range resp.Answer {
- if c.Header().Rrtype != dns.TypeCNAME {
- continue
- }
- for _, a := range resp.Answer[:i] {
- if a.Header().Name != c.(*dns.CNAME).Target {
- continue
- }
- t.Errorf("%v: CNAME found after target record\n", testname)
- t.Logf("%v Received:\n %v\n", testname, resp)
-
- }
- }
+ test.CNAMEOrder(t, resp)
+
test.SortAndCheck(t, resp, tc)
}
}
diff --git a/middleware/test/helpers.go b/middleware/test/helpers.go
index 2074f46c2..35316dd38 100644
--- a/middleware/test/helpers.go
+++ b/middleware/test/helpers.go
@@ -13,7 +13,7 @@ type sect int
const (
// Answer is the answer section in an Msg.
Answer sect = iota
- // Ns is the authrotitative section in an Msg.
+ // Ns is the authoritative section in an Msg.
Ns
// Extra is the additional section in an Msg.
Extra
@@ -264,6 +264,23 @@ func Section(t *testing.T, tc Case, sec sect, rr []dns.RR) bool {
return true
}
+// CNAMEOrder makes sure that CNAMES do not appear after their target records
+func CNAMEOrder(t *testing.T, res *dns.Msg) {
+ for i, c := range res.Answer {
+ if c.Header().Rrtype != dns.TypeCNAME {
+ continue
+ }
+ for _, a := range res.Answer[:i] {
+ if a.Header().Name != c.(*dns.CNAME).Target {
+ continue
+ }
+ t.Errorf("CNAME found after target record\n")
+ t.Logf("%v\n", res)
+
+ }
+ }
+}
+
// SortAndCheck sorts resp and the checks the header and three sections against the testcase in tc.
func SortAndCheck(t *testing.T, resp *dns.Msg, tc Case) {
sort.Sort(RRSet(resp.Answer))
diff --git a/test/kubernetes_test.go b/test/kubernetes_test.go
index 881394c00..2e7207da2 100644
--- a/test/kubernetes_test.go
+++ b/test/kubernetes_test.go
@@ -6,6 +6,10 @@ import (
"io/ioutil"
"log"
"os"
+ "os/exec"
+ "sort"
+ "strconv"
+ "strings"
"testing"
"time"
@@ -20,7 +24,6 @@ func init() {
}
// Test data
-// TODO: Fix the actual RR values
var dnsTestCases = []test.Case{
{
@@ -34,197 +37,241 @@ var dnsTestCases = []test.Case{
Qname: "bogusservice.test-1.svc.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeNameError,
Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502313310 7200 1800 86400 60"),
+ },
},
{
Qname: "bogusendpoint.svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeNameError,
Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502313310 7200 1800 86400 60"),
+ },
},
{
Qname: "bogusendpoint.headless-svc.test-1.svc.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeNameError,
Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502313310 7200 1800 86400 60"),
+ },
},
{
Qname: "svc-1-a.*.svc.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeSuccess,
Answer: []dns.RR{
- test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
+ test.A("svc-1-a.*.svc.cluster.local. 303 IN A 10.0.0.100"),
},
},
{
Qname: "svc-1-a.any.svc.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeSuccess,
Answer: []dns.RR{
- test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
+ test.A("svc-1-a.any.svc.cluster.local. 303 IN A 10.0.0.100"),
},
},
{
Qname: "bogusservice.*.svc.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeNameError,
Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502313310 7200 1800 86400 60"),
+ },
},
{
Qname: "bogusservice.any.svc.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeNameError,
Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502313310 7200 1800 86400 60"),
+ },
},
{
Qname: "*.test-1.svc.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeSuccess,
- Answer: []dns.RR{
- test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
- test.A("svc-1-b.test-1.svc.cluster.local. 303 IN A 10.0.0.110"),
- test.A("svc-c.test-1.svc.cluster.local. 303 IN A 10.0.0.115"),
- test.A("headless-svc.test-1.svc.cluster.local. 303 IN A 172.17.0.5"),
- test.A("headless-svc.test-1.svc.cluster.local. 303 IN A 172.17.0.6"),
- test.CNAME("ext-svc.test-1.svc.cluster.local. 0 IN CNAME example.net."),
- test.A("example.net. 68974 IN A 13.14.15.16"),
- },
+ Answer: append([]dns.RR{
+ test.A("*.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
+ test.A("*.test-1.svc.cluster.local. 303 IN A 10.0.0.110"),
+ test.A("*.test-1.svc.cluster.local. 303 IN A 10.0.0.115"),
+ test.CNAME("*.test-1.svc.cluster.local. 303 IN CNAME example.net."),
+ test.A("example.net. 303 IN A 13.14.15.16"),
+ }, headlessAResponse("*.test-1.svc.cluster.local.", "headless-svc", "test-1")...),
},
{
Qname: "any.test-1.svc.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeSuccess,
- Answer: []dns.RR{
- test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
- test.A("svc-1-b.test-1.svc.cluster.local. 303 IN A 10.0.0.110"),
- test.A("svc-c.test-1.svc.cluster.local. 303 IN A 10.0.0.115"),
- test.A("headless-svc.test-1.svc.cluster.local. 303 IN A 172.17.0.5"),
- test.A("headless-svc.test-1.svc.cluster.local. 303 IN A 172.17.0.6"),
- test.CNAME("ext-svc.test-1.svc.cluster.local. 0 IN CNAME example.net."),
- test.A("example.net. 68974 IN A 13.14.15.16"),
- },
+ Answer: append([]dns.RR{
+ test.A("any.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
+ test.A("any.test-1.svc.cluster.local. 303 IN A 10.0.0.110"),
+ test.A("any.test-1.svc.cluster.local. 303 IN A 10.0.0.115"),
+ test.CNAME("any.test-1.svc.cluster.local. 303 IN CNAME example.net."),
+ test.A("example.net. 303 IN A 13.14.15.16"),
+ }, headlessAResponse("any.test-1.svc.cluster.local.", "headless-svc", "test-1")...),
},
{
Qname: "any.test-2.svc.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeNameError,
Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502313310 7200 1800 86400 60"),
+ },
},
{
Qname: "*.test-2.svc.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeNameError,
Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502313310 7200 1800 86400 60"),
+ },
},
{
Qname: "*.*.svc.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeSuccess,
- Answer: []dns.RR{
- test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
- test.A("svc-1-b.test-1.svc.cluster.local. 303 IN A 10.0.0.110"),
- test.A("svc-c.test-1.svc.cluster.local. 303 IN A 10.0.0.115"),
- test.A("headless-svc.test-1.svc.cluster.local. 303 IN A 172.17.0.5"),
- test.A("headless-svc.test-1.svc.cluster.local. 303 IN A 172.17.0.6"),
- test.CNAME("ext-svc.test-1.svc.cluster.local. 0 IN CNAME example.net."),
- test.A("example.net. 68974 IN A 13.14.15.16"),
- },
+ Answer: append([]dns.RR{
+ test.A("*.*.svc.cluster.local. 303 IN A 10.0.0.100"),
+ test.A("*.*.svc.cluster.local. 303 IN A 10.0.0.110"),
+ test.A("*.*.svc.cluster.local. 303 IN A 10.0.0.115"),
+ test.CNAME("*.*.svc.cluster.local. 303 IN CNAME example.net."),
+ test.A("example.net. 303 IN A 13.14.15.16"),
+ }, headlessAResponse("*.*.svc.cluster.local.", "headless-svc", "test-1")...),
},
{
Qname: "headless-svc.test-1.svc.cluster.local.", Qtype: dns.TypeA,
- Rcode: dns.RcodeSuccess,
- Answer: []dns.RR{
- test.A("headless-svc.test-1.svc.cluster.local. 303 IN A 172.17.0.5"),
- test.A("headless-svc.test-1.svc.cluster.local. 303 IN A 172.17.0.6"),
- },
+ Rcode: dns.RcodeSuccess,
+ Answer: headlessAResponse("headless-svc.test-1.svc.cluster.local.", "headless-svc", "test-1"),
},
{
Qname: "*._TcP.svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeSRV,
Rcode: dns.RcodeSuccess,
Answer: []dns.RR{
- test.SRV("_http._tcp.svc-1-a.test-1.svc.cluster.local. 303 IN SRV 10 100 80 svc-1-a.test-1.svc.cluster.local."),
- test.SRV("_https._tcp.svc-1-a.test-1.svc.cluster.local. 303 IN SRV 10 100 443 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("*._TcP.svc-1-a.test-1.svc.cluster.local. 303 IN SRV 0 50 443 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("*._TcP.svc-1-a.test-1.svc.cluster.local. 303 IN SRV 0 50 80 svc-1-a.test-1.svc.cluster.local."),
+ },
+ Extra: []dns.RR{
+ test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
},
},
{
Qname: "*.*.bogusservice.test-1.svc.cluster.local.", Qtype: dns.TypeSRV,
Rcode: dns.RcodeNameError,
Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502313310 7200 1800 86400 60"),
+ },
},
{
Qname: "*.any.svc-1-a.*.svc.cluster.local.", Qtype: dns.TypeSRV,
Rcode: dns.RcodeSuccess,
Answer: []dns.RR{
- test.SRV("_http._tcp.svc-1-a.test-1.svc.cluster.local. 303 IN SRV 10 100 80 svc-1-a.test-1.svc.cluster.local."),
- test.SRV("_https._tcp.svc-1-a.test-1.svc.cluster.local. 303 IN SRV 10 100 443 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("*.any.svc-1-a.*.svc.cluster.local. 303 IN SRV 0 50 443 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("*.any.svc-1-a.*.svc.cluster.local. 303 IN SRV 0 50 80 svc-1-a.test-1.svc.cluster.local."),
+ },
+ Extra: []dns.RR{
+ test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
},
},
{
Qname: "ANY.*.svc-1-a.any.svc.cluster.local.", Qtype: dns.TypeSRV,
Rcode: dns.RcodeSuccess,
Answer: []dns.RR{
- test.SRV("_http._tcp.svc-1-a.test-1.svc.cluster.local. 303 IN SRV 10 100 80 svc-1-a.test-1.svc.cluster.local."),
- test.SRV("_https._tcp.svc-1-a.test-1.svc.cluster.local. 303 IN SRV 10 100 443 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("ANY.*.svc-1-a.any.svc.cluster.local. 303 IN SRV 0 50 443 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("ANY.*.svc-1-a.any.svc.cluster.local. 303 IN SRV 0 50 80 svc-1-a.test-1.svc.cluster.local."),
+ },
+ Extra: []dns.RR{
+ test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
},
},
{
Qname: "*.*.bogusservice.*.svc.cluster.local.", Qtype: dns.TypeSRV,
Rcode: dns.RcodeNameError,
Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502313310 7200 1800 86400 60"),
+ },
},
{
Qname: "*.*.bogusservice.any.svc.cluster.local.", Qtype: dns.TypeSRV,
Rcode: dns.RcodeNameError,
Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502313310 7200 1800 86400 60"),
+ },
},
{
Qname: "_c-port._UDP.*.test-1.svc.cluster.local.", Qtype: dns.TypeSRV,
Rcode: dns.RcodeSuccess,
- Answer: []dns.RR{
- test.SRV("_c-port._udp.svc-c.test-1.svc.cluster.local. 303 IN SRV 10 100 1234 svc-c.test-1.svc.cluster.local."),
- test.SRV("_c-port._udp.headless-svc.test-1.svc.cluster.local. 303 IN SRV 10 100 1234 172-17-0-5.headless-svc.test-1.svc.cluster.local."),
- test.SRV("_c-port._udp.headless-svc.test-1.svc.cluster.local. 303 IN SRV 10 100 1234 172-17-0-6.headless-svc.test-1.svc.cluster.local."),
- },
+ Answer: append(srvResponse("_c-port._UDP.*.test-1.svc.cluster.local.", "TypeSRV", "headless-svc", "test-1"),
+ []dns.RR{
+ test.SRV("_c-port._UDP.*.test-1.svc.cluster.local. 303 IN SRV 0 33 1234 svc-c.test-1.svc.cluster.local.")}...),
+ Extra: append(srvResponse("_c-port._UDP.*.test-1.svc.cluster.local.", "TypeA", "headless-svc", "test-1"),
+ []dns.RR{
+ test.A("svc-c.test-1.svc.cluster.local. 303 IN A 10.0.0.115")}...),
},
{
Qname: "*._tcp.any.test-1.svc.cluster.local.", Qtype: dns.TypeSRV,
Rcode: dns.RcodeSuccess,
Answer: []dns.RR{
- test.SRV("_http._tcp.svc-1-a.test-1.svc.cluster.local. 303 IN SRV 10 100 80 svc-1-a.test-1.svc.cluster.local."),
- test.SRV("_https._tcp.svc-1-a.test-1.svc.cluster.local. 303 IN SRV 10 100 443 svc-1-a.test-1.svc.cluster.local."),
- test.SRV("_http._tcp.svc-1-b.test-1.svc.cluster.local. 303 IN SRV 10 100 80 svc-1-b.test-1.svc.cluster.local."),
+ test.SRV("*._tcp.any.test-1.svc.cluster.local. 303 IN SRV 0 33 443 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("*._tcp.any.test-1.svc.cluster.local. 303 IN SRV 0 33 80 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("*._tcp.any.test-1.svc.cluster.local. 303 IN SRV 0 33 80 svc-1-b.test-1.svc.cluster.local."),
+ },
+ Extra: []dns.RR{
+ test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
+ test.A("svc-1-b.test-1.svc.cluster.local. 303 IN A 10.0.0.110"),
},
},
{
Qname: "*.*.any.test-2.svc.cluster.local.", Qtype: dns.TypeSRV,
Rcode: dns.RcodeNameError,
Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502313310 7200 1800 86400 60"),
+ },
},
{
Qname: "*.*.*.test-2.svc.cluster.local.", Qtype: dns.TypeSRV,
Rcode: dns.RcodeNameError,
Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502313310 7200 1800 86400 60"),
+ },
},
{
Qname: "_http._tcp.*.*.svc.cluster.local.", Qtype: dns.TypeSRV,
Rcode: dns.RcodeSuccess,
Answer: []dns.RR{
- test.SRV("_http._tcp.svc-1-a.test-1.svc.cluster.local. 303 IN SRV 10 100 80 svc-1-a.test-1.svc.cluster.local."),
- test.SRV("_http._tcp.svc-1-b.test-1.svc.cluster.local. 303 IN SRV 10 100 80 svc-1-b.test-1.svc.cluster.local."),
+ test.SRV("_http._tcp.*.*.svc.cluster.local. 303 IN SRV 0 50 80 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("_http._tcp.*.*.svc.cluster.local. 303 IN SRV 0 50 80 svc-1-b.test-1.svc.cluster.local."),
+ },
+ Extra: []dns.RR{
+ test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
+ test.A("svc-1-b.test-1.svc.cluster.local. 303 IN A 10.0.0.110"),
},
},
{
Qname: "*.svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeSRV,
- Rcode: dns.RcodeSuccess,
- Answer: []dns.RR{
- test.SRV("*.svc-1-a.test-1.svc.cluster.local. 0 IN SRV 0 50 443 172-17-0-7.svc-1-a.test-1.svc.cluster.local."),
- test.SRV("*.svc-1-a.test-1.svc.cluster.local. 0 IN SRV 0 50 80 172-17-0-7.svc-1-a.test-1.svc.cluster.local."),
- },
- Extra: []dns.RR{
- test.A("172-17-0-7.svc-1-a.test-1.svc.cluster.local. 0 IN A 172.17.0.7"),
- },
+ Rcode: dns.RcodeSuccess,
+ Answer: srvResponse("*.svc-1-a.test-1.svc.cluster.local.", "TypeSRV", "svc-1-a", "test-1"),
+ Extra: srvResponse("*.svc-1-a.test-1.svc.cluster.local.", "TypeA", "svc-1-a", "test-1"),
},
{
Qname: "*._not-udp-or-tcp.svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeSRV,
- Rcode: dns.RcodeNameError,
+ Rcode: dns.RcodeNameError,
+ Answer: []dns.RR{},
Ns: []dns.RR{
- test.SOA("cluster.local. 300 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1499347823 7200 1800 86400 60"),
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502313310 7200 1800 86400 60"),
},
},
{
Qname: "svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeSRV,
Rcode: dns.RcodeSuccess,
Answer: []dns.RR{
- test.SRV("_http._tcp.svc-1-a.test-1.svc.cluster.local. 303 IN SRV 10 100 80 svc-1-a.test-1.svc.cluster.local."),
- test.SRV("_https._tcp.svc-1-a.test-1.svc.cluster.local. 303 IN SRV 10 100 443 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("svc-1-a.test-1.svc.cluster.local. 303 IN SRV 0 50 443 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("svc-1-a.test-1.svc.cluster.local. 303 IN SRV 0 50 80 svc-1-a.test-1.svc.cluster.local."),
+ },
+ Extra: []dns.RR{
+ test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
},
},
{
@@ -236,29 +283,22 @@ var dnsTestCases = []test.Case{
Qname: "dns-version.cluster.local.", Qtype: dns.TypeTXT,
Rcode: dns.RcodeSuccess,
Answer: []dns.RR{
- test.TXT("dns-version.cluster.local. 28800 IN TXT \"1.0.0\""),
- },
- },
- {
- Qname: "cluster.local.", Qtype: dns.TypeNS,
- Rcode: dns.RcodeSuccess,
- Answer: []dns.RR{
- test.NS("cluster.local. 0 IN NS kubernetes.default.svc.cluster.local."),
+ test.TXT(`dns-version.cluster.local. 303 IN TXT "1.0.1"`),
},
},
{
Qname: "ext-svc.test-1.svc.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeSuccess,
Answer: []dns.RR{
- test.CNAME("ext-svc.test-1.svc.cluster.local. 0 IN CNAME example.net."),
- test.A("example.net. 72031 IN A 13.14.15.16"),
+ test.A("example.net. 303 IN A 13.14.15.16"),
+ test.CNAME("ext-svc.test-1.svc.cluster.local. 303 IN CNAME example.net."),
},
},
{
Qname: "ext-svc.test-1.svc.cluster.local.", Qtype: dns.TypeCNAME,
Rcode: dns.RcodeSuccess,
Answer: []dns.RR{
- test.CNAME("ext-svc.test-1.svc.cluster.local. 0 IN CNAME example.net."),
+ test.CNAME("ext-svc.test-1.svc.cluster.local. 303 IN CNAME example.net."),
},
},
}
@@ -268,13 +308,16 @@ var dnsTestCasesPodsInsecure = []test.Case{
Qname: "10-20-0-101.test-1.pod.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeSuccess,
Answer: []dns.RR{
- test.A("10-20-0-101.test-1.pod.cluster.local. 0 IN A 10.20.0.101"),
+ test.A("10-20-0-101.test-1.pod.cluster.local. 303 IN A 10.20.0.101"),
},
},
{
Qname: "10-20-0-101.test-X.pod.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeNameError,
Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502307903 7200 1800 86400 60"),
+ },
},
}
@@ -283,11 +326,17 @@ var dnsTestCasesPodsVerified = []test.Case{
Qname: "10-20-0-101.test-1.pod.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeNameError,
Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502308197 7200 1800 86400 60"),
+ },
},
{
Qname: "10-20-0-101.test-X.pod.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeNameError,
Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502307960 7200 1800 86400 60"),
+ },
},
}
@@ -303,18 +352,300 @@ var dnsTestCasesAllNSExposed = []test.Case{
Qname: "svc-c.test-2.svc.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeSuccess,
Answer: []dns.RR{
- test.A("svc-c.test-1.svc.cluster.local. 303 IN A 10.0.0.120"),
+ test.A("svc-c.test-2.svc.cluster.local. 303 IN A 10.0.0.120"),
},
},
}
var dnsTestCasesFallthrough = []test.Case{
{
+ Qname: "svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeSuccess,
+ Answer: []dns.RR{
+ test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
+ },
+ },
+ {
+ Qname: "bogusservice.test-1.svc.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeNameError,
+ Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600"),
+ },
+ },
+ {
+ Qname: "bogusendpoint.svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeNameError,
+ Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600"),
+ },
+ },
+ {
+ Qname: "bogusendpoint.headless-svc.test-1.svc.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeNameError,
+ Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600"),
+ },
+ },
+ {
+ Qname: "svc-1-a.*.svc.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeSuccess,
+ Answer: []dns.RR{
+ test.A("svc-1-a.*.svc.cluster.local. 303 IN A 10.0.0.100"),
+ },
+ },
+ {
+ Qname: "svc-1-a.any.svc.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeSuccess,
+ Answer: []dns.RR{
+ test.A("svc-1-a.any.svc.cluster.local. 303 IN A 10.0.0.100"),
+ },
+ },
+ {
+ Qname: "bogusservice.*.svc.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeNameError,
+ Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600"),
+ },
+ },
+ {
+ Qname: "bogusservice.any.svc.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeNameError,
+ Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600"),
+ },
+ },
+ {
+ Qname: "*.test-1.svc.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeSuccess,
+ Answer: append([]dns.RR{
+ test.A("*.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
+ test.A("*.test-1.svc.cluster.local. 303 IN A 10.0.0.110"),
+ test.A("*.test-1.svc.cluster.local. 303 IN A 10.0.0.115"),
+ test.CNAME("*.test-1.svc.cluster.local. 303 IN CNAME example.net."),
+ test.A("example.net. 303 IN A 13.14.15.16"),
+ }, headlessAResponse("*.test-1.svc.cluster.local.", "headless-svc", "test-1")...),
+ },
+ {
+ Qname: "any.test-1.svc.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeSuccess,
+ Answer: append([]dns.RR{
+ test.A("any.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
+ test.A("any.test-1.svc.cluster.local. 303 IN A 10.0.0.110"),
+ test.A("any.test-1.svc.cluster.local. 303 IN A 10.0.0.115"),
+ test.CNAME("any.test-1.svc.cluster.local. 303 IN CNAME example.net."),
+ test.A("example.net. 303 IN A 13.14.15.16"),
+ }, headlessAResponse("any.test-1.svc.cluster.local.", "headless-svc", "test-1")...),
+ },
+ {
+ Qname: "any.test-2.svc.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeNameError,
+ Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600"),
+ },
+ },
+ {
+ Qname: "*.test-2.svc.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeNameError,
+ Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600"),
+ },
+ },
+ {
+ Qname: "*.*.svc.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeSuccess,
+ Answer: append([]dns.RR{
+ test.A("*.*.svc.cluster.local. 303 IN A 10.0.0.100"),
+ test.A("*.*.svc.cluster.local. 303 IN A 10.0.0.110"),
+ test.A("*.*.svc.cluster.local. 303 IN A 10.0.0.115"),
+ test.CNAME("*.*.svc.cluster.local. 303 IN CNAME example.net."),
+ test.A("example.net. 303 IN A 13.14.15.16"),
+ }, headlessAResponse("*.*.svc.cluster.local.", "headless-svc", "test-1")...),
+ },
+ {
+ Qname: "headless-svc.test-1.svc.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeSuccess,
+ Answer: headlessAResponse("headless-svc.test-1.svc.cluster.local.", "headless-svc", "test-1"),
+ },
+ {
+ Qname: "*._TcP.svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeSRV,
+ Rcode: dns.RcodeSuccess,
+ Answer: []dns.RR{
+ test.SRV("*._TcP.svc-1-a.test-1.svc.cluster.local. 303 IN SRV 0 50 443 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("*._TcP.svc-1-a.test-1.svc.cluster.local. 303 IN SRV 0 50 80 svc-1-a.test-1.svc.cluster.local."),
+ },
+ Extra: []dns.RR{
+ test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
+ },
+ },
+ {
+ Qname: "*.*.bogusservice.test-1.svc.cluster.local.", Qtype: dns.TypeSRV,
+ Rcode: dns.RcodeNameError,
+ Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600"),
+ },
+ },
+ {
+ Qname: "*.any.svc-1-a.*.svc.cluster.local.", Qtype: dns.TypeSRV,
+ Rcode: dns.RcodeSuccess,
+ Answer: []dns.RR{
+ test.SRV("*.any.svc-1-a.*.svc.cluster.local. 303 IN SRV 0 50 443 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("*.any.svc-1-a.*.svc.cluster.local. 303 IN SRV 0 50 80 svc-1-a.test-1.svc.cluster.local."),
+ },
+ Extra: []dns.RR{
+ test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
+ },
+ },
+ {
+ Qname: "ANY.*.svc-1-a.any.svc.cluster.local.", Qtype: dns.TypeSRV,
+ Rcode: dns.RcodeSuccess,
+ Answer: []dns.RR{
+ test.SRV("ANY.*.svc-1-a.any.svc.cluster.local. 303 IN SRV 0 50 443 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("ANY.*.svc-1-a.any.svc.cluster.local. 303 IN SRV 0 50 80 svc-1-a.test-1.svc.cluster.local."),
+ },
+ Extra: []dns.RR{
+ test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
+ },
+ },
+ {
+ Qname: "*.*.bogusservice.*.svc.cluster.local.", Qtype: dns.TypeSRV,
+ Rcode: dns.RcodeNameError,
+ Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600"),
+ },
+ },
+ {
+ Qname: "*.*.bogusservice.any.svc.cluster.local.", Qtype: dns.TypeSRV,
+ Rcode: dns.RcodeNameError,
+ Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600"),
+ },
+ },
+ {
+ Qname: "_c-port._UDP.*.test-1.svc.cluster.local.", Qtype: dns.TypeSRV,
+ Rcode: dns.RcodeSuccess,
+ Answer: append(srvResponse("_c-port._UDP.*.test-1.svc.cluster.local.", "TypeSRV", "headless-svc", "test-1"),
+ []dns.RR{
+ test.SRV("_c-port._UDP.*.test-1.svc.cluster.local. 303 IN SRV 0 33 1234 svc-c.test-1.svc.cluster.local."),
+ }...),
+
+ Extra: append(srvResponse("_c-port._UDP.*.test-1.svc.cluster.local.", "TypeA", "headless-svc", "test-1"),
+ []dns.RR{
+ test.A("svc-c.test-1.svc.cluster.local. 303 IN A 10.0.0.115"),
+ }...),
+ },
+ {
+ Qname: "*._tcp.any.test-1.svc.cluster.local.", Qtype: dns.TypeSRV,
+ Rcode: dns.RcodeSuccess,
+ Answer: []dns.RR{
+ test.SRV("*._tcp.any.test-1.svc.cluster.local. 303 IN SRV 0 33 443 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("*._tcp.any.test-1.svc.cluster.local. 303 IN SRV 0 33 80 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("*._tcp.any.test-1.svc.cluster.local. 303 IN SRV 0 33 80 svc-1-b.test-1.svc.cluster.local."),
+ },
+ Extra: []dns.RR{
+ test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
+ test.A("svc-1-b.test-1.svc.cluster.local. 303 IN A 10.0.0.110"),
+ },
+ },
+ {
+ Qname: "*.*.any.test-2.svc.cluster.local.", Qtype: dns.TypeSRV,
+ Rcode: dns.RcodeNameError,
+ Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600"),
+ },
+ },
+ {
+ Qname: "*.*.*.test-2.svc.cluster.local.", Qtype: dns.TypeSRV,
+ Rcode: dns.RcodeNameError,
+ Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600"),
+ },
+ },
+ {
+ Qname: "_http._tcp.*.*.svc.cluster.local.", Qtype: dns.TypeSRV,
+ Rcode: dns.RcodeSuccess,
+ Answer: []dns.RR{
+ test.SRV("_http._tcp.*.*.svc.cluster.local. 303 IN SRV 0 50 80 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("_http._tcp.*.*.svc.cluster.local. 303 IN SRV 0 50 80 svc-1-b.test-1.svc.cluster.local."),
+ },
+ Extra: []dns.RR{
+ test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
+ test.A("svc-1-b.test-1.svc.cluster.local. 303 IN A 10.0.0.110"),
+ },
+ },
+ {
+ Qname: "*.svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeSRV,
+ Rcode: dns.RcodeSuccess,
+ Answer: srvResponse("*.svc-1-a.test-1.svc.cluster.local.", "TypeSRV", "svc-1-a", "test-1"),
+ Extra: srvResponse("*.svc-1-a.test-1.svc.cluster.local.", "TypeA", "svc-1-a", "test-1"),
+ },
+ {
+ Qname: "*._not-udp-or-tcp.svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeSRV,
+ Rcode: dns.RcodeNameError,
+ Answer: []dns.RR{},
+ Ns: []dns.RR{
+ test.SOA("cluster.local. 303 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600"),
+ },
+ },
+ {
+ Qname: "svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeSRV,
+ Rcode: dns.RcodeSuccess,
+ Answer: []dns.RR{
+ test.SRV("svc-1-a.test-1.svc.cluster.local. 303 IN SRV 0 50 443 svc-1-a.test-1.svc.cluster.local."),
+ test.SRV("svc-1-a.test-1.svc.cluster.local. 303 IN SRV 0 50 80 svc-1-a.test-1.svc.cluster.local."),
+ },
+ Extra: []dns.RR{
+ test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
+ },
+ },
+ {
+ Qname: "10-20-0-101.test-1.pod.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeServerFailure,
+ Answer: []dns.RR{},
+ },
+ {
+ Qname: "dns-version.cluster.local.", Qtype: dns.TypeTXT,
+ Rcode: dns.RcodeSuccess,
+ Answer: []dns.RR{
+ test.TXT("dns-version.cluster.local. 28800 IN TXT \"1.0.1\""),
+ },
+ },
+ {
+ Qname: "ext-svc.test-1.svc.cluster.local.", Qtype: dns.TypeA,
+ Rcode: dns.RcodeSuccess,
+ Answer: []dns.RR{
+ test.A("example.net. 303 IN A 13.14.15.16"),
+ test.CNAME("ext-svc.test-1.svc.cluster.local. 0 IN CNAME example.net."),
+ },
+ },
+ {
+ Qname: "ext-svc.test-1.svc.cluster.local.", Qtype: dns.TypeCNAME,
+ Rcode: dns.RcodeSuccess,
+ Answer: []dns.RR{
+ test.CNAME("ext-svc.test-1.svc.cluster.local. 0 IN CNAME example.net."),
+ },
+ },
+ {
Qname: "f.b.svc.cluster.local.", Qtype: dns.TypeA,
Rcode: dns.RcodeSuccess,
Answer: []dns.RR{
test.A("f.b.svc.cluster.local. 303 IN A 10.10.10.11"),
},
+ Ns: []dns.RR{
+ test.NS("cluster.local. 303 IN NS a.iana-servers.net."),
+ test.NS("cluster.local. 303 IN NS b.iana-servers.net."),
+ },
},
{
Qname: "foo.cluster.local.", Qtype: dns.TypeA,
@@ -322,6 +653,10 @@ var dnsTestCasesFallthrough = []test.Case{
Answer: []dns.RR{
test.A("foo.cluster.local. 303 IN A 10.10.10.10"),
},
+ Ns: []dns.RR{
+ test.NS("cluster.local. 303 IN NS a.iana-servers.net."),
+ test.NS("cluster.local. 303 IN NS b.iana-servers.net."),
+ },
},
}
@@ -359,17 +694,18 @@ func doIntegrationTests(t *testing.T, corefile string, testCases []test.Case) {
t.Fatalf("Could not send query: %s", err)
}
- // check the answer
- if res.Rcode != tc.Rcode {
- t.Errorf("Expected rcode %d but got %d for query %s, %d", tc.Rcode, res.Rcode, tc.Qname, tc.Qtype)
- }
+ // Before sorting, make sure that CNAMES do not appear after their target records
+ test.CNAMEOrder(t, res)
- if len(res.Answer) != len(tc.Answer) {
- t.Errorf("Expected %d answers but got %d for query %s, %d\nfull reply %s", len(tc.Answer), len(res.Answer), tc.Qname, tc.Qtype, res)
- }
+ // Sorting the test cases to check with the response
+ sort.Sort(test.RRSet(tc.Answer))
+ sort.Sort(test.RRSet(tc.Ns))
+ sort.Sort(test.RRSet(tc.Extra))
+
+ test.SortAndCheck(t, res, tc)
- //TODO: Check the actual RR values
}
+
}
func createUpstreamServer(t *testing.T) (func(), *caddy.Instance, string) {
@@ -487,8 +823,70 @@ func TestKubernetesIntegrationFallthrough(t *testing.T) {
drop 0
}
`
- cases := append(dnsTestCases, dnsTestCasesFallthrough...)
- doIntegrationTests(t, corefile, cases)
+ doIntegrationTests(t, corefile, dnsTestCasesFallthrough)
+}
+
+//headlessAResponse returns the answer to an A request for the specific name and namespace
+func headlessAResponse(qname, namespace, name string) []dns.RR {
+ rr := []dns.RR{}
+
+ str, err := endpointIPs(name, namespace)
+ if err != nil {
+ log.Fatal("Error running kubectl command: ", err.Error())
+ }
+ result := strings.Split(string(str), " ")
+ lr := len(result)
+
+ for i := 0; i < lr; i++ {
+ rr = append(rr, test.A(qname+" 303 IN A "+result[i]))
+ }
+ return rr
+}
+
+// srvResponse returns the answer to a SRV request for the specific name and namespace
+// responsetype is the type of answer to generate, eg: TypeSRV ( for answer section) or TypeA (for extra section)
+func srvResponse(qname, responsetype, namespace, name string) []dns.RR {
+ rr := []dns.RR{}
+
+ str, err := endpointIPs(name, namespace)
+
+ if err != nil {
+ log.Fatal("Error running kubectl command: ", err.Error())
+ }
+ result := strings.Split(string(str), " ")
+ lr := len(result)
+
+ for i := 0; i < lr; i++ {
+ ip := strings.Replace(result[i], ".", "-", -1)
+ t := strconv.Itoa(100 / (lr + 1))
+ if responsetype == "TypeA" {
+ rr = append(rr, test.A(ip+"."+namespace+"."+name+".svc.cluster.local. 0 IN A "+result[i]))
+ }
+ if responsetype == "TypeSRV" && namespace == "headless-svc" {
+ rr = append(rr, test.SRV(qname+" 303 IN SRV 0 "+t+" 1234 "+ip+"."+namespace+"."+name+".svc.cluster.local."))
+ }
+ if responsetype == "TypeSRV" && namespace != "headless-svc" {
+ rr = append(rr, test.SRV(qname+" 303 IN SRV 0 "+t+" 443 "+ip+"."+namespace+"."+name+".svc.cluster.local."))
+ rr = append(rr, test.SRV(qname+" 303 IN SRV 0 "+t+" 80 "+ip+"."+namespace+"."+name+".svc.cluster.local."))
+ }
+
+ }
+ return rr
+}
+
+//endpointIPs retrieves the IP address for a given name and namespace by parsing json using kubectl command
+func endpointIPs(name, namespace string) (cmdOut []byte, err error) {
+
+ kctl := os.Getenv("KUBECTL")
+
+ if kctl == "" {
+ kctl = "kubectl"
+ }
+ cmdArgs := kctl + " -n " + name + " get endpoints " + namespace + " -o jsonpath={.subsets[*].addresses[*].ip}"
+ if cmdOut, err = exec.Command("sh", "-c", cmdArgs).Output(); err != nil {
+ return nil, err
+ }
+ return cmdOut, nil
}
const clusterLocal = `; cluster.local test file for fallthrough