mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 10:13:14 -04:00 
			
		
		
		
	middleware/kubernetes: autopath in sub package (#848)
Put the autopath stuff in a separate sub package. Tests are still included in the main kubernetes directory. Next steps (after this is merged), is pulling the autopath handling into the subpackage and fixing the tests.
This commit is contained in:
		| @@ -1,8 +1,8 @@ | |||||||
| package kubernetes | package autopath | ||||||
| 
 | 
 | ||||||
| import "github.com/miekg/dns" | import "github.com/miekg/dns" | ||||||
| 
 | 
 | ||||||
| // AutoPathWriter implements a ResponseWriter that also does the following: | // Writer implements a ResponseWriter that also does the following: | ||||||
| // * reverts question section of a packet to its original state. | // * reverts question section of a packet to its original state. | ||||||
| //   This is done to avoid the 'Question section mismatch:' error in client. | //   This is done to avoid the 'Question section mismatch:' error in client. | ||||||
| // * Defers write to the client if the response code is NXDOMAIN.  This is needed | // * Defers write to the client if the response code is NXDOMAIN.  This is needed | ||||||
| @@ -10,40 +10,48 @@ import "github.com/miekg/dns" | |||||||
| // * Allow forced write to client regardless of response code.  This is needed to | // * Allow forced write to client regardless of response code.  This is needed to | ||||||
| //   write the packet to the client if the final search in the path fails to | //   write the packet to the client if the final search in the path fails to | ||||||
| //   produce results. | //   produce results. | ||||||
| // * Overwrites response code with AutoPathWriter.Rcode if the response code | // * Overwrites response code with Writer.Rcode if the response code | ||||||
| //   is NXDOMAIN (NameError).  This is needed to support the AutoPath.OnNXDOMAIN | //   is NXDOMAIN (NameError).  This is needed to support the AutoPath.OnNXDOMAIN | ||||||
| //   function, which returns a NOERROR to client instead of NXDOMAIN if the final | //   function, which returns a NOERROR to client instead of NXDOMAIN if the final | ||||||
| //   search in the path fails to produce results. | //   search in the path fails to produce results. | ||||||
| type AutoPathWriter struct { | type Writer struct { | ||||||
| 	dns.ResponseWriter | 	dns.ResponseWriter | ||||||
| 	original dns.Question | 	original dns.Question | ||||||
| 	Rcode    int | 	Rcode    int | ||||||
| 	Sent     bool | 	Sent     bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NewAutoPathWriter returns a pointer to a new AutoPathWriter | // AutoPath enables server side search path lookups for pods. | ||||||
| func NewAutoPathWriter(w dns.ResponseWriter, r *dns.Msg) *AutoPathWriter { | type AutoPath struct { | ||||||
| 	return &AutoPathWriter{ | 	NDots          int | ||||||
|  | 	ResolvConfFile string | ||||||
|  | 	HostSearchPath []string | ||||||
|  | 	OnNXDOMAIN     int | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewWriter returns a pointer to a new Writer | ||||||
|  | func NewWriter(w dns.ResponseWriter, r *dns.Msg) *Writer { | ||||||
|  | 	return &Writer{ | ||||||
| 		ResponseWriter: w, | 		ResponseWriter: w, | ||||||
| 		original:       r.Question[0], | 		original:       r.Question[0], | ||||||
| 		Rcode:          dns.RcodeSuccess, | 		Rcode:          dns.RcodeSuccess, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // WriteMsg writes to client, unless response will be NXDOMAIN | // WriteMsg writes to client, unless response will be NXDOMAIN. | ||||||
| func (apw *AutoPathWriter) WriteMsg(res *dns.Msg) error { | func (apw *Writer) WriteMsg(res *dns.Msg) error { | ||||||
| 	return apw.overrideMsg(res, false) | 	return apw.overrideMsg(res, false) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ForceWriteMsg forces the write to client regardless of response code | // ForceWriteMsg forces the write to client regardless of response code. | ||||||
| func (apw *AutoPathWriter) ForceWriteMsg(res *dns.Msg) error { | func (apw *Writer) ForceWriteMsg(res *dns.Msg) error { | ||||||
| 	return apw.overrideMsg(res, true) | 	return apw.overrideMsg(res, true) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // overrideMsg overrides rcode, reverts question, adds CNAME, and calls the | // overrideMsg overrides rcode, reverts question, adds CNAME, and calls the | ||||||
| // underlying ResponseWriter's WriteMsg method unless the write is deferred, | // underlying ResponseWriter's WriteMsg method unless the write is deferred, | ||||||
| // or force = true. | // or force = true. | ||||||
| func (apw *AutoPathWriter) overrideMsg(res *dns.Msg, force bool) error { | func (apw *Writer) overrideMsg(res *dns.Msg, force bool) error { | ||||||
| 	if res.Rcode == dns.RcodeNameError { | 	if res.Rcode == dns.RcodeNameError { | ||||||
| 		res.Rcode = apw.Rcode | 		res.Rcode = apw.Rcode | ||||||
| 	} | 	} | ||||||
| @@ -56,7 +64,7 @@ func (apw *AutoPathWriter) overrideMsg(res *dns.Msg, force bool) error { | |||||||
| 		} | 		} | ||||||
| 		res.Answer = append(res.Answer, nil) | 		res.Answer = append(res.Answer, nil) | ||||||
| 		copy(res.Answer[1:], res.Answer) | 		copy(res.Answer[1:], res.Answer) | ||||||
| 		res.Answer[0] = newCNAME(apw.original.Name, dns.Fqdn(a.Header().Name), a.Header().Ttl) | 		res.Answer[0] = CNAME(apw.original.Name, a.Header().Name, a.Header().Ttl) | ||||||
| 	} | 	} | ||||||
| 	res.Question[0] = apw.original | 	res.Question[0] = apw.original | ||||||
| 	apw.Sent = true | 	apw.Sent = true | ||||||
| @@ -64,14 +72,14 @@ func (apw *AutoPathWriter) overrideMsg(res *dns.Msg, force bool) error { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Write is a wrapper that records the size of the message that gets written. | // Write is a wrapper that records the size of the message that gets written. | ||||||
| func (apw *AutoPathWriter) Write(buf []byte) (int, error) { | func (apw *Writer) Write(buf []byte) (int, error) { | ||||||
| 	n, err := apw.ResponseWriter.Write(buf) | 	n, err := apw.ResponseWriter.Write(buf) | ||||||
| 	return n, err | 	return n, err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Hijack implements dns.Hijacker. It simply wraps the underlying | // Hijack implements dns.Hijacker. It simply wraps the underlying | ||||||
| // ResponseWriter's Hijack method if there is one, or returns an error. | // ResponseWriter's Hijack method if there is one, or returns an error. | ||||||
| func (apw *AutoPathWriter) Hijack() { | func (apw *Writer) Hijack() { | ||||||
| 	apw.ResponseWriter.Hijack() | 	apw.ResponseWriter.Hijack() | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
							
								
								
									
										10
									
								
								middleware/kubernetes/autopath/cname.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								middleware/kubernetes/autopath/cname.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | package autopath | ||||||
|  |  | ||||||
|  | import "github.com/miekg/dns" | ||||||
|  |  | ||||||
|  | // CNAME returns a new CNAME formed from name target and ttl. | ||||||
|  | func CNAME(name string, target string, ttl uint32) *dns.CNAME { | ||||||
|  | 	return &dns.CNAME{ | ||||||
|  | 		Hdr:    dns.RR_Header{Name: name, Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Ttl: ttl}, | ||||||
|  | 		Target: dns.Fqdn(target)} | ||||||
|  | } | ||||||
| @@ -5,6 +5,7 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"github.com/coredns/coredns/middleware" | 	"github.com/coredns/coredns/middleware" | ||||||
|  | 	"github.com/coredns/coredns/middleware/kubernetes/autopath" | ||||||
| 	"github.com/coredns/coredns/middleware/pkg/dnsutil" | 	"github.com/coredns/coredns/middleware/pkg/dnsutil" | ||||||
| 	"github.com/coredns/coredns/request" | 	"github.com/coredns/coredns/request" | ||||||
|  |  | ||||||
| @@ -41,14 +42,14 @@ func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M | |||||||
| 	records, extra, _, err := k.routeRequest(zone, state) | 	records, extra, _, err := k.routeRequest(zone, state) | ||||||
|  |  | ||||||
| 	// Check for Autopath search eligibility | 	// Check for Autopath search eligibility | ||||||
| 	if k.AutoPath.Enabled && k.IsNameError(err) && (state.QType() == dns.TypeA || state.QType() == dns.TypeAAAA) { | 	if (k.autoPath != nil) && k.IsNameError(err) && (state.QType() == dns.TypeA || state.QType() == dns.TypeAAAA) { | ||||||
| 		p := k.findPodWithIP(state.IP()) | 		p := k.findPodWithIP(state.IP()) | ||||||
| 		for p != nil { | 		for p != nil { | ||||||
| 			name, path, ok := splitSearch(zone, state.QName(), p.Namespace) | 			name, path, ok := splitSearch(zone, state.QName(), p.Namespace) | ||||||
| 			if !ok { | 			if !ok { | ||||||
| 				break | 				break | ||||||
| 			} | 			} | ||||||
| 			if (dns.CountLabel(name) - 1) < k.AutoPath.NDots { | 			if (dns.CountLabel(name) - 1) < k.autoPath.NDots { | ||||||
| 				break | 				break | ||||||
| 			} | 			} | ||||||
| 			origQName := state.QName() | 			origQName := state.QName() | ||||||
| @@ -60,7 +61,7 @@ func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M | |||||||
| 				if !k.IsNameError(err) && len(records) > 0 { | 				if !k.IsNameError(err) && len(records) > 0 { | ||||||
| 					records = append(records, nil) | 					records = append(records, nil) | ||||||
| 					copy(records[1:], records) | 					copy(records[1:], records) | ||||||
| 					records[0] = newCNAME(origQName, records[0].Header().Name, records[0].Header().Ttl) | 					records[0] = autopath.CNAME(origQName, records[0].Header().Name, records[0].Header().Ttl) | ||||||
| 					break | 					break | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| @@ -68,8 +69,8 @@ func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M | |||||||
| 				break | 				break | ||||||
| 			} | 			} | ||||||
| 			// Try host search path (if set) in the next middleware | 			// Try host search path (if set) in the next middleware | ||||||
| 			apw := NewAutoPathWriter(w, r) | 			apw := autopath.NewWriter(w, r) | ||||||
| 			for _, hostsearch := range k.AutoPath.HostSearchPath { | 			for _, hostsearch := range k.autoPath.HostSearchPath { | ||||||
| 				newstate := state.NewWithQuestion(strings.Join([]string{name, hostsearch}, "."), state.QType()) | 				newstate := state.NewWithQuestion(strings.Join([]string{name, hostsearch}, "."), state.QType()) | ||||||
| 				rcode, nextErr := middleware.NextOrFailure(k.Name(), k.Next, ctx, apw, newstate.Req) | 				rcode, nextErr := middleware.NextOrFailure(k.Name(), k.Next, ctx, apw, newstate.Req) | ||||||
| 				if apw.Sent { | 				if apw.Sent { | ||||||
| @@ -82,11 +83,11 @@ func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M | |||||||
| 			if !k.IsNameError(err) && len(records) > 0 { | 			if !k.IsNameError(err) && len(records) > 0 { | ||||||
| 				records = append(records, nil) | 				records = append(records, nil) | ||||||
| 				copy(records[1:], records) | 				copy(records[1:], records) | ||||||
| 				records[0] = newCNAME(origQName, records[0].Header().Name, records[0].Header().Ttl) | 				records[0] = autopath.CNAME(origQName, records[0].Header().Name, records[0].Header().Ttl) | ||||||
| 				break | 				break | ||||||
| 			} | 			} | ||||||
| 			// Search . in the next middleware | 			// Search . in the next middleware | ||||||
| 			apw.Rcode = k.AutoPath.OnNXDOMAIN | 			apw.Rcode = k.autoPath.OnNXDOMAIN | ||||||
| 			newstate = state.NewWithQuestion(strings.Join([]string{name, "."}, ""), state.QType()) | 			newstate = state.NewWithQuestion(strings.Join([]string{name, "."}, ""), state.QType()) | ||||||
| 			r = newstate.Req | 			r = newstate.Req | ||||||
| 			rcode, nextErr := middleware.NextOrFailure(k.Name(), k.Next, ctx, apw, r) | 			rcode, nextErr := middleware.NextOrFailure(k.Name(), k.Next, ctx, apw, r) | ||||||
| @@ -125,11 +126,6 @@ func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M | |||||||
| 	return dns.RcodeSuccess, nil | 	return dns.RcodeSuccess, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func newCNAME(name string, target string, ttl uint32) *dns.CNAME { |  | ||||||
| 	// TODO factor this out and put in dnsutil |  | ||||||
| 	return &dns.CNAME{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Ttl: ttl}, Target: dns.Fqdn(target)} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (k *Kubernetes) routeRequest(zone string, state request.Request) (records []dns.RR, extra []dns.RR, debug []dns.RR, err error) { | func (k *Kubernetes) routeRequest(zone string, state request.Request) (records []dns.RR, extra []dns.RR, debug []dns.RR, err error) { | ||||||
| 	switch state.Type() { | 	switch state.Type() { | ||||||
| 	case "A": | 	case "A": | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ import ( | |||||||
| 	"sort" | 	"sort" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	"github.com/coredns/coredns/middleware/kubernetes/autopath" | ||||||
| 	"github.com/coredns/coredns/middleware/pkg/dnsrecorder" | 	"github.com/coredns/coredns/middleware/pkg/dnsrecorder" | ||||||
| 	"github.com/coredns/coredns/middleware/test" | 	"github.com/coredns/coredns/middleware/test" | ||||||
|  |  | ||||||
| @@ -267,8 +268,8 @@ func TestServeDNS(t *testing.T) { | |||||||
| 	k.ReverseCidrs = []net.IPNet{*cidr} | 	k.ReverseCidrs = []net.IPNet{*cidr} | ||||||
| 	k.Federations = []Federation{{name: "fed", zone: "federal.test."}} | 	k.Federations = []Federation{{name: "fed", zone: "federal.test."}} | ||||||
| 	k.APIConn = &APIConnServeTest{} | 	k.APIConn = &APIConnServeTest{} | ||||||
| 	k.AutoPath.Enabled = true | 	k.autoPath = new(autopath.AutoPath) | ||||||
| 	k.AutoPath.HostSearchPath = []string{"hostdom.test"} | 	k.autoPath.HostSearchPath = []string{"hostdom.test"} | ||||||
| 	k.interfaceAddrsFunc = localPodIP | 	k.interfaceAddrsFunc = localPodIP | ||||||
| 	k.Next = testHandler(nextMWMap) | 	k.Next = testHandler(nextMWMap) | ||||||
|  |  | ||||||
| @@ -288,11 +289,11 @@ func TestServeDNS(t *testing.T) { | |||||||
| 	runServeDNSTests(ctx, t, podModeVerifiedCases, k) | 	runServeDNSTests(ctx, t, podModeVerifiedCases, k) | ||||||
|  |  | ||||||
| 	// Set ndots to 2 for the ndots test cases | 	// Set ndots to 2 for the ndots test cases | ||||||
| 	k.AutoPath.NDots = 2 | 	k.autoPath.NDots = 2 | ||||||
| 	runServeDNSTests(ctx, t, autopath2NDotsCases, k) | 	runServeDNSTests(ctx, t, autopath2NDotsCases, k) | ||||||
| 	k.AutoPath.NDots = defautNdots | 	k.autoPath.NDots = defautNdots | ||||||
| 	// Disable the NXDOMAIN override (enabled by default) | 	// Disable the NXDOMAIN override (enabled by default) | ||||||
| 	k.OnNXDOMAIN = dns.RcodeNameError | 	k.autoPath.OnNXDOMAIN = dns.RcodeNameError | ||||||
| 	runServeDNSTests(ctx, t, autopathCases, k) | 	runServeDNSTests(ctx, t, autopathCases, k) | ||||||
| 	runServeDNSTests(ctx, t, autopathBareSearchExpectNameErr, k) | 	runServeDNSTests(ctx, t, autopathBareSearchExpectNameErr, k) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/coredns/coredns/middleware" | 	"github.com/coredns/coredns/middleware" | ||||||
| 	"github.com/coredns/coredns/middleware/etcd/msg" | 	"github.com/coredns/coredns/middleware/etcd/msg" | ||||||
|  | 	"github.com/coredns/coredns/middleware/kubernetes/autopath" | ||||||
| 	"github.com/coredns/coredns/middleware/pkg/dnsutil" | 	"github.com/coredns/coredns/middleware/pkg/dnsutil" | ||||||
| 	dnsstrings "github.com/coredns/coredns/middleware/pkg/strings" | 	dnsstrings "github.com/coredns/coredns/middleware/pkg/strings" | ||||||
| 	"github.com/coredns/coredns/middleware/proxy" | 	"github.com/coredns/coredns/middleware/proxy" | ||||||
| @@ -45,17 +46,9 @@ type Kubernetes struct { | |||||||
| 	PodMode       string | 	PodMode       string | ||||||
| 	ReverseCidrs  []net.IPNet | 	ReverseCidrs  []net.IPNet | ||||||
| 	Fallthrough   bool | 	Fallthrough   bool | ||||||
| 	AutoPath |  | ||||||
| 	interfaceAddrsFunc func() net.IP |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AutoPath enables server side search path lookups for pods | 	autoPath           *autopath.AutoPath | ||||||
| type AutoPath struct { | 	interfaceAddrsFunc func() net.IP | ||||||
| 	Enabled        bool |  | ||||||
| 	NDots          int |  | ||||||
| 	ResolvConfFile string |  | ||||||
| 	HostSearchPath []string |  | ||||||
| 	OnNXDOMAIN     int |  | ||||||
| } | } | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| @@ -259,7 +252,7 @@ func (k *Kubernetes) InitKubeCache() (err error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	opts := dnsControlOpts{ | 	opts := dnsControlOpts{ | ||||||
| 		initPodCache: (k.PodMode == PodModeVerified || k.AutoPath.Enabled), | 		initPodCache: (k.PodMode == PodModeVerified || (k.autoPath != nil)), | ||||||
| 	} | 	} | ||||||
| 	k.APIConn = newdnsController(kubeClient, k.ResyncPeriod, k.Selector, opts) | 	k.APIConn = newdnsController(kubeClient, k.ResyncPeriod, k.Selector, opts) | ||||||
|  |  | ||||||
| @@ -468,7 +461,7 @@ func (k *Kubernetes) getRecordsForK8sItems(services []service, pods []pod, r rec | |||||||
| } | } | ||||||
|  |  | ||||||
| func (k *Kubernetes) findPodWithIP(ip string) (p *api.Pod) { | func (k *Kubernetes) findPodWithIP(ip string) (p *api.Pod) { | ||||||
| 	if !k.AutoPath.Enabled { | 	if k.autoPath == nil { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	objList := k.APIConn.PodIndex(ip) | 	objList := k.APIConn.PodIndex(ip) | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/coredns/coredns/core/dnsserver" | 	"github.com/coredns/coredns/core/dnsserver" | ||||||
| 	"github.com/coredns/coredns/middleware" | 	"github.com/coredns/coredns/middleware" | ||||||
|  | 	"github.com/coredns/coredns/middleware/kubernetes/autopath" | ||||||
| 	"github.com/coredns/coredns/middleware/pkg/dnsutil" | 	"github.com/coredns/coredns/middleware/pkg/dnsutil" | ||||||
| 	"github.com/coredns/coredns/middleware/proxy" | 	"github.com/coredns/coredns/middleware/proxy" | ||||||
| 	"github.com/miekg/dns" | 	"github.com/miekg/dns" | ||||||
| @@ -192,7 +193,7 @@ func kubernetesParse(c *caddy.Controller) (*Kubernetes, error) { | |||||||
| 					return nil, fmt.Errorf("incorrect number of arguments for federation, got %v, expected 2", len(args)) | 					return nil, fmt.Errorf("incorrect number of arguments for federation, got %v, expected 2", len(args)) | ||||||
| 				case "autopath": // name zone | 				case "autopath": // name zone | ||||||
| 					args := c.RemainingArgs() | 					args := c.RemainingArgs() | ||||||
| 					k8s.AutoPath = AutoPath{ | 					k8s.autoPath = &autopath.AutoPath{ | ||||||
| 						NDots:          defautNdots, | 						NDots:          defautNdots, | ||||||
| 						HostSearchPath: []string{}, | 						HostSearchPath: []string{}, | ||||||
| 						ResolvConfFile: defaultResolvConfFile, | 						ResolvConfFile: defaultResolvConfFile, | ||||||
| @@ -207,30 +208,29 @@ func kubernetesParse(c *caddy.Controller) (*Kubernetes, error) { | |||||||
| 						if err != nil { | 						if err != nil { | ||||||
| 							return nil, fmt.Errorf("invalid NDOTS argument for autopath, got '%v', expected an integer", ndots) | 							return nil, fmt.Errorf("invalid NDOTS argument for autopath, got '%v', expected an integer", ndots) | ||||||
| 						} | 						} | ||||||
| 						k8s.AutoPath.NDots = ndots | 						k8s.autoPath.NDots = ndots | ||||||
| 					} | 					} | ||||||
| 					if len(args) > 1 { | 					if len(args) > 1 { | ||||||
| 						switch args[1] { | 						switch args[1] { | ||||||
| 						case dns.RcodeToString[dns.RcodeNameError]: | 						case dns.RcodeToString[dns.RcodeNameError]: | ||||||
| 							k8s.AutoPath.OnNXDOMAIN = dns.RcodeNameError | 							k8s.autoPath.OnNXDOMAIN = dns.RcodeNameError | ||||||
| 						case dns.RcodeToString[dns.RcodeSuccess]: | 						case dns.RcodeToString[dns.RcodeSuccess]: | ||||||
| 							k8s.AutoPath.OnNXDOMAIN = dns.RcodeSuccess | 							k8s.autoPath.OnNXDOMAIN = dns.RcodeSuccess | ||||||
| 						case dns.RcodeToString[dns.RcodeServerFailure]: | 						case dns.RcodeToString[dns.RcodeServerFailure]: | ||||||
| 							k8s.AutoPath.OnNXDOMAIN = dns.RcodeServerFailure | 							k8s.autoPath.OnNXDOMAIN = dns.RcodeServerFailure | ||||||
| 						default: | 						default: | ||||||
| 							return nil, fmt.Errorf("invalid RESPONSE argument for autopath, got '%v', expected SERVFAIL, NOERROR, or NXDOMAIN", args[1]) | 							return nil, fmt.Errorf("invalid RESPONSE argument for autopath, got '%v', expected SERVFAIL, NOERROR, or NXDOMAIN", args[1]) | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 					if len(args) > 2 { | 					if len(args) > 2 { | ||||||
| 						k8s.AutoPath.ResolvConfFile = args[2] | 						k8s.autoPath.ResolvConfFile = args[2] | ||||||
| 					} | 					} | ||||||
| 					rc, err := dns.ClientConfigFromFile(k8s.AutoPath.ResolvConfFile) | 					rc, err := dns.ClientConfigFromFile(k8s.autoPath.ResolvConfFile) | ||||||
| 					if err != nil { | 					if err != nil { | ||||||
| 						return nil, fmt.Errorf("error when parsing %v: %v", k8s.AutoPath.ResolvConfFile, err) | 						return nil, fmt.Errorf("error when parsing %v: %v", k8s.autoPath.ResolvConfFile, err) | ||||||
| 					} | 					} | ||||||
| 					k8s.AutoPath.HostSearchPath = rc.Search | 					k8s.autoPath.HostSearchPath = rc.Search | ||||||
| 					middleware.Zones(k8s.AutoPath.HostSearchPath).Normalize() | 					middleware.Zones(k8s.autoPath.HostSearchPath).Normalize() | ||||||
| 					k8s.AutoPath.Enabled = true |  | ||||||
| 					continue | 					continue | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/coredns/coredns/middleware/kubernetes/autopath" | ||||||
| 	"github.com/coredns/coredns/middleware/test" | 	"github.com/coredns/coredns/middleware/test" | ||||||
|  |  | ||||||
| 	"github.com/mholt/caddy" | 	"github.com/mholt/caddy" | ||||||
| @@ -42,7 +43,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 		expectedFallthrough   bool | 		expectedFallthrough   bool | ||||||
| 		expectedUpstreams     []string | 		expectedUpstreams     []string | ||||||
| 		expectedFederations   []Federation | 		expectedFederations   []Federation | ||||||
| 		expectedAutoPath      AutoPath | 		expectedAutoPath      *autopath.AutoPath | ||||||
| 	}{ | 	}{ | ||||||
| 		// positive | 		// positive | ||||||
| 		{ | 		{ | ||||||
| @@ -59,7 +60,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"kubernetes keyword with multiple zones", | 			"kubernetes keyword with multiple zones", | ||||||
| @@ -75,7 +76,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"kubernetes keyword with zone and empty braces", | 			"kubernetes keyword with zone and empty braces", | ||||||
| @@ -92,7 +93,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"endpoint keyword with url", | 			"endpoint keyword with url", | ||||||
| @@ -110,7 +111,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"namespaces keyword with one namespace", | 			"namespaces keyword with one namespace", | ||||||
| @@ -128,7 +129,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			nil, | 			nil, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"namespaces keyword with multiple namespaces", | 			"namespaces keyword with multiple namespaces", | ||||||
| @@ -146,7 +147,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"resync period in seconds", | 			"resync period in seconds", | ||||||
| @@ -164,7 +165,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"resync period in minutes", | 			"resync period in minutes", | ||||||
| @@ -182,7 +183,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"basic label selector", | 			"basic label selector", | ||||||
| @@ -200,7 +201,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"multi-label selector", | 			"multi-label selector", | ||||||
| @@ -218,7 +219,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"fully specified valid config", | 			"fully specified valid config", | ||||||
| @@ -240,7 +241,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			true, | 			true, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		// negative | 		// negative | ||||||
| 		{ | 		{ | ||||||
| @@ -257,7 +258,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"kubernetes keyword without a zone", | 			"kubernetes keyword without a zone", | ||||||
| @@ -273,7 +274,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"endpoint keyword without an endpoint value", | 			"endpoint keyword without an endpoint value", | ||||||
| @@ -291,7 +292,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"namespace keyword without a namespace value", | 			"namespace keyword without a namespace value", | ||||||
| @@ -309,7 +310,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"resyncperiod keyword without a duration value", | 			"resyncperiod keyword without a duration value", | ||||||
| @@ -327,7 +328,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"resync period no units", | 			"resync period no units", | ||||||
| @@ -345,7 +346,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"resync period invalid", | 			"resync period invalid", | ||||||
| @@ -363,7 +364,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"labels with no selector value", | 			"labels with no selector value", | ||||||
| @@ -381,7 +382,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"labels with invalid selector value", | 			"labels with invalid selector value", | ||||||
| @@ -399,7 +400,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		// pods disabled | 		// pods disabled | ||||||
| 		{ | 		{ | ||||||
| @@ -418,7 +419,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		// pods insecure | 		// pods insecure | ||||||
| 		{ | 		{ | ||||||
| @@ -437,7 +438,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		// pods verified | 		// pods verified | ||||||
| 		{ | 		{ | ||||||
| @@ -456,7 +457,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		// pods invalid | 		// pods invalid | ||||||
| 		{ | 		{ | ||||||
| @@ -475,7 +476,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		// cidrs ok | 		// cidrs ok | ||||||
| 		{ | 		{ | ||||||
| @@ -494,7 +495,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		// cidrs ok | 		// cidrs ok | ||||||
| 		{ | 		{ | ||||||
| @@ -513,7 +514,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		// fallthrough invalid | 		// fallthrough invalid | ||||||
| 		{ | 		{ | ||||||
| @@ -532,7 +533,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		// Valid upstream | 		// Valid upstream | ||||||
| 		{ | 		{ | ||||||
| @@ -551,7 +552,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			[]string{"13.14.15.16:53"}, | 			[]string{"13.14.15.16:53"}, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		// Invalid upstream | 		// Invalid upstream | ||||||
| 		{ | 		{ | ||||||
| @@ -570,7 +571,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		// Valid federations | 		// Valid federations | ||||||
| 		{ | 		{ | ||||||
| @@ -593,7 +594,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 				{name: "foo", zone: "bar.crawl.com"}, | 				{name: "foo", zone: "bar.crawl.com"}, | ||||||
| 				{name: "fed", zone: "era.tion.com"}, | 				{name: "fed", zone: "era.tion.com"}, | ||||||
| 			}, | 			}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		// Invalid federations | 		// Invalid federations | ||||||
| 		{ | 		{ | ||||||
| @@ -612,7 +613,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			[]Federation{}, | 			[]Federation{}, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		// autopath | 		// autopath | ||||||
| 		{ | 		{ | ||||||
| @@ -631,8 +632,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			nil, | 			nil, | ||||||
| 			AutoPath{ | 			&autopath.AutoPath{ | ||||||
| 				Enabled:        true, |  | ||||||
| 				NDots:          1, | 				NDots:          1, | ||||||
| 				HostSearchPath: []string{"bar.com.", "baz.com."}, | 				HostSearchPath: []string{"bar.com.", "baz.com."}, | ||||||
| 				ResolvConfFile: autoPathResolvConfFile, | 				ResolvConfFile: autoPathResolvConfFile, | ||||||
| @@ -655,7 +655,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			nil, | 			nil, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"invalid autopath NDOTS", | 			"invalid autopath NDOTS", | ||||||
| @@ -673,7 +673,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			nil, | 			nil, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"invalid autopath RESOLV-CONF", | 			"invalid autopath RESOLV-CONF", | ||||||
| @@ -691,7 +691,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			nil, | 			nil, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"invalid autopath invalid option", | 			"invalid autopath invalid option", | ||||||
| @@ -709,7 +709,7 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			false, | 			false, | ||||||
| 			nil, | 			nil, | ||||||
| 			nil, | 			nil, | ||||||
| 			AutoPath{}, | 			nil, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -811,8 +811,8 @@ func TestKubernetesParse(t *testing.T) { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		// autopath | 		// autopath | ||||||
| 		if !reflect.DeepEqual(test.expectedAutoPath, k8sController.AutoPath) { | 		if !reflect.DeepEqual(test.expectedAutoPath, k8sController.autoPath) { | ||||||
| 			t.Errorf("Test %d: Expected kubernetes controller to be initialized with autopath '%v'. Instead found autopath '%v' for input '%s'", i, test.expectedAutoPath, k8sController.AutoPath, test.input) | 			t.Errorf("Test %d: Expected kubernetes controller to be initialized with autopath '%v'. Instead found autopath '%v' for input '%s'", i, test.expectedAutoPath, k8sController.autoPath, test.input) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user