aboutsummaryrefslogtreecommitdiff
path: root/plugin/kubernetes
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/kubernetes')
-rw-r--r--plugin/kubernetes/controller.go34
-rw-r--r--plugin/kubernetes/external.go37
-rw-r--r--plugin/kubernetes/external_test.go1
-rw-r--r--plugin/kubernetes/handler_test.go13
-rw-r--r--plugin/kubernetes/kubernetes_test.go15
-rw-r--r--plugin/kubernetes/ns_test.go17
-rw-r--r--plugin/kubernetes/reverse_test.go17
7 files changed, 100 insertions, 34 deletions
diff --git a/plugin/kubernetes/controller.go b/plugin/kubernetes/controller.go
index f2c349dba..f8c2ee144 100644
--- a/plugin/kubernetes/controller.go
+++ b/plugin/kubernetes/controller.go
@@ -25,6 +25,7 @@ const (
podIPIndex = "PodIP"
svcNameNamespaceIndex = "ServiceNameNamespace"
svcIPIndex = "ServiceIP"
+ svcExtIPIndex = "ServiceExternalIP"
epNameNamespaceIndex = "EndpointNameNamespace"
epIPIndex = "EndpointsIP"
)
@@ -34,6 +35,7 @@ type dnsController interface {
EndpointsList() []*object.Endpoints
SvcIndex(string) []*object.Service
SvcIndexReverse(string) []*object.Service
+ SvcExtIndexReverse(string) []*object.Service
PodIndex(string) []*object.Pod
EpIndex(string) []*object.Endpoints
EpIndexReverse(string) []*object.Endpoints
@@ -122,7 +124,7 @@ func newdnsController(ctx context.Context, kubeClient kubernetes.Interface, opts
},
&api.Service{},
cache.ResourceEventHandlerFuncs{AddFunc: dns.Add, UpdateFunc: dns.Update, DeleteFunc: dns.Delete},
- cache.Indexers{svcNameNamespaceIndex: svcNameNamespaceIndexFunc, svcIPIndex: svcIPIndexFunc},
+ cache.Indexers{svcNameNamespaceIndex: svcNameNamespaceIndexFunc, svcIPIndex: svcIPIndexFunc, svcExtIPIndex: svcExtIPIndexFunc},
object.DefaultProcessor(object.ToService, nil),
)
@@ -232,12 +234,18 @@ func svcIPIndexFunc(obj interface{}) ([]string, error) {
if !ok {
return nil, errObj
}
- idx := make([]string, len(svc.ClusterIPs)+len(svc.ExternalIPs))
+ idx := make([]string, len(svc.ClusterIPs))
copy(idx, svc.ClusterIPs)
- if len(svc.ExternalIPs) == 0 {
- return idx, nil
+ return idx, nil
+}
+
+func svcExtIPIndexFunc(obj interface{}) ([]string, error) {
+ svc, ok := obj.(*object.Service)
+ if !ok {
+ return nil, errObj
}
- copy(idx[len(svc.ClusterIPs):], svc.ExternalIPs)
+ idx := make([]string, len(svc.ExternalIPs))
+ copy(idx, svc.ExternalIPs)
return idx, nil
}
@@ -502,6 +510,22 @@ func (dns *dnsControl) SvcIndexReverse(ip string) (svcs []*object.Service) {
return svcs
}
+func (dns *dnsControl) SvcExtIndexReverse(ip string) (svcs []*object.Service) {
+ os, err := dns.svcLister.ByIndex(svcExtIPIndex, ip)
+ if err != nil {
+ return nil
+ }
+
+ for _, o := range os {
+ s, ok := o.(*object.Service)
+ if !ok {
+ continue
+ }
+ svcs = append(svcs, s)
+ }
+ return svcs
+}
+
func (dns *dnsControl) EpIndex(idx string) (ep []*object.Endpoints) {
dns.epLock.RLock()
defer dns.epLock.RUnlock()
diff --git a/plugin/kubernetes/external.go b/plugin/kubernetes/external.go
index 74e7151fc..702bdc30c 100644
--- a/plugin/kubernetes/external.go
+++ b/plugin/kubernetes/external.go
@@ -14,6 +14,18 @@ import (
// External implements the ExternalFunc call from the external plugin.
// It returns any services matching in the services' ExternalIPs.
func (k *Kubernetes) External(state request.Request) ([]msg.Service, int) {
+ if state.QType() == dns.TypePTR {
+ ip := dnsutil.ExtractAddressFromReverse(state.Name())
+ if ip != "" {
+ svcs, err := k.ExternalReverse(ip)
+ if err != nil {
+ return nil, dns.RcodeNameError
+ }
+ return svcs, dns.RcodeSuccess
+ }
+ // for invalid reverse names, fall through to determine proper nxdomain/nodata response
+ }
+
base, _ := dnsutil.TrimZone(state.Name(), state.Zone)
segs := dns.SplitDomainName(base)
@@ -76,6 +88,10 @@ func (k *Kubernetes) External(state request.Request) ([]msg.Service, int) {
}
}
}
+ if state.QType() == dns.TypePTR {
+ // if this was a PTR request, return empty service list, but retain rcode for proper nxdomain/nodata response
+ return nil, rcode
+ }
return services, rcode
}
@@ -111,3 +127,24 @@ func (k *Kubernetes) ExternalServices(zone string) (services []msg.Service) {
func (k *Kubernetes) ExternalSerial(string) uint32 {
return uint32(k.APIConn.Modified(true))
}
+
+// ExternalReverse does a reverse lookup for the external IPs
+func (k *Kubernetes) ExternalReverse(ip string) ([]msg.Service, error) {
+ records := k.serviceRecordForExternalIP(ip)
+ if len(records) == 0 {
+ return records, errNoItems
+ }
+ return records, nil
+}
+
+func (k *Kubernetes) serviceRecordForExternalIP(ip string) []msg.Service {
+ var svcs []msg.Service
+ for _, service := range k.APIConn.SvcExtIndexReverse(ip) {
+ if len(k.Namespaces) > 0 && !k.namespaceExposed(service.Namespace) {
+ continue
+ }
+ domain := strings.Join([]string{service.Name, service.Namespace}, ".")
+ svcs = append(svcs, msg.Service{Host: domain, TTL: k.ttl})
+ }
+ return svcs
+}
diff --git a/plugin/kubernetes/external_test.go b/plugin/kubernetes/external_test.go
index 28ccc608e..b0e89e000 100644
--- a/plugin/kubernetes/external_test.go
+++ b/plugin/kubernetes/external_test.go
@@ -80,6 +80,7 @@ func (external) Run()
func (external) Stop() error { return nil }
func (external) EpIndexReverse(string) []*object.Endpoints { return nil }
func (external) SvcIndexReverse(string) []*object.Service { return nil }
+func (external) SvcExtIndexReverse(string) []*object.Service { return nil }
func (external) Modified(bool) int64 { return 0 }
func (external) EpIndex(s string) []*object.Endpoints { return nil }
func (external) EndpointsList() []*object.Endpoints { return nil }
diff --git a/plugin/kubernetes/handler_test.go b/plugin/kubernetes/handler_test.go
index d867f727a..d991f79d6 100644
--- a/plugin/kubernetes/handler_test.go
+++ b/plugin/kubernetes/handler_test.go
@@ -536,12 +536,13 @@ type APIConnServeTest struct {
notSynced bool
}
-func (a APIConnServeTest) HasSynced() bool { return !a.notSynced }
-func (APIConnServeTest) Run() {}
-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(bool) int64 { return int64(3) }
+func (a APIConnServeTest) HasSynced() bool { return !a.notSynced }
+func (APIConnServeTest) Run() {}
+func (APIConnServeTest) Stop() error { return nil }
+func (APIConnServeTest) EpIndexReverse(string) []*object.Endpoints { return nil }
+func (APIConnServeTest) SvcIndexReverse(string) []*object.Service { return nil }
+func (APIConnServeTest) SvcExtIndexReverse(string) []*object.Service { return nil }
+func (APIConnServeTest) Modified(bool) int64 { return int64(3) }
func (APIConnServeTest) PodIndex(ip string) []*object.Pod {
if ip != "10.240.0.1" {
diff --git a/plugin/kubernetes/kubernetes_test.go b/plugin/kubernetes/kubernetes_test.go
index 9832fbd92..acdfd4c64 100644
--- a/plugin/kubernetes/kubernetes_test.go
+++ b/plugin/kubernetes/kubernetes_test.go
@@ -39,13 +39,14 @@ func TestEndpointHostname(t *testing.T) {
type APIConnServiceTest struct{}
-func (APIConnServiceTest) HasSynced() bool { return true }
-func (APIConnServiceTest) Run() {}
-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(bool) int64 { return 0 }
+func (APIConnServiceTest) HasSynced() bool { return true }
+func (APIConnServiceTest) Run() {}
+func (APIConnServiceTest) Stop() error { return nil }
+func (APIConnServiceTest) PodIndex(string) []*object.Pod { return nil }
+func (APIConnServiceTest) SvcIndexReverse(string) []*object.Service { return nil }
+func (APIConnServiceTest) SvcExtIndexReverse(string) []*object.Service { return nil }
+func (APIConnServiceTest) EpIndexReverse(string) []*object.Endpoints { return nil }
+func (APIConnServiceTest) Modified(bool) int64 { return 0 }
func (APIConnServiceTest) SvcIndex(string) []*object.Service {
svcs := []*object.Service{
diff --git a/plugin/kubernetes/ns_test.go b/plugin/kubernetes/ns_test.go
index ca69c7c3b..abc5fa935 100644
--- a/plugin/kubernetes/ns_test.go
+++ b/plugin/kubernetes/ns_test.go
@@ -14,14 +14,15 @@ import (
type APIConnTest struct{}
-func (APIConnTest) HasSynced() bool { return true }
-func (APIConnTest) Run() {}
-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(bool) int64 { return 0 }
+func (APIConnTest) HasSynced() bool { return true }
+func (APIConnTest) Run() {}
+func (APIConnTest) Stop() error { return nil }
+func (APIConnTest) PodIndex(string) []*object.Pod { return nil }
+func (APIConnTest) SvcIndexReverse(string) []*object.Service { return nil }
+func (APIConnTest) SvcExtIndexReverse(string) []*object.Service { return nil }
+func (APIConnTest) EpIndex(string) []*object.Endpoints { return nil }
+func (APIConnTest) EndpointsList() []*object.Endpoints { return nil }
+func (APIConnTest) Modified(bool) int64 { return 0 }
func (a APIConnTest) SvcIndex(s string) []*object.Service {
switch s {
diff --git a/plugin/kubernetes/reverse_test.go b/plugin/kubernetes/reverse_test.go
index aa21a9f86..b1835b3c8 100644
--- a/plugin/kubernetes/reverse_test.go
+++ b/plugin/kubernetes/reverse_test.go
@@ -15,14 +15,15 @@ import (
type APIConnReverseTest struct{}
-func (APIConnReverseTest) HasSynced() bool { return true }
-func (APIConnReverseTest) Run() {}
-func (APIConnReverseTest) Stop() error { return nil }
-func (APIConnReverseTest) PodIndex(string) []*object.Pod { 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(bool) int64 { return 0 }
+func (APIConnReverseTest) HasSynced() bool { return true }
+func (APIConnReverseTest) Run() {}
+func (APIConnReverseTest) Stop() error { return nil }
+func (APIConnReverseTest) PodIndex(string) []*object.Pod { 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) SvcExtIndexReverse(string) []*object.Service { return nil }
+func (APIConnReverseTest) Modified(bool) int64 { return 0 }
func (APIConnReverseTest) SvcIndex(svc string) []*object.Service {
if svc != "svc1.testns" {