aboutsummaryrefslogtreecommitdiff
path: root/middleware/federation/federation.go
diff options
context:
space:
mode:
Diffstat (limited to 'middleware/federation/federation.go')
-rw-r--r--middleware/federation/federation.go141
1 files changed, 0 insertions, 141 deletions
diff --git a/middleware/federation/federation.go b/middleware/federation/federation.go
deleted file mode 100644
index bc74d9fc9..000000000
--- a/middleware/federation/federation.go
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
-Package federation implements kubernetes federation. It checks if the qname matches
-a possible federation. If this is the case and the captured answer is an NXDOMAIN,
-federation is performed. If this is not the case the original answer is returned.
-
-The federation label is always the 2nd to last once the zone is chopped of. For
-instance "nginx.mynamespace.myfederation.svc.example.com" has "myfederation" as
-the federation label. For federation to work we do a normal k8s lookup
-*without* that label, if that comes back with NXDOMAIN or NODATA(??) we create
-a federation record and return that.
-
-Federation is only useful in conjunction with the kubernetes middleware, without it is a noop.
-*/
-package federation
-
-import (
- "github.com/coredns/coredns/middleware"
- "github.com/coredns/coredns/middleware/etcd/msg"
- "github.com/coredns/coredns/middleware/pkg/dnsutil"
- "github.com/coredns/coredns/middleware/pkg/nonwriter"
- "github.com/coredns/coredns/request"
-
- "github.com/miekg/dns"
- "golang.org/x/net/context"
-)
-
-// Federation contains the name to zone mapping used for federation in kubernetes.
-type Federation struct {
- f map[string]string
- zones []string
-
- Next middleware.Handler
- Federations Func
-}
-
-// Func needs to be implemented by any middleware that implements
-// federation. Right now this is only the kubernetes middleware.
-type Func func(state request.Request, fname, fzone string) (msg.Service, error)
-
-// New returns a new federation.
-func New() *Federation {
- return &Federation{f: make(map[string]string)}
-}
-
-// ServeDNS implements the middleware.Handle interface.
-func (f *Federation) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
- if f.Federations == nil {
- return middleware.NextOrFailure(f.Name(), f.Next, ctx, w, r)
- }
-
- state := request.Request{W: w, Req: r}
- zone := middleware.Zones(f.zones).Matches(state.Name())
- if zone == "" {
- return middleware.NextOrFailure(f.Name(), f.Next, ctx, w, r)
- }
-
- state.Zone = zone
-
- // Remove the federation label from the qname to see if something exists.
- without, label := f.isNameFederation(state.Name(), state.Zone)
- if without == "" {
- return middleware.NextOrFailure(f.Name(), f.Next, ctx, w, r)
- }
-
- qname := r.Question[0].Name
- r.Question[0].Name = without
- state.Clear()
-
- // Start the next middleware, but with a nowriter, capture the result, if NXDOMAIN
- // perform federation, otherwise just write the result.
- nw := nonwriter.New(w)
- ret, err := middleware.NextOrFailure(f.Name(), f.Next, ctx, nw, r)
-
- if !middleware.ClientWrite(ret) {
- // something went wrong
- r.Question[0].Name = qname
- return ret, err
- }
-
- if m := nw.Msg; m.Rcode != dns.RcodeNameError {
- // If positive answer we need to substitute the original qname in the answer.
- m.Question[0].Name = qname
- for _, a := range m.Answer {
- a.Header().Name = qname
- }
-
- state.SizeAndDo(m)
- m, _ = state.Scrub(m)
- w.WriteMsg(m)
-
- return dns.RcodeSuccess, nil
- }
-
- // Still here, we've seen NXDOMAIN and need to perform federation.
- service, err := f.Federations(state, label, f.f[label]) // state references Req which has updated qname
- if err != nil {
- r.Question[0].Name = qname
- return dns.RcodeServerFailure, err
- }
-
- r.Question[0].Name = qname
-
- m := new(dns.Msg)
- m.SetReply(r)
- m.Authoritative, m.RecursionAvailable, m.Compress = true, true, true
-
- m.Answer = []dns.RR{service.NewCNAME(state.QName(), service.Host)}
-
- state.SizeAndDo(m)
- m, _ = state.Scrub(m)
- w.WriteMsg(m)
-
- return dns.RcodeSuccess, nil
-}
-
-// Name implements the middleware.Handle interface.
-func (f *Federation) Name() string { return "federation" }
-
-// IsNameFederation checks the qname to see if it is a potential federation. The federation
-// label is always the 2nd to last once the zone is chopped of. For instance
-// "nginx.mynamespace.myfederation.svc.example.com" has "myfederation" as the federation label.
-// IsNameFederation returns a new qname with the federation label and the label itself or two
-// empty strings if there wasn't a hit.
-func (f *Federation) isNameFederation(name, zone string) (string, string) {
- base, _ := dnsutil.TrimZone(name, zone)
-
- // TODO(miek): dns.PrevLabel is better for memory, or dns.Split.
- labels := dns.SplitDomainName(base)
- ll := len(labels)
- if ll < 2 {
- return "", ""
- }
-
- fed := labels[ll-2]
-
- if _, ok := f.f[fed]; ok {
- without := dnsutil.Join(labels[:ll-2]) + labels[ll-1] + "." + zone
- return without, fed
- }
- return "", ""
-}