plugin/secondary: fix a bunch of things and tests (#1406)
Fix the error handling. Log when we have an error during any of the transfer state. And if there isn't an error transfer the zones. Also fix the tests in test/ so we, at least, check the initial transfer. Update the docs to show more about how errors are handled. Ref #1400
This commit is contained in:
parent
7d371edb2d
commit
85457cf50d
4 changed files with 62 additions and 146 deletions
|
@ -118,19 +118,6 @@ Restart:
|
|||
retry := time.Second * time.Duration(z.Apex.SOA.Retry)
|
||||
expire := time.Second * time.Duration(z.Apex.SOA.Expire)
|
||||
|
||||
if refresh < time.Hour {
|
||||
refresh = time.Hour
|
||||
}
|
||||
if retry < time.Hour {
|
||||
retry = time.Hour
|
||||
}
|
||||
if refresh > 24*time.Hour {
|
||||
refresh = 24 * time.Hour
|
||||
}
|
||||
if retry > 12*time.Hour {
|
||||
retry = 12 * time.Hour
|
||||
}
|
||||
|
||||
refreshTicker := time.NewTicker(refresh)
|
||||
retryTicker := time.NewTicker(retry)
|
||||
expireTicker := time.NewTicker(expire)
|
||||
|
@ -151,7 +138,12 @@ Restart:
|
|||
time.Sleep(jitter(2000)) // 2s randomize
|
||||
|
||||
ok, err := z.shouldTransfer()
|
||||
if err != nil && ok {
|
||||
if err != nil {
|
||||
log.Printf("[WARNING] Failed retry check %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if ok {
|
||||
if err := z.TransferIn(); err != nil {
|
||||
// transfer failed, leave retryActive true
|
||||
break
|
||||
|
@ -169,8 +161,13 @@ Restart:
|
|||
time.Sleep(jitter(5000)) // 5s randomize
|
||||
|
||||
ok, err := z.shouldTransfer()
|
||||
retryActive = err != nil
|
||||
if err != nil && ok {
|
||||
if err != nil {
|
||||
log.Printf("[WARNING] Failed refresh check %s", err)
|
||||
retryActive = true
|
||||
continue
|
||||
}
|
||||
|
||||
if ok {
|
||||
if err := z.TransferIn(); err != nil {
|
||||
// transfer failed
|
||||
retryActive = true
|
||||
|
|
|
@ -35,6 +35,10 @@ secondary [zones...] {
|
|||
normal authoritative serving you don't need *or* want to use this. **ADDRESS** can be an IP
|
||||
address, and IP:port or a string pointing to a file that is structured as /etc/resolv.conf.
|
||||
|
||||
When a zone is due to be refreshed (Refresh timer fires) a random jitter of 5 seconds is
|
||||
applied, before fetching. In the case of retry this will be 2 seconds. If there are any errors
|
||||
during the transfer the transfer fails; this will be logged.
|
||||
|
||||
## Examples
|
||||
|
||||
Transfer `example.org` from 10.0.1.1, and if that fails try 10.1.2.1.
|
||||
|
|
|
@ -1,126 +0,0 @@
|
|||
// +build net
|
||||
|
||||
package test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
func TestSecondaryZoneTransfer(t *testing.T) {
|
||||
/*
|
||||
Test will only work when there is a CoreDNS running on part 32054
|
||||
with example.com and willing to transfer
|
||||
coredns -conf Corefile -dns.port 32054
|
||||
Corefile:
|
||||
example.com {
|
||||
file example.com {
|
||||
transfer to 127.0.0.1:32053
|
||||
}
|
||||
}
|
||||
example.com:
|
||||
example.com. 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2017042730 7200 3600 1209600 3600
|
||||
|
||||
example.com. 65118 IN NS a.iana-servers.net.
|
||||
example.com. 65118 IN NS b.iana-servers.net.
|
||||
cname.example.com. 434334 IN CNAME a.miek.nl.
|
||||
*/
|
||||
|
||||
corefile := `example.com:32053 {
|
||||
secondary {
|
||||
transfer from 127.0.0.1:32054
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
sec, err := CoreDNSServer(corefile)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get CoreDNS serving instance: %s", err)
|
||||
}
|
||||
|
||||
defer sec.Stop()
|
||||
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("cname.example.com.", dns.TypeCNAME)
|
||||
|
||||
r, err := dns.Exchange(m, "127.0.0.1:32053")
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to receive reply, but didn't: %s", err)
|
||||
}
|
||||
|
||||
if len(r.Answer) == 0 {
|
||||
t.Fatalf("Expected answer section")
|
||||
}
|
||||
|
||||
if r.Answer[0].(*dns.CNAME).Target != "a.miek.nl." {
|
||||
t.Fatalf("Expected target of %s, got %s", "a.miek.nl.", r.Answer[0].(*dns.CNAME).Target)
|
||||
}
|
||||
|
||||
m = new(dns.Msg)
|
||||
m.SetQuestion("example.com.", dns.TypeSOA)
|
||||
r, err = dns.Exchange(m, "127.0.0.1:32053")
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to receive reply, but didn't: %s", err)
|
||||
}
|
||||
if len(r.Answer) == 0 {
|
||||
t.Fatalf("Expected answer section")
|
||||
}
|
||||
if r.Answer[0].(*dns.SOA).Serial != 2017042730 {
|
||||
t.Fatalf("Expected serial of %d, got %d", 2017042730, r.Answer[0].(*dns.SOA).Serial)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSecondaryZoneTransferUpstream(t *testing.T) {
|
||||
/*
|
||||
Test will only work when there is a CoreDNS running on part 32054
|
||||
with example.com and willing to transfer
|
||||
coredns -conf Corefile -dns.port 32054
|
||||
Corefile:
|
||||
example.com {
|
||||
file example.com {
|
||||
transfer to 127.0.0.1:32053
|
||||
}
|
||||
}
|
||||
example.com:
|
||||
example.com. 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2017042730 7200 3600 1209600 3600
|
||||
|
||||
example.com. 65118 IN NS a.iana-servers.net.
|
||||
example.com. 65118 IN NS b.iana-servers.net.
|
||||
cname.example.com. 434334 IN CNAME a.miek.nl.
|
||||
*/
|
||||
|
||||
corefile := `example.com:32053 {
|
||||
secondary {
|
||||
transfer from 127.0.0.1:32054
|
||||
upstream 8.8.8.8
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
sec, err := CoreDNSServer(corefile)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get CoreDNS serving instance: %s", err)
|
||||
}
|
||||
|
||||
defer sec.Stop()
|
||||
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("cname.example.com.", dns.TypeA)
|
||||
|
||||
r, err := dns.Exchange(m, "127.0.0.1:32053")
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to receive reply, but didn't: %s", err)
|
||||
}
|
||||
|
||||
if len(r.Answer) != 2 {
|
||||
t.Fatalf("Expected answer section, with 2 records, got %d", len(r.Answer))
|
||||
}
|
||||
|
||||
if r.Answer[0].(*dns.CNAME).Target != "a.miek.nl." {
|
||||
t.Fatalf("Expected target of %s, got %s", "a.miek.nl.", r.Answer[0].(*dns.CNAME).Target)
|
||||
}
|
||||
if r.Answer[1].Header().Name != "a.miek.nl." {
|
||||
t.Fatalf("Expected name of %s, got %s", "a.miek.nl.", r.Answer[1].Header().Name)
|
||||
}
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/coredns/coredns/plugin/proxy"
|
||||
|
@ -27,8 +25,6 @@ func TestEmptySecondaryZone(t *testing.T) {
|
|||
}
|
||||
defer i.Stop()
|
||||
|
||||
log.SetOutput(ioutil.Discard)
|
||||
|
||||
p := proxy.NewLookup([]string{udp})
|
||||
state := request.Request{W: &test.ResponseWriter{}, Req: new(dns.Msg)}
|
||||
|
||||
|
@ -40,3 +36,48 @@ func TestEmptySecondaryZone(t *testing.T) {
|
|||
t.Fatalf("Expected reply to be a SERVFAIL, got %d", resp.Rcode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSecondaryZoneTransfer(t *testing.T) {
|
||||
name, rm, err := test.TempFile(".", exampleOrg)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create zone: %s", err)
|
||||
}
|
||||
defer rm()
|
||||
|
||||
corefile := `example.org:0 {
|
||||
file ` + name + ` {
|
||||
transfer to *
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
i, _, tcp, err := CoreDNSServerAndPorts(corefile)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get CoreDNS serving instance: %s", err)
|
||||
}
|
||||
defer i.Stop()
|
||||
|
||||
corefile = `example.org:0 {
|
||||
secondary {
|
||||
transfer from ` + tcp + `
|
||||
}
|
||||
}
|
||||
`
|
||||
i1, udp, _, err := CoreDNSServerAndPorts(corefile)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get CoreDNS serving instance: %s", err)
|
||||
}
|
||||
defer i1.Stop()
|
||||
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("example.org.", dns.TypeSOA)
|
||||
|
||||
r, err := dns.Exchange(m, udp)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to receive reply, but didn't: %s", err)
|
||||
}
|
||||
|
||||
if len(r.Answer) == 0 {
|
||||
t.Fatalf("Expected answer section")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue