Files
vibedns/web/templates/pages/zone_form.html
T
owenandClaude Sonnet 5 b9cfe5ddce Add extended forward zone type for overriding public domain records
An extended zone answers authoritatively only for the records it holds
locally; any name with nothing configured falls through to recursive
resolution instead of a synthesized NXDOMAIN, so a public domain's
records don't need to be duplicated just to override a few of them.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V8c76Xr2BycaHHu5N4buqi
2026-08-20 17:35:41 -05:00

203 lines
9.3 KiB
HTML

{{define "content"}}
{{$z := .Data.Zone}}{{$new := .Data.IsNew}}{{$kind := .Data.Kind}}
{{$isReverse := hasPrefix $kind "reverse"}}
<nav aria-label="breadcrumb">
<ol class="breadcrumb small">
<li class="breadcrumb-item">
<a href="{{if $isReverse}}/zones/reverse{{else}}/zones{{end}}">
{{if $isReverse}}Reverse Zones{{else}}Forward Zones{{end}}
</a>
</li>
<li class="breadcrumb-item active" aria-current="page">
{{if $new}}New zone{{else}}{{trimDot $z.Name}}{{end}}
</li>
</ol>
</nav>
<h1 class="page-title mb-4">{{if $new}}Create a zone{{else}}Edit {{trimDot $z.Name}}{{end}}</h1>
<form method="post" action="{{.Data.FormAction}}">
<input type="hidden" name="_csrf" value="{{.CSRF}}">
<div class="row g-3">
<div class="col-12 col-xl-8">
<div class="card mb-3">
<div class="card-header">Zone identity</div>
<div class="card-body">
{{if $new}}
<div class="mb-3">
<label class="form-label" for="kindSelect">Zone type</label>
<select class="form-select" id="kindSelect" name="kind">
<option value="forward" {{if eq $kind "forward"}}selected{{end}}>Forward — resolve names to addresses</option>
<option value="extended" {{if eq $kind "extended"}}selected{{end}}>Extended — override records for a domain otherwise resolved on the public DNS</option>
<option value="reverse4" {{if eq $kind "reverse4"}}selected{{end}}>Reverse IPv4 — resolve addresses back to names</option>
<option value="reverse6" {{if eq $kind "reverse6"}}selected{{end}}>Reverse IPv6 — resolve addresses back to names</option>
</select>
</div>
{{if $isReverse}}
<div class="mb-3">
<label class="form-label" for="reverseCidr">Subnet</label>
<input type="text" class="form-control mono" id="reverseCidr" name="cidr"
placeholder="192.168.1.0/24" autocomplete="off">
<div class="form-text" id="reversePreview"></div>
<div class="form-text">
Enter the subnet and the matching <code>in-addr.arpa</code> or <code>ip6.arpa</code>
zone name is worked out for you. Leave the zone name below blank to use it.
</div>
</div>
{{end}}
{{else}}
<input type="hidden" name="kind" value="{{$kind}}">
{{end}}
{{if eq $kind "extended"}}
<div class="alert alert-info small mb-3">
An extended zone answers locally only for the records you add below. Any other
name or record type under this zone is forwarded to the public DNS, and only
fails if the internet lookup also fails.
</div>
{{end}}
<div class="mb-3">
<label class="form-label" for="zoneName">
Zone name {{if and $new $isReverse}}<span class="text-body-secondary fw-normal">(optional if a subnet is given)</span>{{end}}
</label>
<input type="text" class="form-control mono" id="zoneName" name="name"
value="{{trimDot $z.Name}}" placeholder="example.com"
{{if not $isReverse}}required{{end}} autocomplete="off">
<div class="form-text">The apex of the zone. A trailing dot is added automatically.</div>
</div>
<div class="mb-3">
<label class="form-label" for="zoneDescription">Description</label>
<input type="text" class="form-control" id="zoneDescription" name="description"
value="{{$z.Description}}" placeholder="What this zone is for">
</div>
<div class="form-check form-switch">
<input type="hidden" name="enabled" value="false">
<input class="form-check-input" type="checkbox" role="switch" id="zoneEnabled"
name="enabled" value="true" {{if or $new $z.Enabled}}checked{{end}}>
<label class="form-check-label" for="zoneEnabled">
Enabled — the server answers authoritatively for this zone
</label>
</div>
</div>
</div>
<div class="card mb-3">
<div class="card-header">Start of authority</div>
<div class="card-body">
<p class="text-body-secondary small">
The SOA record is maintained for you. These values are what it will contain.
</p>
<div class="row g-3">
<div class="col-12 col-md-6">
<label class="form-label" for="primaryNS">Primary name server</label>
<input type="text" class="form-control mono" id="primaryNS" name="primary_ns"
value="{{trimDot $z.PrimaryNS}}" placeholder="ns1.example.com">
</div>
<div class="col-12 col-md-6">
<label class="form-label" for="adminEmail">Responsible email</label>
<input type="text" class="form-control" id="adminEmail" name="admin_email"
value="{{$z.AdminEmail}}" placeholder="hostmaster@example.com">
<div class="form-text">Stored in the SOA in its DNS form.</div>
</div>
<div class="col-6 col-md-3">
<label class="form-label" for="defaultTTL">Default TTL</label>
<input type="number" class="form-control" id="defaultTTL" name="default_ttl"
value="{{default 3600 $z.DefaultTTL}}" min="1" max="604800" required>
<div class="form-text">Seconds</div>
</div>
<div class="col-6 col-md-3">
<label class="form-label" for="refresh">Refresh</label>
<input type="number" class="form-control" id="refresh" name="refresh"
value="{{default 7200 $z.Refresh}}" min="1">
</div>
<div class="col-6 col-md-3">
<label class="form-label" for="retry">Retry</label>
<input type="number" class="form-control" id="retry" name="retry"
value="{{default 3600 $z.Retry}}" min="1">
</div>
<div class="col-6 col-md-3">
<label class="form-label" for="expire">Expire</label>
<input type="number" class="form-control" id="expire" name="expire"
value="{{default 1209600 $z.Expire}}" min="1">
</div>
<div class="col-6 col-md-3">
<label class="form-label" for="minimum">Negative TTL</label>
<input type="number" class="form-control" id="minimum" name="minimum"
value="{{default 3600 $z.Minimum}}" min="1">
<div class="form-text">SOA minimum</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-12 col-xl-4">
<div class="card mb-3">
<div class="card-header">Serial number</div>
<div class="card-body">
<div class="mb-3">
<div class="text-body-secondary small">Current serial</div>
<div class="fs-4 fw-semibold mono">{{default 1 $z.Serial}}</div>
</div>
<div class="form-check form-switch mb-3">
<input type="hidden" name="auto_serial" value="false">
<input class="form-check-input" type="checkbox" role="switch" id="autoSerial"
name="auto_serial" value="true" {{if or $new $z.AutoSerial}}checked{{end}}>
<label class="form-check-label" for="autoSerial">Increment automatically</label>
<div class="form-text">
The serial advances on every record change, which is what secondary servers
watch to know a zone was updated.
</div>
</div>
<div class="form-check mb-2">
<input type="hidden" name="override_serial" value="false">
<input class="form-check-input" type="checkbox" id="overrideSerial"
name="override_serial" value="true">
<label class="form-check-label" for="overrideSerial">Set the serial manually</label>
</div>
<input type="number" class="form-control mono" name="serial"
value="{{default 1 $z.Serial}}" min="1" max="4294967295"
aria-label="Manual serial number">
<div class="form-text">
Only needed when migrating a zone from another server that is already at a
higher serial. Tick the box above for this value to be used.
</div>
</div>
</div>
{{if not $new}}
<div class="card mb-3">
<div class="card-header">Zone file</div>
<div class="card-body d-grid gap-2">
<a href="/zones/{{$z.ID}}/export" class="btn btn-outline-secondary btn-sm">
<i class="bi bi-download me-1"></i>Export as BIND zone file
</a>
<a href="/zones/{{$z.ID}}" class="btn btn-outline-secondary btn-sm">
<i class="bi bi-list-ul me-1"></i>Manage records
</a>
</div>
</div>
{{end}}
<div class="card">
<div class="card-body d-grid gap-2">
<button type="submit" class="btn btn-primary">
<i class="bi bi-check-lg me-1"></i>{{if $new}}Create zone{{else}}Save changes{{end}}
</button>
<a href="{{if $isReverse}}/zones/reverse{{else}}/zones{{end}}" class="btn btn-outline-secondary">Cancel</a>
</div>
</div>
</div>
</div>
</form>
{{end}}