Fix zone list filtering and BIND warning display; add a views guide

- jarl zone list showed only primary zones. zone create binds its --type
  flag (default "primary") to the same variable as list's --type, so the
  default leaked into the list filter and hid hint, secondary and forward
  zones. list now has its own variable. TestListQueries runs list
  commands against a fake server and checks the filters they send.
- named-checkconf/named-checkzone messages are classified by the tool's
  exit code: on success, everything printed is a warning. Warnings such
  as 'both "recursion no;" and "allow-recursion" active' were shown as
  errors. The CLI, jarld check and the web UI now label them as warnings
  and skip the routine "loaded serial" lines.
- The zone_outside_view error points at --adopt-zones.
- docs/views.md: step-by-step split DNS for a server that has no views
  yet, tested on a copy of a stock Ubuntu 26.04 setup. Linked from the
  README, concepts and validation docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
abrown38andClaude Opus 5.5 committed 2026-10-07 15:36:24 +00:00
1 parent 3c73afe0e1
commit 0795a1001e
13 files changed
+261 -26

No files matched your search

+41
View File
@@ -2,6 +2,10 @@ package main
import (
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"path/filepath"
"testing"
"go.yaml.in/yaml/v3"
@@ -102,3 +106,40 @@ func TestListValue(t *testing.T) {
t.Errorf("listValue = %q", got)
}
}
// TestListQueries runs list commands against a fake server and checks the
// filters they send: flags bound to variables shared between subcommands
// must not leak defaults (zone create's --type primary once hid every
// non-primary zone from 'zone list').
func TestListQueries(t *testing.T) {
var got string
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
got = r.URL.Path + "?" + r.URL.RawQuery
w.Header().Set("Content-Type", "application/json")
w.Write([]byte("[]"))
}))
defer srv.Close()
t.Setenv("JARL_CLI_CONFIG", filepath.Join(t.TempDir(), "cli.yaml"))
for _, tc := range []struct {
args []string
want string
}{
{[]string{"zone", "list"}, "/api/v1/zones?"},
{[]string{"zone", "list", "--type", "hint"}, "/api/v1/zones?type=hint"},
{[]string{"zone", "list", "--view", "internal"}, "/api/v1/zones?view=internal"},
{[]string{"changeset", "list"}, "/api/v1/changesets?status=open"},
{[]string{"option", "list", "--all"}, "/api/v1/options?"},
} {
got = ""
root := rootCmd()
root.SetArgs(append(tc.args, "--server", srv.URL, "--token", "jarl_test_token", "-o", "json"))
root.SetOut(io.Discard)
if err := root.Execute(); err != nil {
t.Errorf("%v: %v", tc.args, err)
continue
}
if got != tc.want {
t.Errorf("%v sent %q, want %q", tc.args, got, tc.want)
}
}
}