aboutsummaryrefslogtreecommitdiff
path: root/plugin/kubernetes/external.go
diff options
context:
space:
mode:
authorGravatar Miek Gieben <miek@miek.nl> 2018-12-14 09:41:51 +0000
committerGravatar GitHub <noreply@github.com> 2018-12-14 09:41:51 +0000
commitc1c98924c3733b853115c62adc1a2b5978ae2df3 (patch)
tree6006978128c2ffd02eb9c5eaaeb16993f38f205b /plugin/kubernetes/external.go
parentd9880681c3b28f8506e2a5b15bbc404b2a155b00 (diff)
downloadcoredns-c1c98924c3733b853115c62adc1a2b5978ae2df3.tar.gz
coredns-c1c98924c3733b853115c62adc1a2b5978ae2df3.tar.zst
coredns-c1c98924c3733b853115c62adc1a2b5978ae2df3.zip
Add new plugin: external - resolve k8s ingress and LB address with external names (#2379)
* Add new plugin: external This plugin works in conjunction with the kubernetes plugin and exports ingress and LB addresses as DNS records. It bypasses backend.go and backend_lookup.go flow because it is not needed. README, tests are implemented. The tests only exercise the unit tests, this has not been tested in any ci. Signed-off-by: Miek Gieben <miek@miek.nl> * Rename to k8s_external Signed-off-by: Miek Gieben <miek@miek.nl> * go gen Signed-off-by: Miek Gieben <miek@miek.nl>
Diffstat (limited to 'plugin/kubernetes/external.go')
-rw-r--r--plugin/kubernetes/external.go92
1 files changed, 92 insertions, 0 deletions
diff --git a/plugin/kubernetes/external.go b/plugin/kubernetes/external.go
new file mode 100644
index 000000000..1770872b3
--- /dev/null
+++ b/plugin/kubernetes/external.go
@@ -0,0 +1,92 @@
+package kubernetes
+
+import (
+ "strings"
+
+ "github.com/coredns/coredns/plugin/etcd/msg"
+ "github.com/coredns/coredns/plugin/kubernetes/object"
+ "github.com/coredns/coredns/plugin/pkg/dnsutil"
+ "github.com/coredns/coredns/request"
+
+ "github.com/miekg/dns"
+)
+
+// 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) {
+ base, _ := dnsutil.TrimZone(state.Name(), state.Zone)
+
+ segs := dns.SplitDomainName(base)
+ last := len(segs) - 1
+ if last < 0 {
+ return nil, dns.RcodeServerFailure
+ }
+ // We dealing with a fairly normal domain name here, but; we still need to have the service
+ // and the namespace:
+ // service.namespace.<base>
+ //
+ // for service (and SRV) you can also say _tcp, and port (i.e. _http), we need those be picked
+ // up, unless they are not specified, then we use an internal wildcard.
+ port := "*"
+ protocol := "*"
+ namespace := segs[last]
+ if !k.namespaceExposed(namespace) || !k.namespace(namespace) {
+ return nil, dns.RcodeNameError
+ }
+
+ last--
+ if last < 0 {
+ return nil, dns.RcodeSuccess
+ }
+
+ service := segs[last]
+ last--
+ if last == 1 {
+ protocol = stripUnderscore(segs[last])
+ port = stripUnderscore(segs[last-1])
+ last -= 2
+ }
+
+ if last != -1 {
+ // too long
+ return nil, dns.RcodeNameError
+ }
+
+ idx := object.ServiceKey(service, namespace)
+ serviceList := k.APIConn.SvcIndex(idx)
+
+ services := []msg.Service{}
+ zonePath := msg.Path(state.Zone, coredns)
+ rcode := dns.RcodeNameError
+
+ for _, svc := range serviceList {
+ if namespace != svc.Namespace {
+ continue
+ }
+ if service != svc.Name {
+ continue
+ }
+
+ for _, ip := range svc.ExternalIPs {
+ for _, p := range svc.Ports {
+ if !(match(port, p.Name) && match(protocol, string(p.Protocol))) {
+ continue
+ }
+ rcode = dns.RcodeSuccess
+ s := msg.Service{Host: ip, Port: int(p.Port), TTL: k.ttl}
+ s.Key = strings.Join([]string{zonePath, svc.Namespace, svc.Name}, "/")
+
+ services = append(services, s)
+ }
+ }
+ }
+ return services, rcode
+}
+
+// ExternalAddress returns the external service address(es) for the CoreDNS service.
+func (k *Kubernetes) ExternalAddress(state request.Request) []dns.RR {
+ // This is probably wrong, because of all the fallback behavior of k.nsAddr, i.e. can get
+ // an address that isn't reacheable from outside the cluster.
+ rrs := []dns.RR{k.nsAddr()}
+ return rrs
+}