Remove debug queries (#1058)

* Remove debug from interface and methods

* remove debug queries from etcd

* remove debug queries from k8s - they were not used

* And remove from mw/proxy-google as well

* Remove debug query test
This commit is contained in:
Miek Gieben 2017-09-12 10:52:43 +01:00 committed by GitHub
parent c2105a4f41
commit 3e252deabb
17 changed files with 99 additions and 462 deletions

View file

@ -11,27 +11,22 @@ import (
type ServiceBackend interface { type ServiceBackend interface {
// Services communicates with the backend to retrieve the service definition. Exact indicates // Services communicates with the backend to retrieve the service definition. 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, error)
// Reverse communicates with the backend to retrieve service definition based on a IP address // Reverse communicates with the backend to retrieve service definition based on a IP address
// instead of a name. I.e. a reverse DNS lookup. // instead of a name. I.e. a reverse DNS lookup.
Reverse(state request.Request, exact bool, opt Options) ([]msg.Service, []msg.Service, error) Reverse(state request.Request, exact bool, opt Options) ([]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)
// IsNameError return true if err indicated a record not found condition
IsNameError(err error) bool
// Debug returns a string used when returning debug services.
Debug() string
// Returns _all_ services that matches a certain name. // Returns _all_ services that matches a certain name.
// Note: it does not implement a specific service. // Note: it does not implement a specific service.
Records(state request.Request, exact bool) ([]msg.Service, error) Records(state request.Request, exact bool) ([]msg.Service, error)
// IsNameError return true if err indicated a record not found condition
IsNameError(err error) bool
} }
// Options are extra options that can be specified for a lookup. // Options are extra options that can be specified for a lookup.
type Options struct { type Options struct{}
Debug string // This is a debug query. A query prefixed with debug.o-o
}

View file

@ -14,10 +14,10 @@ import (
) )
// A returns A records from Backend or an error. // A returns A records from Backend or an error.
func A(b ServiceBackend, zone string, state request.Request, previousRecords []dns.RR, opt Options) (records []dns.RR, debug []msg.Service, err error) { func A(b ServiceBackend, zone string, state request.Request, previousRecords []dns.RR, opt Options) (records []dns.RR, err error) {
services, debug, err := b.Services(state, false, opt) services, err := b.Services(state, false, opt)
if err != nil { if err != nil {
return nil, debug, err return nil, err
} }
for _, serv := range services { for _, serv := range services {
@ -41,14 +41,13 @@ func A(b ServiceBackend, zone string, state request.Request, previousRecords []d
} }
state1 := state.NewWithQuestion(serv.Host, state.QType()) state1 := state.NewWithQuestion(serv.Host, state.QType())
nextRecords, nextDebug, err := A(b, zone, state1, append(previousRecords, newRecord), opt) nextRecords, err := A(b, zone, state1, append(previousRecords, newRecord), opt)
if err == nil { if err == nil {
// Not only have we found something we should add the CNAME and the IP addresses. // Not only have we found something we should add the CNAME and the IP addresses.
if len(nextRecords) > 0 { if len(nextRecords) > 0 {
records = append(records, newRecord) records = append(records, newRecord)
records = append(records, nextRecords...) records = append(records, nextRecords...)
debug = append(debug, nextDebug...)
} }
continue continue
} }
@ -61,8 +60,6 @@ func A(b ServiceBackend, zone string, state request.Request, previousRecords []d
// Lookup // Lookup
m1, e1 := b.Lookup(state, target, state.QType()) m1, e1 := b.Lookup(state, target, state.QType())
if e1 != nil { if e1 != nil {
debugMsg := msg.Service{Key: msg.Path(target, b.Debug()), Host: target, Text: " IN " + state.Type() + ": " + e1.Error()}
debug = append(debug, debugMsg)
continue continue
} }
// Len(m1.Answer) > 0 here is well? // Len(m1.Answer) > 0 here is well?
@ -77,14 +74,14 @@ func A(b ServiceBackend, zone string, state request.Request, previousRecords []d
// nodata? // nodata?
} }
} }
return records, debug, nil return records, nil
} }
// AAAA returns AAAA records from Backend or an error. // AAAA returns AAAA records from Backend or an error.
func AAAA(b ServiceBackend, zone string, state request.Request, previousRecords []dns.RR, opt Options) (records []dns.RR, debug []msg.Service, err error) { func AAAA(b ServiceBackend, zone string, state request.Request, previousRecords []dns.RR, opt Options) (records []dns.RR, err error) {
services, debug, err := b.Services(state, false, opt) services, err := b.Services(state, false, opt)
if err != nil { if err != nil {
return nil, debug, err return nil, err
} }
for _, serv := range services { for _, serv := range services {
@ -109,14 +106,13 @@ func AAAA(b ServiceBackend, zone string, state request.Request, previousRecords
} }
state1 := state.NewWithQuestion(serv.Host, state.QType()) state1 := state.NewWithQuestion(serv.Host, state.QType())
nextRecords, nextDebug, err := AAAA(b, zone, state1, append(previousRecords, newRecord), opt) nextRecords, err := AAAA(b, zone, state1, append(previousRecords, newRecord), opt)
if err == nil { if err == nil {
// Not only have we found something we should add the CNAME and the IP addresses. // Not only have we found something we should add the CNAME and the IP addresses.
if len(nextRecords) > 0 { if len(nextRecords) > 0 {
records = append(records, newRecord) records = append(records, newRecord)
records = append(records, nextRecords...) records = append(records, nextRecords...)
debug = append(debug, nextDebug...)
} }
continue continue
} }
@ -128,8 +124,6 @@ func AAAA(b ServiceBackend, zone string, state request.Request, previousRecords
} }
m1, e1 := b.Lookup(state, target, state.QType()) m1, e1 := b.Lookup(state, target, state.QType())
if e1 != nil { if e1 != nil {
debugMsg := msg.Service{Key: msg.Path(target, b.Debug()), Host: target, Text: " IN " + state.Type() + ": " + e1.Error()}
debug = append(debug, debugMsg)
continue continue
} }
// Len(m1.Answer) > 0 here is well? // Len(m1.Answer) > 0 here is well?
@ -145,15 +139,15 @@ func AAAA(b ServiceBackend, zone string, state request.Request, previousRecords
records = append(records, serv.NewAAAA(state.QName(), ip)) records = append(records, serv.NewAAAA(state.QName(), ip))
} }
} }
return records, debug, nil return records, nil
} }
// SRV returns SRV records from the Backend. // SRV returns SRV records from the Backend.
// If the Target is not a name but an IP address, a name is created on the fly. // If the Target is not a name but an IP address, a name is created on the fly.
func SRV(b ServiceBackend, zone string, state request.Request, opt Options) (records, extra []dns.RR, debug []msg.Service, err error) { func SRV(b ServiceBackend, zone string, state request.Request, opt Options) (records, extra []dns.RR, err error) {
services, debug, err := b.Services(state, false, opt) services, err := b.Services(state, false, opt)
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, err
} }
// Looping twice to get the right weight vs priority // Looping twice to get the right weight vs priority
@ -196,9 +190,6 @@ func SRV(b ServiceBackend, zone string, state request.Request, opt Options) (rec
m1, e1 := b.Lookup(state, srv.Target, dns.TypeA) m1, e1 := b.Lookup(state, srv.Target, dns.TypeA)
if e1 == nil { if e1 == nil {
extra = append(extra, m1.Answer...) extra = append(extra, m1.Answer...)
} else {
debugMsg := msg.Service{Key: msg.Path(srv.Target, b.Debug()), Host: srv.Target, Text: " IN A: " + e1.Error()}
debug = append(debug, debugMsg)
} }
m1, e1 = b.Lookup(state, srv.Target, dns.TypeAAAA) m1, e1 = b.Lookup(state, srv.Target, dns.TypeAAAA)
@ -209,19 +200,15 @@ func SRV(b ServiceBackend, zone string, state request.Request, opt Options) (rec
extra = append(extra, a) extra = append(extra, a)
} }
} }
} else {
debugMsg := msg.Service{Key: msg.Path(srv.Target, b.Debug()), Host: srv.Target, Text: " IN AAAA: " + e1.Error()}
debug = append(debug, debugMsg)
} }
break break
} }
// Internal name, we should have some info on them, either v4 or v6 // Internal name, we should have some info on them, either v4 or v6
// Clients expect a complete answer, because we are a recursor in their view. // Clients expect a complete answer, because we are a recursor in their view.
state1 := state.NewWithQuestion(srv.Target, dns.TypeA) state1 := state.NewWithQuestion(srv.Target, dns.TypeA)
addr, debugAddr, e1 := A(b, zone, state1, nil, opt) addr, e1 := A(b, zone, state1, nil, opt)
if e1 == nil { if e1 == nil {
extra = append(extra, addr...) extra = append(extra, addr...)
debug = append(debug, debugAddr...)
} }
// IPv6 lookups here as well? AAAA(zone, state1, nil). // IPv6 lookups here as well? AAAA(zone, state1, nil).
@ -233,14 +220,14 @@ func SRV(b ServiceBackend, zone string, state request.Request, opt Options) (rec
extra = append(extra, newAddress(serv, srv.Target, ip, what)) extra = append(extra, newAddress(serv, srv.Target, ip, what))
} }
} }
return records, extra, debug, nil return records, extra, nil
} }
// MX returns MX records from the Backend. If the Target is not a name but an IP address, a name is created on the fly. // MX returns MX records from the Backend. If the Target is not a name but an IP address, a name is created on the fly.
func MX(b ServiceBackend, zone string, state request.Request, opt Options) (records, extra []dns.RR, debug []msg.Service, err error) { func MX(b ServiceBackend, zone string, state request.Request, opt Options) (records, extra []dns.RR, err error) {
services, debug, err := b.Services(state, false, opt) services, err := b.Services(state, false, opt)
if err != nil { if err != nil {
return nil, nil, debug, err return nil, nil, err
} }
lookup := make(map[string]bool) lookup := make(map[string]bool)
@ -263,10 +250,8 @@ func MX(b ServiceBackend, zone string, state request.Request, opt Options) (reco
m1, e1 := b.Lookup(state, mx.Mx, dns.TypeA) m1, e1 := b.Lookup(state, mx.Mx, dns.TypeA)
if e1 == nil { if e1 == nil {
extra = append(extra, m1.Answer...) extra = append(extra, m1.Answer...)
} else {
debugMsg := msg.Service{Key: msg.Path(mx.Mx, b.Debug()), Host: mx.Mx, Text: " IN A: " + e1.Error()}
debug = append(debug, debugMsg)
} }
m1, e1 = b.Lookup(state, mx.Mx, dns.TypeAAAA) m1, e1 = b.Lookup(state, mx.Mx, dns.TypeAAAA)
if e1 == nil { if e1 == nil {
// If we have seen CNAME's we *assume* that they are already added. // If we have seen CNAME's we *assume* that they are already added.
@ -275,18 +260,14 @@ func MX(b ServiceBackend, zone string, state request.Request, opt Options) (reco
extra = append(extra, a) extra = append(extra, a)
} }
} }
} else {
debugMsg := msg.Service{Key: msg.Path(mx.Mx, b.Debug()), Host: mx.Mx, Text: " IN AAAA: " + e1.Error()}
debug = append(debug, debugMsg)
} }
break break
} }
// Internal name // Internal name
state1 := state.NewWithQuestion(mx.Mx, dns.TypeA) state1 := state.NewWithQuestion(mx.Mx, dns.TypeA)
addr, debugAddr, e1 := A(b, zone, state1, nil, opt) addr, e1 := A(b, zone, state1, nil, opt)
if e1 == nil { if e1 == nil {
extra = append(extra, addr...) extra = append(extra, addr...)
debug = append(debug, debugAddr...)
} }
// e.AAAA as well // e.AAAA as well
@ -296,14 +277,14 @@ func MX(b ServiceBackend, zone string, state request.Request, opt Options) (reco
extra = append(extra, newAddress(serv, serv.Host, ip, what)) extra = append(extra, newAddress(serv, serv.Host, ip, what))
} }
} }
return records, extra, debug, nil return records, extra, nil
} }
// CNAME returns CNAME records from the backend or an error. // CNAME returns CNAME records from the backend or an error.
func CNAME(b ServiceBackend, zone string, state request.Request, opt Options) (records []dns.RR, debug []msg.Service, err error) { func CNAME(b ServiceBackend, zone string, state request.Request, opt Options) (records []dns.RR, err error) {
services, debug, err := b.Services(state, true, opt) services, err := b.Services(state, true, opt)
if err != nil { if err != nil {
return nil, debug, err return nil, err
} }
if len(services) > 0 { if len(services) > 0 {
@ -312,14 +293,14 @@ func CNAME(b ServiceBackend, zone string, state request.Request, opt Options) (r
records = append(records, serv.NewCNAME(state.QName(), serv.Host)) records = append(records, serv.NewCNAME(state.QName(), serv.Host))
} }
} }
return records, debug, nil return records, nil
} }
// TXT returns TXT records from Backend or an error. // TXT returns TXT records from Backend or an error.
func TXT(b ServiceBackend, zone string, state request.Request, opt Options) (records []dns.RR, debug []msg.Service, err error) { func TXT(b ServiceBackend, zone string, state request.Request, opt Options) (records []dns.RR, err error) {
services, debug, err := b.Services(state, false, opt) services, err := b.Services(state, false, opt)
if err != nil { if err != nil {
return nil, debug, err return nil, err
} }
for _, serv := range services { for _, serv := range services {
@ -328,14 +309,14 @@ func TXT(b ServiceBackend, zone string, state request.Request, opt Options) (rec
} }
records = append(records, serv.NewTXT(state.QName())) records = append(records, serv.NewTXT(state.QName()))
} }
return records, debug, nil return records, nil
} }
// 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.
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, err error) {
services, debug, err := b.Reverse(state, true, opt) services, err := b.Reverse(state, true, opt)
if err != nil { if err != nil {
return nil, debug, err return nil, err
} }
for _, serv := range services { for _, serv := range services {
@ -343,20 +324,20 @@ func PTR(b ServiceBackend, zone string, state request.Request, opt Options) (rec
records = append(records, serv.NewPTR(state.QName(), serv.Host)) records = append(records, serv.NewPTR(state.QName(), serv.Host))
} }
} }
return records, debug, nil return records, nil
} }
// NS returns NS records from the backend // NS returns NS records from the backend
func NS(b ServiceBackend, zone string, state request.Request, opt Options) (records, extra []dns.RR, debug []msg.Service, err error) { func NS(b ServiceBackend, zone string, state request.Request, opt Options) (records, extra []dns.RR, err error) {
// NS record for this zone live in a special place, ns.dns.<zone>. Fake our lookup. // NS record for this zone live in a special place, ns.dns.<zone>. Fake our lookup.
// only a tad bit fishy... // only a tad bit fishy...
old := state.QName() old := state.QName()
state.Clear() state.Clear()
state.Req.Question[0].Name = "ns.dns." + zone state.Req.Question[0].Name = "ns.dns." + zone
services, debug, err := b.Services(state, false, opt) services, err := b.Services(state, false, opt)
if err != nil { if err != nil {
return nil, nil, debug, err return nil, nil, err
} }
// ... and reset // ... and reset
state.Req.Question[0].Name = old state.Req.Question[0].Name = old
@ -365,7 +346,7 @@ func NS(b ServiceBackend, zone string, state request.Request, opt Options) (reco
what, ip := serv.HostType() what, ip := serv.HostType()
switch what { switch what {
case dns.TypeCNAME: case dns.TypeCNAME:
return nil, nil, debug, fmt.Errorf("NS record must be an IP address: %s", serv.Host) return nil, nil, fmt.Errorf("NS record must be an IP address: %s", serv.Host)
case dns.TypeA, dns.TypeAAAA: case dns.TypeA, dns.TypeAAAA:
serv.Host = msg.Domain(serv.Key) serv.Host = msg.Domain(serv.Key)
@ -373,11 +354,11 @@ func NS(b ServiceBackend, zone string, state request.Request, opt Options) (reco
extra = append(extra, newAddress(serv, serv.Host, ip, what)) extra = append(extra, newAddress(serv, serv.Host, ip, what))
} }
} }
return records, extra, debug, nil return records, extra, nil
} }
// SOA returns a SOA record from the backend. // SOA returns a SOA record from the backend.
func SOA(b ServiceBackend, zone string, state request.Request, opt Options) ([]dns.RR, []msg.Service, error) { func SOA(b ServiceBackend, zone string, state request.Request, opt Options) ([]dns.RR, error) {
header := dns.RR_Header{Name: zone, Rrtype: dns.TypeSOA, Ttl: 300, Class: dns.ClassINET} header := dns.RR_Header{Name: zone, Rrtype: dns.TypeSOA, Ttl: 300, Class: dns.ClassINET}
Mbox := hostmaster + "." Mbox := hostmaster + "."
@ -396,60 +377,22 @@ func SOA(b ServiceBackend, zone string, state request.Request, opt Options) ([]d
Expire: 86400, Expire: 86400,
Minttl: minTTL, Minttl: minTTL,
} }
return []dns.RR{soa}, nil, nil return []dns.RR{soa}, nil
} }
// BackendError writes an error response to the client. // BackendError writes an error response to the client.
func BackendError(b ServiceBackend, zone string, rcode int, state request.Request, debug []msg.Service, err error, opt Options) (int, error) { func BackendError(b ServiceBackend, zone string, rcode int, state request.Request, err error, opt Options) (int, error) {
m := new(dns.Msg) m := new(dns.Msg)
m.SetRcode(state.Req, rcode) m.SetRcode(state.Req, rcode)
m.Authoritative, m.RecursionAvailable, m.Compress = true, true, true m.Authoritative, m.RecursionAvailable, m.Compress = true, true, true
m.Ns, _, _ = SOA(b, zone, state, opt) m.Ns, _ = SOA(b, zone, state, opt)
if opt.Debug != "" {
m.Extra = ServicesToTxt(debug)
txt := ErrorToTxt(err)
if txt != nil {
m.Extra = append(m.Extra, ErrorToTxt(err))
}
}
state.SizeAndDo(m) state.SizeAndDo(m)
state.W.WriteMsg(m) state.W.WriteMsg(m)
// Return success as the rcode to signal we have written to the client. // Return success as the rcode to signal we have written to the client.
return dns.RcodeSuccess, err return dns.RcodeSuccess, err
} }
// ServicesToTxt puts debug in TXT RRs.
func ServicesToTxt(debug []msg.Service) []dns.RR {
if debug == nil {
return nil
}
rr := make([]dns.RR, len(debug))
for i, d := range debug {
rr[i] = d.RR()
}
return rr
}
// ErrorToTxt puts in error's text into an TXT RR.
func ErrorToTxt(err error) dns.RR {
if err == nil {
return nil
}
msg := err.Error()
if len(msg) > 255 {
msg = msg[:255]
}
t := new(dns.TXT)
t.Hdr.Class = dns.ClassCHAOS
t.Hdr.Ttl = 0
t.Hdr.Rrtype = dns.TypeTXT
t.Hdr.Name = "."
t.Txt = []string{msg}
return t
}
func newAddress(s msg.Service, name string, ip net.IP, what uint16) dns.RR { func newAddress(s msg.Service, name string, ip net.IP, what uint16) dns.RR {
hdr := dns.RR_Header{Name: name, Rrtype: what, Class: dns.ClassINET, Ttl: s.TTL} hdr := dns.RR_Header{Name: name, Rrtype: what, Class: dns.ClassINET, Ttl: s.TTL}

View file

@ -28,7 +28,6 @@ etcd [ZONES...] {
endpoint ENDPOINT... endpoint ENDPOINT...
upstream ADDRESS... upstream ADDRESS...
tls CERT KEY CACERT tls CERT KEY CACERT
debug
} }
~~~ ~~~
@ -46,8 +45,6 @@ etcd [ZONES...] {
* a single argument that is the CA PEM file, if the server cert is not signed by a system CA and no client cert is needed * a single argument that is the CA PEM file, if the server cert is not signed by a system CA and no client cert is needed
* two arguments - path to cert PEM file, the path to private key PEM file - if the server certificate is signed by a system-installed CA and a client certificate is needed * two arguments - path to cert PEM file, the path to private key PEM file - if the server certificate is signed by a system-installed CA and a client certificate is needed
* three arguments - path to cert PEM file, path to client private key PEM file, path to CA PEM file - if the server certificate is not signed by a system-installed CA and client certificate is needed * three arguments - path to cert PEM file, path to client private key PEM file, path to CA PEM file - if the server certificate is not signed by a system-installed CA and client certificate is needed
* `debug` allows for debug queries. Prefix the name with `o-o.debug.` to retrieve extra information in the
additional section of the reply in the form of TXT records.
## Examples ## Examples
@ -110,44 +107,3 @@ Querying with dig:
% dig @localhost -x 10.0.0.127 +short % dig @localhost -x 10.0.0.127 +short
reverse.atoom.net. reverse.atoom.net.
~~~ ~~~
Or with *debug* queries enabled:
~~~
% dig @localhost -p 1053 o-o.debug.127.0.0.10.in-addr.arpa. PTR
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;o-o.debug.127.0.0.10.in-addr.arpa. IN PTR
;; ANSWER SECTION:
127.0.0.10.in-addr.arpa. 300 IN PTR reverse.atoom.net.
;; ADDITIONAL SECTION:
127.0.0.10.in-addr.arpa. 300 CH TXT "reverse.atoom.net.:0(10,0,,false)[0,]"
~~~
## Debug queries
When debug queries are enabled CoreDNS will return errors and etcd records encountered during the resolution
process in the response. The general form looks like this:
skydns.test.skydns.dom.a. 0 CH TXT "127.0.0.1:0(10,0,,false)[0,]"
This shows the complete key as the owername, the rdata of the TXT record has:
`host:port(priority,weight,txt content,mail)[targetstrip,group]`.
Errors when communicating with an upstream will be returned as: `host:0(0,0,error message,false)[0,]`.
An example:
www.example.org. 0 CH TXT "www.example.org.:0(0,0, IN A: unreachable backend,false)[0,]"
Signalling that an A record for www.example.org. was sought, but it failed with that error.
Any errors seen doing parsing will show up like this:
. 0 CH TXT "/skydns/local/skydns/r/a: invalid character '.' after object key:value pair"
which shows `a.r.skydns.local.` has a json encoding problem.

View file

@ -1,97 +0,0 @@
// +build etcd
package etcd
import (
"testing"
"github.com/coredns/coredns/middleware/etcd/msg"
"github.com/coredns/coredns/middleware/pkg/dnsrecorder"
"github.com/coredns/coredns/middleware/test"
"github.com/miekg/dns"
)
func TestDebugLookup(t *testing.T) {
etc := newEtcdMiddleware()
etc.Debugging = true
for _, serv := range servicesDebug {
set(t, etc, serv.Key, 0, serv)
defer delete(t, etc, serv.Key)
}
for _, tc := range dnsTestCasesDebug {
m := tc.Msg()
rec := dnsrecorder.New(&test.ResponseWriter{})
etc.ServeDNS(ctxt, rec, m)
resp := rec.Msg
test.SortAndCheck(t, resp, tc)
}
}
func TestDebugLookupFalse(t *testing.T) {
etc := newEtcdMiddleware()
for _, serv := range servicesDebug {
set(t, etc, serv.Key, 0, serv)
defer delete(t, etc, serv.Key)
}
for _, tc := range dnsTestCasesDebugFalse {
m := tc.Msg()
rec := dnsrecorder.New(&test.ResponseWriter{})
etc.ServeDNS(ctxt, rec, m)
resp := rec.Msg
test.SortAndCheck(t, resp, tc)
}
}
var servicesDebug = []*msg.Service{
{Host: "127.0.0.1", Key: "a.dom.skydns.test."},
{Host: "127.0.0.2", Key: "b.sub.dom.skydns.test."},
}
var dnsTestCasesDebug = []test.Case{
{
Qname: "o-o.debug.dom.skydns.test.", Qtype: dns.TypeA,
Answer: []dns.RR{
test.A("dom.skydns.test. 300 IN A 127.0.0.1"),
test.A("dom.skydns.test. 300 IN A 127.0.0.2"),
},
Extra: []dns.RR{
test.TXT(`a.dom.skydns.test. 300 CH TXT "127.0.0.1:0(10,0,,false)[0,]"`),
test.TXT(`b.sub.dom.skydns.test. 300 CH TXT "127.0.0.2:0(10,0,,false)[0,]"`),
},
},
{
Qname: "o-o.debug.dom.skydns.test.", Qtype: dns.TypeTXT,
Ns: []dns.RR{
test.SOA("skydns.test. 300 IN SOA ns.dns.skydns.test. hostmaster.skydns.test. 1463943291 7200 1800 86400 60"),
},
Extra: []dns.RR{
test.TXT(`a.dom.skydns.test. 300 CH TXT "127.0.0.1:0(10,0,,false)[0,]"`),
test.TXT(`b.sub.dom.skydns.test. 300 CH TXT "127.0.0.2:0(10,0,,false)[0,]"`),
},
},
}
var dnsTestCasesDebugFalse = []test.Case{
{
Qname: "o-o.debug.dom.skydns.test.", Qtype: dns.TypeA,
Rcode: dns.RcodeNameError,
Ns: []dns.RR{
test.SOA("skydns.test. 300 IN SOA ns.dns.skydns.test. hostmaster.skydns.test. 1463943291 7200 1800 86400 60"),
},
},
{
Qname: "o-o.debug.dom.skydns.test.", Qtype: dns.TypeTXT,
Rcode: dns.RcodeNameError,
Ns: []dns.RR{
test.SOA("skydns.test. 300 IN SOA ns.dns.skydns.test. hostmaster.skydns.test. 1463943291 7200 1800 86400 60"),
},
},
}

View file

@ -30,26 +30,23 @@ type Etcd struct {
Ctx context.Context Ctx context.Context
Inflight *singleflight.Group Inflight *singleflight.Group
Stubmap *map[string]proxy.Proxy // list of proxies for stub resolving. Stubmap *map[string]proxy.Proxy // list of proxies for stub resolving.
Debugging bool // Do we allow debug queries.
endpoints []string // Stored here as well, to aid in testing. endpoints []string // Stored here as well, to aid in testing.
} }
// Services implements the ServiceBackend interface. // Services implements the ServiceBackend interface.
func (e *Etcd) Services(state request.Request, exact bool, opt middleware.Options) (services, debug []msg.Service, err error) { func (e *Etcd) Services(state request.Request, exact bool, opt middleware.Options) (services []msg.Service, err error) {
services, err = e.Records(state, exact) services, err = e.Records(state, exact)
if err != nil { if err != nil {
return return
} }
if opt.Debug != "" {
debug = services
}
services = msg.Group(services) services = msg.Group(services)
return return
} }
// Reverse implements the ServiceBackend interface. // Reverse implements the ServiceBackend interface.
func (e *Etcd) Reverse(state request.Request, exact bool, opt middleware.Options) (services, debug []msg.Service, err error) { func (e *Etcd) Reverse(state request.Request, exact bool, opt middleware.Options) (services []msg.Service, err error) {
return e.Services(state, exact, opt) return e.Services(state, exact, opt)
} }
@ -66,11 +63,6 @@ func (e *Etcd) IsNameError(err error) bool {
return false return false
} }
// Debug implements the ServiceBackend interface.
func (e *Etcd) Debug() string {
return e.PathPrefix
}
// Records looks up records in etcd. If exact is true, it will lookup just this // Records looks up records in etcd. If exact is true, it will lookup just this
// name. This is used when find matches when completing SRV lookups for instance. // name. This is used when find matches when completing SRV lookups for instance.
func (e *Etcd) Records(state request.Request, exact bool) ([]msg.Service, error) { func (e *Etcd) Records(state request.Request, exact bool) ([]msg.Service, error) {

View file

@ -2,8 +2,6 @@ package etcd
import ( import (
"github.com/coredns/coredns/middleware" "github.com/coredns/coredns/middleware"
"github.com/coredns/coredns/middleware/etcd/msg"
"github.com/coredns/coredns/middleware/pkg/debug"
"github.com/coredns/coredns/middleware/pkg/dnsutil" "github.com/coredns/coredns/middleware/pkg/dnsutil"
"github.com/coredns/coredns/request" "github.com/coredns/coredns/request"
@ -17,13 +15,6 @@ func (e *Etcd) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (
state := request.Request{W: w, Req: r} state := request.Request{W: w, Req: r}
name := state.Name() name := state.Name()
if e.Debugging {
if bug := debug.IsDebug(name); bug != "" {
opt.Debug = r.Question[0].Name
state.Clear()
state.Req.Question[0].Name = bug
}
}
// We need to check stubzones first, because we may get a request for a zone we // We need to check stubzones first, because we may get a request for a zone we
// are not auth. for *but* do have a stubzone forward for. If we do the stubzone // are not auth. for *but* do have a stubzone forward for. If we do the stubzone
@ -39,49 +30,39 @@ func (e *Etcd) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (
zone := middleware.Zones(e.Zones).Matches(state.Name()) zone := middleware.Zones(e.Zones).Matches(state.Name())
if zone == "" { if zone == "" {
if opt.Debug != "" {
r.Question[0].Name = opt.Debug
}
return middleware.NextOrFailure(e.Name(), e.Next, ctx, w, r) return middleware.NextOrFailure(e.Name(), e.Next, ctx, w, r)
} }
var ( var (
records, extra []dns.RR records, extra []dns.RR
debug []msg.Service
err error err error
) )
switch state.Type() { switch state.Type() {
case "A": case "A":
records, debug, err = middleware.A(e, zone, state, nil, opt) records, err = middleware.A(e, zone, state, nil, opt)
case "AAAA": case "AAAA":
records, debug, err = middleware.AAAA(e, zone, state, nil, opt) records, err = middleware.AAAA(e, zone, state, nil, opt)
case "TXT": case "TXT":
records, debug, err = middleware.TXT(e, zone, state, opt) records, err = middleware.TXT(e, zone, state, opt)
case "CNAME": case "CNAME":
records, debug, err = middleware.CNAME(e, zone, state, opt) records, err = middleware.CNAME(e, zone, state, opt)
case "PTR": case "PTR":
records, debug, err = middleware.PTR(e, zone, state, opt) records, err = middleware.PTR(e, zone, state, opt)
case "MX": case "MX":
records, extra, debug, err = middleware.MX(e, zone, state, opt) records, extra, err = middleware.MX(e, zone, state, opt)
case "SRV": case "SRV":
records, extra, debug, err = middleware.SRV(e, zone, state, opt) records, extra, err = middleware.SRV(e, zone, state, opt)
case "SOA": case "SOA":
records, debug, err = middleware.SOA(e, zone, state, opt) records, err = middleware.SOA(e, zone, state, opt)
case "NS": case "NS":
if state.Name() == zone { if state.Name() == zone {
records, extra, debug, err = middleware.NS(e, zone, state, opt) records, extra, err = middleware.NS(e, zone, state, opt)
break break
} }
fallthrough fallthrough
default: default:
// Do a fake A lookup, so we can distinguish between NODATA and NXDOMAIN // Do a fake A lookup, so we can distinguish between NODATA and NXDOMAIN
_, debug, err = middleware.A(e, zone, state, nil, opt) _, err = middleware.A(e, zone, state, nil, opt)
}
if opt.Debug != "" {
// Substitute this name with the original when we return the request.
state.Clear()
state.Req.Question[0].Name = opt.Debug
} }
if e.IsNameError(err) { if e.IsNameError(err) {
@ -89,14 +70,14 @@ func (e *Etcd) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (
return middleware.NextOrFailure(e.Name(), e.Next, ctx, w, r) return middleware.NextOrFailure(e.Name(), e.Next, ctx, w, r)
} }
// Make err nil when returning here, so we don't log spam for NXDOMAIN. // Make err nil when returning here, so we don't log spam for NXDOMAIN.
return middleware.BackendError(e, zone, dns.RcodeNameError, state, debug, nil /* err */, opt) return middleware.BackendError(e, zone, dns.RcodeNameError, state, nil /* err */, opt)
} }
if err != nil { if err != nil {
return middleware.BackendError(e, zone, dns.RcodeServerFailure, state, debug, err, opt) return middleware.BackendError(e, zone, dns.RcodeServerFailure, state, err, opt)
} }
if len(records) == 0 { if len(records) == 0 {
return middleware.BackendError(e, zone, dns.RcodeSuccess, state, debug, err, opt) return middleware.BackendError(e, zone, dns.RcodeSuccess, state, err, opt)
} }
m := new(dns.Msg) m := new(dns.Msg)
@ -104,9 +85,6 @@ func (e *Etcd) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (
m.Authoritative, m.RecursionAvailable, m.Compress = true, true, true m.Authoritative, m.RecursionAvailable, m.Compress = true, true, true
m.Answer = append(m.Answer, records...) m.Answer = append(m.Answer, records...)
m.Extra = append(m.Extra, extra...) m.Extra = append(m.Extra, extra...)
if opt.Debug != "" {
m.Extra = append(m.Extra, middleware.ServicesToTxt(debug)...)
}
m = dnsutil.Dedup(m) m = dnsutil.Dedup(m)
state.SizeAndDo(m) state.SizeAndDo(m)

View file

@ -1,57 +0,0 @@
// +build etcd
package etcd
import (
"testing"
"github.com/coredns/coredns/middleware/etcd/msg"
"github.com/coredns/coredns/middleware/pkg/dnsrecorder"
"github.com/coredns/coredns/middleware/proxy"
"github.com/coredns/coredns/middleware/test"
"github.com/miekg/dns"
)
func TestProxyLookupFailDebug(t *testing.T) {
etc := newEtcdMiddleware()
etc.Proxy = proxy.NewLookup([]string{"127.0.0.1:154"})
etc.Debugging = true
for _, serv := range servicesProxy {
set(t, etc, serv.Key, 0, serv)
defer delete(t, etc, serv.Key)
}
for _, tc := range dnsTestCasesProxy {
m := tc.Msg()
rec := dnsrecorder.New(&test.ResponseWriter{})
_, err := etc.ServeDNS(ctxt, rec, m)
if err != nil {
t.Errorf("expected no error, got %v\n", err)
continue
}
resp := rec.Msg
test.SortAndCheck(t, resp, tc)
}
}
var servicesProxy = []*msg.Service{
{Host: "www.example.org", Key: "a.dom.skydns.test."},
}
var dnsTestCasesProxy = []test.Case{
{
Qname: "o-o.debug.dom.skydns.test.", Qtype: dns.TypeSRV,
Answer: []dns.RR{
test.SRV("dom.skydns.test. 300 IN SRV 10 100 0 www.example.org."),
},
Extra: []dns.RR{
test.TXT("a.dom.skydns.test. 300 CH TXT \"www.example.org:0(10,0,,false)[0,]\""),
test.TXT("www.example.org. 0 CH TXT \"www.example.org.:0(0,0, IN A: unreachable backend: no upstream host,false)[0,]\""),
test.TXT("www.example.org. 0 CH TXT \"www.example.org.:0(0,0, IN AAAA: unreachable backend: no upstream host,false)[0,]\""),
},
},
}

View file

@ -77,7 +77,7 @@ func etcdParse(c *caddy.Controller) (*Etcd, bool, error) {
case "fallthrough": case "fallthrough":
etc.Fallthrough = true etc.Fallthrough = true
case "debug": case "debug":
etc.Debugging = true /* it is a noop now */
case "path": case "path":
if !c.NextArg() { if !c.NextArg() {
return &Etcd{}, false, c.ArgErr() return &Etcd{}, false, c.ArgErr()

View file

@ -32,44 +32,44 @@ func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M
switch state.Type() { switch state.Type() {
case "A": case "A":
records, _, err = middleware.A(&k, zone, state, nil, middleware.Options{}) records, err = middleware.A(&k, zone, state, nil, middleware.Options{})
case "AAAA": case "AAAA":
records, _, err = middleware.AAAA(&k, zone, state, nil, middleware.Options{}) records, err = middleware.AAAA(&k, zone, state, nil, middleware.Options{})
case "TXT": case "TXT":
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": case "PTR":
records, _, err = middleware.PTR(&k, zone, state, middleware.Options{}) 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":
records, extra, _, err = middleware.SRV(&k, zone, state, middleware.Options{}) records, extra, err = middleware.SRV(&k, zone, state, middleware.Options{})
case "SOA": case "SOA":
records, _, err = middleware.SOA(&k, zone, state, middleware.Options{}) records, err = middleware.SOA(&k, zone, state, middleware.Options{})
case "NS": case "NS":
if state.Name() == zone { if state.Name() == zone {
records, extra, _, err = middleware.NS(&k, zone, state, middleware.Options{}) records, extra, err = middleware.NS(&k, zone, state, middleware.Options{})
break break
} }
fallthrough fallthrough
default: default:
// Do a fake A lookup, so we can distinguish between NODATA and NXDOMAIN // Do a fake A lookup, so we can distinguish between NODATA and NXDOMAIN
_, _, err = middleware.A(&k, zone, state, nil, middleware.Options{}) _, err = middleware.A(&k, zone, state, nil, middleware.Options{})
} }
if k.IsNameError(err) { if k.IsNameError(err) {
if k.Fallthrough { if k.Fallthrough {
return middleware.NextOrFailure(k.Name(), k.Next, ctx, w, r) return middleware.NextOrFailure(k.Name(), k.Next, ctx, w, r)
} }
return middleware.BackendError(&k, zone, dns.RcodeNameError, state, nil /*debug*/, nil /* err */, middleware.Options{}) return middleware.BackendError(&k, zone, dns.RcodeNameError, state, nil /* err */, middleware.Options{})
} }
if err != nil { if err != nil {
return dns.RcodeServerFailure, err return dns.RcodeServerFailure, err
} }
if len(records) == 0 { if len(records) == 0 {
return middleware.BackendError(&k, zone, dns.RcodeSuccess, state, nil /*debug*/, nil, middleware.Options{}) return middleware.BackendError(&k, zone, dns.RcodeSuccess, state, nil, middleware.Options{})
} }
m.Answer = append(m.Answer, records...) m.Answer = append(m.Answer, records...)

View file

@ -81,7 +81,7 @@ var (
) )
// Services implements the ServiceBackend interface. // Services implements the ServiceBackend interface.
func (k *Kubernetes) Services(state request.Request, exact bool, opt middleware.Options) (svcs []msg.Service, debug []msg.Service, err error) { func (k *Kubernetes) Services(state request.Request, exact bool, opt middleware.Options) (svcs []msg.Service, err error) {
// We're looking again at types, which we've already done in ServeDNS, but there are some types k8s just can't answer. // We're looking again at types, which we've already done in ServeDNS, but there are some types k8s just can't answer.
switch state.QType() { switch state.QType() {
@ -92,19 +92,19 @@ func (k *Kubernetes) Services(state request.Request, exact bool, opt middleware.
segs := dns.SplitDomainName(t) segs := dns.SplitDomainName(t)
if len(segs) != 1 { if len(segs) != 1 {
return nil, nil, fmt.Errorf("kubernetes: TXT query can only be for dns-version: %s", state.QName()) return nil, fmt.Errorf("kubernetes: TXT query can only be for dns-version: %s", state.QName())
} }
if segs[0] != "dns-version" { if segs[0] != "dns-version" {
return nil, nil, nil return nil, nil
} }
svc := msg.Service{Text: DNSSchemaVersion, TTL: 28800, Key: msg.Path(state.QName(), "coredns")} svc := msg.Service{Text: DNSSchemaVersion, TTL: 28800, Key: msg.Path(state.QName(), "coredns")}
return []msg.Service{svc}, nil, nil return []msg.Service{svc}, nil
case dns.TypeNS: case dns.TypeNS:
// We can only get here if the qname equal the zone, see ServeDNS in handler.go. // We can only get here if the qname equal the zone, see ServeDNS in handler.go.
ns := k.nsAddr() ns := k.nsAddr()
svc := msg.Service{Host: ns.A.String(), Key: msg.Path(state.QName(), "coredns")} svc := msg.Service{Host: ns.A.String(), Key: msg.Path(state.QName(), "coredns")}
return []msg.Service{svc}, nil, nil return []msg.Service{svc}, nil
} }
if state.QType() == dns.TypeA && isDefaultNS(state.Name(), state.Zone) { if state.QType() == dns.TypeA && isDefaultNS(state.Name(), state.Zone) {
@ -112,7 +112,7 @@ func (k *Kubernetes) Services(state request.Request, exact bool, opt middleware.
// SOA records always use this hardcoded name // SOA records always use this hardcoded name
ns := k.nsAddr() ns := k.nsAddr()
svc := msg.Service{Host: ns.A.String(), Key: msg.Path(state.QName(), "coredns")} svc := msg.Service{Host: ns.A.String(), Key: msg.Path(state.QName(), "coredns")}
return []msg.Service{svc}, nil, nil return []msg.Service{svc}, nil
} }
s, e := k.Records(state, false) s, e := k.Records(state, false)
@ -120,7 +120,7 @@ func (k *Kubernetes) Services(state request.Request, exact bool, opt middleware.
// SRV for external services is not yet implemented, so remove those records. // SRV for external services is not yet implemented, so remove those records.
if state.QType() != dns.TypeSRV { if state.QType() != dns.TypeSRV {
return s, nil, e return s, e
} }
internal := []msg.Service{} internal := []msg.Service{}
@ -130,13 +130,11 @@ func (k *Kubernetes) Services(state request.Request, exact bool, opt middleware.
} }
} }
return internal, nil, e return internal, e
} }
// primaryZone will return the first non-reverse zone being handled by this middleware // primaryZone will return the first non-reverse zone being handled by this middleware
func (k *Kubernetes) primaryZone() string { func (k *Kubernetes) primaryZone() string { return k.Zones[k.primaryZoneIndex] }
return k.Zones[k.primaryZoneIndex]
}
// 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) {
@ -148,9 +146,6 @@ func (k *Kubernetes) IsNameError(err error) bool {
return err == errNoItems || err == errNsNotExposed || err == errInvalidRequest return err == errNoItems || err == errNsNotExposed || err == errInvalidRequest
} }
// Debug implements the ServiceBackend interface.
func (k *Kubernetes) Debug() string { return "debug" }
func (k *Kubernetes) getClientConfig() (*rest.Config, error) { func (k *Kubernetes) getClientConfig() (*rest.Config, error) {
loadingRules := &clientcmd.ClientConfigLoadingRules{} loadingRules := &clientcmd.ClientConfigLoadingRules{}
overrides := &clientcmd.ConfigOverrides{} overrides := &clientcmd.ConfigOverrides{}

View file

@ -222,7 +222,7 @@ func TestServices(t *testing.T) {
Req: &dns.Msg{Question: []dns.Question{{Name: test.qname, Qtype: test.qtype}}}, Req: &dns.Msg{Question: []dns.Question{{Name: test.qname, Qtype: test.qtype}}},
Zone: "interwebs.test.", // must match from k.Zones[0] Zone: "interwebs.test.", // must match from k.Zones[0]
} }
svcs, _, e := k.Services(state, false, middleware.Options{}) svcs, e := k.Services(state, false, middleware.Options{})
if e != nil { if e != nil {
t.Errorf("Test %d: got error '%v'", i, e) t.Errorf("Test %d: got error '%v'", i, e)
continue continue

View file

@ -10,15 +10,15 @@ import (
) )
// Reverse implements the ServiceBackend interface. // Reverse implements the ServiceBackend interface.
func (k *Kubernetes) Reverse(state request.Request, exact bool, opt middleware.Options) ([]msg.Service, []msg.Service, error) { func (k *Kubernetes) Reverse(state request.Request, exact bool, opt middleware.Options) ([]msg.Service, error) {
ip := dnsutil.ExtractAddressFromReverse(state.Name()) ip := dnsutil.ExtractAddressFromReverse(state.Name())
if ip == "" { if ip == "" {
return nil, nil, nil return nil, nil
} }
records := k.serviceRecordForIP(ip, state.Name()) records := k.serviceRecordForIP(ip, state.Name())
return records, nil, nil return records, nil
} }
// serviceRecordForIP gets a service record with a cluster ip matching the ip argument // serviceRecordForIP gets a service record with a cluster ip matching the ip argument

View file

@ -1,21 +0,0 @@
package debug
import "strings"
// Name is the domain prefix we check for when it is a debug query.
const Name = "o-o.debug."
// IsDebug checks if name is a debugging name, i.e. starts with o-o.debug.
// it returns the empty string if it is not a debug message, otherwise it will return the
// name with o-o.debug. stripped off. Name will be lowercased before comparing.
func IsDebug(name string) string {
if len(name) == len(Name) {
return ""
}
name = strings.ToLower(name)
debug := strings.HasPrefix(name, Name)
if !debug {
return ""
}
return name[len(Name):]
}

View file

@ -1,21 +0,0 @@
package debug
import (
"strings"
"testing"
)
func TestIsDebug(t *testing.T) {
if ok := IsDebug("o-o.debug.miek.nl."); ok != "miek.nl." {
t.Errorf("expected o-o.debug.miek.nl. to be debug")
}
if ok := IsDebug(strings.ToLower("o-o.Debug.miek.nl.")); ok != "miek.nl." {
t.Errorf("expected o-o.Debug.miek.nl. to be debug")
}
if ok := IsDebug("i-o.debug.miek.nl."); ok != "" {
t.Errorf("expected i-o.Debug.miek.nl. to be non-debug")
}
if ok := IsDebug(strings.ToLower("i-o.Debug.")); ok != "" {
t.Errorf("expected o-o.Debug. to be non-debug")
}
}

View file

@ -13,7 +13,6 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"github.com/coredns/coredns/middleware/pkg/debug"
"github.com/coredns/coredns/middleware/pkg/healthcheck" "github.com/coredns/coredns/middleware/pkg/healthcheck"
"github.com/coredns/coredns/request" "github.com/coredns/coredns/request"
@ -50,12 +49,6 @@ func (g *google) Exchange(ctx context.Context, addr string, state request.Reques
v.Set("name", state.Name()) v.Set("name", state.Name())
v.Set("type", fmt.Sprintf("%d", state.QType())) v.Set("type", fmt.Sprintf("%d", state.QType()))
optDebug := false
if bug := debug.IsDebug(state.Name()); bug != "" {
optDebug = true
v.Set("name", bug)
}
buf, backendErr := g.exchangeJSON(addr, v.Encode()) buf, backendErr := g.exchangeJSON(addr, v.Encode())
if backendErr == nil { if backendErr == nil {
@ -64,19 +57,11 @@ func (g *google) Exchange(ctx context.Context, addr string, state request.Reques
return nil, err return nil, err
} }
m, debug, err := toMsg(gm) m, err := toMsg(gm)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if optDebug {
// reset question
m.Question[0].Name = state.QName()
// prepend debug RR to the additional section
m.Extra = append([]dns.RR{debug}, m.Extra...)
}
m.Id = state.Req.Id m.Id = state.Req.Id
return m, nil return m, nil
} }

View file

@ -6,8 +6,8 @@ import (
"github.com/miekg/dns" "github.com/miekg/dns"
) )
// toMsg converts a googleMsg into the dns message. The returned RR is the comment disquised as a TXT record. // toMsg converts a googleMsg into the dns message.
func toMsg(g *googleMsg) (*dns.Msg, dns.RR, error) { func toMsg(g *googleMsg) (*dns.Msg, error) {
m := new(dns.Msg) m := new(dns.Msg)
m.Response = true m.Response = true
m.Rcode = g.Status m.Rcode = g.Status
@ -28,24 +28,23 @@ func toMsg(g *googleMsg) (*dns.Msg, dns.RR, error) {
for i := 0; i < len(m.Answer); i++ { for i := 0; i < len(m.Answer); i++ {
m.Answer[i], err = toRR(g.Answer[i]) m.Answer[i], err = toRR(g.Answer[i])
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
} }
for i := 0; i < len(m.Ns); i++ { for i := 0; i < len(m.Ns); i++ {
m.Ns[i], err = toRR(g.Authority[i]) m.Ns[i], err = toRR(g.Authority[i])
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
} }
for i := 0; i < len(m.Extra); i++ { for i := 0; i < len(m.Extra); i++ {
m.Extra[i], err = toRR(g.Additional[i]) m.Extra[i], err = toRR(g.Additional[i])
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
} }
txt, _ := dns.NewRR(". 0 CH TXT " + g.Comment) return m, nil
return m, txt, nil
} }
// toRR transforms a "google" RR to a dns.RR. // toRR transforms a "google" RR to a dns.RR.

View file

@ -18,11 +18,10 @@ import (
// uses some stuff from etcd_tests.go // uses some stuff from etcd_tests.go
func TestEtcdCacheAndDebug(t *testing.T) { func TestEtcdCache(t *testing.T) {
corefile := `.:0 { corefile := `.:0 {
etcd skydns.test { etcd skydns.test {
path /skydns path /skydns
debug
} }
cache skydns.test cache skydns.test
}` }`
@ -51,15 +50,6 @@ func TestEtcdCacheAndDebug(t *testing.T) {
} }
checkResponse(t, resp) checkResponse(t, resp)
resp, err = p.Lookup(state, "o-o.debug.b.example.skydns.test.", dns.TypeA)
if err != nil {
t.Errorf("Expected to receive reply, but didn't: %s", err)
}
checkResponse(t, resp)
if len(resp.Extra) != 1 {
t.Errorf("Expected one RR in additional section, got: %d", len(resp.Extra))
}
resp, err = p.Lookup(state, "b.example.skydns.test.", dns.TypeA) resp, err = p.Lookup(state, "b.example.skydns.test.", dns.TypeA)
if err != nil { if err != nil {
t.Errorf("Expected to receive reply, but didn't: %s", err) t.Errorf("Expected to receive reply, but didn't: %s", err)