Files
catz/bindconf.go
Ask Bjørn Hansen 49f7ad2987 Allow catalog-only zones without file= in --bind-conf mode
Zones without a file= property (e.g. ddns zones) are included in
catalog zone output for secondaries but skipped in domains.conf.
Previously --bind-conf required every zone to have file= set.
2026-03-28 11:56:49 -07:00

56 lines
1.5 KiB
Go

package main
import (
"fmt"
"os"
"sort"
"strings"
)
// generateBindConf produces a BIND domains.conf from all zone entries.
// Zones are sorted alphabetically. Each zone block uses 8-space indentation.
// DNSSEC zones get dnssec-policy and inline-signing directives on the file line.
func generateBindConf(entries []ZoneEntry) string {
sorted := make([]ZoneEntry, len(entries))
copy(sorted, entries)
sort.Slice(sorted, func(i, j int) bool {
return sorted[i].Zone < sorted[j].Zone
})
var b strings.Builder
b.WriteString("# THIS FILE IS GENERATED BY catalog-zone-gen\n")
b.WriteString("#=============================================\n")
b.WriteString("#\n")
for _, entry := range sorted {
if entry.ZoneFile == "" {
continue // catalog-only zone, no BIND config needed
}
// Strip trailing dot for BIND zone name
zoneName := strings.TrimSuffix(entry.Zone, ".")
fmt.Fprintf(&b, "zone \"%s\" {\n", zoneName)
b.WriteString(" type master;\n")
fileLine := fmt.Sprintf(" file \"%s\";", entry.ZoneFile)
if entry.DNSSEC {
fileLine += " dnssec-policy standard; inline-signing yes;"
}
b.WriteString(fileLine + "\n")
b.WriteString("};\n")
}
return b.String()
}
// writeBindConf writes the BIND config to path.
// Zones without a ZoneFile are skipped (catalog-only zones).
func writeBindConf(path string, entries []ZoneEntry) error {
content := generateBindConf(entries)
if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
return fmt.Errorf("writing bind config %s: %w", path, err)
}
return nil
}