mirror of
				https://github.com/coredns/coredns.git
				synced 2025-11-03 18:53:13 -05:00 
			
		
		
		
	* 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>
		
			
				
	
	
		
			93 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			93 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
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
 | 
						|
}
 |