Zones, address redirects, inline rules, lists and groups are cluster objects now (see the previous commits and deploy/MIGRATION.md), so the mechanisms that held them are gone: * internal/kubezones and the resolver's service-account access to a ConfigMap, the address-overrides read/write path and its poller, the zone-file poller and the Local zones editor with its /api/local-zones routes. * localzone.Managed, the directory of console-written master files, and the blocklist.managed_zones key. The resolver now writes no zone data at all; its zone hooks only list. The shared half of that file (the record validator, the renderer and the round-trip check) stays as zonestate.go, because DNSZone rendering is built on it. Its tests are ported to RenderZone, which keeps the coverage of every editable record type, wildcards, relative owners, the SOA/NS rule and the delegation rule. * Tests of the removed write paths: the contract test now builds its zone from a DNSZone, and a new test pins that every zone write route on the resolver is refused and changes nothing. Standalone installs keep editing master files on disk and SIGHUP, and the YAML-backed domain, client, upstream and settings editors, which have not moved. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
52 lines
1.5 KiB
Go
52 lines
1.5 KiB
Go
package app
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"git.k8s-git-k6n.net/mats/fancy-dns/internal/api"
|
|
"git.k8s-git-k6n.net/mats/fancy-dns/internal/localzone"
|
|
)
|
|
|
|
// The resolver only reads zones. Master files from blocklist.local_zones and the
|
|
// rendered DNSZone objects are compiled into one store; editing is the
|
|
// console's job and happens on the objects.
|
|
|
|
// listZones renders the compiled store for the console.
|
|
func (a *App) listZones() (any, error) {
|
|
// The zones that can be edited are the DNSZone objects, which the Kubernetes
|
|
// source renders into a directory of its own. The resolver itself writes
|
|
// nothing; the console, which can, reports the zones writable.
|
|
dir := a.kubeZoneDir()
|
|
store := a.local.Get()
|
|
// The slices are never nil: the console reads lengths and maps without
|
|
// a null check, and an empty list is a list.
|
|
res := api.ZonesResponse{
|
|
Zones: []api.Zone{},
|
|
Files: []string{},
|
|
ManagedDir: dir,
|
|
Writable: false,
|
|
Types: localzone.EditableTypes(),
|
|
}
|
|
if store != nil {
|
|
res.Files = store.Files()
|
|
res.BuiltAt = store.BuiltAt()
|
|
for _, zone := range store.SnapshotAll(dir) {
|
|
res.Zones = append(res.Zones, *zone)
|
|
res.Records += zone.RecordCount
|
|
}
|
|
}
|
|
res.Error = a.localZoneError()
|
|
return res, nil
|
|
}
|
|
|
|
// localZoneError is the reason the store is stale, or "" when it is current.
|
|
// It comes from the degraded list, so the console and /healthz agree.
|
|
func (a *App) localZoneError() string {
|
|
for _, d := range a.Degraded() {
|
|
if rest, ok := strings.CutPrefix(d, "local zones: "); ok {
|
|
return rest
|
|
}
|
|
}
|
|
return ""
|
|
}
|