96 lines
4.1 KiB
HTML
96 lines
4.1 KiB
HTML
{{define "content"}}
|
|
{{$csrf := .CSRF}}
|
|
|
|
<div class="d-flex flex-wrap justify-content-between align-items-start gap-3 mb-4">
|
|
<div>
|
|
<h1 class="page-title">Policy Rules</h1>
|
|
<p class="text-body-secondary mb-0">
|
|
A policy pairs a set of blacklists and allowlists with what to do when a name matches.
|
|
</p>
|
|
</div>
|
|
<a href="/policies/rules/new" class="btn btn-primary btn-sm">
|
|
<i class="bi bi-plus-lg me-1"></i>Add Policy
|
|
</a>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-body">
|
|
{{if .Data.Policies}}
|
|
<div class="table-responsive">
|
|
<table class="table table-hover align-middle">
|
|
<thead>
|
|
<tr>
|
|
<th>Policy</th><th>Blocks</th><th>Allows</th>
|
|
<th>Action</th><th class="text-end">Networks</th>
|
|
<th>Status</th><th class="row-actions">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .Data.Policies}}
|
|
<tr {{if not .Enabled}}class="is-disabled"{{end}}>
|
|
<td>
|
|
<a href="/policies/rules/{{.ID}}" class="fw-semibold text-decoration-none">{{.Name}}</a>
|
|
{{if .Description}}<div class="small text-body-secondary">{{truncate 70 .Description}}</div>{{end}}
|
|
</td>
|
|
<td>
|
|
{{if .BlacklistName}}
|
|
<div class="d-flex flex-wrap gap-1">
|
|
{{range .BlacklistName}}
|
|
<span class="badge text-bg-danger-subtle border border-danger-subtle text-danger-emphasis">{{.}}</span>
|
|
{{end}}
|
|
</div>
|
|
{{else}}<span class="text-body-secondary small">—</span>{{end}}
|
|
</td>
|
|
<td>
|
|
{{if .AllowlistName}}
|
|
<div class="d-flex flex-wrap gap-1">
|
|
{{range .AllowlistName}}
|
|
<span class="badge text-bg-success-subtle border border-success-subtle text-success-emphasis">{{.}}</span>
|
|
{{end}}
|
|
</div>
|
|
{{else}}<span class="text-body-secondary small">—</span>{{end}}
|
|
</td>
|
|
<td>
|
|
<span class="badge text-bg-light text-dark">{{.BlockAction.Label}}</span>
|
|
{{if eq (printf "%s" .BlockAction) "sinkhole"}}
|
|
<div class="small text-body-secondary mono">{{.SinkholeIPv4}} / {{.SinkholeIPv6}}</div>
|
|
{{end}}
|
|
</td>
|
|
<td class="text-end">{{.NetworkCount}}</td>
|
|
<td><span class="badge {{badgeFor .Enabled}}">{{statusWord .Enabled}}</span></td>
|
|
<td class="row-actions">
|
|
<div class="btn-group">
|
|
<a href="/policies/rules/{{.ID}}" class="btn btn-sm btn-outline-secondary" title="Edit policy">
|
|
<i class="bi bi-pencil"></i>
|
|
</a>
|
|
{{template "postform" dict
|
|
"Action" (printf "/policies/rules/%d/toggle" .ID) "CSRF" $csrf
|
|
"ReturnTo" "/policies"
|
|
"Fields" (dict "enabled" (boolstr (not .Enabled)))
|
|
"Icon" (toggleIcon .Enabled)
|
|
"Class" "btn btn-sm btn-outline-secondary"
|
|
"Title" (printf "%s this policy" (toggleVerb .Enabled))}}
|
|
{{template "confirmform" dict
|
|
"Action" (printf "/policies/rules/%d/delete" .ID) "CSRF" $csrf
|
|
"Icon" "bi-trash"
|
|
"Message" (printf "Delete the policy %q? It will be removed from %d network(s)." .Name .NetworkCount)}}
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{{else}}
|
|
{{template "empty" dict "Icon" "bi-sliders" "Title" "No policies yet"
|
|
"Message" "A policy decides what happens when a query matches one of its blacklists — return NXDOMAIN, refuse the query, or answer with a sinkhole address. Assign the policy to a client network to put it into effect."}}
|
|
<div class="text-center pb-3">
|
|
<a href="/policies/rules/new" class="btn btn-primary">
|
|
<i class="bi bi-plus-lg me-1"></i>Create the first policy
|
|
</a>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
{{end}}
|