package validate import ( "testing" "jarl/internal/model" ) func TestDNSSEC(t *testing.T) { b := newBuilder() ok := b.primary("signed.example", nil) ok.DNSSECPolicy = model.DNSSECDefault ps := State(b.s, Options{}) if len(codes(ps, Error)) != 0 { t.Fatalf("a signed zone: %v", ps) } sec := b.zone("copy.example", nil, model.ZoneSecondary) b.opt(model.ScopeZone, sec.ID, "primaries", "{ 192.0.2.1; }") sec.DNSSECPolicy = model.DNSSECDefault unknown := b.primary("custom.example", nil) unknown.DNSSECPolicy = "fast" long := b.primary("long.example", nil) long.DNSSECPolicy = model.DNSSECInsecure r := b.rec(long, "www", "A", "192.0.2.80") r.TTL = model.Ptr(uint32(172800)) b.opt(model.ScopeZone, ok.ID, "inline-signing", "no") ps = State(b.s, Options{}) for _, c := range []string{"dnssec_zone_type", "dnssec_policy_unknown", "dnssec_ttl_too_long", "dnssec_inline_signing"} { if !hasCode(ps, c) { t.Errorf("missing %s in %v", c, ps) } } // A custom policy: its max-zone-ttl applies; an empty keys list would // crash named. b2 := newBuilder() z := b2.primary("custom.example", nil) z.DNSSECPolicy = "fast" z.DefaultTTL = 600 b2.opt(model.ScopeTopLevel, 0, "dnssec-policy", `fast { keys { csk lifetime unlimited algorithm 13; }; max-zone-ttl PT5M; }`) b2.opt(model.ScopeTopLevel, 0, "dnssec-policy", `"off" { keys { }; }`) ps = State(b2.s, Options{}) if !hasCode(ps, "dnssec_ttl_too_long") || !hasCode(ps, "dnssec_policy_no_keys") || hasCode(ps, "dnssec_policy_unknown") { t.Errorf("custom policy: %v", ps) } // dnssec-policy is set per zone in Jarl, not as an option. b3 := newBuilder() z = b3.primary("example.com", nil) b3.opt(model.ScopeZone, z.ID, "dnssec-policy", "default") b3.opt(model.ScopeOptions, 0, "dnssec-policy", "default") b3.opt(model.ScopeZone, z.ID, "key-directory", `"/tmp"`) if n := len(codes(State(b3.s, Options{}), Error)); n != 3 { t.Errorf("managed options: %v", State(b3.s, Options{})) } } func TestParseDuration(t *testing.T) { for in, want := range map[string]uint32{"86400": 86400, "P1D": 86400, "PT5M": 300, "P1W": 604800, "1d": 86400, "12h30m": 45000, "pt1h": 3600} { if got, ok := parseDuration(in); !ok || got != want { t.Errorf("parseDuration(%q) = %d %v, want %d", in, got, ok, want) } } for _, bad := range []string{"", "P", "unlimited", "1x"} { if _, ok := parseDuration(bad); ok { t.Errorf("parseDuration(%q) accepted", bad) } } }