Files
synthetic/setup.go
T
Donavan Fritz ff3ec65719
Synthetic CoreDNS Plugin CI/CD Build / test (push) Has been cancelled
Fix build and polish codebase to OSS quality
Dockerfile used golang:1.21 but go.mod requires 1.25; CI was broken.
Refactored plugin code with proper godoc comments, extracted helpers to
eliminate duplicated response-building logic, modernized tests with
t.Run subtests and shared assertion helpers, and rewrote README with
configuration reference table and professional structure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 13:33:25 -05:00

104 lines
2.5 KiB
Go

package synthetic
import (
"fmt"
"net"
"strconv"
"strings"
"github.com/coredns/caddy"
"github.com/coredns/coredns/core/dnsserver"
"github.com/coredns/coredns/plugin"
)
// syntheticConfig holds the parsed Corefile configuration for the synthetic plugin.
type syntheticConfig struct {
// net is the set of IP networks for which synthetic forward responses are
// generated. Only addresses falling within these CIDRs will be resolved.
net []*net.IPNet
// forward is the DNS zone appended to synthetic hostnames when generating
// PTR records (e.g., "example.com").
forward string
// ttl is the time-to-live value applied to all synthetic responses.
// Defaults to 0 (no caching).
ttl uint32
// prefix is the hostname label prefix used to identify synthetic queries
// (e.g., "ip-"). A trailing dash is appended automatically if absent.
prefix string
}
func init() { plugin.Register("synthetic", setup) }
// setup parses the Corefile configuration block for the synthetic plugin and
// registers it in the CoreDNS handler chain.
func setup(c *caddy.Controller) error {
config, err := parseConfig(c)
if err != nil {
return err
}
dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler {
return synthetic{Next: next, Config: config}
})
return nil
}
// parseConfig reads the synthetic { ... } block from the Corefile and returns
// a validated syntheticConfig.
func parseConfig(c *caddy.Controller) (syntheticConfig, error) {
var config syntheticConfig
for c.Next() {
for c.NextBlock() {
switch v := c.Val(); v {
case "net":
for _, arg := range c.RemainingArgs() {
_, cidr, err := net.ParseCIDR(arg)
if err != nil {
return config, fmt.Errorf("synthetic: invalid CIDR notation: %v", arg)
}
config.net = append(config.net, cidr)
}
case "forward":
args := c.RemainingArgs()
if len(args) > 0 {
config.forward = args[0]
}
case "ttl":
for _, arg := range c.RemainingArgs() {
ttl64, err := strconv.ParseUint(arg, 10, 32)
if err != nil {
return config, fmt.Errorf("synthetic: invalid ttl value: %v", arg)
}
config.ttl = uint32(ttl64)
}
case "prefix":
args := c.RemainingArgs()
if len(args) > 0 {
config.prefix = args[0]
}
default:
return config, c.Errf("unknown property '%s'", v)
}
}
}
// Apply defaults.
if config.prefix == "" {
config.prefix = "ip"
}
if !strings.HasSuffix(config.prefix, "-") {
config.prefix += "-"
}
return config, nil
}