[plugin/route53]: Do not return NXDOMAIN where it should be NODATA. (#2734)

* [plugin/route53]: Do not return NXDOMAIN where it should be NODATA.

Signed-off-by: Dmitry Ilyevskiy <dmitry.ilyevskiy@getcruise.com>

* Fix bad merge.

Signed-off-by: Dmitry Ilyevskiy <dmitry.ilyevskiy@getcruise.com>
This commit is contained in:
dilyevsky 2019-03-31 10:12:33 -07:00 committed by Yong Tang
parent db34c10589
commit 1e150674c5
2 changed files with 62 additions and 45 deletions

View file

@ -119,12 +119,15 @@ func (h *Route53) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg
h.zMu.RLock() h.zMu.RLock()
m.Answer, m.Ns, m.Extra, result = hostedZone.z.Lookup(ctx, state, qname) m.Answer, m.Ns, m.Extra, result = hostedZone.z.Lookup(ctx, state, qname)
h.zMu.RUnlock() h.zMu.RUnlock()
if len(m.Answer) != 0 {
// Take the answer if it's non-empty OR if there is another
// record type exists for this name (NODATA).
if len(m.Answer) != 0 || result == file.NoData {
break break
} }
} }
if len(m.Answer) == 0 && h.Fall.Through(qname) { if len(m.Answer) == 0 && result != file.NoData && h.Fall.Through(qname) {
return plugin.NextOrFailure(h.Name(), h.Next, ctx, w, r) return plugin.NextOrFailure(h.Name(), h.Next, ctx, w, r)
} }

View file

@ -43,11 +43,14 @@ func (fakeRoute53) ListResourceRecordSetsPagesWithContext(_ aws.Context, in *rou
{"PTR", "example.org.", "ptr.example.org.", "1234567890"}, {"PTR", "example.org.", "ptr.example.org.", "1234567890"},
{"SOA", "org.", "ns-1536.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400", "1234567890"}, {"SOA", "org.", "ns-1536.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400", "1234567890"},
{"NS", "com.", "ns-1536.awsdns-00.co.uk.", "1234567890"}, {"NS", "com.", "ns-1536.awsdns-00.co.uk.", "1234567890"},
{"A", "split-example.gov.", "1.2.3.4", "1234567890"},
// Unsupported type should be ignored. // Unsupported type should be ignored.
{"YOLO", "swag.", "foobar", "1234567890"}, {"YOLO", "swag.", "foobar", "1234567890"},
// hosted zone with the same name, but a different id // Hosted zone with the same name, but a different id.
{"A", "other-example.org.", "3.5.7.9", "1357986420"}, {"A", "other-example.org.", "3.5.7.9", "1357986420"},
{"A", "split-example.org.", "1.2.3.4", "1357986420"},
{"SOA", "org.", "ns-15.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400", "1357986420"}, {"SOA", "org.", "ns-15.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400", "1357986420"},
// Hosted zone without SOA.
} { } {
rrs, ok := rrsResponse[r.hostedZoneID] rrs, ok := rrsResponse[r.hostedZoneID]
if !ok { if !ok {
@ -84,7 +87,7 @@ func TestRoute53(t *testing.T) {
t.Fatalf("Expected errors for zone bad.") t.Fatalf("Expected errors for zone bad.")
} }
r, err = New(ctx, fakeRoute53{}, map[string][]string{"org.": []string{"1357986420", "1234567890"}, "gov": []string{"Z098765432"}}, &upstream.Upstream{}) r, err = New(ctx, fakeRoute53{}, map[string][]string{"org.": []string{"1357986420", "1234567890"}, "gov.": []string{"Z098765432", "1234567890"}}, &upstream.Upstream{})
if err != nil { if err != nil {
t.Fatalf("Failed to create Route53: %v", err) t.Fatalf("Failed to create Route53: %v", err)
} }
@ -105,6 +108,7 @@ func TestRoute53(t *testing.T) {
m.Authoritative = true m.Authoritative = true
rcode = dns.RcodeSuccess rcode = dns.RcodeSuccess
} }
m.SetRcode(r, rcode) m.SetRcode(r, rcode)
@ -119,38 +123,35 @@ func TestRoute53(t *testing.T) {
tests := []struct { tests := []struct {
qname string qname string
qtype uint16 qtype uint16
expectedCode int wantRetCode int
wantAnswer []string // ownernames for the records in the additional section. wantAnswer []string // ownernames for the records in the additional section.
wantMsgRCode int
wantNS []string wantNS []string
expectedErr error expectedErr error
}{ }{
// 0. example.org A found - success. // 0. example.org A found - success.
{ {
qname: "example.org", qname: "example.org",
qtype: dns.TypeA, qtype: dns.TypeA,
expectedCode: dns.RcodeSuccess,
wantAnswer: []string{"example.org. 300 IN A 1.2.3.4"}, wantAnswer: []string{"example.org. 300 IN A 1.2.3.4"},
}, },
// 1. example.org AAAA found - success. // 1. example.org AAAA found - success.
{ {
qname: "example.org", qname: "example.org",
qtype: dns.TypeAAAA, qtype: dns.TypeAAAA,
expectedCode: dns.RcodeSuccess,
wantAnswer: []string{"example.org. 300 IN AAAA 2001:db8:85a3::8a2e:370:7334"}, wantAnswer: []string{"example.org. 300 IN AAAA 2001:db8:85a3::8a2e:370:7334"},
}, },
// 2. exampled.org PTR found - success. // 2. exampled.org PTR found - success.
{ {
qname: "example.org", qname: "example.org",
qtype: dns.TypePTR, qtype: dns.TypePTR,
expectedCode: dns.RcodeSuccess,
wantAnswer: []string{"example.org. 300 IN PTR ptr.example.org."}, wantAnswer: []string{"example.org. 300 IN PTR ptr.example.org."},
}, },
// 3. sample.example.org points to example.org CNAME. // 3. sample.example.org points to example.org CNAME.
// Query must return both CNAME and A recs. // Query must return both CNAME and A recs.
{ {
qname: "sample.example.org", qname: "sample.example.org",
qtype: dns.TypeA, qtype: dns.TypeA,
expectedCode: dns.RcodeSuccess,
wantAnswer: []string{ wantAnswer: []string{
"sample.example.org. 300 IN CNAME example.org.", "sample.example.org. 300 IN CNAME example.org.",
"example.org. 300 IN A 1.2.3.4", "example.org. 300 IN A 1.2.3.4",
@ -159,57 +160,66 @@ func TestRoute53(t *testing.T) {
// 4. Explicit CNAME query for sample.example.org. // 4. Explicit CNAME query for sample.example.org.
// Query must return just CNAME. // Query must return just CNAME.
{ {
qname: "sample.example.org", qname: "sample.example.org",
qtype: dns.TypeCNAME, qtype: dns.TypeCNAME,
expectedCode: dns.RcodeSuccess,
wantAnswer: []string{"sample.example.org. 300 IN CNAME example.org."}, wantAnswer: []string{"sample.example.org. 300 IN CNAME example.org."},
}, },
// 5. Explicit SOA query for example.org. // 5. Explicit SOA query for example.org.
{ {
qname: "example.org", qname: "example.org",
qtype: dns.TypeSOA, qtype: dns.TypeSOA,
expectedCode: dns.RcodeSuccess,
wantAnswer: []string{"org. 300 IN SOA ns-15.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"}, wantAnswer: []string{"org. 300 IN SOA ns-15.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"},
}, },
// 6. Explicit SOA query for example.org. // 6. Explicit SOA query for example.org.
{ {
qname: "example.org", qname: "example.org",
qtype: dns.TypeNS, qtype: dns.TypeNS,
expectedCode: dns.RcodeSuccess,
wantNS: []string{"org. 300 IN SOA ns-1536.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"}, wantNS: []string{"org. 300 IN SOA ns-1536.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"},
}, },
// 7. Zone not configured. // 7. AAAA query for split-example.org must return NODATA.
{
qname: "split-example.gov",
qtype: dns.TypeAAAA,
wantRetCode: dns.RcodeSuccess,
wantNS: []string{"org. 300 IN SOA ns-1536.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"},
},
// 8. Zone not configured.
{ {
qname: "badexample.com", qname: "badexample.com",
qtype: dns.TypeA, qtype: dns.TypeA,
expectedCode: dns.RcodeServerFailure, wantRetCode: dns.RcodeServerFailure,
wantMsgRCode: dns.RcodeServerFailure,
}, },
// 8. No record found. Return SOA record. // 9. No record found. Return SOA record.
{ {
qname: "bad.org", qname: "bad.org",
qtype: dns.TypeA, qtype: dns.TypeA,
expectedCode: dns.RcodeSuccess, wantRetCode: dns.RcodeSuccess,
wantMsgRCode: dns.RcodeNameError,
wantNS: []string{"org. 300 IN SOA ns-1536.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"}, wantNS: []string{"org. 300 IN SOA ns-1536.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"},
}, },
// 9. No record found. Fallthrough. // 10. No record found. Fallthrough.
{ {
qname: "example.gov", qname: "example.gov",
qtype: dns.TypeA, qtype: dns.TypeA,
expectedCode: dns.RcodeSuccess,
wantAnswer: []string{"example.gov. 300 IN A 2.4.6.8"}, wantAnswer: []string{"example.gov. 300 IN A 2.4.6.8"},
}, },
// 10. other-zone.example.org is stored in a different hosted zone. success // 11. other-zone.example.org is stored in a different hosted zone. success
{ {
qname: "other-example.org", qname: "other-example.org",
qtype: dns.TypeA, qtype: dns.TypeA,
expectedCode: dns.RcodeSuccess,
wantAnswer: []string{"other-example.org. 300 IN A 3.5.7.9"}, wantAnswer: []string{"other-example.org. 300 IN A 3.5.7.9"},
}, },
// 11. *.www.example.org is a wildcard CNAME to www.example.org. // 12. split-example.org only has A record. Expect NODATA.
{ {
qname: "a.www.example.org", qname: "split-example.org",
qtype: dns.TypeA, qtype: dns.TypeAAAA,
expectedCode: dns.RcodeSuccess, wantNS: []string{"org. 300 IN SOA ns-15.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"},
},
// 13. *.www.example.org is a wildcard CNAME to www.example.org.
{
qname: "a.www.example.org",
qtype: dns.TypeA,
wantAnswer: []string{ wantAnswer: []string{
"a.www.example.org. 300 IN CNAME www.example.org.", "a.www.example.org. 300 IN CNAME www.example.org.",
"www.example.org. 300 IN A 1.2.3.4", "www.example.org. 300 IN A 1.2.3.4",
@ -227,8 +237,12 @@ func TestRoute53(t *testing.T) {
if err != tc.expectedErr { if err != tc.expectedErr {
t.Fatalf("Test %d: Expected error %v, but got %v", ti, tc.expectedErr, err) t.Fatalf("Test %d: Expected error %v, but got %v", ti, tc.expectedErr, err)
} }
if code != int(tc.expectedCode) { if code != int(tc.wantRetCode) {
t.Fatalf("Test %d: Expected status code %s, but got %s", ti, dns.RcodeToString[tc.expectedCode], dns.RcodeToString[code]) t.Fatalf("Test %d: Expected returned status code %s, but got %s", ti, dns.RcodeToString[tc.wantRetCode], dns.RcodeToString[code])
}
if tc.wantMsgRCode != rec.Msg.Rcode {
t.Errorf("Test %d: Unexpected msg status code. Want: %s, got: %s", ti, dns.RcodeToString[tc.wantMsgRCode], dns.RcodeToString[rec.Msg.Rcode])
} }
if len(tc.wantAnswer) != len(rec.Msg.Answer) { if len(tc.wantAnswer) != len(rec.Msg.Answer) {
@ -250,7 +264,7 @@ func TestRoute53(t *testing.T) {
t.Errorf("Test %d: Unexpected NS type. Want: SOA, got: %v", ti, reflect.TypeOf(got)) t.Errorf("Test %d: Unexpected NS type. Want: SOA, got: %v", ti, reflect.TypeOf(got))
} }
if got.String() != tc.wantNS[i] { if got.String() != tc.wantNS[i] {
t.Errorf("Test %d: Unexpected NS. Want: %v, got: %v", ti, tc.wantNS[i], got) t.Errorf("Test %d: Unexpected NS.\nWant: %v\nGot: %v", ti, tc.wantNS[i], got)
} }
} }
} }