Linked zones: shared records kept in step across views

Zones of the same name in different views can be linked. Shared records
are kept in step: a change in one view reaches the others in the same
changeset, as explicit operations, so the diff, permission checks,
history and undo cover every view. Records local to a view override the
shared records of that name and type there; removing the override brings
the shared ones back, and sharing a view's version makes it every view's.
Each zone keeps its own options, serial and file.

Linking existing zones changes no answer: what is the same everywhere
becomes shared, the rest stays local. Unlinking keeps every record, all
local. ACME challenges are written once per link, and --view all changes
a link once. jarl zone link/unlink, zone create --link-with, record
--local/--shared, LINK column, web UI controls, POST /zones/{zone}/link
and /unlink, validation checks linked_*, store migration 11, docs and
e2e.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adamandClaude Opus 5.5 committed 2026-10-12 15:53:58 +01:00
1 parent 6313fa51f8
commit 057433c198
31 files changed
+1729 -55

No files matched your search

+15
View File
@@ -342,6 +342,21 @@ registrar_error`.
### Records
In a linked zone ([views.md](views.md#linked-zones)), records carry
`shared_id` and `linked` (`shared` or `local`). Creating, updating
(`PATCH /records/{id}`) and setting (`PUT .../rrsets/...`) take `"local":
true` (this view only, an override) or `false` (shared; on an update or a
set it makes this view's version every view's). Zones carry `link_group`
and `linked_with` (the other views).
| Method | Path | Body |
|--------|------|------|
| POST | `/zones/{zone}/link` | `{"with": ["external"]}` (default: every view with that zone). Names and types that are the same everywhere become shared, the rest stay local |
| POST | `/zones/{zone}/unlink` | Takes the zone out of its link; its records stay, all local |
`POST /zones` takes `"link_with": "VIEW"` to create a zone linked with
that view's zone of the same name.
| Method | Path | Body / query |
|--------|------|--------------|
| GET | `/zones/{zone}/records` | `?name=`, `?type=`, `?q=`, `?disabled=1` (only disabled records) or `0` (only enabled ones) |