diff options
author | 2017-10-25 15:40:48 -0400 | |
---|---|---|
committer | 2017-10-25 15:40:48 -0400 | |
commit | e8184d3a5ace2770487a689cbc72be4303b53f2e (patch) | |
tree | 4b20fa60f55299a3085b3328296721c69c523ea7 | |
parent | c2d93f7182a55e0e9a819f44b87735f635200423 (diff) | |
download | coredns-e8184d3a5ace2770487a689cbc72be4303b53f2e.tar.gz coredns-e8184d3a5ace2770487a689cbc72be4303b53f2e.tar.zst coredns-e8184d3a5ace2770487a689cbc72be4303b53f2e.zip |
plugin/kubernetes: Modify integration tests for coredns/ci (#1152)
* integration ci
* rename test
* unfunctionalize DoIntegrationTests
* alphabetize expected answers
* Enable out-of-cluster test
* Enable out-of-cluster test
* move integration tests back to ci repo
-rw-r--r-- | .travis.yml | 24 | ||||
-rw-r--r-- | .travis/kubernetes/dns-test.yaml | 199 | ||||
-rw-r--r-- | Makefile | 15 | ||||
-rw-r--r-- | test/kubernetes_api_fallthrough_test.go | 49 | ||||
-rw-r--r-- | test/kubernetes_fallthrough_test.go | 75 | ||||
-rw-r--r-- | test/kubernetes_nsexposed_test.go | 56 | ||||
-rw-r--r-- | test/kubernetes_pods_test.go | 103 | ||||
-rw-r--r-- | test/kubernetes_test.go | 419 |
8 files changed, 13 insertions, 927 deletions
diff --git a/.travis.yml b/.travis.yml index 9458eb6cc..7d42ca0dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,18 +15,17 @@ git: depth: 3 env: - - TEST_TYPE=coverage ETCD_VERSION=2.3.1 K8S_VERSION=1.5.0 KUBECTL="docker exec hyperkube /hyperkube kubectl" - - TEST_TYPE=integration ETCD_VERSION=2.3.1 K8S_VERSION=1.5.0 KUBECTL="docker exec hyperkube /hyperkube kubectl" - - TEST_TYPE=core ETCD_VERSION=2.3.1 K8S_VERSION=1.5.0 KUBECTL="docker exec hyperkube /hyperkube kubectl" - - TEST_TYPE=plugin ETCD_VERSION=2.3.1 K8S_VERSION=1.5.0 KUBECTL="docker exec hyperkube /hyperkube kubectl" + - TEST_TYPE=coverage ETCD_VERSION=2.3.1 + - TEST_TYPE=integration ETCD_VERSION=2.3.1 + - TEST_TYPE=core ETCD_VERSION=2.3.1 + - TEST_TYPE=plugin ETCD_VERSION=2.3.1 # In the Travis VM-based build environment, IPv6 networking is not # enabled by default. The sysctl operations below enable IPv6. # 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. -# (Dependencies are fun! :) ) +# needed to have docker in the test environment. + before_install: - cat /proc/net/if_inet6 - uname -a @@ -36,17 +35,6 @@ before_install: before_script: - docker run -d --net=host --name=etcd quay.io/coreos/etcd:v$ETCD_VERSION - - docker run -d --volume=/:/rootfs:ro --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:rw --volume=/var/lib/kubelet/:/var/lib/kubelet:rw --volume=/var/run:/var/run:rw --volume=`pwd`/.travis:/travis --net=host --pid=host --privileged --name=hyperkube gcr.io/google_containers/hyperkube-amd64:v$K8S_VERSION /hyperkube kubelet --containerized --hostname-override=127.0.0.1 --api-servers=http://localhost:8080 --config=/etc/kubernetes/manifests --allow-privileged --v=2 - # Wait until kubectl is ready - - for i in {1..10}; do $KUBECTL version && break || sleep 5; done - - $KUBECTL version - - $KUBECTL config set-cluster test-doc --server=http://localhost:8080 - - $KUBECTL config set-context test-doc --cluster=test-doc - - $KUBECTL config use-context test-doc - # Wait until k8s is ready - - for i in {1..30}; do $KUBECTL get nodes && break || sleep 5; done - - $KUBECTL create -f /travis/kubernetes/dns-test.yaml - - docker ps -a script: - make TEST_TYPE=$TEST_TYPE travis diff --git a/.travis/kubernetes/dns-test.yaml b/.travis/kubernetes/dns-test.yaml deleted file mode 100644 index d98e516a6..000000000 --- a/.travis/kubernetes/dns-test.yaml +++ /dev/null @@ -1,199 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: test-1 ---- -apiVersion: v1 -kind: Namespace -metadata: - name: test-2 ---- -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: de-1-a - namespace: test-1 -spec: - replicas: 1 - template: - metadata: - labels: - app: app-1-a - spec: - containers: - - name: app-1-a-c - image: gcr.io/google_containers/pause-amd64:3.0 - ports: - - containerPort: 80 - name: http - protocol: TCP - - containerPort: 443 - name: https - protocol: TCP ---- -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: de-1-b - namespace: test-1 -spec: - replicas: 1 - template: - metadata: - labels: - app: app-1-b - spec: - containers: - - name: app-1-b-c - image: gcr.io/google_containers/pause-amd64:3.0 - ports: - - containerPort: 80 - name: http - protocol: TCP ---- -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: de-c - namespace: test-1 -spec: - replicas: 1 - template: - metadata: - labels: - app: app-c - spec: - containers: - - name: app-c-c - image: gcr.io/google_containers/pause-amd64:3.0 - ports: - - containerPort: 1234 - name: c-port - protocol: UDP ---- -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: de-c - namespace: test-2 -spec: - replicas: 1 - template: - metadata: - labels: - app: app-c - spec: - containers: - - name: app-c-c - image: gcr.io/google_containers/pause-amd64:3.0 - ports: - - containerPort: 1234 - name: c-port - protocol: UDP ---- -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: de-d1 - namespace: test-1 -spec: - replicas: 2 - template: - metadata: - labels: - app: app-d - spec: - containers: - - name: app-d-c - image: gcr.io/google_containers/pause-amd64:3.0 - ports: - - containerPort: 1234 - name: c-port - protocol: UDP ---- -apiVersion: v1 -kind: Service -metadata: - name: svc-1-a - namespace: test-1 -spec: - selector: - app: app-1-a - clusterIP: 10.0.0.100 - ports: - - name: http - port: 80 - protocol: TCP - - name: https - port: 443 - protocol: TCP ---- -apiVersion: v1 -kind: Service -metadata: - name: svc-1-b - namespace: test-1 -spec: - selector: - app: app-1-b - clusterIP: 10.0.0.110 - ports: - - name: http - port: 80 - protocol: TCP ---- -apiVersion: v1 -kind: Service -metadata: - name: svc-c - namespace: test-1 -spec: - selector: - app: app-c - clusterIP: 10.0.0.115 - ports: - - name: c-port - port: 1234 - protocol: UDP ---- -apiVersion: v1 -kind: Service -metadata: - name: svc-c - namespace: test-2 -spec: - selector: - app: app-c - clusterIP: 10.0.0.120 - ports: - - name: c-port - port: 1234 - protocol: UDP ---- -apiVersion: v1 -kind: Service -metadata: - name: headless-svc - namespace: test-1 -spec: - selector: - app: app-d - clusterIP: None - ports: - - name: c-port - port: 1234 - protocol: UDP ---- -apiVersion: v1 -kind: Service -metadata: - name: ext-svc - namespace: test-1 -spec: - type: ExternalName - externalName: example.net - ports: - - name: c-port - port: 1234 - protocol: UDP - @@ -31,21 +31,21 @@ godeps: .PHONY: travis travis: check ifeq ($(TEST_TYPE),core) - ( cd request ; go test -v -tags 'etcd k8s' -race ./... ) - ( cd core ; go test -v -tags 'etcd k8s' -race ./... ) - ( cd coremain go test -v -tags 'etcd k8s' -race ./... ) + ( cd request ; go test -v -tags 'etcd' -race ./... ) + ( cd core ; go test -v -tags 'etcd' -race ./... ) + ( cd coremain go test -v -tags 'etcd' -race ./... ) endif ifeq ($(TEST_TYPE),integration) - ( cd test ; go test -v -tags 'etcd k8s' -race ./... ) + ( cd test ; go test -v -tags 'etcd' -race ./... ) endif ifeq ($(TEST_TYPE),plugin) - ( cd plugin ; go test -v -tags 'etcd k8s' -race ./... ) + ( cd plugin ; go test -v -tags 'etcd' -race ./... ) endif ifeq ($(TEST_TYPE),coverage) for d in `go list ./... | grep -v vendor`; do \ t=$$(date +%s); \ - go test -i -tags 'etcd k8s' -coverprofile=cover.out -covermode=atomic $$d || exit 1; \ - go test -v -tags 'etcd k8s' -coverprofile=cover.out -covermode=atomic $$d || exit 1; \ + go test -i -tags 'etcd' -coverprofile=cover.out -covermode=atomic $$d || exit 1; \ + go test -v -tags 'etcd' -coverprofile=cover.out -covermode=atomic $$d || exit 1; \ echo "Coverage test $$d took $$(($$(date +%s)-t)) seconds"; \ if [ -f cover.out ]; then \ cat cover.out >> coverage.txt; \ @@ -54,7 +54,6 @@ ifeq ($(TEST_TYPE),coverage) done endif - core/zplugin.go core/dnsserver/zdirectives.go: plugin.cfg go generate coredns.go diff --git a/test/kubernetes_api_fallthrough_test.go b/test/kubernetes_api_fallthrough_test.go deleted file mode 100644 index d12789c24..000000000 --- a/test/kubernetes_api_fallthrough_test.go +++ /dev/null @@ -1,49 +0,0 @@ -// +build k8s - -package test - -import ( - "testing" - - "github.com/coredns/coredns/plugin/test" - - "github.com/miekg/dns" -) - -func TestKubernetesAPIFallthrough(t *testing.T) { - tests := []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"), - }, - }, - } - - corefile := - `.:0 { - kubernetes cluster.local { - endpoint http://nonexistance:8080,http://invalidip:8080,http://localhost:8080 - namespaces test-1 - pods disabled - }` - - server, udp, _, err := CoreDNSServerAndPorts(corefile) - if err != nil { - t.Fatalf("Could not get CoreDNS serving instance: %s", err) - } - defer server.Stop() - - for _, tc := range tests { - - c := new(dns.Client) - m := tc.Msg() - - res, _, err := c.Exchange(m, udp) - if err != nil { - t.Fatalf("Could not send query: %s", err) - } - test.SortAndCheck(t, res, tc) - } -} diff --git a/test/kubernetes_fallthrough_test.go b/test/kubernetes_fallthrough_test.go deleted file mode 100644 index 1b0545056..000000000 --- a/test/kubernetes_fallthrough_test.go +++ /dev/null @@ -1,75 +0,0 @@ -// +build k8s - -package test - -import ( - "io/ioutil" - "log" - "os" - "testing" - - "github.com/coredns/coredns/plugin/test" - - "github.com/miekg/dns" -) - -func init() { - log.SetOutput(ioutil.Discard) -} - -var dnsTestCasesFallthrough = []test.Case{ - { - 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. 303 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, - Rcode: dns.RcodeSuccess, - 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."), - }, - }, -} - -func TestKubernetesFallthrough(t *testing.T) { - dbfile, rmFunc, err := TempFile(os.TempDir(), clusterLocal) - if err != nil { - t.Fatalf("Could not create zonefile for fallthrough server: %s", err) - } - defer rmFunc() - - rmFunc, upstream, udp := upstreamServer(t) - defer upstream.Stop() - defer rmFunc() - - corefile := - `.:0 { - file ` + dbfile + ` cluster.local - kubernetes cluster.local { - endpoint http://localhost:8080 - namespaces test-1 - upstream ` + udp + ` - fallthrough - } -` - doIntegrationTests(t, corefile, dnsTestCasesFallthrough) -} diff --git a/test/kubernetes_nsexposed_test.go b/test/kubernetes_nsexposed_test.go deleted file mode 100644 index 1b271a825..000000000 --- a/test/kubernetes_nsexposed_test.go +++ /dev/null @@ -1,56 +0,0 @@ -// +build k8s - -package test - -import ( - "testing" - - "github.com/coredns/coredns/plugin/test" - - "github.com/miekg/dns" -) - -var dnsTestCasesAllNSExposed = []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: "svc-c.test-2.svc.cluster.local.", Qtype: dns.TypeA, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.A("svc-c.test-2.svc.cluster.local. 303 IN A 10.0.0.120"), - }, - }, -} - -func TestKubernetesNSExposed(t *testing.T) { - corefile := - `.:0 { - kubernetes cluster.local { - endpoint http://localhost:8080 - } -` - - server, udp, _, err := CoreDNSServerAndPorts(corefile) - if err != nil { - t.Fatalf("Could not get CoreDNS serving instance: %s", err) - } - defer server.Stop() - - for _, tc := range dnsTestCasesAllNSExposed { - - c := new(dns.Client) - m := tc.Msg() - - res, _, err := c.Exchange(m, udp) - if err != nil { - t.Fatalf("Could not send query: %s", err) - } - - test.SortAndCheck(t, res, tc) - } -} diff --git a/test/kubernetes_pods_test.go b/test/kubernetes_pods_test.go deleted file mode 100644 index 345366a41..000000000 --- a/test/kubernetes_pods_test.go +++ /dev/null @@ -1,103 +0,0 @@ -// +build k8s - -package test - -import ( - "testing" - - "github.com/coredns/coredns/plugin/test" - - "github.com/miekg/dns" -) - -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. 303 IN A 10.20.0.101"), - }, - }, - { - Qname: "10-20-0-101.test-X.pod.cluster.local.", Qtype: dns.TypeA, - Rcode: dns.RcodeNameError, - Ns: []dns.RR{ - test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502307903 7200 1800 86400 60"), - }, - }, -} - -func TestKubernetesPodsInsecure(t *testing.T) { - corefile := `.:0 { -kubernetes cluster.local 0.0.10.in-addr.arpa { - endpoint http://localhost:8080 - namespaces test-1 - pods insecure -} -` - - server, udp, _, err := CoreDNSServerAndPorts(corefile) - if err != nil { - t.Fatalf("Could not get CoreDNS serving instance: %s", err) - } - defer server.Stop() - - for _, tc := range dnsTestCasesPodsInsecure { - - c := new(dns.Client) - m := tc.Msg() - - res, _, err := c.Exchange(m, udp) - if err != nil { - t.Fatalf("Could not send query: %s", err) - } - - test.SortAndCheck(t, res, tc) - } -} - -var dnsTestCasesPodsVerified = []test.Case{ - { - Qname: "10-20-0-101.test-1.pod.cluster.local.", Qtype: dns.TypeA, - Rcode: dns.RcodeNameError, - 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, - Ns: []dns.RR{ - test.SOA("cluster.local. 303 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1502307960 7200 1800 86400 60"), - }, - }, -} - -func TestKubernetesPodsVerified(t *testing.T) { - corefile := `.:0 { - kubernetes cluster.local 0.0.10.in-addr.arpa { - endpoint http://localhost:8080 - namespaces test-1 - pods verified - } -` - - server, udp, _, err := CoreDNSServerAndPorts(corefile) - if err != nil { - t.Fatalf("Could not get CoreDNS serving instance: %s", err) - } - defer server.Stop() - - for _, tc := range dnsTestCasesPodsVerified { - - c := new(dns.Client) - m := tc.Msg() - - res, _, err := c.Exchange(m, udp) - if err != nil { - t.Fatalf("Could not send query: %s", err) - } - - test.SortAndCheck(t, res, tc) - } -} diff --git a/test/kubernetes_test.go b/test/kubernetes_test.go deleted file mode 100644 index d217f7e72..000000000 --- a/test/kubernetes_test.go +++ /dev/null @@ -1,419 +0,0 @@ -// +build k8s - -package test - -import ( - "io/ioutil" - "log" - "os" - "os/exec" - "sort" - "strconv" - "strings" - "testing" - "time" - - "github.com/coredns/coredns/plugin/test" - - "github.com/mholt/caddy" - "github.com/miekg/dns" -) - -func init() { - log.SetOutput(ioutil.Discard) -} - -var dnsTestCases = []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. 5 IN A 10.0.0.100"), - }, - }, - { - Qname: "bogusservice.test-1.svc.cluster.local.", Qtype: dns.TypeA, - Rcode: dns.RcodeNameError, - 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, - 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, - 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.*.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, - 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, - 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: 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, - 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, - 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: 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, - 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("*.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, - 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, - 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: append(srvResponse("_c-port._UDP.*.test-1.svc.cluster.local.", dns.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.", dns.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, - 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, - 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.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.", dns.TypeSRV, "svc-1-a", "test-1"), - Extra: srvResponse("*.svc-1-a.test-1.svc.cluster.local.", dns.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, - 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.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, - }, - { - Qname: "dns-version.cluster.local.", Qtype: dns.TypeTXT, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.TXT(`dns-version.cluster.local. 303 IN TXT "1.0.1"`), - }, - }, -} - -func doIntegrationTests(t *testing.T, corefile string, testCases []test.Case) { - server, udp, _, err := CoreDNSServerAndPorts(corefile) - if err != nil { - t.Fatalf("Could not get CoreDNS serving instance: %s", err) - } - defer server.Stop() - - time.Sleep(3 * time.Second) - - for _, tc := range testCases { - - c := new(dns.Client) - m := tc.Msg() - - res, _, err := c.Exchange(m, udp) - if err != nil { - t.Fatalf("Could not send query: %s", err) - } - - // Before sorting, make sure that CNAMES do not appear after their target records and then sort the tc. - test.CNAMEOrder(t, res) - sort.Sort(test.RRSet(tc.Answer)) - sort.Sort(test.RRSet(tc.Ns)) - sort.Sort(test.RRSet(tc.Extra)) - - test.SortAndCheck(t, res, tc) - } -} - -func upstreamServer(t *testing.T) (func(), *caddy.Instance, string) { - upfile, rmFunc, err := TempFile(os.TempDir(), exampleNet) - if err != nil { - t.Fatalf("Could not create file for CNAME upstream lookups: %s", err) - } - upstreamCorefile := `.:0 { - file ` + upfile + ` example.net -}` - server, udp, _, err := CoreDNSServerAndPorts(upstreamCorefile) - if err != nil { - t.Fatalf("Could not get CoreDNS serving instance: %s", err) - } - return rmFunc, server, udp -} - -func TestKubernetes(t *testing.T) { - - rmFunc, upstream, udp := upstreamServer(t) - defer upstream.Stop() - defer rmFunc() - - corefile := - `.:0 { - kubernetes cluster.local 0.0.10.in-addr.arpa { - endpoint http://localhost:8080 - namespaces test-1 - pods disabled - upstream ` + udp + ` - } -` - doIntegrationTests(t, corefile, dnsTestCases) -} - -// 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 -// qtype is the type of answer to generate, eg: TypeSRV (for answer section) or TypeA (for extra section). -func srvResponse(qname string, qtype uint16, 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)) - - switch qtype { - case dns.TypeA: - rr = append(rr, test.A(ip+"."+namespace+"."+name+".svc.cluster.local. 303 IN A "+result[i])) - case dns.TypeSRV: - if namespace == "headless-svc" { - rr = append(rr, test.SRV(qname+" 303 IN SRV 0 "+t+" 1234 "+ip+"."+namespace+"."+name+".svc.cluster.local.")) - } else { - 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 -cluster.local. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600 -cluster.local. IN NS b.iana-servers.net. -cluster.local. IN NS a.iana-servers.net. -cluster.local. IN A 127.0.0.1 -cluster.local. IN A 127.0.0.2 -foo.cluster.local. IN A 10.10.10.10 -f.b.svc.cluster.local. IN A 10.10.10.11 -*.w.cluster.local. IN TXT "Wildcard" -a.b.svc.cluster.local. IN TXT "Not a wildcard" -cname.cluster.local. IN CNAME www.example.net. - -service.namespace.svc.cluster.local. IN SRV 8080 10 10 cluster.local. -` - -const exampleNet = `; example.net. test file for cname tests -example.net. IN SOA ns.example.net. admin.example.net. 2015082541 7200 3600 1209600 3600 -example.net. IN A 13.14.15.16 -` |