diff options
Diffstat (limited to 'plugin/kubernetes')
-rw-r--r-- | plugin/kubernetes/controller.go | 34 | ||||
-rw-r--r-- | plugin/kubernetes/external.go | 37 | ||||
-rw-r--r-- | plugin/kubernetes/external_test.go | 1 | ||||
-rw-r--r-- | plugin/kubernetes/handler_test.go | 13 | ||||
-rw-r--r-- | plugin/kubernetes/kubernetes_test.go | 15 | ||||
-rw-r--r-- | plugin/kubernetes/ns_test.go | 17 | ||||
-rw-r--r-- | plugin/kubernetes/reverse_test.go | 17 |
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" { |