diff --git a/middleware/kubernetes/kubernetes.go b/middleware/kubernetes/kubernetes.go index dc20e109a..209e09eb4 100644 --- a/middleware/kubernetes/kubernetes.go +++ b/middleware/kubernetes/kubernetes.go @@ -112,7 +112,7 @@ func (k *Kubernetes) Services(state request.Request, exact bool, opt middleware. return []msg.Service{svc}, nil, nil case dns.TypeNS: // We can only get here if the qname equal the zone, see ServeDNS in handler.go. - ns := k.coreDNSRecord() + ns := k.nsAddr() svc := msg.Service{Host: ns.A.String(), Key: msg.Path(state.QName(), "coredns")} return []msg.Service{svc}, nil, nil } diff --git a/middleware/kubernetes/ns.go b/middleware/kubernetes/ns.go index d14a1e96d..8f521e36a 100644 --- a/middleware/kubernetes/ns.go +++ b/middleware/kubernetes/ns.go @@ -10,15 +10,11 @@ import ( "k8s.io/client-go/1.5/pkg/api" ) -const defaultNSName = "ns.dns." - -var corednsRecord dns.A - // DefaultNSMsg returns an msg.Service representing an A record for // ns.dns.[zone] -> dns service ip. This A record is needed to legitimize // the SOA response in middleware.NS(), which is hardcoded at ns.dns.[zone]. func (k *Kubernetes) defaultNSMsg(r recordRequest) msg.Service { - ns := k.coreDNSRecord() + ns := k.nsAddr() s := msg.Service{ Key: msg.Path(strings.Join([]string{defaultNSName, r.zone}, "."), "coredns"), Host: ns.A.String(), @@ -30,57 +26,55 @@ func isDefaultNS(name string, r recordRequest) bool { return strings.Index(name, defaultNSName) == 0 && strings.Index(name, r.zone) == len(defaultNSName) } -func (k *Kubernetes) coreDNSRecord() dns.A { +func (k *Kubernetes) nsAddr() *dns.A { var ( svcName string svcNamespace string - dnsIP net.IP ) - if len(corednsRecord.Hdr.Name) == 0 || corednsRecord.A == nil { - // get local Pod IP - localIP := k.interfaceAddrsFunc() - // Find endpoint matching IP to get service and namespace - endpointsList := k.APIConn.EndpointsList() + rr := new(dns.A) + localIP := k.interfaceAddrsFunc() + endpointsList := k.APIConn.EndpointsList() - FindEndpoint: - for _, ep := range endpointsList.Items { - for _, eps := range ep.Subsets { - for _, addr := range eps.Addresses { - if localIP.Equal(net.ParseIP(addr.IP)) { + rr.A = localIP - svcNamespace = ep.ObjectMeta.Namespace - svcName = ep.ObjectMeta.Name - break FindEndpoint - } +FindEndpoint: + for _, ep := range endpointsList.Items { + for _, eps := range ep.Subsets { + for _, addr := range eps.Addresses { + if localIP.Equal(net.ParseIP(addr.IP)) { + + svcNamespace = ep.ObjectMeta.Namespace + svcName = ep.ObjectMeta.Name + break FindEndpoint } } } - - if len(svcName) == 0 { - corednsRecord.Hdr.Name = defaultNSName - corednsRecord.A = localIP - return corednsRecord - } - // Find service to get ClusterIP - serviceList := k.APIConn.ServiceList() - FindService: - for _, svc := range serviceList { - if svcName == svc.Name && svcNamespace == svc.Namespace { - if svc.Spec.ClusterIP == api.ClusterIPNone { - dnsIP = localIP - } else { - dnsIP = net.ParseIP(svc.Spec.ClusterIP) - } - break FindService - } - } - if dnsIP == nil { - dnsIP = localIP - } - - corednsRecord.Hdr.Name = strings.Join([]string{svcName, svcNamespace, "svc."}, ".") - corednsRecord.A = dnsIP } - return corednsRecord + + if len(svcName) == 0 { + rr.Hdr.Name = defaultNSName + rr.A = localIP + return rr + } + // Find service to get ClusterIP + serviceList := k.APIConn.ServiceList() + +FindService: + for _, svc := range serviceList { + if svcName == svc.Name && svcNamespace == svc.Namespace { + if svc.Spec.ClusterIP == api.ClusterIPNone { + rr.A = localIP + } else { + rr.A = net.ParseIP(svc.Spec.ClusterIP) + } + break FindService + } + } + + rr.Hdr.Name = strings.Join([]string{svcName, svcNamespace, "svc."}, ".") + + return rr } + +const defaultNSName = "ns.dns." diff --git a/middleware/kubernetes/ns_test.go b/middleware/kubernetes/ns_test.go index e5e45afb1..7815ade7e 100644 --- a/middleware/kubernetes/ns_test.go +++ b/middleware/kubernetes/ns_test.go @@ -1,42 +1,11 @@ package kubernetes -import "testing" -import "net" +import ( + "net" + "testing" -import "k8s.io/client-go/1.5/pkg/api" -import "github.com/miekg/dns" - -func TestDefaultNSMsg(t *testing.T) { - k := Kubernetes{Zones: []string{"inter.webs.test."}} - corednsRecord.Hdr.Name = "coredns.kube-system." - corednsRecord.A = net.IP("1.2.3.4") - r, _ := k.parseRequest("ns.dns.inter.webs.test.", dns.TypeA, "inter.webs.test.") - - expected := "/coredns/test/webs/inter/dns/ns" - svc := k.defaultNSMsg(r) - if svc.Key != expected { - t.Errorf("Expected result '%v'. Instead got result '%v'.", expected, svc.Key) - } -} - -func TestIsDefaultNS(t *testing.T) { - k := Kubernetes{Zones: []string{"inter.webs.test."}} - r, _ := k.parseRequest("ns.dns.inter.webs.test", dns.TypeA, "inter.webs.test.") - - var name string - var expected bool - - name = "ns.dns.inter.webs.test." - expected = true - if isDefaultNS(name, r) != expected { - t.Errorf("Expected IsDefaultNS('%v') to be '%v'.", name, expected) - } - name = "ns.dns.blah.inter.webs.test" - expected = false - if isDefaultNS(name, r) != expected { - t.Errorf("Expected IsDefaultNS('%v') to be '%v'.", name, expected) - } -} + "k8s.io/client-go/1.5/pkg/api" +) type APIConnTest struct{} @@ -83,24 +52,20 @@ func (APIConnTest) EndpointsList() api.EndpointsList { func (APIConnTest) GetNodeByName(name string) (api.Node, error) { return api.Node{}, nil } -func TestDoCoreDNSRecord(t *testing.T) { +func TestNsAddr(t *testing.T) { - corednsRecord = dns.A{} k := Kubernetes{Zones: []string{"inter.webs.test"}} - k.interfaceAddrsFunc = func() net.IP { return net.ParseIP("172.0.40.10") } - k.APIConn = &APIConnTest{} - cdr := k.coreDNSRecord() - + cdr := k.nsAddr() expected := "10.0.0.111" if cdr.A.String() != expected { - t.Errorf("Expected A to be '%v', got '%v'", expected, cdr.A.String()) + t.Errorf("Expected A to be %q, got %q", expected, cdr.A.String()) } expected = "dns-service.kube-system.svc." if cdr.Hdr.Name != expected { - t.Errorf("Expected Hdr.Name to be '%v', got '%v'", expected, cdr.Hdr.Name) + t.Errorf("Expected Hdr.Name to be %q, got %q", expected, cdr.Hdr.Name) } }