Files
bind-operator/internal/bind/nsupdate_test.go
T
unkin-agent cc714dc2b4
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
apply records before the apex NS, so in-zone glue exists first
named rejects an apex NS pointing at an in-zone name with no address record,
so the glue has to land in an earlier transaction.
2026-09-26 19:41:53 +10:00

65 lines
2.2 KiB
Go

package bind
import (
"strings"
"testing"
)
func TestNSUpdateScriptReplaceSemantics(t *testing.T) {
got := nsupdateScript("acme.unkin.net", []RecordUpdate{
{FQDN: "www", Type: "A", TTL: 60, Values: []string{"10.0.0.1", "10.0.0.2"}},
{FQDN: "old.acme.unkin.net.", Type: "TXT", Delete: true},
})
want := `server 127.0.0.1
zone acme.unkin.net.
update delete www. A
update add www. 60 A 10.0.0.1
update add www. 60 A 10.0.0.2
update delete old.acme.unkin.net. TXT
send
`
if got != want {
t.Errorf("got:\n%s\nwant:\n%s", got, want)
}
}
// At the apex BIND ignores an RRset-wide delete of NS, so the apex sync must add
// the new names and delete the old ones record by record, adds first: named
// refuses to leave an apex with no NS record.
func TestNSUpdateScriptPerValueApexNS(t *testing.T) {
got := nsupdateScript("acme.unkin.net", []RecordUpdate{
{FQDN: "acme.unkin.net.", Type: "NS", TTL: 60, Values: []string{"acme-ns1.unkin.net."}, PerValue: true},
{FQDN: "acme.unkin.net.", Type: "NS", Values: []string{"ns1.acme.unkin.net."}, PerValue: true, Delete: true},
{FQDN: "ns1.acme.unkin.net.", Type: "A", Delete: true},
})
want := `server 127.0.0.1
zone acme.unkin.net.
update add acme.unkin.net. 60 NS acme-ns1.unkin.net.
update delete acme.unkin.net. NS ns1.acme.unkin.net.
update delete ns1.acme.unkin.net. A
send
`
if got != want {
t.Errorf("got:\n%s\nwant:\n%s", got, want)
}
}
func TestParseDigNames(t *testing.T) {
cases := []struct {
name, out, want string
}{
{"answers", "a.ns.unkin.net.\nb.ns.unkin.net.\n", "a.ns.unkin.net.,b.ns.unkin.net."},
{"REFUSED, SERVFAIL and NXDOMAIN all answer empty", "", ""},
// A zone behind a key-matched view answers an unsigned query REFUSED, and
// dig reports the key problem on a ';' line that happens to end in a dot.
{"dig diagnostics are not answers", ";; WARNING -- TSIG key was not used.\n", ""},
{"relative or partial lines are not names", "10.0.0.1\nns1\n", ""},
{"whitespace is trimmed", " ns1.unkin.net. \n\n", "ns1.unkin.net."},
}
for _, c := range cases {
if got := strings.Join(parseDigNames(c.out), ","); got != c.want {
t.Errorf("%s: parseDigNames(%q) = %q; want %q", c.name, c.out, got, c.want)
}
}
}