aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugin/federation/kubernetes_api_test.go27
-rw-r--r--plugin/kubernetes/controller.go90
-rw-r--r--plugin/kubernetes/handler_test.go169
-rw-r--r--plugin/kubernetes/kubernetes.go9
-rw-r--r--plugin/kubernetes/kubernetes_test.go115
-rw-r--r--plugin/kubernetes/local.go16
-rw-r--r--plugin/kubernetes/ns.go21
-rw-r--r--plugin/kubernetes/ns_test.go54
-rw-r--r--plugin/kubernetes/object/endpoint.go4
-rw-r--r--plugin/kubernetes/object/service.go2
-rw-r--r--plugin/kubernetes/reverse.go36
-rw-r--r--plugin/kubernetes/reverse_test.go68
-rw-r--r--plugin/kubernetes/xfr.go58
13 files changed, 379 insertions, 290 deletions
diff --git a/plugin/federation/kubernetes_api_test.go b/plugin/federation/kubernetes_api_test.go
index 2fa274a6d..4b62605d1 100644
--- a/plugin/federation/kubernetes_api_test.go
+++ b/plugin/federation/kubernetes_api_test.go
@@ -16,24 +16,22 @@ type APIConnFederationTest struct {
func (APIConnFederationTest) HasSynced() bool { return true }
func (APIConnFederationTest) Run() { return }
func (APIConnFederationTest) Stop() error { return nil }
-func (APIConnFederationTest) SvcIndexReverse(string) *object.Service { return nil }
-func (APIConnFederationTest) EpIndexReverse(string) *object.Endpoints { return nil }
+func (APIConnFederationTest) SvcIndexReverse(string) []*object.Service { return nil }
+func (APIConnFederationTest) EpIndexReverse(string) []*object.Endpoints { return nil }
func (APIConnFederationTest) Modified() int64 { return 0 }
func (APIConnFederationTest) SetWatchChan(watch.Chan) {}
func (APIConnFederationTest) Watch(string) error { return nil }
func (APIConnFederationTest) StopWatching(string) {}
-
func (APIConnFederationTest) PodIndex(string) []*object.Pod {
return []*object.Pod{
{Namespace: "podns", PodIP: "10.240.0.1"}, // Remote IP set in test.ResponseWriter
}
}
-
-func (APIConnFederationTest) SvcIndex(key string) *object.Service {
- svcs := map[string]*object.Service{
- "testns/svc1": {
+func (APIConnFederationTest) SvcIndex(string) []*object.Service {
+ svcs := []*object.Service{
+ {
Name: "svc1",
Namespace: "testns",
ClusterIP: "10.0.0.1",
@@ -41,12 +39,12 @@ func (APIConnFederationTest) SvcIndex(key string) *object.Service {
{Name: "http", Protocol: "tcp", Port: 80},
},
},
- "testns/hdls1": {
+ {
Name: "hdls1",
Namespace: "testns",
ClusterIP: api.ClusterIPNone,
},
- "testns/external": {
+ {
Name: "external",
Namespace: "testns",
ExternalName: "ext.interwebs.test",
@@ -55,10 +53,9 @@ func (APIConnFederationTest) SvcIndex(key string) *object.Service {
},
},
}
- return svcs[key]
+ return svcs
}
-
func (APIConnFederationTest) ServiceList() []*object.Service {
svcs := []*object.Service{
{
@@ -86,9 +83,9 @@ func (APIConnFederationTest) ServiceList() []*object.Service {
return svcs
}
-func (APIConnFederationTest) EpIndex(key string) *object.Endpoints {
- eps := map[string]*object.Endpoints{
- "testns/svc1": {
+func (APIConnFederationTest) EpIndex(string) []*object.Endpoints {
+ eps := []*object.Endpoints{
+ {
Subsets: []object.EndpointSubset{
{
Addresses: []object.EndpointAddress{
@@ -103,7 +100,7 @@ func (APIConnFederationTest) EpIndex(key string) *object.Endpoints {
Namespace: "testns",
},
}
- return eps[key]
+ return eps
}
func (APIConnFederationTest) EndpointsList() []*object.Endpoints {
diff --git a/plugin/kubernetes/controller.go b/plugin/kubernetes/controller.go
index b1619a624..1c41b6ddf 100644
--- a/plugin/kubernetes/controller.go
+++ b/plugin/kubernetes/controller.go
@@ -20,19 +20,21 @@ import (
)
const (
- podIPIndex = "PodIP"
- svcIPIndex = "ServiceIP"
- epIPIndex = "EndpointsIP"
+ podIPIndex = "PodIP"
+ svcNameNamespaceIndex = "NameNamespace"
+ svcIPIndex = "ServiceIP"
+ epNameNamespaceIndex = "EndpointNameNamespace"
+ epIPIndex = "EndpointsIP"
)
type dnsController interface {
ServiceList() []*object.Service
EndpointsList() []*object.Endpoints
- SvcIndex(string) *object.Service
- SvcIndexReverse(string) *object.Service
+ SvcIndex(string) []*object.Service
+ SvcIndexReverse(string) []*object.Service
PodIndex(string) []*object.Pod
- EpIndex(string) *object.Endpoints
- EpIndexReverse(string) *object.Endpoints
+ EpIndex(string) []*object.Endpoints
+ EpIndexReverse(string) []*object.Endpoints
GetNodeByName(string) (*api.Node, error)
GetNamespaceByName(string) (*api.Namespace, error)
@@ -116,7 +118,7 @@ func newdnsController(kubeClient kubernetes.Interface, opts dnsControlOpts) *dns
&object.Service{},
opts.resyncPeriod,
cache.ResourceEventHandlerFuncs{AddFunc: dns.Add, UpdateFunc: dns.Update, DeleteFunc: dns.Delete},
- cache.Indexers{svcIPIndex: svcIPIndexFunc},
+ cache.Indexers{svcNameNamespaceIndex: svcNameNamespaceIndexFunc, svcIPIndex: svcIPIndexFunc},
object.ToService,
)
@@ -143,7 +145,7 @@ func newdnsController(kubeClient kubernetes.Interface, opts dnsControlOpts) *dns
&api.Endpoints{},
opts.resyncPeriod,
cache.ResourceEventHandlerFuncs{AddFunc: dns.Add, UpdateFunc: dns.Update, DeleteFunc: dns.Delete},
- cache.Indexers{epIPIndex: epIPIndexFunc},
+ cache.Indexers{epNameNamespaceIndex: epNameNamespaceIndexFunc, epIPIndex: epIPIndexFunc},
object.ToEndpoints)
}
@@ -173,6 +175,22 @@ func svcIPIndexFunc(obj interface{}) ([]string, error) {
return []string{svc.ClusterIP}, nil
}
+func svcNameNamespaceIndexFunc(obj interface{}) ([]string, error) {
+ s, ok := obj.(*object.Service)
+ if !ok {
+ return nil, errObj
+ }
+ return []string{s.Index}, nil
+}
+
+func epNameNamespaceIndexFunc(obj interface{}) ([]string, error) {
+ s, ok := obj.(*object.Endpoints)
+ if !ok {
+ return nil, errObj
+ }
+ return []string{s.Index}, nil
+}
+
func epIPIndexFunc(obj interface{}) ([]string, error) {
ep, ok := obj.(*object.Endpoints)
if !ok {
@@ -341,9 +359,6 @@ func (dns *dnsControl) EndpointsList() (eps []*object.Endpoints) {
}
func (dns *dnsControl) PodIndex(ip string) (pods []*object.Pod) {
- if dns.podLister == nil {
- return nil
- }
os, err := dns.podLister.ByIndex(podIPIndex, ip)
if err != nil {
return nil
@@ -353,24 +368,27 @@ func (dns *dnsControl) PodIndex(ip string) (pods []*object.Pod) {
if !ok {
continue
}
- return []*object.Pod{p}
+ pods = append(pods, p)
}
- return nil
+ return pods
}
-func (dns *dnsControl) SvcIndex(key string) *object.Service {
- o, _, err := dns.svcLister.GetByKey(key)
+func (dns *dnsControl) SvcIndex(idx string) (svcs []*object.Service) {
+ os, err := dns.svcLister.ByIndex(svcNameNamespaceIndex, idx)
if err != nil {
return nil
}
- s, ok := o.(*object.Service)
- if !ok {
- return nil
+ for _, o := range os {
+ s, ok := o.(*object.Service)
+ if !ok {
+ continue
+ }
+ svcs = append(svcs, s)
}
- return s
+ return svcs
}
-func (dns *dnsControl) SvcIndexReverse(ip string) *object.Service {
+func (dns *dnsControl) SvcIndexReverse(ip string) (svcs []*object.Service) {
os, err := dns.svcLister.ByIndex(svcIPIndex, ip)
if err != nil {
return nil
@@ -381,27 +399,27 @@ func (dns *dnsControl) SvcIndexReverse(ip string) *object.Service {
if !ok {
continue
}
- return s
+ svcs = append(svcs, s)
}
- return nil
+ return svcs
}
-func (dns *dnsControl) EpIndex(key string) (ep *object.Endpoints) {
- o, _, err := dns.epLister.GetByKey(key)
+func (dns *dnsControl) EpIndex(idx string) (ep []*object.Endpoints) {
+ os, err := dns.epLister.ByIndex(epNameNamespaceIndex, idx)
if err != nil {
return nil
}
- e, ok := o.(*object.Endpoints)
- if !ok {
- return nil
+ for _, o := range os {
+ e, ok := o.(*object.Endpoints)
+ if !ok {
+ continue
+ }
+ ep = append(ep, e)
}
- return e
+ return ep
}
-func (dns *dnsControl) EpIndexReverse(ip string) (ep *object.Endpoints) {
- if dns.epLister == nil {
- return nil
- }
+func (dns *dnsControl) EpIndexReverse(ip string) (ep []*object.Endpoints) {
os, err := dns.epLister.ByIndex(epIPIndex, ip)
if err != nil {
return nil
@@ -411,9 +429,9 @@ func (dns *dnsControl) EpIndexReverse(ip string) (ep *object.Endpoints) {
if !ok {
continue
}
- return e
+ ep = append(ep, e)
}
- return nil
+ return ep
}
// GetNodeByName return the node by name. If nothing is found an error is
@@ -432,7 +450,7 @@ func (dns *dnsControl) GetNamespaceByName(name string) (*api.Namespace, error) {
if !ok {
continue
}
- if name == ns.GetName() {
+ if name == ns.ObjectMeta.Name {
return ns, nil
}
}
diff --git a/plugin/kubernetes/handler_test.go b/plugin/kubernetes/handler_test.go
index b3353af1b..604f00fab 100644
--- a/plugin/kubernetes/handler_test.go
+++ b/plugin/kubernetes/handler_test.go
@@ -379,15 +379,15 @@ func TestServeDNS(t *testing.T) {
type APIConnServeTest struct{}
-func (APIConnServeTest) HasSynced() bool { return true }
-func (APIConnServeTest) Run() { return }
-func (APIConnServeTest) Stop() error { return nil }
-func (APIConnServeTest) EpIndexReverse(string) *object.Endpoints { return nil }
-func (APIConnServeTest) SvcIndexReverse(string) *object.Service { return nil }
-func (APIConnServeTest) Modified() int64 { return time.Now().Unix() }
-func (APIConnServeTest) SetWatchChan(watch.Chan) {}
-func (APIConnServeTest) Watch(string) error { return nil }
-func (APIConnServeTest) StopWatching(string) {}
+func (APIConnServeTest) HasSynced() bool { return true }
+func (APIConnServeTest) Run() { return }
+func (APIConnServeTest) Stop() error { return nil }
+func (APIConnServeTest) EpIndexReverse(string) []*object.Endpoints { return nil }
+func (APIConnServeTest) SvcIndexReverse(string) []*object.Service { return nil }
+func (APIConnServeTest) Modified() int64 { return time.Now().Unix() }
+func (APIConnServeTest) SetWatchChan(watch.Chan) {}
+func (APIConnServeTest) Watch(string) error { return nil }
+func (APIConnServeTest) StopWatching(string) {}
func (APIConnServeTest) PodIndex(string) []*object.Pod {
a := []*object.Pod{
@@ -396,90 +396,103 @@ func (APIConnServeTest) PodIndex(string) []*object.Pod {
return a
}
-var svcIndex = map[string]*object.Service{
- "testns/svc1": {
- Name: "svc1",
- Namespace: "testns",
- Type: api.ServiceTypeClusterIP,
- ClusterIP: "10.0.0.1",
- Ports: []api.ServicePort{
- {Name: "http", Protocol: "tcp", Port: 80},
+var svcIndex = map[string][]*object.Service{
+ "svc1.testns": {
+ {
+ Name: "svc1",
+ Namespace: "testns",
+ Type: api.ServiceTypeClusterIP,
+ ClusterIP: "10.0.0.1",
+ Ports: []api.ServicePort{
+ {Name: "http", Protocol: "tcp", Port: 80},
+ },
},
},
- "testns/svcempty": {
- Name: "svcempty",
- Namespace: "testns",
- Type: api.ServiceTypeClusterIP,
- ClusterIP: "10.0.0.1",
- Ports: []api.ServicePort{
- {Name: "http", Protocol: "tcp", Port: 80},
+ "svcempty.testns": {
+ {
+ Name: "svcempty",
+ Namespace: "testns",
+ Type: api.ServiceTypeClusterIP,
+ ClusterIP: "10.0.0.1",
+ Ports: []api.ServicePort{
+ {Name: "http", Protocol: "tcp", Port: 80},
+ },
},
},
- "testns/svc6": {
- Name: "svc6",
- Namespace: "testns",
- Type: api.ServiceTypeClusterIP,
- ClusterIP: "1234:abcd::1",
- Ports: []api.ServicePort{
- {Name: "http", Protocol: "tcp", Port: 80},
+ "svc6.testns": {
+ {
+ Name: "svc6",
+ Namespace: "testns",
+ Type: api.ServiceTypeClusterIP,
+ ClusterIP: "1234:abcd::1",
+ Ports: []api.ServicePort{
+ {Name: "http", Protocol: "tcp", Port: 80},
+ },
},
},
- "testns/hdls1": {
- Name: "hdls1",
- Namespace: "testns",
- Type: api.ServiceTypeClusterIP,
- ClusterIP: api.ClusterIPNone,
+ "hdls1.testns": {
+ {
+ Name: "hdls1",
+ Namespace: "testns",
+ Type: api.ServiceTypeClusterIP,
+ ClusterIP: api.ClusterIPNone,
+ },
},
- "testns/external": {
-
- Name: "external",
- Namespace: "testns",
- ExternalName: "ext.interwebs.test",
- Type: api.ServiceTypeExternalName,
- Ports: []api.ServicePort{
- {Name: "http", Protocol: "tcp", Port: 80},
+ "external.testns": {
+ {
+ Name: "external",
+ Namespace: "testns",
+ ExternalName: "ext.interwebs.test",
+ Type: api.ServiceTypeExternalName,
+ Ports: []api.ServicePort{
+ {Name: "http", Protocol: "tcp", Port: 80},
+ },
},
},
- "testns/external-to-service": {
- Name: "external-to-service",
- Namespace: "testns",
- ExternalName: "svc1.testns.svc.cluster.local.",
- Type: api.ServiceTypeExternalName,
- Ports: []api.ServicePort{
- {Name: "http", Protocol: "tcp", Port: 80},
+ "external-to-service.testns": {
+ {
+ Name: "external-to-service",
+ Namespace: "testns",
+ ExternalName: "svc1.testns.svc.cluster.local.",
+ Type: api.ServiceTypeExternalName,
+ Ports: []api.ServicePort{
+ {Name: "http", Protocol: "tcp", Port: 80},
+ },
},
},
- "testns/hdlsprtls": {
- Name: "hdlsprtls",
- Namespace: "testns",
- Type: api.ServiceTypeClusterIP,
- ClusterIP: api.ClusterIPNone,
+ "hdlsprtls.testns": {
+ {
+ Name: "hdlsprtls",
+ Namespace: "testns",
+ Type: api.ServiceTypeClusterIP,
+ ClusterIP: api.ClusterIPNone,
+ },
},
- "unexposedns/svc1": {
- Name: "svc1",
- Namespace: "unexposedns",
- Type: api.ServiceTypeClusterIP,
- ClusterIP: "10.0.0.2",
- Ports: []api.ServicePort{
- {Name: "http", Protocol: "tcp", Port: 80},
+ "svc1.unexposedns": {
+ {
+ Name: "svc1",
+ Namespace: "unexposedns",
+ Type: api.ServiceTypeClusterIP,
+ ClusterIP: "10.0.0.2",
+ Ports: []api.ServicePort{
+ {Name: "http", Protocol: "tcp", Port: 80},
+ },
},
},
}
-func (APIConnServeTest) SvcIndex(s string) *object.Service {
- return svcIndex[s]
-}
+func (APIConnServeTest) SvcIndex(s string) []*object.Service { return svcIndex[s] }
func (APIConnServeTest) ServiceList() []*object.Service {
var svcs []*object.Service
for _, svc := range svcIndex {
- svcs = append(svcs, svc)
+ svcs = append(svcs, svc...)
}
return svcs
}
-var epsIndex = map[string]*object.Endpoints{
- "testns/svc1": {
+var epsIndex = map[string][]*object.Endpoints{
+ "svc1.testns": {{
Subsets: []object.EndpointSubset{
{
Addresses: []object.EndpointAddress{
@@ -492,8 +505,8 @@ var epsIndex = map[string]*object.Endpoints{
},
Name: "svc1",
Namespace: "testns",
- },
- "testns/svcempty": {
+ }},
+ "svcempty.testns": {{
Subsets: []object.EndpointSubset{
{
Addresses: nil,
@@ -504,8 +517,8 @@ var epsIndex = map[string]*object.Endpoints{
},
Name: "svcempty",
Namespace: "testns",
- },
- "testns/hdls1": {
+ }},
+ "hdls1.testns": {{
Subsets: []object.EndpointSubset{
{
Addresses: []object.EndpointAddress{
@@ -523,8 +536,8 @@ var epsIndex = map[string]*object.Endpoints{
},
Name: "hdls1",
Namespace: "testns",
- },
- "testns/hdlsprtls": {
+ }},
+ "hdlsprtls.testns": {{
Subsets: []object.EndpointSubset{
{
Addresses: []object.EndpointAddress{
@@ -535,17 +548,17 @@ var epsIndex = map[string]*object.Endpoints{
},
Name: "hdlsprtls",
Namespace: "testns",
- },
+ }},
}
-func (APIConnServeTest) EpIndex(s string) *object.Endpoints {
+func (APIConnServeTest) EpIndex(s string) []*object.Endpoints {
return epsIndex[s]
}
func (APIConnServeTest) EndpointsList() []*object.Endpoints {
var eps []*object.Endpoints
for _, ep := range epsIndex {
- eps = append(eps, ep)
+ eps = append(eps, ep...)
}
return eps
}
diff --git a/plugin/kubernetes/kubernetes.go b/plugin/kubernetes/kubernetes.go
index 8ba21a70e..81cf19492 100644
--- a/plugin/kubernetes/kubernetes.go
+++ b/plugin/kubernetes/kubernetes.go
@@ -444,12 +444,9 @@ func (k *Kubernetes) findServices(r recordRequest, zone string) (services []msg.
serviceList = k.APIConn.ServiceList()
endpointsListFunc = func() []*object.Endpoints { return k.APIConn.EndpointsList() }
} else {
- key := object.ServiceKey(r.namespace, r.service)
- s := k.APIConn.SvcIndex(key)
- if s != nil {
- serviceList = append(serviceList, s)
- }
- endpointsListFunc = func() []*object.Endpoints { return []*object.Endpoints{k.APIConn.EpIndex(key)} }
+ idx := object.ServiceKey(r.service, r.namespace)
+ serviceList = k.APIConn.SvcIndex(idx)
+ endpointsListFunc = func() []*object.Endpoints { return k.APIConn.EpIndex(idx) }
}
for _, svc := range serviceList {
diff --git a/plugin/kubernetes/kubernetes_test.go b/plugin/kubernetes/kubernetes_test.go
index b8274d01b..f35c9cd2c 100644
--- a/plugin/kubernetes/kubernetes_test.go
+++ b/plugin/kubernetes/kubernetes_test.go
@@ -59,24 +59,43 @@ func TestEndpointHostname(t *testing.T) {
type APIConnServiceTest struct{}
-func (APIConnServiceTest) HasSynced() bool { return true }
-func (APIConnServiceTest) Run() { return }
-func (APIConnServiceTest) Stop() error { return nil }
-func (APIConnServiceTest) PodIndex(string) []*object.Pod { return nil }
-func (APIConnServiceTest) SvcIndexReverse(string) *object.Service { return nil }
-func (APIConnServiceTest) EpIndexReverse(string) *object.Endpoints { return nil }
-func (APIConnServiceTest) Modified() int64 { return 0 }
-func (APIConnServiceTest) SetWatchChan(watch.Chan) {}
-func (APIConnServiceTest) Watch(string) error { return nil }
-func (APIConnServiceTest) StopWatching(string) {}
+func (APIConnServiceTest) HasSynced() bool { return true }
+func (APIConnServiceTest) Run() { return }
+func (APIConnServiceTest) Stop() error { return nil }
+func (APIConnServiceTest) PodIndex(string) []*object.Pod { return nil }
+func (APIConnServiceTest) SvcIndexReverse(string) []*object.Service { return nil }
+func (APIConnServiceTest) EpIndexReverse(string) []*object.Endpoints { return nil }
+func (APIConnServiceTest) Modified() int64 { return 0 }
+func (APIConnServiceTest) SetWatchChan(watch.Chan) {}
+func (APIConnServiceTest) Watch(string) error { return nil }
+func (APIConnServiceTest) StopWatching(string) {}
-func (a APIConnServiceTest) SvcIndex(key string) *object.Service {
- for _, s := range a.ServiceList() {
- if object.ServiceKey(s.Namespace, s.Name) == key {
- return s
- }
+func (APIConnServiceTest) SvcIndex(string) []*object.Service {
+ svcs := []*object.Service{
+ {
+ Name: "svc1",
+ Namespace: "testns",
+ ClusterIP: "10.0.0.1",
+ Ports: []api.ServicePort{
+ {Name: "http", Protocol: "tcp", Port: 80},
+ },
+ },
+ {
+ Name: "hdls1",
+ Namespace: "testns",
+ ClusterIP: api.ClusterIPNone,
+ },
+ {
+ Name: "external",
+ Namespace: "testns",
+ ExternalName: "coredns.io",
+ Type: api.ServiceTypeExternalName,
+ Ports: []api.ServicePort{
+ {Name: "http", Protocol: "tcp", Port: 80},
+ },
+ },
}
- return nil
+ return svcs
}
func (APIConnServiceTest) ServiceList() []*object.Service {
@@ -107,13 +126,61 @@ func (APIConnServiceTest) ServiceList() []*object.Service {
return svcs
}
-func (a APIConnServiceTest) EpIndex(key string) *object.Endpoints {
- for _, e := range a.EndpointsList() {
- if object.EndpointsKey(e.Namespace, e.Name) == key {
- return e
- }
+func (APIConnServiceTest) EpIndex(string) []*object.Endpoints {
+ eps := []*object.Endpoints{
+ {
+ Subsets: []object.EndpointSubset{
+ {
+ Addresses: []object.EndpointAddress{
+ {IP: "172.0.0.1", Hostname: "ep1a"},
+ },
+ Ports: []object.EndpointPort{
+ {Port: 80, Protocol: "tcp", Name: "http"},
+ },
+ },
+ },
+ Name: "svc1",
+ Namespace: "testns",
+ },
+ {
+ Subsets: []object.EndpointSubset{
+ {
+ Addresses: []object.EndpointAddress{
+ {IP: "172.0.0.2"},
+ },
+ Ports: []object.EndpointPort{
+ {Port: 80, Protocol: "tcp", Name: "http"},
+ },
+ },
+ },
+ Name: "hdls1",
+ Namespace: "testns",
+ },
+ {
+ Subsets: []object.EndpointSubset{
+ {
+ Addresses: []object.EndpointAddress{
+ {IP: "172.0.0.3"},
+ },
+ Ports: []object.EndpointPort{
+ {Port: 80, Protocol: "tcp", Name: "http"},
+ },
+ },
+ },
+ Name: "hdls1",
+ Namespace: "testns",
+ },
+ {
+ Subsets: []object.EndpointSubset{
+ {
+ Addresses: []object.EndpointAddress{
+ {IP: "10.9.8.7", NodeName: "test.node.foo.bar"},
+ },
+ },
+ },
+ },
}
- return nil
+ return eps
}
func (APIConnServiceTest) EndpointsList() []*object.Endpoints {
@@ -157,7 +224,7 @@ func (APIConnServiceTest) EndpointsList() []*object.Endpoints {
},
},
},
- Name: "hdls2",
+ Name: "hdls1",
Namespace: "testns",
},
{
@@ -168,8 +235,6 @@ func (APIConnServiceTest) EndpointsList() []*object.Endpoints {
},
},
},
- Name: "testsvc",
- Namespace: "testns",
},
}
return eps
diff --git a/plugin/kubernetes/local.go b/plugin/kubernetes/local.go
index 7a85de1bf..e15fec497 100644
--- a/plugin/kubernetes/local.go
+++ b/plugin/kubernetes/local.go
@@ -28,18 +28,14 @@ func (k *Kubernetes) localNodeName() string {
}
// Find endpoint matching localIP
- ep := k.APIConn.EpIndexReverse(localIP.String())
- if ep == nil {
- return ""
- }
-
- for _, eps := range ep.Subsets {
- for _, addr := range eps.Addresses {
- if localIP.Equal(net.ParseIP(addr.IP)) {
- return addr.NodeName
+ for _, ep := range k.APIConn.EpIndexReverse(localIP.String()) {
+ for _, eps := range ep.Subsets {
+ for _, addr := range eps.Addresses {
+ if localIP.Equal(net.ParseIP(addr.IP)) {
+ return addr.NodeName
+ }
}
}
}
-
return ""
}
diff --git a/plugin/kubernetes/ns.go b/plugin/kubernetes/ns.go
index 722dc9ef4..2ccb51ef3 100644
--- a/plugin/kubernetes/ns.go
+++ b/plugin/kubernetes/ns.go
@@ -4,7 +4,6 @@ import (
"net"
"strings"
- "github.com/coredns/coredns/plugin/kubernetes/object"
"github.com/miekg/dns"
api "k8s.io/api/core/v1"
)
@@ -23,9 +22,8 @@ func (k *Kubernetes) nsAddr() *dns.A {
localIP := k.interfaceAddrsFunc()
rr.A = localIP
- ep := k.APIConn.EpIndexReverse(localIP.String())
- if ep != nil {
- FindEndpoint:
+FindEndpoint:
+ for _, ep := range k.APIConn.EpIndexReverse(localIP.String()) {
for _, eps := range ep.Subsets {
for _, addr := range eps.Addresses {
if localIP.Equal(net.ParseIP(addr.IP)) {
@@ -43,12 +41,15 @@ func (k *Kubernetes) nsAddr() *dns.A {
return rr
}
- svc := k.APIConn.SvcIndex(object.ServiceKey(svcNamespace, svcName))
- if svc != nil {
- if svc.ClusterIP == api.ClusterIPNone {
- rr.A = localIP
- } else {
- rr.A = net.ParseIP(svc.ClusterIP)
+FindService:
+ for _, svc := range k.APIConn.ServiceList() {
+ if svcName == svc.Name && svcNamespace == svc.Namespace {
+ if svc.ClusterIP == api.ClusterIPNone {
+ rr.A = localIP
+ } else {
+ rr.A = net.ParseIP(svc.ClusterIP)
+ }
+ break FindService
}
}
diff --git a/plugin/kubernetes/ns_test.go b/plugin/kubernetes/ns_test.go
index c9025288b..fd781bc14 100644
--- a/plugin/kubernetes/ns_test.go
+++ b/plugin/kubernetes/ns_test.go
@@ -11,26 +11,18 @@ import (
type APIConnTest struct{}
-func (APIConnTest) HasSynced() bool { return true }
-func (APIConnTest) Run() { return }
-func (APIConnTest) Stop() error { return nil }
-func (APIConnTest) PodIndex(string) []*object.Pod { return nil }
-func (APIConnTest) SvcIndexReverse(string) *object.Service { return nil }
-func (APIConnTest) EpIndex(string) *object.Endpoints { return nil }
-func (APIConnTest) EndpointsList() []*object.Endpoints { return nil }
-func (APIConnTest) Modified() int64 { return 0 }
-func (APIConnTest) SetWatchChan(watch.Chan) {}
-func (APIConnTest) Watch(string) error { return nil }
-func (APIConnTest) StopWatching(string) {}
-
-func (a APIConnTest) SvcIndex(key string) *object.Service {
- for _, s := range a.ServiceList() {
- if object.ServiceKey(s.Namespace, s.Name) == key {
- return s
- }
- }
- return nil
-}
+func (APIConnTest) HasSynced() bool { return true }
+func (APIConnTest) Run() { return }
+func (APIConnTest) Stop() error { return nil }
+func (APIConnTest) PodIndex(string) []*object.Pod { return nil }
+func (APIConnTest) SvcIndex(string) []*object.Service { return nil }
+func (APIConnTest) SvcIndexReverse(string) []*object.Service { return nil }
+func (APIConnTest) EpIndex(string) []*object.Endpoints { return nil }
+func (APIConnTest) EndpointsList() []*object.Endpoints { return nil }
+func (APIConnTest) Modified() int64 { return 0 }
+func (APIConnTest) SetWatchChan(watch.Chan) {}
+func (APIConnTest) Watch(string) error { return nil }
+func (APIConnTest) StopWatching(string) {}
func (APIConnTest) ServiceList() []*object.Service {
svcs := []*object.Service{
@@ -43,21 +35,23 @@ func (APIConnTest) ServiceList() []*object.Service {
return svcs
}
-func (APIConnTest) EpIndexReverse(string) *object.Endpoints {
- eps := object.Endpoints{
- Subsets: []object.EndpointSubset{
- {
- Addresses: []object.EndpointAddress{
- {
- IP: "127.0.0.1",
+func (APIConnTest) EpIndexReverse(string) []*object.Endpoints {
+ eps := []*object.Endpoints{
+ {
+ Subsets: []object.EndpointSubset{
+ {
+ Addresses: []object.EndpointAddress{
+ {
+ IP: "127.0.0.1",
+ },
},
},
},
+ Name: "dns-service",
+ Namespace: "kube-system",
},
- Name: "dns-service",
- Namespace: "kube-system",
}
- return &eps
+ return eps
}
func (APIConnTest) GetNodeByName(name string) (*api.Node, error) { return &api.Node{}, nil }
diff --git a/plugin/kubernetes/object/endpoint.go b/plugin/kubernetes/object/endpoint.go
index a391c6426..b8531f050 100644
--- a/plugin/kubernetes/object/endpoint.go
+++ b/plugin/kubernetes/object/endpoint.go
@@ -40,7 +40,7 @@ type EndpointPort struct {
}
// EndpointsKey return a string using for the index.
-func EndpointsKey(namespace, name string) string { return namespace + "/" + name }
+func EndpointsKey(name, namespace string) string { return name + "." + namespace }
// ToEndpoints converts an api.Service to a *Service.
func ToEndpoints(obj interface{}) interface{} {
@@ -61,7 +61,7 @@ func ToEndpoints(obj interface{}) interface{} {
Addresses: make([]EndpointAddress, len(eps.Addresses)),
}
if len(eps.Ports) == 0 {
- // Add sentinel if there are no ports.
+ // Add sentinal if there are no ports.
sub.Ports = []EndpointPort{{Port: -1}}
} else {
sub.Ports = make([]EndpointPort, len(eps.Ports))
diff --git a/plugin/kubernetes/object/service.go b/plugin/kubernetes/object/service.go
index 1c716b28b..be010e96b 100644
--- a/plugin/kubernetes/object/service.go
+++ b/plugin/kubernetes/object/service.go
@@ -20,7 +20,7 @@ type Service struct {
}
// ServiceKey return a string using for the index.
-func ServiceKey(namespace, name string) string { return namespace + "/" + name }
+func ServiceKey(name, namespace string) string { return name + "." + namespace }
// ToService converts an api.Service to a *Service.
func ToService(obj interface{}) interface{} {
diff --git a/plugin/kubernetes/reverse.go b/plugin/kubernetes/reverse.go
index 1e060283c..5873bcbc8 100644
--- a/plugin/kubernetes/reverse.go
+++ b/plugin/kubernetes/reverse.go
@@ -18,35 +18,35 @@ func (k *Kubernetes) Reverse(state request.Request, exact bool, opt plugin.Optio
return nil, e
}
- record := k.serviceRecordForIP(ip, state.Name())
- if record == nil {
- return nil, errNoItems
+ records := k.serviceRecordForIP(ip, state.Name())
+ if len(records) == 0 {
+ return records, errNoItems
}
- return []msg.Service{*record}, nil
+ return records, nil
}
// serviceRecordForIP gets a service record with a cluster ip matching the ip argument
// If a service cluster ip does not match, it checks all endpoints
-func (k *Kubernetes) serviceRecordForIP(ip, name string) *msg.Service {
+func (k *Kubernetes) serviceRecordForIP(ip, name string) []msg.Service {
// First check services with cluster ips
- service := k.APIConn.SvcIndexReverse(ip)
- if service != nil {
+ for _, service := range k.APIConn.SvcIndexReverse(ip) {
if len(k.Namespaces) > 0 && !k.namespaceExposed(service.Namespace) {
- return nil
+ continue
}
domain := strings.Join([]string{service.Name, service.Namespace, Svc, k.primaryZone()}, ".")
- return &msg.Service{Host: domain, TTL: k.ttl}
+ return []msg.Service{{Host: domain, TTL: k.ttl}}
}
// If no cluster ips match, search endpoints
- ep := k.APIConn.EpIndexReverse(ip)
- if ep == nil || len(k.Namespaces) > 0 && !k.namespaceExposed(ep.Namespace) {
- return nil
- }
- for _, eps := range ep.Subsets {
- for _, addr := range eps.Addresses {
- if addr.IP == ip {
- domain := strings.Join([]string{endpointHostname(addr, k.endpointNameMode), ep.Name, ep.Namespace, Svc, k.primaryZone()}, ".")
- return &msg.Service{Host: domain, TTL: k.ttl}
+ for _, ep := range k.APIConn.EpIndexReverse(ip) {
+ if len(k.Namespaces) > 0 && !k.namespaceExposed(ep.Namespace) {
+ continue
+ }
+ for _, eps := range ep.Subsets {
+ for _, addr := range eps.Addresses {
+ if addr.IP == ip {
+ domain := strings.Join([]string{endpointHostname(addr, k.endpointNameMode), ep.Name, ep.Namespace, Svc, k.primaryZone()}, ".")
+ return []msg.Service{{Host: domain, TTL: k.ttl}}
+ }
}
}
}
diff --git a/plugin/kubernetes/reverse_test.go b/plugin/kubernetes/reverse_test.go
index 20c8496c7..a706b7585 100644
--- a/plugin/kubernetes/reverse_test.go
+++ b/plugin/kubernetes/reverse_test.go
@@ -20,7 +20,7 @@ func (APIConnReverseTest) HasSynced() bool { return true }
func (APIConnReverseTest) Run() { return }
func (APIConnReverseTest) Stop() error { return nil }
func (APIConnReverseTest) PodIndex(string) []*object.Pod { return nil }
-func (APIConnReverseTest) EpIndex(string) *object.Endpoints { return nil }
+func (APIConnReverseTest) EpIndex(string) []*object.Endpoints { return nil }
func (APIConnReverseTest) EndpointsList() []*object.Endpoints { return nil }
func (APIConnReverseTest) ServiceList() []*object.Service { return nil }
func (APIConnReverseTest) Modified() int64 { return 0 }
@@ -28,34 +28,38 @@ func (APIConnReverseTest) SetWatchChan(watch.Chan) {}
func (APIConnReverseTest) Watch(string) error { return nil }
func (APIConnReverseTest) StopWatching(string) {}
-func (APIConnReverseTest) SvcIndex(key string) *object.Service {
- if key != "testns/svc1" {
+func (APIConnReverseTest) SvcIndex(svc string) []*object.Service {
+ if svc != "svc1.testns" {
return nil
}
- svc := object.Service{
- Name: "svc1",
- Namespace: "testns",
- ClusterIP: "192.168.1.100",
- Ports: []api.ServicePort{{Name: "http", Protocol: "tcp", Port: 80}},
+ svcs := []*object.Service{
+ {
+ Name: "svc1",
+ Namespace: "testns",
+ ClusterIP: "192.168.1.100",
+ Ports: []api.ServicePort{{Name: "http", Protocol: "tcp", Port: 80}},
+ },
}
- return &svc
+ return svcs
}
-func (APIConnReverseTest) SvcIndexReverse(ip string) *object.Service {
+func (APIConnReverseTest) SvcIndexReverse(ip string) []*object.Service {
if ip != "192.168.1.100" {
return nil
}
- svc := object.Service{
- Name: "svc1",
- Namespace: "testns",
- ClusterIP: "192.168.1.100",
- Ports: []api.ServicePort{{Name: "http", Protocol: "tcp", Port: 80}},
+ svcs := []*object.Service{
+ {
+ Name: "svc1",
+ Namespace: "testns",
+ ClusterIP: "192.168.1.100",
+ Ports: []api.ServicePort{{Name: "http", Protocol: "tcp", Port: 80}},
+ },
}
- return &svc
+ return svcs
}
-func (APIConnReverseTest) EpIndexReverse(ip string) *object.Endpoints {
+func (APIConnReverseTest) EpIndexReverse(ip string) []*object.Endpoints {
switch ip {
case "10.0.0.100":
case "1234:abcd::1":
@@ -64,24 +68,26 @@ func (APIConnReverseTest) EpIndexReverse(ip string) *object.Endpoints {
default:
return nil
}
- ep := object.Endpoints{
- Subsets: []object.EndpointSubset{
- {
- Addresses: []object.EndpointAddress{
- {IP: "10.0.0.100", Hostname: "ep1a"},
- {IP: "1234:abcd::1", Hostname: "ep1b"},
- {IP: "fd00:77:30::a", Hostname: "ip6svc1ex"},
- {IP: "fd00:77:30::2:9ba6", Hostname: "ip6svc1in"},
- },
- Ports: []object.EndpointPort{
- {Port: 80, Protocol: "tcp", Name: "http"},
+ eps := []*object.Endpoints{
+ {
+ Subsets: []object.EndpointSubset{
+ {
+ Addresses: []object.EndpointAddress{
+ {IP: "10.0.0.100", Hostname: "ep1a"},
+ {IP: "1234:abcd::1", Hostname: "ep1b"},
+ {IP: "fd00:77:30::a", Hostname: "ip6svc1ex"},
+ {IP: "fd00:77:30::2:9ba6", Hostname: "ip6svc1in"},
+ },
+ Ports: []object.EndpointPort{
+ {Port: 80, Protocol: "tcp", Name: "http"},
+ },
},
},
+ Name: "svc1",
+ Namespace: "testns",
},
- Name: "svc1",
- Namespace: "testns",
}
- return &ep
+ return eps
}
func (APIConnReverseTest) GetNodeByName(name string) (*api.Node, error) {
diff --git a/plugin/kubernetes/xfr.go b/plugin/kubernetes/xfr.go
index b76e1def9..eaf554c6a 100644
--- a/plugin/kubernetes/xfr.go
+++ b/plugin/kubernetes/xfr.go
@@ -9,7 +9,6 @@ import (
"github.com/coredns/coredns/plugin"
"github.com/coredns/coredns/plugin/etcd/msg"
"github.com/coredns/coredns/request"
- "k8s.io/client-go/tools/cache"
"github.com/miekg/dns"
api "k8s.io/api/core/v1"
@@ -115,36 +114,39 @@ func (k *Kubernetes) transfer(c chan dns.RR, zone string) {
continue
}
- key, err := cache.MetaNamespaceKeyFunc(svc)
- if err != nil {
- return
- }
- ep := k.APIConn.EpIndex(key)
- for _, eps := range ep.Subsets {
- srvWeight := calcSRVWeight(len(eps.Addresses))
- for _, addr := range eps.Addresses {
- s := msg.Service{Host: addr.IP, TTL: k.ttl}
- s.Key = strings.Join(svcBase, "/")
- // We don't need to change the msg.Service host from IP to Name yet
- // so disregard the return value here
- emitAddressRecord(c, s)
+ endpointsList := k.APIConn.EpIndex(svc.Name + "." + svc.Namespace)
- s.Key = strings.Join(append(svcBase, endpointHostname(addr, k.endpointNameMode)), "/")
- // Change host from IP to Name for SRV records
- host := emitAddressRecord(c, s)
- s.Host = host
+ for _, ep := range endpointsList {
+ if ep.Name != svc.Name || ep.Namespace != svc.Namespace {
+ continue
+ }
- for _, p := range eps.Ports {
- // As per spec unnamed ports do not have a srv record
- // https://github.com/kubernetes/dns/blob/master/docs/specification.md#232---srv-records
- if p.Name == "" {
- continue
+ for _, eps := range ep.Subsets {
+ srvWeight := calcSRVWeight(len(eps.Addresses))
+ for _, addr := range eps.Addresses {
+ s := msg.Service{Host: addr.IP, TTL: k.ttl}
+ s.Key = strings.Join(svcBase, "/")
+ // We don't need to change the msg.Service host from IP to Name yet
+ // so disregard the return value here
+ emitAddressRecord(c, s)
+
+ s.Key = strings.Join(append(svcBase, endpointHostname(addr, k.endpointNameMode)), "/")
+ // Change host from IP to Name for SRV records
+ host := emitAddressRecord(c, s)
+ s.Host = host
+
+ for _, p := range eps.Ports {
+ // As per spec unnamed ports do not have a srv record
+ // https://github.com/kubernetes/dns/blob/master/docs/specification.md#232---srv-records
+ if p.Name == "" {
+ continue
+ }
+
+ s.Port = int(p.Port)
+
+ s.Key = strings.Join(append(svcBase, strings.ToLower("_"+string(p.Protocol)), strings.ToLower("_"+string(p.Name))), "/")
+ c <- s.NewSRV(msg.Domain(s.Key), srvWeight)
}
-
- s.Port = int(p.Port)
-
- s.Key = strings.Join(append(svcBase, strings.ToLower("_"+string(p.Protocol)), strings.ToLower("_"+string(p.Name))), "/")
- c <- s.NewSRV(msg.Domain(s.Key), srvWeight)
}
}
}