diff options
Diffstat (limited to 'plugin/template/setup.go')
-rw-r--r-- | plugin/template/setup.go | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/plugin/template/setup.go b/plugin/template/setup.go new file mode 100644 index 000000000..61b6728c9 --- /dev/null +++ b/plugin/template/setup.go @@ -0,0 +1,143 @@ +package template + +import ( + "regexp" + gotmpl "text/template" + + "github.com/coredns/coredns/core/dnsserver" + "github.com/coredns/coredns/plugin" + + "github.com/mholt/caddy" + "github.com/miekg/dns" +) + +func init() { + caddy.RegisterPlugin("template", caddy.Plugin{ + ServerType: "dns", + Action: setupTemplate, + }) +} + +func setupTemplate(c *caddy.Controller) error { + templates, err := templateParse(c) + if err != nil { + return plugin.Error("template", err) + } + + c.OnStartup(OnStartupMetrics) + + dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { + return Handler{Next: next, Templates: templates} + }) + + return nil +} + +func templateParse(c *caddy.Controller) (templates []template, err error) { + templates = make([]template, 0) + + for c.Next() { + t := template{} + if !c.NextArg() { + return nil, c.ArgErr() + } + + class, ok := dns.StringToClass[c.Val()] + if !ok { + return nil, c.Errf("invalid query class %s", c.Val()) + } + t.class = class + + if !c.NextArg() { + return nil, c.ArgErr() + } + queryType, ok := dns.StringToType[c.Val()] + if !ok { + return nil, c.Errf("invalid RR type %s", c.Val()) + } + t.qtype = queryType + + t.regex = make([]*regexp.Regexp, 0) + templatePrefix := "" + + for _, regex := range c.RemainingArgs() { + r, err := regexp.Compile(regex) + if err != nil { + return nil, c.Errf("could not parse regex: %s, %v", regex, err) + } + templatePrefix = templatePrefix + regex + " " + t.regex = append(t.regex, r) + } + + if len(t.regex) == 0 { + t.regex = append(t.regex, regexp.MustCompile(".*")) + templatePrefix = ".* " + } + + t.answer = make([]*gotmpl.Template, 0) + + for c.NextBlock() { + switch c.Val() { + case "answer": + args := c.RemainingArgs() + if len(args) == 0 { + return nil, c.ArgErr() + } + for _, answer := range args { + tmpl, err := gotmpl.New("answer").Parse(answer) + if err != nil { + return nil, c.Errf("could not compile template: %s, %v", c.Val(), err) + } + t.answer = append(t.answer, tmpl) + } + + case "additional": + args := c.RemainingArgs() + if len(args) == 0 { + return nil, c.ArgErr() + } + for _, additional := range args { + tmpl, err := gotmpl.New("additional").Parse(additional) + if err != nil { + return nil, c.Errf("could not compile template: %s, %v\n", c.Val(), err) + } + t.additional = append(t.additional, tmpl) + } + + case "authority": + args := c.RemainingArgs() + if len(args) == 0 { + return nil, c.ArgErr() + } + for _, authority := range args { + tmpl, err := gotmpl.New("authority").Parse(authority) + if err != nil { + return nil, c.Errf("could not compile template: %s, %v\n", c.Val(), err) + } + t.authority = append(t.authority, tmpl) + } + + case "rcode": + if !c.NextArg() { + return nil, c.ArgErr() + } + rcode, ok := dns.StringToRcode[c.Val()] + if !ok { + return nil, c.Errf("unknown rcode %s", c.Val()) + } + t.rcode = rcode + + default: + return nil, c.ArgErr() + } + } + + if len(t.answer) == 0 && len(t.additional) == 0 && t.rcode == dns.RcodeSuccess { + return nil, c.Errf("no answer section for template %s %sfound", t.qtype, templatePrefix) + } + + templates = append(templates, t) + } + + return templates, nil +} |