Add secondary support

Allow specifying a primary server and retrieve the zone's content.

Add tests and an Expired bool to zone struct, to stop server zones

that are expired. The zone is retrieved on Startup, no updates of

changed content are done. We also don't respond to notifies yet.
This commit is contained in:
Miek Gieben
2016-04-03 09:02:34 +01:00
parent 7fb959470e
commit f58f1e4285
12 changed files with 252 additions and 50 deletions

View File

@@ -59,6 +59,7 @@ var directiveOrder = []directive{
{"errors", setup.Errors},
{"file", setup.File},
{"secondary", setup.Secondary},
{"etcd", setup.Etcd},
{"proxy", setup.Proxy},
}

View File

@@ -36,9 +36,9 @@ func fileParse(c *Controller) (file.Zones, error) {
if c.NextArg() {
origin = c.Val()
}
// normalize this origin
origin = middleware.Host(origin).Standard()
origin = middleware.Host(origin).Normalize()
// TODO(miek): we should allow more. Issue #54.
reader, err := os.Open(fileName)
if err != nil {
return file.Zones{}, err
@@ -48,27 +48,40 @@ func fileParse(c *Controller) (file.Zones, error) {
z[origin] = zone
}
names = append(names, origin)
if c.NextBlock() {
what := c.Val()
if !c.NextArg() {
return file.Zones{}, c.ArgErr()
}
value := c.Val()
var err error
switch what {
case "transfer":
if value == "out" {
z[origin].Transfer.Out = true
}
if value == "in" {
z[origin].Transfer.In = true
}
}
if err != nil {
return file.Zones{}, err
for c.NextBlock() {
t, _, e := parseTransfer(c)
if e != nil {
return file.Zones{}, e
}
// discard from, here, maybe check and show log when we do?
z[origin].TransferTo = append(z[origin].TransferTo, t)
}
}
}
return file.Zones{Z: z, Names: names}, nil
}
// transfer to [address]
func parseTransfer(c *Controller) (to, from string, err error) {
what := c.Val()
if !c.NextArg() {
return "", "", c.ArgErr()
}
value := c.Val()
switch what {
case "transfer":
if !c.NextArg() {
return "", "", c.ArgErr()
}
if value == "to" {
to = c.Val()
to = middleware.Addr(to).Normalize()
}
if value == "from" {
from = c.Val()
from = middleware.Addr(from).Normalize()
}
}
return
}

59
core/setup/secondary.go Normal file
View File

@@ -0,0 +1,59 @@
package setup
import (
"github.com/miekg/coredns/middleware"
"github.com/miekg/coredns/middleware/file"
"github.com/miekg/coredns/middleware/secondary"
)
// Secondary sets up the secondary middleware.
func Secondary(c *Controller) (middleware.Middleware, error) {
zones, err := secondaryParse(c)
if err != nil {
return nil, err
}
// Setup retrieve the zone.
for _, n := range zones.Names {
if len(zones.Z[n].TransferFrom) > 0 {
c.Startup = append(c.Startup, func() error {
err := zones.Z[n].TransferIn()
return err
})
}
}
return func(next middleware.Handler) middleware.Handler {
return secondary.Secondary{file.File{Next: next, Zones: zones}}
}, nil
}
func secondaryParse(c *Controller) (file.Zones, error) {
z := make(map[string]*file.Zone)
names := []string{}
for c.Next() {
if c.Val() == "secondary" {
// secondary [origin]
origin := c.ServerBlockHosts[c.ServerBlockHostIndex]
if c.NextArg() {
origin = c.Val()
}
// TODO(miek): we should allow more. Issue #54.
origin = middleware.Host(origin).Normalize()
z[origin] = file.NewZone(origin)
names = append(names, origin)
for c.NextBlock() {
t, f, e := parseTransfer(c)
if e != nil {
return file.Zones{}, e
}
z[origin].TransferTo = append(z[origin].TransferTo, t)
z[origin].TransferFrom = append(z[origin].TransferFrom, f)
}
}
}
return file.Zones{Z: z, Names: names}, nil
}