milestone 8: web server, rest api, sse, auth, metrics and static assets

This commit is contained in:
2026-08-02 00:54:13 +02:00
parent a8092bb1b9
commit 5253c47303
59 changed files with 19640 additions and 150 deletions
+59
View File
@@ -0,0 +1,59 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>nxdns</title>
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<style>
body { font: 16px/1.5 system-ui, sans-serif; margin: 0; background: #101418; color: #d8dee6; }
main { max-width: 40rem; margin: 4rem auto; padding: 0 1.5rem; }
h1 { font-size: 1.5rem; margin: 0 0 0.25rem; }
h1 + p { margin-top: 0; color: #8b98a8; }
dl { display: grid; grid-template-columns: max-content 1fr; gap: 0.25rem 1.5rem; background: #171d24; border: 1px solid #232c36; border-radius: 8px; padding: 1rem 1.25rem; }
dt { color: #8b98a8; }
dd { margin: 0; font-variant-numeric: tabular-nums; }
.ok { color: #6fce8f; }
.degraded { color: #e0b25b; }
.unreachable { color: #e07a6c; }
nav { margin-top: 1.5rem; }
nav a { color: #7fb3e8; margin-right: 1.25rem; }
</style>
</head>
<body>
<main>
<h1>nxdns</h1>
<p>DNS sinkhole — the admin interface ships in a later release.</p>
<dl>
<dt>Status</dt><dd id="status">loading…</dd>
<dt>Upstreams</dt><dd id="upstreams"></dd>
<dt>Disk</dt><dd id="disk"></dd>
<dt>Version</dt><dd id="version"></dd>
</dl>
<nav>
<a href="/metrics">Metrics</a>
<a href="/api/health">Health</a>
<a href="/api/openapi.yaml">API reference</a>
</nav>
</main>
<script>
const el = (id) => document.getElementById(id);
fetch("/api/health")
.then((r) => r.json())
.then((h) => {
el("status").textContent = h.status;
el("status").className = h.status === "ok" ? "ok" : "degraded";
el("upstreams").textContent = h.upstreams.available + " of " + h.upstreams.total + " available";
el("disk").textContent = h.disk.state + ", " + Math.round(h.disk.free_bytes / 1048576) + " MiB free";
})
.catch(() => {
el("status").textContent = "unreachable";
el("status").className = "unreachable";
});
fetch("/api/version")
.then((r) => r.json())
.then((v) => { el("version").textContent = v.version + " (" + v.git_commit + ")"; })
.catch(() => {});
</script>
</body>
</html>