coredns/middleware/etcd/stub.go
Miek Gieben ebef64280a Support SkyDNS' stubzones
This implements stubzones in the same way as SkyDNS. This
also works with multiple configured domains and has tests.
Also add more configuration parameters for TLS and path prefix and
enabling stubzones.  Run StubUpdates as a startup command to keep up to
date with the list in etcd.
2016-03-26 16:29:35 +00:00

71 lines
1.7 KiB
Go

package etcd
import (
"net"
"strconv"
"strings"
"time"
"github.com/miekg/coredns/middleware/proxy"
"github.com/miekg/dns"
)
func (e Etcd) UpdateStubZones() {
go func() {
for {
e.updateStubZones()
time.Sleep(15 * time.Second)
}
}()
}
// Look in .../dns/stub/<zone>/xx for msg.Services. Loop through them
// extract <zone> and add them as forwarders (ip:port-combos) for
// the stub zones. Only numeric (i.e. IP address) hosts are used.
func (e Etcd) updateStubZones() {
stubmap := make(map[string]proxy.Proxy)
for _, zone := range e.Zones {
services, err := e.Records(stubDomain+"."+zone, false)
if err != nil {
continue
}
// track the nameservers on a per domain basis, but allow a list on the domain.
nameservers := map[string][]string{}
for _, serv := range services {
if serv.Port == 0 {
serv.Port = 53
}
ip := net.ParseIP(serv.Host)
if ip == nil {
continue
}
domain := e.Domain(serv.Key)
labels := dns.SplitDomainName(domain)
// nameserver need to be tracked by domain and *then* added
// If the remaining name equals any of the zones we have, we ignore it.
for _, z := range e.Zones {
// Chop of left most label, because that is used as the nameserver place holder
// and drop the right most labels that belong to zone.
domain = dns.Fqdn(strings.Join(labels[1:len(labels)-dns.CountLabel(z)], "."))
if domain == z {
continue
}
nameservers[domain] = append(nameservers[domain], net.JoinHostPort(serv.Host, strconv.Itoa(serv.Port)))
}
}
for domain, nss := range nameservers {
stubmap[domain] = proxy.New(nss)
}
}
// atomic swap (at least that's what we hope it is)
if len(stubmap) > 0 {
e.Stubmap = &stubmap
}
return
}