mirror of
https://github.com/coredns/coredns.git
synced 2025-11-01 10:43:17 -04:00
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:
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
19
plugin/auto/xfr.go
Normal 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)
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user