coredns/middleware/secondary/setup.go
Miek Gieben 9fb266aebe middleware/secondary: multiple fixes (#745)
Fix transferring the zone from a master and the matching of notifies
to source and dst IP addresses.

Add `upstream` keyword as well, because it is needed for the same
reasons as in the *file* middlware.
Add some dire warning about upstream in the readme of both middlewares.

Out of band testing, hidden by net build tag was added. Integration
testing still needs to be setup.
2017-06-21 23:46:20 -07:00

105 lines
2.4 KiB
Go

package secondary
import (
"github.com/coredns/coredns/core/dnsserver"
"github.com/coredns/coredns/middleware"
"github.com/coredns/coredns/middleware/file"
"github.com/coredns/coredns/middleware/pkg/dnsutil"
"github.com/coredns/coredns/middleware/proxy"
"github.com/mholt/caddy"
)
func init() {
caddy.RegisterPlugin("secondary", caddy.Plugin{
ServerType: "dns",
Action: setup,
})
}
func setup(c *caddy.Controller) error {
zones, err := secondaryParse(c)
if err != nil {
return middleware.Error("secondary", err)
}
// Add startup functions to retrieve the zone and keep it up to date.
for _, n := range zones.Names {
if len(zones.Z[n].TransferFrom) > 0 {
c.OnStartup(func() error {
zones.Z[n].StartupOnce.Do(func() {
zones.Z[n].TransferIn()
go func() {
zones.Z[n].Update()
}()
})
return nil
})
}
}
dnsserver.GetConfig(c).AddMiddleware(func(next middleware.Handler) middleware.Handler {
return Secondary{file.File{Next: next, Zones: zones}}
})
return nil
}
func secondaryParse(c *caddy.Controller) (file.Zones, error) {
z := make(map[string]*file.Zone)
names := []string{}
origins := []string{}
prxy := proxy.Proxy{}
for c.Next() {
if c.Val() == "secondary" {
// secondary [origin]
origins = make([]string, len(c.ServerBlockKeys))
copy(origins, c.ServerBlockKeys)
args := c.RemainingArgs()
if len(args) > 0 {
origins = args
}
for i := range origins {
origins[i] = middleware.Host(origins[i]).Normalize()
z[origins[i]] = file.NewZone(origins[i], "stdin")
names = append(names, origins[i])
}
for c.NextBlock() {
t, f := []string{}, []string{}
var e error
switch c.Val() {
case "transfer":
t, f, e = file.TransferParse(c, true)
if e != nil {
return file.Zones{}, e
}
case "upstream":
args := c.RemainingArgs()
if len(args) == 0 {
return file.Zones{}, c.ArgErr()
}
ups, err := dnsutil.ParseHostPortOrFile(args...)
if err != nil {
return file.Zones{}, err
}
prxy = proxy.NewLookup(ups)
}
for _, origin := range origins {
if t != nil {
z[origin].TransferTo = append(z[origin].TransferTo, t...)
}
if f != nil {
z[origin].TransferFrom = append(z[origin].TransferFrom, f...)
}
z[origin].Proxy = prxy
}
}
}
}
return file.Zones{Z: z, Names: names}, nil
}