coredns-yaml/yamlplugin.go
2025-11-30 19:39:59 -07:00

99 lines
2.1 KiB
Go

package yamlzone
import (
"context"
"fmt"
"strconv"
"github.com/coredns/caddy"
"github.com/coredns/coredns/core/dnsserver"
"github.com/coredns/coredns/plugin"
clog "github.com/coredns/coredns/plugin/pkg/log"
"github.com/coredns/coredns/request"
"github.com/miekg/dns"
)
type YamlPlugin struct {
Next plugin.Handler
Zone *Zone
Config YamlPluginConfig
}
type YamlPluginConfig struct {
DefaultTtl uint64
}
var log = clog.NewWithPlugin("yaml")
func (y YamlPlugin) lookupRRs(qname string, qtype string) ([]dns.RR, bool) {
records, ok := y.Zone.LookupType(qname, qtype)
if !ok {
return nil, false
}
rrs := []dns.RR{}
for _, record := range records {
ttl := record.Ttl
if ttl == 0 {
ttl = y.Config.DefaultTtl
}
rr, err := dns.NewRR(fmt.Sprintf("%s %d %s %s", qname, ttl, record.Type, record.Value))
if err != nil {
return nil, false
}
rrs = append(rrs, rr)
}
return rrs, true
}
func (y YamlPlugin) Name() string { return "yaml" }
func (y YamlPlugin) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
state := request.Request{W: w, Req: r}
qname := state.Name()
qtype := state.Type()
reply := new(dns.Msg)
reply.SetReply(r)
reply.Authoritative = true
rrs, ok := y.lookupRRs(qname, qtype)
if !ok {
return dns.RcodeNameError, nil
}
reply.Answer = rrs
w.WriteMsg(reply)
return dns.RcodeSuccess, nil
}
func setup(c *caddy.Controller) error {
c.Next() // yaml
filename := "zones.yaml"
if c.NextArg() {
filename = c.Val()
}
defaultTtl := uint64(60)
if c.NextArg() {
var err error
defaultTtl, err = strconv.ParseUint(c.Val(), 10, 32)
if err != nil {
return plugin.Error("yaml", fmt.Errorf("failed to parse default TTL: %w", err))
}
}
zone, err := LoadZone(filename)
if err != nil {
return plugin.Error("yaml", fmt.Errorf("failed to load zone from %s: %w", filename, err))
}
dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler {
return &YamlPlugin{
Next: next,
Zone: zone,
Config: YamlPluginConfig{
DefaultTtl: defaultTtl,
},
}
})
return nil
}
func init() { plugin.Register("yaml", setup) }