BackendService: add Reverse method (#381)
Add a Reverse method to BackendService because different backends want to to do diff. things. This allows etc/k8s to share even more code and we can unify the PTR handling.
This commit is contained in:
parent
2cca527d9f
commit
8d3418c015
6 changed files with 33 additions and 37 deletions
|
@ -9,10 +9,14 @@ import (
|
||||||
|
|
||||||
// ServiceBackend defines a (dynamic) backend that returns a slice of service definitions.
|
// ServiceBackend defines a (dynamic) backend that returns a slice of service definitions.
|
||||||
type ServiceBackend interface {
|
type ServiceBackend interface {
|
||||||
// Services communitates with the backend to retrieve the service defintion. Exact indicates
|
// Services communicates with the backend to retrieve the service defintion. Exact indicates
|
||||||
// on exact much are that we are allowed to recurs.
|
// on exact much are that we are allowed to recurs.
|
||||||
Services(state request.Request, exact bool, opt Options) ([]msg.Service, []msg.Service, error)
|
Services(state request.Request, exact bool, opt Options) ([]msg.Service, []msg.Service, error)
|
||||||
|
|
||||||
|
// Reverse communicates with the backend to retrieve service definition based on a IP address
|
||||||
|
// instead of a name. I.e. a reverse DNS lookup.
|
||||||
|
Reverse(state request.Request, exact bool, opt Options) ([]msg.Service, []msg.Service, error)
|
||||||
|
|
||||||
// Lookup is used to find records else where.
|
// Lookup is used to find records else where.
|
||||||
Lookup(state request.Request, name string, typ uint16) (*dns.Msg, error)
|
Lookup(state request.Request, name string, typ uint16) (*dns.Msg, error)
|
||||||
|
|
||||||
|
|
|
@ -330,9 +330,8 @@ func TXT(b ServiceBackend, zone string, state request.Request, opt Options) (rec
|
||||||
}
|
}
|
||||||
|
|
||||||
// PTR returns the PTR records from the backend, only services that have a domain name as host are included.
|
// PTR returns the PTR records from the backend, only services that have a domain name as host are included.
|
||||||
// TODO(miek|infoblox): move k8s to this as well.
|
|
||||||
func PTR(b ServiceBackend, zone string, state request.Request, opt Options) (records []dns.RR, debug []msg.Service, err error) {
|
func PTR(b ServiceBackend, zone string, state request.Request, opt Options) (records []dns.RR, debug []msg.Service, err error) {
|
||||||
services, debug, err := b.Services(state, true, opt)
|
services, debug, err := b.Reverse(state, true, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, debug, err
|
return nil, debug, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,11 @@ func (e *Etcd) Services(state request.Request, exact bool, opt middleware.Option
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reverse implements the ServiceBackend interface.
|
||||||
|
func (e *Etcd) Reverse(state request.Request, exact bool, opt middleware.Options) (services, debug []msg.Service, err error) {
|
||||||
|
return e.Services(state, exact, opt)
|
||||||
|
}
|
||||||
|
|
||||||
// Lookup implements the ServiceBackend interface.
|
// Lookup implements the ServiceBackend interface.
|
||||||
func (e *Etcd) Lookup(state request.Request, name string, typ uint16) (*dns.Msg, error) {
|
func (e *Etcd) Lookup(state request.Request, name string, typ uint16) (*dns.Msg, error) {
|
||||||
return e.Proxy.Lookup(state, name, typ)
|
return e.Proxy.Lookup(state, name, typ)
|
||||||
|
|
|
@ -5,13 +5,13 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/client-go/1.5/kubernetes"
|
||||||
"k8s.io/client-go/1.5/pkg/api"
|
"k8s.io/client-go/1.5/pkg/api"
|
||||||
"k8s.io/client-go/1.5/pkg/api/v1"
|
"k8s.io/client-go/1.5/pkg/api/v1"
|
||||||
"k8s.io/client-go/1.5/tools/cache"
|
|
||||||
"k8s.io/client-go/1.5/kubernetes"
|
|
||||||
"k8s.io/client-go/1.5/pkg/labels"
|
"k8s.io/client-go/1.5/pkg/labels"
|
||||||
"k8s.io/client-go/1.5/pkg/runtime"
|
"k8s.io/client-go/1.5/pkg/runtime"
|
||||||
"k8s.io/client-go/1.5/pkg/watch"
|
"k8s.io/client-go/1.5/pkg/watch"
|
||||||
|
"k8s.io/client-go/1.5/tools/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -22,24 +22,6 @@ func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M
|
||||||
m.SetReply(r)
|
m.SetReply(r)
|
||||||
m.Authoritative, m.RecursionAvailable, m.Compress = true, true, true
|
m.Authoritative, m.RecursionAvailable, m.Compress = true, true, true
|
||||||
|
|
||||||
// TODO: find an alternative to this block
|
|
||||||
// TODO(miek): Why is this even here, why does the path Etcd takes not work?
|
|
||||||
// Should be a "case PTR" below. I would also like to use middleware.PTR for this.
|
|
||||||
ip := dnsutil.ExtractAddressFromReverse(state.Name())
|
|
||||||
if ip != "" {
|
|
||||||
records := k.getServiceRecordForIP(ip, state.Name())
|
|
||||||
if len(records) > 0 {
|
|
||||||
srvPTR := &records[0]
|
|
||||||
m.Answer = append(m.Answer, srvPTR.NewPTR(state.QName(), ip))
|
|
||||||
|
|
||||||
m = dnsutil.Dedup(m)
|
|
||||||
state.SizeAndDo(m)
|
|
||||||
m, _ = state.Scrub(m)
|
|
||||||
w.WriteMsg(m)
|
|
||||||
return dns.RcodeSuccess, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that query matches one of the zones served by this middleware,
|
// Check that query matches one of the zones served by this middleware,
|
||||||
// otherwise delegate to the next in the pipeline.
|
// otherwise delegate to the next in the pipeline.
|
||||||
zone := middleware.Zones(k.Zones).Matches(state.Name())
|
zone := middleware.Zones(k.Zones).Matches(state.Name())
|
||||||
|
@ -63,6 +45,8 @@ func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M
|
||||||
records, _, err = middleware.TXT(&k, zone, state, middleware.Options{})
|
records, _, err = middleware.TXT(&k, zone, state, middleware.Options{})
|
||||||
case "CNAME":
|
case "CNAME":
|
||||||
records, _, err = middleware.CNAME(&k, zone, state, middleware.Options{})
|
records, _, err = middleware.CNAME(&k, zone, state, middleware.Options{})
|
||||||
|
case "PTR":
|
||||||
|
records, _, err = middleware.PTR(&k, zone, state, middleware.Options{})
|
||||||
case "MX":
|
case "MX":
|
||||||
records, extra, _, err = middleware.MX(&k, zone, state, middleware.Options{})
|
records, extra, _, err = middleware.MX(&k, zone, state, middleware.Options{})
|
||||||
case "SRV":
|
case "SRV":
|
||||||
|
|
|
@ -18,13 +18,13 @@ import (
|
||||||
"github.com/miekg/coredns/request"
|
"github.com/miekg/coredns/request"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
|
"k8s.io/client-go/1.5/kubernetes"
|
||||||
"k8s.io/client-go/1.5/pkg/api"
|
"k8s.io/client-go/1.5/pkg/api"
|
||||||
unversionedapi "k8s.io/client-go/1.5/pkg/api/unversioned"
|
unversionedapi "k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||||
"k8s.io/client-go/1.5/kubernetes"
|
"k8s.io/client-go/1.5/pkg/labels"
|
||||||
"k8s.io/client-go/1.5/rest"
|
"k8s.io/client-go/1.5/rest"
|
||||||
"k8s.io/client-go/1.5/tools/clientcmd"
|
"k8s.io/client-go/1.5/tools/clientcmd"
|
||||||
clientcmdapi "k8s.io/client-go/1.5/tools/clientcmd/api"
|
clientcmdapi "k8s.io/client-go/1.5/tools/clientcmd/api"
|
||||||
"k8s.io/client-go/1.5/pkg/labels"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Kubernetes implements a middleware that connects to a Kubernetes cluster.
|
// Kubernetes implements a middleware that connects to a Kubernetes cluster.
|
||||||
|
@ -50,6 +50,17 @@ func (k *Kubernetes) Services(state request.Request, exact bool, opt middleware.
|
||||||
return s, nil, e // Haven't implemented debug queries yet.
|
return s, nil, e // Haven't implemented debug queries yet.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reverse implements the ServiceBackend interface.
|
||||||
|
func (k *Kubernetes) Reverse(state request.Request, exact bool, opt middleware.Options) ([]msg.Service, []msg.Service, error) {
|
||||||
|
ip := dnsutil.ExtractAddressFromReverse(state.Name())
|
||||||
|
if ip == "" {
|
||||||
|
return nil, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
records := k.getServiceRecordForIP(ip, state.Name())
|
||||||
|
return records, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Lookup implements the ServiceBackend interface.
|
// Lookup implements the ServiceBackend interface.
|
||||||
func (k *Kubernetes) Lookup(state request.Request, name string, typ uint16) (*dns.Msg, error) {
|
func (k *Kubernetes) Lookup(state request.Request, name string, typ uint16) (*dns.Msg, error) {
|
||||||
return k.Proxy.Lookup(state, name, typ)
|
return k.Proxy.Lookup(state, name, typ)
|
||||||
|
@ -156,13 +167,6 @@ func (k *Kubernetes) getZoneForName(name string) (string, []string) {
|
||||||
// just this name. This is used when find matches when completing SRV lookups
|
// just this name. This is used when find matches when completing SRV lookups
|
||||||
// for instance.
|
// for instance.
|
||||||
func (k *Kubernetes) Records(name string, exact bool) ([]msg.Service, error) {
|
func (k *Kubernetes) Records(name string, exact bool) ([]msg.Service, error) {
|
||||||
// TODO: refactor this.
|
|
||||||
// Right now NamespaceFromSegmentArray do not supports PRE queries
|
|
||||||
ip := dnsutil.ExtractAddressFromReverse(name)
|
|
||||||
if ip != "" {
|
|
||||||
records := k.getServiceRecordForIP(ip, name)
|
|
||||||
return records, nil
|
|
||||||
}
|
|
||||||
var (
|
var (
|
||||||
serviceName string
|
serviceName string
|
||||||
namespace string
|
namespace string
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue