mirror of
https://github.com/coredns/coredns.git
synced 2025-10-27 08:14:18 -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
|
||||
the proxy middleware.
|
||||
* `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:
|
||||
|
||||
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:
|
||||
`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
|
||||
|
||||
This is the default SkyDNS setup, with everying specified in full:
|
||||
|
||||
@@ -36,3 +36,21 @@ func servicesToTxt(debug []msg.Service) []dns.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 (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -104,7 +105,7 @@ Nodes:
|
||||
}
|
||||
serv := new(msg.Service)
|
||||
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}
|
||||
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) {
|
||||
return e.Err(zone, dns.RcodeNameError, state, debug)
|
||||
return e.Err(zone, dns.RcodeNameError, state, debug, err)
|
||||
}
|
||||
if err != nil {
|
||||
return dns.RcodeServerFailure, err
|
||||
return e.Err(zone, dns.RcodeServerFailure, state, debug, err)
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -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.
|
||||
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.SetRcode(state.Req, rcode)
|
||||
m.Authoritative, m.RecursionAvailable, m.Compress = true, true, true
|
||||
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.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 {
|
||||
|
||||
Reference in New Issue
Block a user