Commit 4d76faa4 authored by Chris O'Haver's avatar Chris O'Haver Committed by GitHub

plugin/etcd: Fix multi record TXT lookups (#5293)

* fix multi-record txt
Signed-off-by: default avatarChris O'Haver <cohaver@infoblox.com>
parent 38ff869d
...@@ -343,7 +343,7 @@ func CNAME(ctx context.Context, b ServiceBackend, zone string, state request.Req ...@@ -343,7 +343,7 @@ func CNAME(ctx context.Context, b ServiceBackend, zone string, state request.Req
// TXT returns TXT records from Backend or an error. // TXT returns TXT records from Backend or an error.
func TXT(ctx context.Context, b ServiceBackend, zone string, state request.Request, previousRecords []dns.RR, opt Options) (records []dns.RR, truncated bool, err error) { func TXT(ctx context.Context, b ServiceBackend, zone string, state request.Request, previousRecords []dns.RR, opt Options) (records []dns.RR, truncated bool, err error) {
services, err := b.Services(ctx, state, true, opt) services, err := b.Services(ctx, state, false, opt)
if err != nil { if err != nil {
return nil, false, err return nil, false, err
} }
...@@ -398,9 +398,9 @@ func TXT(ctx context.Context, b ServiceBackend, zone string, state request.Reque ...@@ -398,9 +398,9 @@ func TXT(ctx context.Context, b ServiceBackend, zone string, state request.Reque
continue continue
case dns.TypeTXT: case dns.TypeTXT:
if _, ok := dup[serv.Host]; !ok { if _, ok := dup[serv.Text]; !ok {
dup[serv.Host] = struct{}{} dup[serv.Text] = struct{}{}
return append(records, serv.NewTXT(state.QName())), truncated, nil records = append(records, serv.NewTXT(state.QName()))
} }
} }
......
...@@ -221,12 +221,14 @@ If you query the zone name for `SRV` now, you will get the following response: ...@@ -221,12 +221,14 @@ If you query the zone name for `SRV` now, you will get the following response:
If you would like to use `TXT` records, you can set the following: If you would like to use `TXT` records, you can set the following:
~~~ ~~~
% etcdctl put /skydns/local/skydns/x6 '{"ttl":60,"text":"this is a random text message."}' % etcdctl put /skydns/local/skydns/x6 '{"ttl":60,"text":"this is a random text message."}'
% etcdctl put /skydns/local/skydns/x7 '{"ttl":60,"text":"this is a another random text message."}'
~~~ ~~~
If you query the zone name for `TXT` now, you will get the following response: If you query the zone name for `TXT` now, you will get the following response:
~~~ sh ~~~ sh
% dig +short skydns.local TXT @localhost % dig +short skydns.local TXT @localhost
"this is a random text message." "this is a random text message."
"this is a another random text message."
~~~ ~~~
## See Also ## See Also
......
...@@ -22,7 +22,7 @@ func TestCnameLookup(t *testing.T) { ...@@ -22,7 +22,7 @@ func TestCnameLookup(t *testing.T) {
set(t, etc, serv.Key, 0, serv) set(t, etc, serv.Key, 0, serv)
defer delete(t, etc, serv.Key) defer delete(t, etc, serv.Key)
} }
for _, tc := range dnsTestCasesCname { for i, tc := range dnsTestCasesCname {
m := tc.Msg() m := tc.Msg()
rec := dnstest.NewRecorder(&test.ResponseWriter{}) rec := dnstest.NewRecorder(&test.ResponseWriter{})
...@@ -34,17 +34,17 @@ func TestCnameLookup(t *testing.T) { ...@@ -34,17 +34,17 @@ func TestCnameLookup(t *testing.T) {
resp := rec.Msg resp := rec.Msg
if err := test.Header(tc, resp); err != nil { if err := test.Header(tc, resp); err != nil {
t.Error(err) t.Errorf("Test %d: %v", i, err)
continue continue
} }
if err := test.Section(tc, test.Answer, resp.Answer); err != nil { if err := test.Section(tc, test.Answer, resp.Answer); err != nil {
t.Error(err) t.Errorf("Test %d: %v", i, err)
} }
if err := test.Section(tc, test.Ns, resp.Ns); err != nil { if err := test.Section(tc, test.Ns, resp.Ns); err != nil {
t.Error(err) t.Errorf("Test %d: %v", i, err)
} }
if err := test.Section(tc, test.Extra, resp.Extra); err != nil { if err := test.Section(tc, test.Extra, resp.Extra); err != nil {
t.Error(err) t.Errorf("Test %d: %v", i, err)
} }
} }
} }
...@@ -57,16 +57,18 @@ var servicesCname = []*msg.Service{ ...@@ -57,16 +57,18 @@ var servicesCname = []*msg.Service{
{Host: "cname5.region2.skydns.test", Key: "cname4.region2.skydns.test."}, {Host: "cname5.region2.skydns.test", Key: "cname4.region2.skydns.test."},
{Host: "cname6.region2.skydns.test", Key: "cname5.region2.skydns.test."}, {Host: "cname6.region2.skydns.test", Key: "cname5.region2.skydns.test."},
{Host: "endpoint.region2.skydns.test", Key: "cname6.region2.skydns.test."}, {Host: "endpoint.region2.skydns.test", Key: "cname6.region2.skydns.test."},
{Host: "10.240.0.1", Key: "endpoint.region2.skydns.test."},
{Host: "mainendpoint.region2.skydns.test", Key: "region2.skydns.test."}, {Host: "mainendpoint.region2.skydns.test", Key: "region2.skydns.test."},
{Host: "cname2.region3.skydns.test", Key: "cname3.region3.skydns.test."}, {Host: "cname2.region3.skydns.test", Key: "cname3.region3.skydns.test."},
{Host: "cname1.region3.skydns.test", Key: "cname2.region3.skydns.test."}, {Host: "cname1.region3.skydns.test", Key: "cname2.region3.skydns.test."},
{Host: "region3.skydns.test", Key: "cname1.region3.skydns.test."}, {Host: "endpoint.region3.skydns.test", Key: "cname1.region3.skydns.test."},
{Host: "", Key: "region3.skydns.test.", Text: "SOME-RECORD-TEXT"}, {Host: "", Key: "endpoint.region3.skydns.test.", Text: "SOME-RECORD-TEXT"},
{Host: "10.240.0.1", Key: "endpoint.region2.skydns.test."},
} }
var dnsTestCasesCname = []test.Case{ var dnsTestCasesCname = []test.Case{
{ { // Test 0
Qname: "a.server1.dev.region1.skydns.test.", Qtype: dns.TypeSRV, Qname: "a.server1.dev.region1.skydns.test.", Qtype: dns.TypeSRV,
Answer: []dns.RR{ Answer: []dns.RR{
test.SRV("a.server1.dev.region1.skydns.test. 300 IN SRV 10 100 0 cname1.region2.skydns.test."), test.SRV("a.server1.dev.region1.skydns.test. 300 IN SRV 10 100 0 cname1.region2.skydns.test."),
...@@ -81,26 +83,26 @@ var dnsTestCasesCname = []test.Case{ ...@@ -81,26 +83,26 @@ var dnsTestCasesCname = []test.Case{
test.A("endpoint.region2.skydns.test. 300 IN A 10.240.0.1"), test.A("endpoint.region2.skydns.test. 300 IN A 10.240.0.1"),
}, },
}, },
{ { // Test 1
Qname: "region2.skydns.test.", Qtype: dns.TypeCNAME, Qname: "region2.skydns.test.", Qtype: dns.TypeCNAME,
Answer: []dns.RR{ Answer: []dns.RR{
test.CNAME("region2.skydns.test. 300 IN CNAME mainendpoint.region2.skydns.test."), test.CNAME("region2.skydns.test. 300 IN CNAME mainendpoint.region2.skydns.test."),
}, },
}, },
{ { // Test 2
Qname: "region3.skydns.test.", Qtype: dns.TypeCNAME, Qname: "endpoint.region3.skydns.test.", Qtype: dns.TypeCNAME,
Rcode: dns.RcodeSuccess, Rcode: dns.RcodeSuccess,
Ns: []dns.RR{ Ns: []dns.RR{
test.SOA("skydns.test. 303 IN SOA ns.dns.skydns.test. hostmaster.skydns.test. 1546424605 7200 1800 86400 30"), test.SOA("skydns.test. 303 IN SOA ns.dns.skydns.test. hostmaster.skydns.test. 1546424605 7200 1800 86400 30"),
}, },
}, },
{ { // Test 3
Qname: "cname3.region3.skydns.test.", Qtype: dns.TypeTXT, Qname: "cname3.region3.skydns.test.", Qtype: dns.TypeTXT,
Answer: []dns.RR{ Answer: []dns.RR{
test.CNAME("cname3.region3.skydns.test. 300 IN CNAME cname2.region3.skydns.test."), test.CNAME("cname3.region3.skydns.test. 300 IN CNAME cname2.region3.skydns.test."),
test.CNAME("cname2.region3.skydns.test. 300 IN CNAME cname1.region3.skydns.test."), test.CNAME("cname2.region3.skydns.test. 300 IN CNAME cname1.region3.skydns.test."),
test.CNAME("cname1.region3.skydns.test. 300 IN CNAME region3.skydns.test."), test.CNAME("cname1.region3.skydns.test. 300 IN CNAME endpoint.region3.skydns.test."),
test.TXT("region3.skydns.test. 300 IN TXT \"SOME-RECORD-TEXT\""), test.TXT("endpoint.region3.skydns.test. 300 IN TXT \"SOME-RECORD-TEXT\""),
}, },
}, },
} }
...@@ -46,12 +46,15 @@ var servicesGroup = []*msg.Service{ ...@@ -46,12 +46,15 @@ var servicesGroup = []*msg.Service{
{Host: "127.0.0.1", Key: "a.dom1.skydns.test.", Group: "g1"}, {Host: "127.0.0.1", Key: "a.dom1.skydns.test.", Group: "g1"},
{Host: "127.0.0.2", Key: "b.sub.dom1.skydns.test.", Group: "g2"}, {Host: "127.0.0.2", Key: "b.sub.dom1.skydns.test.", Group: "g2"},
{Text: "foo", Key: "a.dom3.skydns.test.", Group: "g1"},
{Text: "bar", Key: "b.sub.dom3.skydns.test.", Group: "g1"},
} }
var dnsTestCasesGroup = []test.Case{ var dnsTestCasesGroup = []test.Case{
// Groups // Groups
{ {
// hits the group 'g1' and only includes those records // hits the group 'g1' and only includes those A records
Qname: "dom.skydns.test.", Qtype: dns.TypeA, Qname: "dom.skydns.test.", Qtype: dns.TypeA,
Answer: []dns.RR{ 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.1"),
...@@ -73,4 +76,12 @@ var dnsTestCasesGroup = []test.Case{ ...@@ -73,4 +76,12 @@ var dnsTestCasesGroup = []test.Case{
test.A("dom1.skydns.test. 300 IN A 127.0.0.1"), test.A("dom1.skydns.test. 300 IN A 127.0.0.1"),
}, },
}, },
{
// hits the group 'g1' and only includes those TXT records
Qname: "dom3.skydns.test.", Qtype: dns.TypeTXT,
Answer: []dns.RR{
test.TXT("dom3.skydns.test. 300 IN TXT bar"),
test.TXT("dom3.skydns.test. 300 IN TXT foo"),
},
},
} }
...@@ -28,7 +28,8 @@ var services = []*msg.Service{ ...@@ -28,7 +28,8 @@ var services = []*msg.Service{
{Host: "10.0.0.2", Port: 8080, Key: "b.server1.prod.region1.skydns.test."}, {Host: "10.0.0.2", Port: 8080, Key: "b.server1.prod.region1.skydns.test."},
{Host: "::1", Port: 8080, Key: "b.server6.prod.region1.skydns.test."}, {Host: "::1", Port: 8080, Key: "b.server6.prod.region1.skydns.test."},
// TXT record in server1. // TXT record in server1.
{Host: "", Port: 8080, Text: "sometext", Key: "txt.server1.prod.region1.skydns.test."}, {Text: "sometext", Key: "a.txt.server1.prod.region1.skydns.test."},
{Text: "moretext", Key: "b.txt.server1.prod.region1.skydns.test."},
// Unresolvable internal name. // Unresolvable internal name.
{Host: "unresolvable.skydns.test", Key: "cname.prod.region1.skydns.test."}, {Host: "unresolvable.skydns.test", Key: "cname.prod.region1.skydns.test."},
// Priority. // Priority.
...@@ -145,6 +146,7 @@ var dnsTestCases = []test.Case{ ...@@ -145,6 +146,7 @@ var dnsTestCases = []test.Case{
{ {
Qname: "txt.server1.prod.region1.skydns.test.", Qtype: dns.TypeTXT, Qname: "txt.server1.prod.region1.skydns.test.", Qtype: dns.TypeTXT,
Answer: []dns.RR{ Answer: []dns.RR{
test.TXT("txt.server1.prod.region1.skydns.test. 303 IN TXT moretext"),
test.TXT("txt.server1.prod.region1.skydns.test. 303 IN TXT sometext"), test.TXT("txt.server1.prod.region1.skydns.test. 303 IN TXT sometext"),
}, },
}, },
...@@ -337,7 +339,7 @@ func TestLookup(t *testing.T) { ...@@ -337,7 +339,7 @@ func TestLookup(t *testing.T) {
defer delete(t, etc, serv.Key) defer delete(t, etc, serv.Key)
} }
for _, tc := range dnsTestCases { for i, tc := range dnsTestCases {
m := tc.Msg() m := tc.Msg()
rec := dnstest.NewRecorder(&test.ResponseWriter{}) rec := dnstest.NewRecorder(&test.ResponseWriter{})
...@@ -345,7 +347,7 @@ func TestLookup(t *testing.T) { ...@@ -345,7 +347,7 @@ func TestLookup(t *testing.T) {
resp := rec.Msg resp := rec.Msg
if err := test.SortAndCheck(resp, tc); err != nil { if err := test.SortAndCheck(resp, tc); err != nil {
t.Error(err) t.Errorf("Test %d: %v", i, err)
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment