Fix build and polish codebase to OSS quality
Synthetic CoreDNS Plugin CI/CD Build / test (push) Has been cancelled

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>
This commit is contained in:
Donavan Fritz
2026-04-05 13:33:25 -05:00
parent d9e08599cd
commit ff3ec65719
5 changed files with 515 additions and 504 deletions
+79 -64
View File
@@ -2,82 +2,42 @@ package synthetic
import (
"fmt"
"github.com/coredns/caddy"
"github.com/coredns/coredns/core/dnsserver"
"github.com/coredns/coredns/plugin"
"net"
"strconv"
"strings"
"github.com/coredns/caddy"
"github.com/coredns/coredns/core/dnsserver"
"github.com/coredns/coredns/plugin"
)
// syntheticConfig holds the configuration options for the synthetic plugin.
// syntheticConfig holds the parsed Corefile configuration for the synthetic plugin.
type syntheticConfig struct {
net []*net.IPNet
// 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 uint32
prefix 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
}
// init registers this plugin.
func init() { plugin.Register("synthetic", setup) }
// setup is the function that gets called when the config parser see the token "synthetic".
// setup parses the Corefile configuration block for the synthetic plugin and
// registers it in the CoreDNS handler chain.
func setup(c *caddy.Controller) error {
var config syntheticConfig
// Parse the configuration file
for c.Next() {
for c.NextBlock() {
switch v := c.Val(); v {
// Configuration for forward lookup zones for which to do resolution
case "net":
args := c.RemainingArgs()
for _, arg := range args {
_, cidr, err := net.ParseCIDR(arg)
if err == nil {
config.net = append(config.net, cidr)
} else {
return fmt.Errorf("synthetic: invalid reverse lookup cidr: %v", arg)
}
}
// Configuration for reverse lookup zones for the forward lookup zone name
case "forward":
args := c.RemainingArgs()
for _, arg := range args {
config.forward = arg
}
// Configuration for the TTL value
case "ttl":
args := c.RemainingArgs()
for _, arg := range args {
ttl64, err := strconv.ParseUint(arg, 10, 32)
if err != nil {
return fmt.Errorf("synthetic: invalid ttl value: %v", arg)
}
config.ttl = uint32(ttl64)
}
// configuration for the prefix value (defaults to `ip`)
case "prefix":
args := c.RemainingArgs()
for _, arg := range args {
config.prefix = arg
}
default:
return c.Errf("unknown property '%s'", v)
}
}
}
if config.prefix == "" {
config.prefix = "ip"
}
if !strings.HasSuffix(config.prefix, "-") {
config.prefix = config.prefix + "-"
config, err := parseConfig(c)
if err != nil {
return err
}
dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler {
@@ -86,3 +46,58 @@ func setup(c *caddy.Controller) error {
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
}