Switch over to k8s notification API (#202)

* Merge notification code by @aledbf and update for recent changes.
* Fix travis environment to correctly build with k8s.io and forked repositories.
* Refactored kubernetes Corefile parser
* Added lots of Corefile parsing tests
This commit is contained in:
Michael Richmond
2016-08-05 18:19:51 -07:00
committed by GitHub
parent 604d2a3730
commit 6d90b745e0
13 changed files with 609 additions and 237 deletions

View File

@@ -4,6 +4,7 @@ import (
"fmt"
"math"
"net"
"strings"
"time"
"github.com/miekg/coredns/middleware"
@@ -12,6 +13,11 @@ import (
"github.com/miekg/dns"
)
const (
// arpaSuffix is the standard suffix for PTR IP reverse lookups.
arpaSuffix = ".in-addr.arpa."
)
func (k Kubernetes) records(state middleware.State, exact bool) ([]msg.Service, error) {
services, err := k.Records(state.Name(), exact)
if err != nil {
@@ -64,13 +70,13 @@ func (k Kubernetes) A(zone string, state middleware.State, previousRecords []dns
// We should already have found it
continue
}
m1, e1 := k.Proxy.Lookup(state, target, state.QType())
if e1 != nil {
mes, err := k.Proxy.Lookup(state, target, state.QType())
if err != nil {
continue
}
// Len(m1.Answer) > 0 here is well?
// Len(mes.Answer) > 0 here is well?
records = append(records, newRecord)
records = append(records, m1.Answer...)
records = append(records, mes.Answer...)
continue
case ip.To4() != nil:
records = append(records, serv.NewA(state.QName(), ip.To4()))
@@ -285,7 +291,33 @@ func (k Kubernetes) SOA(zone string, state middleware.State) *dns.SOA {
}
}
// TODO(miek): DNSKEY and friends... intercepted by the DNSSEC middleware?
func (k Kubernetes) PTR(zone string, state middleware.State) ([]dns.RR, error) {
reverseIP, ok := extractIP(state.Name())
if !ok {
return nil, fmt.Errorf("does not support reverse lookup for %s", state.QName())
}
records := make([]dns.RR, 1)
services, err := k.records(state, false)
if err != nil {
return nil, err
}
for _, serv := range services {
ip := net.ParseIP(serv.Host)
if reverseIP != serv.Host {
continue
}
switch {
case ip.To4() != nil:
records = append(records, serv.NewPTR(state.QName(), ip.To4().String()))
break
case ip.To4() == nil:
// nodata?
}
}
return records, nil
}
func isDuplicateCNAME(r *dns.CNAME, records []dns.RR) bool {
for _, rec := range records {
@@ -300,6 +332,27 @@ func isDuplicateCNAME(r *dns.CNAME, records []dns.RR) bool {
func copyState(state middleware.State, target string, typ uint16) middleware.State {
state1 := middleware.State{W: state.W, Req: state.Req.Copy()}
state1.Req.Question[0] = dns.Question{dns.Fqdn(target), dns.ClassINET, typ}
state1.Req.Question[0] = dns.Question{Name: dns.Fqdn(target), Qtype: dns.ClassINET, Qclass: typ}
return state1
}
// extractIP turns a standard PTR reverse record lookup name
// into an IP address
func extractIP(reverseName string) (string, bool) {
if !strings.HasSuffix(reverseName, arpaSuffix) {
return "", false
}
search := strings.TrimSuffix(reverseName, arpaSuffix)
// reverse the segments and then combine them
segments := reverseArray(strings.Split(search, "."))
return strings.Join(segments, "."), true
}
func reverseArray(arr []string) []string {
for i := 0; i < len(arr)/2; i++ {
j := len(arr) - i - 1
arr[i], arr[j] = arr[j], arr[i]
}
return arr
}