Add --bind-conf flag for BIND domains.conf generation
Generate a BIND-format domains.conf file alongside catalog zones. New input properties: file= (zone data path) and dnssec (bare flag). When --bind-conf is set, every zone must have file= or it errors. Renames ZoneEntry.File to ZonesFile (input path for error messages) and adds ZoneFile (BIND file path) and DNSSEC (bool) fields.
This commit is contained in:
64
bindconf.go
Normal file
64
bindconf.go
Normal file
@@ -0,0 +1,64 @@
|
||||
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 {
|
||||
// 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()
|
||||
}
|
||||
|
||||
// validateBindConf checks that every zone entry has a non-empty ZoneFile.
|
||||
func validateBindConf(entries []ZoneEntry) error {
|
||||
for _, entry := range entries {
|
||||
if entry.ZoneFile == "" {
|
||||
return fmt.Errorf("%s:%d: zone %s missing file= property (required for --bind-conf)",
|
||||
entry.ZonesFile, entry.Line, entry.Zone)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// writeBindConf validates entries and writes the BIND config to path.
|
||||
func writeBindConf(path string, entries []ZoneEntry) error {
|
||||
if err := validateBindConf(entries); err != nil {
|
||||
return err
|
||||
}
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user