Implement notifies for transfer plugin (#3972)

* Fix notifies in transfer plugin

Signed-off-by: Miek Gieben <miek@miek.nl>

* Make it compile

Signed-off-by: Miek Gieben <miek@miek.nl>

* Port more plugins

Signed-off-by: Miek Gieben <miek@miek.nl>

* golint

Signed-off-by: Miek Gieben <miek@miek.nl>

* Fix tests

Signed-off-by: Miek Gieben <miek@miek.nl>

* Fix notifies in transfer plugin

Signed-off-by: Miek Gieben <miek@miek.nl>

* Make it compile

Signed-off-by: Miek Gieben <miek@miek.nl>

* Port more plugins

Signed-off-by: Miek Gieben <miek@miek.nl>

* golint

Signed-off-by: Miek Gieben <miek@miek.nl>

* Fix tests

Signed-off-by: Miek Gieben <miek@miek.nl>

* Fix tests

Signed-off-by: Miek Gieben <miek@miek.nl>

* really fix test

Signed-off-by: Miek Gieben <miek@miek.nl>

* Implement ixfr fallback and unify file and auto for transfering

Signed-off-by: Miek Gieben <miek@miek.nl>

* Add transfer tests

copied and modified from #3452

Signed-off-by: Miek Gieben <miek@miek.nl>

* Test correct selection of plugin

Signed-off-by: Miek Gieben <miek@miek.nl>

* add upstream back in

Signed-off-by: Miek Gieben <miek@miek.nl>

* Implement ixfr fallback and unify file and auto for transfering

Signed-off-by: Miek Gieben <miek@miek.nl>

* fix test

Signed-off-by: Miek Gieben <miek@miek.nl>

* properly merge

Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
Miek Gieben
2020-07-07 21:38:07 +02:00
committed by GitHub
parent 435d27b58d
commit 68f1dd5ddf
42 changed files with 705 additions and 986 deletions

View File

@@ -16,7 +16,6 @@ zonefile. New or changed zones are automatically picked up from disk.
~~~
auto [ZONES...] {
directory DIR [REGEXP ORIGIN_TEMPLATE]
transfer to ADDRESS...
reload DURATION
}
~~~
@@ -29,14 +28,12 @@ are used.
like `{<number>}` are replaced with the respective matches in the file name, e.g. `{1}` is the
first match, `{2}` is the second. The default is: `db\.(.*) {1}` i.e. from a file with the
name `db.example.com`, the extracted origin will be `example.com`.
* `transfer` enables zone transfers. It may be specified multiples times. `To` or `from` signals
the direction. **ADDRESS** must be denoted in CIDR notation (e.g., 127.0.0.1/32) or just as plain
addresses. The special wildcard `*` means: the entire internet (only valid for 'transfer to').
When an address is specified a notify message will be send whenever the zone is reloaded.
* `reload` interval to perform reloads of zones if SOA version changes and zonefiles. It specifies how often CoreDNS should scan the directory to watch for file removal and addition. Default is one minute.
Value of `0` means to not scan for changes and reload. eg. `30s` checks zonefile every 30 seconds
and reloads zone when serial changes.
For enabling zone transfers look at the *transfer* plugin.
All directives from the *file* plugin are supported. Note that *auto* will load all zones found,
even though the directive might only receive queries for a specific zone. I.e:
@@ -59,8 +56,10 @@ notifies to 10.240.1.1
org {
auto {
directory /etc/coredns/zones/org
transfer to *
transfer to 10.240.1.1
}
transfer {
to *
to 10.240.1.1
}
}
~~~
@@ -76,3 +75,8 @@ org {
}
}
~~~
## Also
Use the *root* plugin to help you specify the location of the zone files. See the *transfer* plugin
to enable outgoing zone transfers.

View File

@@ -10,6 +10,7 @@ import (
"github.com/coredns/coredns/plugin/file"
"github.com/coredns/coredns/plugin/metrics"
"github.com/coredns/coredns/plugin/pkg/upstream"
"github.com/coredns/coredns/plugin/transfer"
"github.com/coredns/coredns/request"
"github.com/miekg/dns"
@@ -21,7 +22,8 @@ type (
Next plugin.Handler
*Zones
metrics *metrics.Metrics
metrics *metrics.Metrics
transfer *transfer.Transfer
loader
}
@@ -30,8 +32,6 @@ type (
template string
re *regexp.Regexp
// In the future this should be something like ZoneMeta that contains all this stuff.
transferTo []string
ReloadInterval time.Duration
upstream *upstream.Upstream // Upstream for looking up names during the resolution process.
}
@@ -59,11 +59,6 @@ func (a Auto) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i
return dns.RcodeServerFailure, nil
}
if state.QType() == dns.TypeAXFR || state.QType() == dns.TypeIXFR {
xfr := file.Xfr{Zone: z}
return xfr.ServeDNS(ctx, w, r)
}
answer, ns, extra, result := z.Lookup(ctx, state, qname)
m := new(dns.Msg)

View File

@@ -10,8 +10,8 @@ import (
"github.com/coredns/coredns/plugin"
"github.com/coredns/coredns/plugin/metrics"
clog "github.com/coredns/coredns/plugin/pkg/log"
"github.com/coredns/coredns/plugin/pkg/parse"
"github.com/coredns/coredns/plugin/pkg/upstream"
"github.com/coredns/coredns/plugin/transfer"
"github.com/caddyserver/caddy"
)
@@ -28,10 +28,13 @@ func setup(c *caddy.Controller) error {
c.OnStartup(func() error {
m := dnsserver.GetConfig(c).Handler("prometheus")
if m == nil {
return nil
if m != nil {
(&a).metrics = m.(*metrics.Metrics)
}
t := dnsserver.GetConfig(c).Handler("transfer")
if t != nil {
(&a).transfer = t.(*transfer.Transfer)
}
(&a).metrics = m.(*metrics.Metrics)
return nil
})
@@ -147,15 +150,6 @@ func autoParse(c *caddy.Controller) (Auto, error) {
// remove soon
c.RemainingArgs() // eat remaining args
case "transfer":
t, _, e := parse.Transfer(c, false)
if e != nil {
return a, e
}
if t != nil {
a.loader.transferTo = append(a.loader.transferTo, t...)
}
default:
return Auto{}, c.Errf("unknown property '%s'", c.Val())
}

View File

@@ -15,48 +15,38 @@ func TestAutoParse(t *testing.T) {
expectedTempl string
expectedRe string
expectedReloadInterval time.Duration
expectedTo []string
}{
{
`auto example.org {
directory /tmp
transfer to 127.0.0.1
}`,
false, "/tmp", "${1}", `db\.(.*)`, 60 * time.Second, []string{"127.0.0.1:53"},
false, "/tmp", "${1}", `db\.(.*)`, 60 * time.Second,
},
{
`auto 10.0.0.0/24 {
directory /tmp
}`,
false, "/tmp", "${1}", `db\.(.*)`, 60 * time.Second, nil,
false, "/tmp", "${1}", `db\.(.*)`, 60 * time.Second,
},
{
`auto {
directory /tmp
reload 0
}`,
false, "/tmp", "${1}", `db\.(.*)`, 0 * time.Second, nil,
false, "/tmp", "${1}", `db\.(.*)`, 0 * time.Second,
},
{
`auto {
directory /tmp (.*) bliep
}`,
false, "/tmp", "bliep", `(.*)`, 60 * time.Second, nil,
false, "/tmp", "bliep", `(.*)`, 60 * time.Second,
},
{
`auto {
directory /tmp (.*) bliep
reload 10s
}`,
false, "/tmp", "bliep", `(.*)`, 10 * time.Second, nil,
},
{
`auto {
directory /tmp (.*) bliep
transfer to 127.0.0.1
transfer to 127.0.0.2
}`,
false, "/tmp", "bliep", `(.*)`, 60 * time.Second, []string{"127.0.0.1:53", "127.0.0.2:53"},
false, "/tmp", "bliep", `(.*)`, 10 * time.Second,
},
// errors
// NO_RELOAD has been deprecated.
@@ -65,42 +55,50 @@ func TestAutoParse(t *testing.T) {
directory /tmp
no_reload
}`,
true, "/tmp", "${1}", `db\.(.*)`, 0 * time.Second, nil,
true, "/tmp", "${1}", `db\.(.*)`, 0 * time.Second,
},
// TIMEOUT has been deprecated.
{
`auto {
directory /tmp (.*) bliep 10
}`,
true, "/tmp", "bliep", `(.*)`, 10 * time.Second, nil,
true, "/tmp", "bliep", `(.*)`, 10 * time.Second,
},
// TRANSFER has been deprecated.
{
`auto {
directory /tmp (.*) bliep 10
transfer to 127.0.0.1
}`,
true, "/tmp", "bliep", `(.*)`, 10 * time.Second,
},
// no template specified.
{
`auto {
directory /tmp (.*)
}`,
true, "/tmp", "", `(.*)`, 60 * time.Second, nil,
true, "/tmp", "", `(.*)`, 60 * time.Second,
},
// no directory specified.
{
`auto example.org {
directory
}`,
true, "", "${1}", `db\.(.*)`, 60 * time.Second, nil,
true, "", "${1}", `db\.(.*)`, 60 * time.Second,
},
// illegal REGEXP.
{
`auto example.org {
directory /tmp * {1}
}`,
true, "/tmp", "${1}", ``, 60 * time.Second, nil,
true, "/tmp", "${1}", ``, 60 * time.Second,
},
// unexpected argument.
{
`auto example.org {
directory /tmp (.*) {1} aa
}`,
true, "/tmp", "${1}", ``, 60 * time.Second, nil,
true, "/tmp", "${1}", ``, 60 * time.Second,
},
}
@@ -125,13 +123,6 @@ func TestAutoParse(t *testing.T) {
if a.loader.ReloadInterval != test.expectedReloadInterval {
t.Fatalf("Test %d expected %v, got %v", i, test.expectedReloadInterval, a.loader.ReloadInterval)
}
if test.expectedTo != nil {
for j, got := range a.loader.transferTo {
if got != test.expectedTo[j] {
t.Fatalf("Test %d expected %v, got %v", i, test.expectedTo[j], got)
}
}
}
}
}
}

View File

@@ -53,15 +53,14 @@ func (a Auto) Walk() error {
zo.ReloadInterval = a.loader.ReloadInterval
zo.Upstream = a.loader.upstream
zo.TransferTo = a.loader.transferTo
a.Zones.Add(zo, origin)
a.Zones.Add(zo, origin, a.transfer)
if a.metrics != nil {
a.metrics.AddZone(origin)
}
zo.Notify()
a.transfer.Notify(origin)
log.Infof("Inserting zone `%s' from: %s", origin, path)

19
plugin/auto/xfr.go Normal file
View File

@@ -0,0 +1,19 @@
package auto
import (
"github.com/coredns/coredns/plugin/transfer"
"github.com/miekg/dns"
)
// Transfer implements the transfer.Transfer interface.
func (a Auto) Transfer(zone string, serial uint32) (<-chan []dns.RR, error) {
a.Zones.RLock()
z, ok := a.Zones.Z[zone]
a.Zones.RUnlock()
if !ok || z == nil {
return nil, transfer.ErrNotAuthoritative
}
return z.Transfer(serial)
}

View File

@@ -5,6 +5,7 @@ import (
"sync"
"github.com/coredns/coredns/plugin/file"
"github.com/coredns/coredns/plugin/transfer"
)
// Zones maps zone names to a *Zone. This keeps track of what zones we have loaded at
@@ -42,7 +43,7 @@ func (z *Zones) Zones(name string) *file.Zone {
// Add adds a new zone into z. If zo.NoReload is false, the
// reload goroutine is started.
func (z *Zones) Add(zo *file.Zone, name string) {
func (z *Zones) Add(zo *file.Zone, name string, t *transfer.Transfer) {
z.Lock()
if z.Z == nil {
@@ -51,7 +52,7 @@ func (z *Zones) Add(zo *file.Zone, name string) {
z.Z[name] = zo
z.names = append(z.names, name)
zo.Reload()
zo.Reload(t)
z.Unlock()
}