primeiro commit

This commit is contained in:
2026-06-18 22:32:42 -03:00
commit 968f4ef5d9
25 changed files with 3222 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
{{ define "layout" }}
<!doctype html>
<html lang="en" data-bs-theme="light">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ .Title }} - AehooDNS</title>
<link rel="stylesheet" href="/static/vendor/tabler.min.css">
<link rel="stylesheet" href="/static/app.css">
</head>
<body class="layout-fluid">
<div class="page">
<header class="navbar navbar-expand-md d-print-none">
<div class="container-xl">
<h1 class="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0 pe-md-3">
<a href="/">AehooDNS</a>
</h1>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar-menu" aria-controls="navbar-menu" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbar-menu">
<div class="navbar-nav">
<a class="nav-link" href="/">
<span class="nav-link-title">Dashboard</span>
</a>
<a class="nav-link" href="/zones">
<span class="nav-link-title">Zones</span>
</a>
</div>
{{ if .AuthEnabled }}
{{ if .CurrentUser }}
<div class="navbar-nav ms-auto">
<span class="nav-link text-secondary">{{ .CurrentUser }}</span>
<a class="nav-link" href="/logout">
<span class="nav-link-title">Logout</span>
</a>
</div>
{{ end }}
{{ end }}
</div>
</div>
</header>
<div class="page-wrapper">
<main class="page-body">
<div class="container-xl">
{{ if .Error }}
<div class="alert alert-danger" role="alert">{{ .Error }}</div>
{{ end }}
{{ template "content" . }}
</div>
</main>
</div>
</div>
<script src="/static/vendor/tabler.min.js"></script>
</body>
</html>
{{ end }}

View File

@@ -0,0 +1,69 @@
{{ define "content" }}
<div class="page-header d-print-none">
<div class="row align-items-center">
<div class="col">
<div class="page-pretitle">PowerDNS</div>
<h2 class="page-title">Dashboard</h2>
</div>
</div>
</div>
<div class="row row-deck row-cards mb-3">
<div class="col-sm-6 col-lg-3">
<div class="card">
<div class="card-body">
<div class="subheader">Server ID</div>
<div class="h2 mb-0 text-truncate">{{ .Server.ID }}</div>
</div>
</div>
</div>
<div class="col-sm-6 col-lg-3">
<div class="card">
<div class="card-body">
<div class="subheader">Daemon</div>
<div class="h2 mb-0 text-truncate">{{ .Server.DaemonType }}</div>
</div>
</div>
</div>
<div class="col-sm-6 col-lg-3">
<div class="card">
<div class="card-body">
<div class="subheader">Version</div>
<div class="h2 mb-0 text-truncate">{{ .Server.Version }}</div>
</div>
</div>
</div>
<div class="col-sm-6 col-lg-3">
<div class="card">
<div class="card-body">
<div class="subheader">Zones</div>
<div class="h2 mb-0">{{ len .Zones }}</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h3 class="card-title">Recent zones</h3>
</div>
{{ if .Zones }}
<div class="list-group list-group-flush">
{{ range .Zones }}
<a class="list-group-item list-group-item-action" href="/zones/{{ .ID }}">
<div class="row align-items-center">
<div class="col text-truncate">
<strong>{{ .Name }}</strong>
<div class="text-secondary text-truncate">{{ .DisplayKind }} · serial {{ .Serial }}</div>
</div>
</div>
</a>
{{ end }}
</div>
{{ else }}
<div class="card-body text-secondary">No zones returned by PowerDNS.</div>
{{ end }}
</div>
{{ end }}
{{ template "layout" . }}

View File

@@ -0,0 +1,25 @@
{{ define "content" }}
<div class="row justify-content-center">
<div class="col-md-6 col-lg-4">
<div class="card card-md">
<div class="card-body">
<h2 class="h2 text-center mb-2">Login</h2>
<form method="post" action="/login">
<input type="hidden" name="next" value="{{ .Next }}">
<div class="mb-3">
<label class="form-label">Username</label>
<input class="form-control" name="username" autocomplete="username" required autofocus>
</div>
<div class="mb-3">
<label class="form-label">Password</label>
<input class="form-control" name="password" type="password" autocomplete="current-password" required>
</div>
<button class="btn btn-primary w-100" type="submit">Sign in</button>
</form>
</div>
</div>
</div>
</div>
{{ end }}
{{ template "layout" . }}

View File

@@ -0,0 +1,63 @@
{{ define "content" }}
<div class="page-header d-print-none">
<div class="row align-items-center">
<div class="col">
<div class="page-pretitle">{{ .Zone.Name }}</div>
<h2 class="page-title">{{ .RecordForm.Title }}</h2>
</div>
<div class="col-auto ms-auto">
<a class="btn btn-outline-secondary" href="/zones/{{ .ZoneID }}">Back to records</a>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card">
<div class="card-body">
{{ if .RecordForm.IsEdit }}
<div class="row mb-4">
<div class="col-sm-8">
<div class="subheader">Name</div>
<div class="h3 mb-0">{{ .RecordForm.Name }}</div>
</div>
<div class="col-sm-4">
<div class="subheader">Type</div>
<div class="h3 mb-0">{{ .RecordForm.Type }}</div>
</div>
</div>
{{ end }}
<form method="post" action="{{ if .RecordForm.IsEdit }}/zones/{{ .ZoneID }}/rrsets/edit?name={{ urlQuery .RecordForm.Name }}&type={{ urlQuery .RecordForm.Type }}{{ else }}/zones/{{ .ZoneID }}/rrsets{{ end }}">
{{ if not .RecordForm.IsEdit }}
<div class="mb-3">
<label class="form-label">Name</label>
<input class="form-control" name="name" value="{{ .RecordForm.Name }}" placeholder="www.{{ .Zone.Name }}" required>
</div>
<div class="mb-3">
<label class="form-label">Type</label>
<select class="form-select" name="type" required>
{{ range .RecordTypes }}
<option {{ if eq . $.RecordForm.Type }}selected{{ end }}>{{ . }}</option>
{{ end }}
</select>
</div>
{{ end }}
<div class="mb-3">
<label class="form-label">TTL</label>
<input class="form-control" name="ttl" type="number" min="1" value="{{ .RecordForm.TTL }}" required>
</div>
<div class="mb-3">
<label class="form-label">Records</label>
<textarea class="form-control" name="records" rows="8" placeholder="One record value per line" required>{{ .RecordForm.Records }}</textarea>
<div class="form-hint">Strict formats are enforced. TXT and CAA string values must be quoted. Adding A, AAAA, CAA, MX, NS, SRV, or TXT records appends to an existing RRset with the same name and type. SOA records can be edited here but cannot be deleted.</div>
</div>
<button class="btn btn-primary" type="submit">{{ .RecordForm.SubmitLabel }}</button>
</form>
</div>
</div>
</div>
</div>
{{ end }}
{{ template "layout" . }}

View File

@@ -0,0 +1,70 @@
{{ define "content" }}
<div class="page-header d-print-none">
<div class="row align-items-center">
<div class="col">
<div class="page-pretitle">Zone</div>
<h2 class="page-title">{{ .Zone.Name }}</h2>
<div class="text-secondary">{{ len .Zone.RRSets }} RRsets</div>
</div>
<div class="col-auto ms-auto">
<div class="btn-list">
<a class="btn btn-outline-secondary" href="/zones">Back to zones</a>
<a class="btn btn-primary" href="/zones/{{ .ZoneID }}/rrsets/new">Add record</a>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h3 class="card-title">Records</h3>
</div>
{{ if .Zone.RRSets }}
<div class="table-responsive">
<table class="table table-vcenter card-table">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>TTL</th>
<th>Records</th>
<th class="w-1"></th>
</tr>
</thead>
<tbody>
{{ range .Zone.RRSets }}
<tr>
<td class="text-nowrap">{{ .Name }}</td>
<td><span class="badge bg-azure-lt">{{ .Type }}</span></td>
<td>{{ .TTL }}</td>
<td>
<div class="record-values">
{{ range .Records }}
<div><code>{{ .Content }}</code></div>
{{ end }}
</div>
</td>
<td>
<div class="btn-list flex-nowrap">
<a class="btn btn-outline-primary btn-sm" href="/zones/{{ $.ZoneID }}/rrsets/edit?name={{ urlQuery .Name }}&type={{ urlQuery .Type }}">Edit</a>
{{ if not (isSOA .Type) }}
<form method="post" action="/zones/{{ $.ZoneID }}/rrsets/delete">
<input type="hidden" name="name" value="{{ .Name }}">
<input type="hidden" name="type" value="{{ .Type }}">
<button class="btn btn-outline-danger btn-sm" type="submit">Delete</button>
</form>
{{ end }}
</div>
</td>
</tr>
{{ end }}
</tbody>
</table>
</div>
{{ else }}
<div class="card-body text-secondary">No records returned for this zone.</div>
{{ end }}
</div>
{{ end }}
{{ template "layout" . }}

View File

@@ -0,0 +1,86 @@
{{ define "content" }}
<div class="page-header d-print-none">
<div class="row align-items-center">
<div class="col">
<div class="page-pretitle">Authoritative DNS</div>
<h2 class="page-title">Zones</h2>
<div class="text-secondary">{{ len .Zones }} zones loaded from PowerDNS.</div>
</div>
</div>
</div>
<div class="row row-cards">
<div class="col-lg-8">
<div class="card">
<div class="card-header">
<h3 class="card-title">Existing zones</h3>
</div>
{{ if .Zones }}
<div class="table-responsive">
<table class="table table-vcenter card-table">
<thead>
<tr>
<th>Name</th>
<th>Kind</th>
<th>Serial</th>
<th class="w-1"></th>
</tr>
</thead>
<tbody>
{{ range .Zones }}
<tr>
<td><a href="/zones/{{ .ID }}">{{ .Name }}</a></td>
<td><span class="badge bg-blue-lt">{{ .DisplayKind }}</span></td>
<td>{{ .Serial }}</td>
<td>
<form method="post" action="/zones/{{ .ID }}/delete">
<button class="btn btn-outline-danger btn-sm" type="submit">Delete</button>
</form>
</td>
</tr>
{{ end }}
</tbody>
</table>
</div>
{{ else }}
<div class="card-body text-secondary">No zones returned by PowerDNS.</div>
{{ end }}
</div>
</div>
<div class="col-lg-4">
<div class="card">
<div class="card-header">
<h3 class="card-title">Add zone</h3>
</div>
<div class="card-body">
<form method="post" action="/zones">
<div class="mb-3">
<label class="form-label">Zone name</label>
<input class="form-control" name="name" placeholder="example.org." required>
</div>
<div class="mb-3">
<label class="form-label">Kind</label>
<select class="form-select" name="kind" required>
<option>Native</option>
<option>Master</option>
<option>Slave</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Nameservers</label>
<textarea class="form-control" name="nameservers" rows="4" placeholder="ns1.example.org.&#10;ns2.example.org."></textarea>
</div>
<div class="mb-3">
<label class="form-label">Masters</label>
<textarea class="form-control" name="masters" rows="3" placeholder="Required for Slave zones"></textarea>
</div>
<button class="btn btn-primary" type="submit">Create zone</button>
</form>
</div>
</div>
</div>
</div>
{{ end }}
{{ template "layout" . }}