core: small cleanup (#877)
Add some docs about normalize.Host and normalize.Name. They are used correctly in the middleware even though they are somewhat confusing, esp when you copy from ServerBlockKeys in your middleware.
This commit is contained in:
parent
28447234b1
commit
3654361be2
7 changed files with 326 additions and 341 deletions
|
@ -81,91 +81,88 @@ func autoParse(c *caddy.Controller) (Auto, error) {
|
|||
config := dnsserver.GetConfig(c)
|
||||
|
||||
for c.Next() {
|
||||
if c.Val() == "auto" {
|
||||
// auto [ZONES...]
|
||||
a.Zones.origins = make([]string, len(c.ServerBlockKeys))
|
||||
copy(a.Zones.origins, c.ServerBlockKeys)
|
||||
// auto [ZONES...]
|
||||
a.Zones.origins = make([]string, len(c.ServerBlockKeys))
|
||||
copy(a.Zones.origins, c.ServerBlockKeys)
|
||||
|
||||
args := c.RemainingArgs()
|
||||
if len(args) > 0 {
|
||||
a.Zones.origins = args
|
||||
}
|
||||
for i := range a.Zones.origins {
|
||||
a.Zones.origins[i] = middleware.Host(a.Zones.origins[i]).Normalize()
|
||||
}
|
||||
args := c.RemainingArgs()
|
||||
if len(args) > 0 {
|
||||
a.Zones.origins = args
|
||||
}
|
||||
for i := range a.Zones.origins {
|
||||
a.Zones.origins[i] = middleware.Host(a.Zones.origins[i]).Normalize()
|
||||
}
|
||||
|
||||
for c.NextBlock() {
|
||||
switch c.Val() {
|
||||
case "directory": // directory DIR [REGEXP [TEMPLATE] [DURATION]]
|
||||
if !c.NextArg() {
|
||||
return a, c.ArgErr()
|
||||
}
|
||||
a.loader.directory = c.Val()
|
||||
if !path.IsAbs(a.loader.directory) && config.Root != "" {
|
||||
a.loader.directory = path.Join(config.Root, a.loader.directory)
|
||||
}
|
||||
_, err := os.Stat(a.loader.directory)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
log.Printf("[WARNING] Directory does not exist: %s", a.loader.directory)
|
||||
} else {
|
||||
return a, c.Errf("Unable to access root path '%s': %v", a.loader.directory, err)
|
||||
}
|
||||
for c.NextBlock() {
|
||||
switch c.Val() {
|
||||
case "directory": // directory DIR [REGEXP [TEMPLATE] [DURATION]]
|
||||
if !c.NextArg() {
|
||||
return a, c.ArgErr()
|
||||
}
|
||||
a.loader.directory = c.Val()
|
||||
if !path.IsAbs(a.loader.directory) && config.Root != "" {
|
||||
a.loader.directory = path.Join(config.Root, a.loader.directory)
|
||||
}
|
||||
_, err := os.Stat(a.loader.directory)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
log.Printf("[WARNING] Directory does not exist: %s", a.loader.directory)
|
||||
} else {
|
||||
return a, c.Errf("Unable to access root path '%s': %v", a.loader.directory, err)
|
||||
}
|
||||
}
|
||||
|
||||
// regexp
|
||||
if c.NextArg() {
|
||||
a.loader.re, err = regexp.Compile(c.Val())
|
||||
if err != nil {
|
||||
return a, err
|
||||
}
|
||||
if a.loader.re.NumSubexp() == 0 {
|
||||
return a, c.Errf("Need at least one sub expression")
|
||||
}
|
||||
}
|
||||
|
||||
// template
|
||||
if c.NextArg() {
|
||||
a.loader.template = rewriteToExpand(c.Val())
|
||||
}
|
||||
|
||||
// duration
|
||||
if c.NextArg() {
|
||||
i, err := strconv.Atoi(c.Val())
|
||||
if err != nil {
|
||||
return a, err
|
||||
}
|
||||
if i < 1 {
|
||||
i = 1
|
||||
}
|
||||
a.loader.duration = time.Duration(i) * time.Second
|
||||
}
|
||||
|
||||
case "no_reload":
|
||||
a.loader.noReload = true
|
||||
|
||||
case "upstream":
|
||||
args := c.RemainingArgs()
|
||||
if len(args) == 0 {
|
||||
return a, c.ArgErr()
|
||||
}
|
||||
ups, err := dnsutil.ParseHostPortOrFile(args...)
|
||||
// regexp
|
||||
if c.NextArg() {
|
||||
a.loader.re, err = regexp.Compile(c.Val())
|
||||
if err != nil {
|
||||
return a, err
|
||||
}
|
||||
a.loader.proxy = proxy.NewLookup(ups)
|
||||
|
||||
default:
|
||||
t, _, e := file.TransferParse(c, false)
|
||||
if e != nil {
|
||||
return a, e
|
||||
}
|
||||
if t != nil {
|
||||
a.loader.transferTo = append(a.loader.transferTo, t...)
|
||||
if a.loader.re.NumSubexp() == 0 {
|
||||
return a, c.Errf("Need at least one sub expression")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// template
|
||||
if c.NextArg() {
|
||||
a.loader.template = rewriteToExpand(c.Val())
|
||||
}
|
||||
|
||||
// duration
|
||||
if c.NextArg() {
|
||||
i, err := strconv.Atoi(c.Val())
|
||||
if err != nil {
|
||||
return a, err
|
||||
}
|
||||
if i < 1 {
|
||||
i = 1
|
||||
}
|
||||
a.loader.duration = time.Duration(i) * time.Second
|
||||
}
|
||||
|
||||
case "no_reload":
|
||||
a.loader.noReload = true
|
||||
|
||||
case "upstream":
|
||||
args := c.RemainingArgs()
|
||||
if len(args) == 0 {
|
||||
return a, c.ArgErr()
|
||||
}
|
||||
ups, err := dnsutil.ParseHostPortOrFile(args...)
|
||||
if err != nil {
|
||||
return a, err
|
||||
}
|
||||
a.loader.proxy = proxy.NewLookup(ups)
|
||||
|
||||
default:
|
||||
t, _, e := file.TransferParse(c, false)
|
||||
if e != nil {
|
||||
return a, e
|
||||
}
|
||||
if t != nil {
|
||||
a.loader.transferTo = append(a.loader.transferTo, t...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return a, nil
|
||||
|
|
|
@ -42,36 +42,34 @@ func dnssecParse(c *caddy.Controller) ([]string, []*DNSKEY, int, error) {
|
|||
|
||||
capacity := defaultCap
|
||||
for c.Next() {
|
||||
if c.Val() == "dnssec" {
|
||||
// dnssec [zones...]
|
||||
zones = make([]string, len(c.ServerBlockKeys))
|
||||
copy(zones, c.ServerBlockKeys)
|
||||
args := c.RemainingArgs()
|
||||
if len(args) > 0 {
|
||||
zones = args
|
||||
}
|
||||
// dnssec [zones...]
|
||||
zones = make([]string, len(c.ServerBlockKeys))
|
||||
copy(zones, c.ServerBlockKeys)
|
||||
args := c.RemainingArgs()
|
||||
if len(args) > 0 {
|
||||
zones = args
|
||||
}
|
||||
|
||||
for c.NextBlock() {
|
||||
switch c.Val() {
|
||||
case "key":
|
||||
k, e := keyParse(c)
|
||||
if e != nil {
|
||||
return nil, nil, 0, e
|
||||
}
|
||||
keys = append(keys, k...)
|
||||
case "cache_capacity":
|
||||
if !c.NextArg() {
|
||||
return nil, nil, 0, c.ArgErr()
|
||||
}
|
||||
value := c.Val()
|
||||
cacheCap, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
capacity = cacheCap
|
||||
for c.NextBlock() {
|
||||
switch c.Val() {
|
||||
case "key":
|
||||
k, e := keyParse(c)
|
||||
if e != nil {
|
||||
return nil, nil, 0, e
|
||||
}
|
||||
|
||||
keys = append(keys, k...)
|
||||
case "cache_capacity":
|
||||
if !c.NextArg() {
|
||||
return nil, nil, 0, c.ArgErr()
|
||||
}
|
||||
value := c.Val()
|
||||
cacheCap, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
capacity = cacheCap
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
for i := range zones {
|
||||
|
|
|
@ -60,71 +60,69 @@ func etcdParse(c *caddy.Controller) (*Etcd, bool, error) {
|
|||
stubzones = false
|
||||
)
|
||||
for c.Next() {
|
||||
if c.Val() == "etcd" {
|
||||
etc.Zones = c.RemainingArgs()
|
||||
if len(etc.Zones) == 0 {
|
||||
etc.Zones = make([]string, len(c.ServerBlockKeys))
|
||||
copy(etc.Zones, c.ServerBlockKeys)
|
||||
}
|
||||
for i, str := range etc.Zones {
|
||||
etc.Zones[i] = middleware.Host(str).Normalize()
|
||||
}
|
||||
etc.Zones = c.RemainingArgs()
|
||||
if len(etc.Zones) == 0 {
|
||||
etc.Zones = make([]string, len(c.ServerBlockKeys))
|
||||
copy(etc.Zones, c.ServerBlockKeys)
|
||||
}
|
||||
for i, str := range etc.Zones {
|
||||
etc.Zones[i] = middleware.Host(str).Normalize()
|
||||
}
|
||||
|
||||
if c.NextBlock() {
|
||||
for {
|
||||
switch c.Val() {
|
||||
case "stubzones":
|
||||
stubzones = true
|
||||
case "debug":
|
||||
etc.Debugging = true
|
||||
case "path":
|
||||
if !c.NextArg() {
|
||||
return &Etcd{}, false, c.ArgErr()
|
||||
}
|
||||
etc.PathPrefix = c.Val()
|
||||
case "endpoint":
|
||||
args := c.RemainingArgs()
|
||||
if len(args) == 0 {
|
||||
return &Etcd{}, false, c.ArgErr()
|
||||
}
|
||||
endpoints = args
|
||||
case "upstream":
|
||||
args := c.RemainingArgs()
|
||||
if len(args) == 0 {
|
||||
return &Etcd{}, false, c.ArgErr()
|
||||
}
|
||||
ups, err := dnsutil.ParseHostPortOrFile(args...)
|
||||
if err != nil {
|
||||
return &Etcd{}, false, err
|
||||
}
|
||||
etc.Proxy = proxy.NewLookup(ups)
|
||||
case "tls": // cert key cacertfile
|
||||
args := c.RemainingArgs()
|
||||
tlsConfig, err = mwtls.NewTLSConfigFromArgs(args...)
|
||||
if err != nil {
|
||||
return &Etcd{}, false, err
|
||||
}
|
||||
default:
|
||||
if c.Val() != "}" {
|
||||
return &Etcd{}, false, c.Errf("unknown property '%s'", c.Val())
|
||||
}
|
||||
if c.NextBlock() {
|
||||
for {
|
||||
switch c.Val() {
|
||||
case "stubzones":
|
||||
stubzones = true
|
||||
case "debug":
|
||||
etc.Debugging = true
|
||||
case "path":
|
||||
if !c.NextArg() {
|
||||
return &Etcd{}, false, c.ArgErr()
|
||||
}
|
||||
|
||||
if !c.Next() {
|
||||
break
|
||||
etc.PathPrefix = c.Val()
|
||||
case "endpoint":
|
||||
args := c.RemainingArgs()
|
||||
if len(args) == 0 {
|
||||
return &Etcd{}, false, c.ArgErr()
|
||||
}
|
||||
endpoints = args
|
||||
case "upstream":
|
||||
args := c.RemainingArgs()
|
||||
if len(args) == 0 {
|
||||
return &Etcd{}, false, c.ArgErr()
|
||||
}
|
||||
ups, err := dnsutil.ParseHostPortOrFile(args...)
|
||||
if err != nil {
|
||||
return &Etcd{}, false, err
|
||||
}
|
||||
etc.Proxy = proxy.NewLookup(ups)
|
||||
case "tls": // cert key cacertfile
|
||||
args := c.RemainingArgs()
|
||||
tlsConfig, err = mwtls.NewTLSConfigFromArgs(args...)
|
||||
if err != nil {
|
||||
return &Etcd{}, false, err
|
||||
}
|
||||
default:
|
||||
if c.Val() != "}" {
|
||||
return &Etcd{}, false, c.Errf("unknown property '%s'", c.Val())
|
||||
}
|
||||
}
|
||||
|
||||
if !c.Next() {
|
||||
break
|
||||
}
|
||||
}
|
||||
client, err := newEtcdClient(endpoints, tlsConfig)
|
||||
if err != nil {
|
||||
return &Etcd{}, false, err
|
||||
}
|
||||
etc.Client = client
|
||||
etc.endpoints = endpoints
|
||||
|
||||
return &etc, stubzones, nil
|
||||
}
|
||||
client, err := newEtcdClient(endpoints, tlsConfig)
|
||||
if err != nil {
|
||||
return &Etcd{}, false, err
|
||||
}
|
||||
etc.Client = client
|
||||
etc.endpoints = endpoints
|
||||
|
||||
return &etc, stubzones, nil
|
||||
}
|
||||
return &Etcd{}, false, nil
|
||||
}
|
||||
|
|
|
@ -55,76 +55,74 @@ func fileParse(c *caddy.Controller) (Zones, error) {
|
|||
config := dnsserver.GetConfig(c)
|
||||
|
||||
for c.Next() {
|
||||
if c.Val() == "file" {
|
||||
// file db.file [zones...]
|
||||
if !c.NextArg() {
|
||||
return Zones{}, c.ArgErr()
|
||||
}
|
||||
fileName := c.Val()
|
||||
// file db.file [zones...]
|
||||
if !c.NextArg() {
|
||||
return Zones{}, c.ArgErr()
|
||||
}
|
||||
fileName := c.Val()
|
||||
|
||||
origins = make([]string, len(c.ServerBlockKeys))
|
||||
copy(origins, c.ServerBlockKeys)
|
||||
args := c.RemainingArgs()
|
||||
if len(args) > 0 {
|
||||
origins = args
|
||||
}
|
||||
origins = make([]string, len(c.ServerBlockKeys))
|
||||
copy(origins, c.ServerBlockKeys)
|
||||
args := c.RemainingArgs()
|
||||
if len(args) > 0 {
|
||||
origins = args
|
||||
}
|
||||
|
||||
if !path.IsAbs(fileName) && config.Root != "" {
|
||||
fileName = path.Join(config.Root, fileName)
|
||||
}
|
||||
if !path.IsAbs(fileName) && config.Root != "" {
|
||||
fileName = path.Join(config.Root, fileName)
|
||||
}
|
||||
|
||||
reader, err := os.Open(fileName)
|
||||
if err != nil {
|
||||
// bail out
|
||||
reader, err := os.Open(fileName)
|
||||
if err != nil {
|
||||
// bail out
|
||||
return Zones{}, err
|
||||
}
|
||||
|
||||
for i := range origins {
|
||||
origins[i] = middleware.Host(origins[i]).Normalize()
|
||||
zone, err := Parse(reader, origins[i], fileName, 0)
|
||||
if err == nil {
|
||||
z[origins[i]] = zone
|
||||
} else {
|
||||
return Zones{}, err
|
||||
}
|
||||
names = append(names, origins[i])
|
||||
}
|
||||
|
||||
for i := range origins {
|
||||
origins[i] = middleware.Host(origins[i]).Normalize()
|
||||
zone, err := Parse(reader, origins[i], fileName, 0)
|
||||
if err == nil {
|
||||
z[origins[i]] = zone
|
||||
} else {
|
||||
noReload := false
|
||||
prxy := proxy.Proxy{}
|
||||
t := []string{}
|
||||
var e error
|
||||
|
||||
for c.NextBlock() {
|
||||
switch c.Val() {
|
||||
case "transfer":
|
||||
t, _, e = TransferParse(c, false)
|
||||
if e != nil {
|
||||
return Zones{}, e
|
||||
}
|
||||
|
||||
case "no_reload":
|
||||
noReload = true
|
||||
|
||||
case "upstream":
|
||||
args := c.RemainingArgs()
|
||||
if len(args) == 0 {
|
||||
return Zones{}, c.ArgErr()
|
||||
}
|
||||
ups, err := dnsutil.ParseHostPortOrFile(args...)
|
||||
if err != nil {
|
||||
return Zones{}, err
|
||||
}
|
||||
names = append(names, origins[i])
|
||||
prxy = proxy.NewLookup(ups)
|
||||
}
|
||||
|
||||
noReload := false
|
||||
prxy := proxy.Proxy{}
|
||||
t := []string{}
|
||||
var e error
|
||||
|
||||
for c.NextBlock() {
|
||||
switch c.Val() {
|
||||
case "transfer":
|
||||
t, _, e = TransferParse(c, false)
|
||||
if e != nil {
|
||||
return Zones{}, e
|
||||
}
|
||||
|
||||
case "no_reload":
|
||||
noReload = true
|
||||
|
||||
case "upstream":
|
||||
args := c.RemainingArgs()
|
||||
if len(args) == 0 {
|
||||
return Zones{}, c.ArgErr()
|
||||
}
|
||||
ups, err := dnsutil.ParseHostPortOrFile(args...)
|
||||
if err != nil {
|
||||
return Zones{}, err
|
||||
}
|
||||
prxy = proxy.NewLookup(ups)
|
||||
}
|
||||
|
||||
for _, origin := range origins {
|
||||
if t != nil {
|
||||
z[origin].TransferTo = append(z[origin].TransferTo, t...)
|
||||
}
|
||||
z[origin].NoReload = noReload
|
||||
z[origin].Proxy = prxy
|
||||
for _, origin := range origins {
|
||||
if t != nil {
|
||||
z[origin].TransferTo = append(z[origin].TransferTo, t...)
|
||||
}
|
||||
z[origin].NoReload = noReload
|
||||
z[origin].Proxy = prxy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,46 +41,44 @@ func hostsParse(c *caddy.Controller) (Hosts, error) {
|
|||
config := dnsserver.GetConfig(c)
|
||||
|
||||
for c.Next() {
|
||||
if c.Val() == "hosts" { // hosts [FILE] [ZONES...]
|
||||
args := c.RemainingArgs()
|
||||
if len(args) >= 1 {
|
||||
h.path = args[0]
|
||||
args = args[1:]
|
||||
args := c.RemainingArgs()
|
||||
if len(args) >= 1 {
|
||||
h.path = args[0]
|
||||
args = args[1:]
|
||||
|
||||
if !path.IsAbs(h.path) && config.Root != "" {
|
||||
h.path = path.Join(config.Root, h.path)
|
||||
}
|
||||
_, err := os.Stat(h.path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
log.Printf("[WARNING] File does not exist: %s", h.path)
|
||||
} else {
|
||||
return h, c.Errf("unable to access hosts file '%s': %v", h.path, err)
|
||||
}
|
||||
if !path.IsAbs(h.path) && config.Root != "" {
|
||||
h.path = path.Join(config.Root, h.path)
|
||||
}
|
||||
_, err := os.Stat(h.path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
log.Printf("[WARNING] File does not exist: %s", h.path)
|
||||
} else {
|
||||
return h, c.Errf("unable to access hosts file '%s': %v", h.path, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
origins := make([]string, len(c.ServerBlockKeys))
|
||||
copy(origins, c.ServerBlockKeys)
|
||||
if len(args) > 0 {
|
||||
origins = args
|
||||
}
|
||||
origins := make([]string, len(c.ServerBlockKeys))
|
||||
copy(origins, c.ServerBlockKeys)
|
||||
if len(args) > 0 {
|
||||
origins = args
|
||||
}
|
||||
|
||||
for i := range origins {
|
||||
origins[i] = middleware.Host(origins[i]).Normalize()
|
||||
}
|
||||
h.Origins = origins
|
||||
for i := range origins {
|
||||
origins[i] = middleware.Host(origins[i]).Normalize()
|
||||
}
|
||||
h.Origins = origins
|
||||
|
||||
for c.NextBlock() {
|
||||
switch c.Val() {
|
||||
case "fallthrough":
|
||||
args := c.RemainingArgs()
|
||||
if len(args) == 0 {
|
||||
h.Fallthrough = true
|
||||
continue
|
||||
}
|
||||
return h, c.ArgErr()
|
||||
for c.NextBlock() {
|
||||
switch c.Val() {
|
||||
case "fallthrough":
|
||||
args := c.RemainingArgs()
|
||||
if len(args) == 0 {
|
||||
h.Fallthrough = true
|
||||
continue
|
||||
}
|
||||
return h, c.ArgErr()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,8 @@ func (z Zones) Matches(qname string) string {
|
|||
return zone
|
||||
}
|
||||
|
||||
// Normalize fully qualifies all zones in z.
|
||||
// Normalize fully qualifies all zones in z. The zones in Z must be domain names, without
|
||||
// a port or protocol prefix.
|
||||
func (z Zones) Normalize() {
|
||||
for i := range z {
|
||||
z[i] = Name(z[i]).Normalize()
|
||||
|
@ -54,7 +55,7 @@ func (n Name) Normalize() string { return strings.ToLower(dns.Fqdn(string(n))) }
|
|||
|
||||
type (
|
||||
// Host represents a host from the Corefile, may contain port.
|
||||
Host string // Host represents a host from the Corefile, may contain port.
|
||||
Host string
|
||||
)
|
||||
|
||||
// Normalize will return the host portion of host, stripping
|
||||
|
|
|
@ -34,116 +34,111 @@ func setupReverse(c *caddy.Controller) error {
|
|||
}
|
||||
|
||||
func reverseParse(c *caddy.Controller) (nets networks, fall bool, err error) {
|
||||
|
||||
// normalize zones, validation is almost done by dnsserver
|
||||
// TODO(miek): need sane helpers for these.
|
||||
zones := make([]string, len(c.ServerBlockKeys))
|
||||
wildcard := false
|
||||
|
||||
// We copy from the serverblock, these contains Hosts.
|
||||
for i, str := range c.ServerBlockKeys {
|
||||
zones[i] = middleware.Host(str).Normalize()
|
||||
}
|
||||
|
||||
for c.Next() {
|
||||
if c.Val() == "reverse" {
|
||||
var cidrs []*net.IPNet
|
||||
|
||||
var cidrs []*net.IPNet
|
||||
|
||||
// parse all networks
|
||||
for _, cidr := range c.RemainingArgs() {
|
||||
if cidr == "{" {
|
||||
break
|
||||
}
|
||||
_, ipnet, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
return nil, false, c.Errf("network needs to be CIDR formatted: %q\n", cidr)
|
||||
}
|
||||
cidrs = append(cidrs, ipnet)
|
||||
// parse all networks
|
||||
for _, cidr := range c.RemainingArgs() {
|
||||
if cidr == "{" {
|
||||
break
|
||||
}
|
||||
if len(cidrs) == 0 {
|
||||
return nil, false, c.ArgErr()
|
||||
_, ipnet, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
return nil, false, c.Errf("network needs to be CIDR formatted: %q\n", cidr)
|
||||
}
|
||||
cidrs = append(cidrs, ipnet)
|
||||
}
|
||||
if len(cidrs) == 0 {
|
||||
return nil, false, c.ArgErr()
|
||||
}
|
||||
|
||||
// set defaults
|
||||
var (
|
||||
template = "ip-" + templateNameIP + ".{zone[1]}"
|
||||
ttl = 60
|
||||
)
|
||||
for c.NextBlock() {
|
||||
switch c.Val() {
|
||||
case "hostname":
|
||||
if !c.NextArg() {
|
||||
return nil, false, c.ArgErr()
|
||||
}
|
||||
template = c.Val()
|
||||
|
||||
case "ttl":
|
||||
if !c.NextArg() {
|
||||
return nil, false, c.ArgErr()
|
||||
}
|
||||
ttl, err = strconv.Atoi(c.Val())
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
case "wildcard":
|
||||
wildcard = true
|
||||
|
||||
case "fallthrough":
|
||||
fall = true
|
||||
|
||||
default:
|
||||
// set defaults
|
||||
var (
|
||||
template = "ip-" + templateNameIP + ".{zone[1]}"
|
||||
ttl = 60
|
||||
)
|
||||
for c.NextBlock() {
|
||||
switch c.Val() {
|
||||
case "hostname":
|
||||
if !c.NextArg() {
|
||||
return nil, false, c.ArgErr()
|
||||
}
|
||||
}
|
||||
template = c.Val()
|
||||
|
||||
// prepare template
|
||||
// replace {zone[index]} by the listen zone/domain of this config block
|
||||
for i, zone := range zones {
|
||||
// TODO: we should be smarter about actually replacing this. This works, but silently allows "zone[-1]"
|
||||
// for instance.
|
||||
template = strings.Replace(template, "{zone["+strconv.Itoa(i+1)+"]}", zone, 1)
|
||||
}
|
||||
if !strings.HasSuffix(template, ".") {
|
||||
template += "."
|
||||
}
|
||||
|
||||
// extract zone from template
|
||||
templateZone := strings.SplitAfterN(template, ".", 2)
|
||||
if len(templateZone) != 2 || templateZone[1] == "" {
|
||||
return nil, false, c.Errf("cannot find domain in template '%v'", template)
|
||||
}
|
||||
|
||||
// Create for each configured network in this stanza
|
||||
for _, ipnet := range cidrs {
|
||||
// precompile regex for hostname to ip matching
|
||||
regexIP := regexMatchV4
|
||||
if ipnet.IP.To4() == nil {
|
||||
regexIP = regexMatchV6
|
||||
case "ttl":
|
||||
if !c.NextArg() {
|
||||
return nil, false, c.ArgErr()
|
||||
}
|
||||
prefix := "^"
|
||||
if wildcard {
|
||||
prefix += ".*"
|
||||
}
|
||||
regex, err := regexp.Compile(
|
||||
prefix + strings.Replace( // inject ip regex into template
|
||||
regexp.QuoteMeta(template), // escape dots
|
||||
regexp.QuoteMeta(templateNameIP),
|
||||
regexIP,
|
||||
1) + "$")
|
||||
ttl, err = strconv.Atoi(c.Val())
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
nets = append(nets, network{
|
||||
IPnet: ipnet,
|
||||
Zone: templateZone[1],
|
||||
Template: template,
|
||||
RegexMatchIP: regex,
|
||||
TTL: uint32(ttl),
|
||||
})
|
||||
case "wildcard":
|
||||
wildcard = true
|
||||
|
||||
case "fallthrough":
|
||||
fall = true
|
||||
|
||||
default:
|
||||
return nil, false, c.ArgErr()
|
||||
}
|
||||
}
|
||||
|
||||
// prepare template
|
||||
// replace {zone[index]} by the listen zone/domain of this config block
|
||||
for i, zone := range zones {
|
||||
// TODO: we should be smarter about actually replacing this. This works, but silently allows "zone[-1]"
|
||||
// for instance.
|
||||
template = strings.Replace(template, "{zone["+strconv.Itoa(i+1)+"]}", zone, 1)
|
||||
}
|
||||
if !strings.HasSuffix(template, ".") {
|
||||
template += "."
|
||||
}
|
||||
|
||||
// extract zone from template
|
||||
templateZone := strings.SplitAfterN(template, ".", 2)
|
||||
if len(templateZone) != 2 || templateZone[1] == "" {
|
||||
return nil, false, c.Errf("cannot find domain in template '%v'", template)
|
||||
}
|
||||
|
||||
// Create for each configured network in this stanza
|
||||
for _, ipnet := range cidrs {
|
||||
// precompile regex for hostname to ip matching
|
||||
regexIP := regexMatchV4
|
||||
if ipnet.IP.To4() == nil {
|
||||
regexIP = regexMatchV6
|
||||
}
|
||||
prefix := "^"
|
||||
if wildcard {
|
||||
prefix += ".*"
|
||||
}
|
||||
regex, err := regexp.Compile(
|
||||
prefix + strings.Replace( // inject ip regex into template
|
||||
regexp.QuoteMeta(template), // escape dots
|
||||
regexp.QuoteMeta(templateNameIP),
|
||||
regexIP,
|
||||
1) + "$")
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
nets = append(nets, network{
|
||||
IPnet: ipnet,
|
||||
Zone: templateZone[1],
|
||||
Template: template,
|
||||
RegexMatchIP: regex,
|
||||
TTL: uint32(ttl),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// sort by cidr
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue