Files
catz/bindconf_test.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

151 lines
4.3 KiB
Go

package main
import (
"os"
"path/filepath"
"strings"
"testing"
)
func TestGenerateBindConf(t *testing.T) {
entries := []ZoneEntry{
{Zone: "bitcard.org.", ZoneFile: "data/misc/bitcard.org", DNSSEC: true, ZonesFile: "test", Line: 1},
{Zone: "askask.com.", ZoneFile: "data/ask/askask.com", ZonesFile: "test", Line: 2},
}
got := generateBindConf(entries)
// Header
assertContains(t, got, "# THIS FILE IS GENERATED BY catalog-zone-gen")
assertContains(t, got, "#=============================================")
// Zones should be sorted alphabetically (askask.com before bitcard.org)
askIdx := strings.Index(got, "askask.com")
bitIdx := strings.Index(got, "bitcard.org")
if askIdx == -1 || bitIdx == -1 {
t.Fatal("expected both zones in output")
}
if askIdx >= bitIdx {
t.Error("expected askask.com before bitcard.org (alphabetical sort)")
}
// Non-DNSSEC zone
assertContains(t, got, `zone "askask.com" {`)
assertContains(t, got, ` type master;`)
assertContains(t, got, ` file "data/ask/askask.com";`)
// DNSSEC zone has directives on file line
assertContains(t, got, ` file "data/misc/bitcard.org"; dnssec-policy standard; inline-signing yes;`)
// No trailing dot in zone name
if strings.Contains(got, `zone "askask.com."`) {
t.Error("zone name should not have trailing dot in BIND config")
}
}
func TestGenerateBindConfEmpty(t *testing.T) {
got := generateBindConf(nil)
// Should just have the header
lines := splitLines(got)
if len(lines) != 3 {
t.Errorf("expected 3 header lines for empty input, got %d", len(lines))
}
}
func TestGenerateBindConfNoDNSSEC(t *testing.T) {
entries := []ZoneEntry{
{Zone: "example.com.", ZoneFile: "data/example.com", ZonesFile: "test", Line: 1},
}
got := generateBindConf(entries)
if strings.Contains(got, "dnssec-policy") {
t.Error("non-DNSSEC zone should not have dnssec-policy")
}
if strings.Contains(got, "inline-signing") {
t.Error("non-DNSSEC zone should not have inline-signing")
}
}
func TestValidateBindConf(t *testing.T) {
t.Run("all zones have file", func(t *testing.T) {
entries := []ZoneEntry{
{Zone: "a.example.com.", ZoneFile: "data/a", ZonesFile: "zones.txt", Line: 1},
{Zone: "b.example.com.", ZoneFile: "data/b", ZonesFile: "zones.txt", Line: 2},
}
if err := writeBindConf(filepath.Join(t.TempDir(), "domains.conf"), entries); err != nil {
t.Fatalf("unexpected error: %v", err)
}
})
t.Run("zones without file are skipped", func(t *testing.T) {
entries := []ZoneEntry{
{Zone: "a.example.com.", ZoneFile: "data/a", ZonesFile: "zones.txt", Line: 1},
{Zone: "dyn.example.com.", ZoneFile: "", ZonesFile: "zones.txt", Line: 3},
}
dir := t.TempDir()
path := filepath.Join(dir, "domains.conf")
if err := writeBindConf(path, entries); err != nil {
t.Fatalf("unexpected error: %v", err)
}
data, err := os.ReadFile(path)
if err != nil {
t.Fatal(err)
}
got := string(data)
assertContains(t, got, `zone "a.example.com"`)
if strings.Contains(got, "dyn.example.com") {
t.Error("catalog-only zone without file= should not appear in BIND config")
}
})
}
func TestWriteBindConf(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "domains.conf")
entries := []ZoneEntry{
{Zone: "example.com.", ZoneFile: "data/example.com", ZonesFile: "test", Line: 1},
{Zone: "example.org.", ZoneFile: "data/example.org", DNSSEC: true, ZonesFile: "test", Line: 2},
}
if err := writeBindConf(path, entries); err != nil {
t.Fatalf("unexpected error: %v", err)
}
data, err := os.ReadFile(path)
if err != nil {
t.Fatal(err)
}
got := string(data)
assertContains(t, got, `zone "example.com"`)
assertContains(t, got, `zone "example.org"`)
assertContains(t, got, "dnssec-policy standard")
}
func TestWriteBindConfSkipsCatalogOnlyZones(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "domains.conf")
entries := []ZoneEntry{
{Zone: "example.com.", ZoneFile: "", ZonesFile: "zones.txt", Line: 5},
}
if err := writeBindConf(path, entries); err != nil {
t.Fatalf("unexpected error: %v", err)
}
data, err := os.ReadFile(path)
if err != nil {
t.Fatal(err)
}
got := string(data)
// Should have header but no zone blocks
assertContains(t, got, "# THIS FILE IS GENERATED BY catalog-zone-gen")
if strings.Contains(got, "example.com") {
t.Error("zone without file= should not appear in BIND config")
}
}