aboutsummaryrefslogtreecommitdiff
path: root/plugin/federation/federation.go
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/federation/federation.go')
-rw-r--r--plugin/federation/federation.go147
1 files changed, 0 insertions, 147 deletions
diff --git a/plugin/federation/federation.go b/plugin/federation/federation.go
deleted file mode 100644
index 7fe2a6f62..000000000
--- a/plugin/federation/federation.go
+++ /dev/null
@@ -1,147 +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 plugin, without it is a noop.
-*/
-package federation
-
-import (
- "context"
-
- "github.com/coredns/coredns/plugin"
- "github.com/coredns/coredns/plugin/etcd/msg"
- "github.com/coredns/coredns/plugin/pkg/dnsutil"
- "github.com/coredns/coredns/plugin/pkg/nonwriter"
- "github.com/coredns/coredns/plugin/pkg/upstream"
- "github.com/coredns/coredns/request"
-
- "github.com/miekg/dns"
-)
-
-// Federation contains the name to zone mapping used for federation in kubernetes.
-type Federation struct {
- f map[string]string
- zones []string
- Upstream *upstream.Upstream
-
- Next plugin.Handler
- Federations Func
-}
-
-// Func needs to be implemented by any plugin that implements
-// federation. Right now this is only the kubernetes plugin.
-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 plugin.Handle interface.
-func (f *Federation) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
- if f.Federations == nil {
- return plugin.NextOrFailure(f.Name(), f.Next, ctx, w, r)
- }
-
- state := request.Request{W: w, Req: r}
-
- zone := plugin.Zones(f.zones).Matches(state.Name())
- if zone == "" {
- return plugin.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 plugin.NextOrFailure(f.Name(), f.Next, ctx, w, r)
- }
-
- qname := r.Question[0].Name
- r.Question[0].Name = without
- state.Clear()
-
- // Start the next plugin, but with a nowriter, capture the result, if NXDOMAIN
- // perform federation, otherwise just write the result.
- nw := nonwriter.New(w)
- ret, err := plugin.NextOrFailure(f.Name(), f.Next, ctx, nw, r)
-
- if !plugin.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
- }
-
- 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 = true
-
- m.Answer = []dns.RR{service.NewCNAME(state.QName(), service.Host)}
-
- if f.Upstream != nil {
- aRecord, err := f.Upstream.Lookup(ctx, state, service.Host, state.QType())
- if err == nil && aRecord != nil && len(aRecord.Answer) > 0 {
- m.Answer = append(m.Answer, aRecord.Answer...)
- }
- }
-
- w.WriteMsg(m)
- return dns.RcodeSuccess, nil
-}
-
-// Name implements the plugin.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 "", ""
-}