mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-30 17:53:21 -04:00 
			
		
		
		
	middleware/etcd: Return json parsing errors (#158)
When coredns unmarshals a json value and it fails it will put the error in the returned message iff the query was a debug query (o-o.debug.<REST>).
This commit is contained in:
		| @@ -39,7 +39,7 @@ etcd [zones...] { | |||||||
|   pointing to external names. If you want CoreDNS to act as a proxy for clients you'll need to add |   pointing to external names. If you want CoreDNS to act as a proxy for clients you'll need to add | ||||||
|   the proxy middleware. |   the proxy middleware. | ||||||
| * `tls` followed the cert, key and the CA's cert filenames. | * `tls` followed the cert, key and the CA's cert filenames. | ||||||
| * `debug` allow debug queries. Prefix the name with `o-o.debug.` to reveive extra information in the | * `debug` allow debug queries. Prefix the name with `o-o.debug.` to retrieve extra information in the | ||||||
|   additional section of the reply in the form of text records: |   additional section of the reply in the form of text records: | ||||||
|  |  | ||||||
|     skydns.test.skydns.dom.a.	300	CH	TXT	"127.0.0.1:0(10,0,,false)[0,]" |     skydns.test.skydns.dom.a.	300	CH	TXT	"127.0.0.1:0(10,0,,false)[0,]" | ||||||
| @@ -47,6 +47,13 @@ etcd [zones...] { | |||||||
|   This shows the complete key as the owername, the rdata of the TXT record has: |   This shows the complete key as the owername, the rdata of the TXT record has: | ||||||
|   `host:port(priority,weight,txt content,mail)[targetstrip,group]`. |   `host:port(priority,weight,txt content,mail)[targetstrip,group]`. | ||||||
|  |  | ||||||
|  |   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. | ||||||
|  |  | ||||||
|  |  | ||||||
| ## Examples | ## Examples | ||||||
|  |  | ||||||
| This is the default SkyDNS setup, with everying specified in full: | This is the default SkyDNS setup, with everying specified in full: | ||||||
|   | |||||||
| @@ -36,3 +36,21 @@ func servicesToTxt(debug []msg.Service) []dns.RR { | |||||||
| 	} | 	} | ||||||
| 	return rr | 	return 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 | ||||||
|  | } | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ package etcd | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| @@ -104,7 +105,7 @@ Nodes: | |||||||
| 		} | 		} | ||||||
| 		serv := new(msg.Service) | 		serv := new(msg.Service) | ||||||
| 		if err := json.Unmarshal([]byte(n.Value), serv); err != nil { | 		if err := json.Unmarshal([]byte(n.Value), serv); err != nil { | ||||||
| 			return nil, err | 			return nil, fmt.Errorf("%s: %s", n.Key, err.Error()) | ||||||
| 		} | 		} | ||||||
| 		b := msg.Service{Host: serv.Host, Port: serv.Port, Priority: serv.Priority, Weight: serv.Weight, Text: serv.Text, Key: n.Key} | 		b := msg.Service{Host: serv.Host, Port: serv.Port, Priority: serv.Priority, Weight: serv.Weight, Text: serv.Text, Key: n.Key} | ||||||
| 		if _, ok := bx[b]; ok { | 		if _, ok := bx[b]; ok { | ||||||
|   | |||||||
| @@ -82,14 +82,14 @@ func (e Etcd) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if isEtcdNameError(err) { | 	if isEtcdNameError(err) { | ||||||
| 		return e.Err(zone, dns.RcodeNameError, state, debug) | 		return e.Err(zone, dns.RcodeNameError, state, debug, err) | ||||||
| 	} | 	} | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return dns.RcodeServerFailure, err | 		return e.Err(zone, dns.RcodeServerFailure, state, debug, err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(records) == 0 { | 	if len(records) == 0 { | ||||||
| 		return e.Err(zone, dns.RcodeSuccess, state, debug) | 		return e.Err(zone, dns.RcodeSuccess, state, debug, err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	m := new(dns.Msg) | 	m := new(dns.Msg) | ||||||
| @@ -109,15 +109,22 @@ func (e Etcd) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i | |||||||
| } | } | ||||||
|  |  | ||||||
| // Err write an error response to the client. | // Err write an error response to the client. | ||||||
| func (e Etcd) Err(zone string, rcode int, state middleware.State, debug []msg.Service) (int, error) { | func (e Etcd) Err(zone string, rcode int, state middleware.State, debug []msg.Service, err error) (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, _, _ = e.SOA(zone, state) | 	m.Ns, _, _ = e.SOA(zone, state) | ||||||
| 	m.Extra = servicesToTxt(debug) | 	if e.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 rcode, nil | 	// Return success as the rcode to signal we have written to the client. | ||||||
|  | 	return dns.RcodeSuccess, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func dedup(m *dns.Msg) *dns.Msg { | func dedup(m *dns.Msg) *dns.Msg { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user