All checks were successful
Build Docker / BuildImage (push) Successful in 1m0s
128 lines
4.9 KiB
HTML
128 lines
4.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>HNSDoH Status</title>
|
|
<link rel="stylesheet" href="/assets/style.css">
|
|
<link rel="icon" type="image/png" href="/favicon.png">
|
|
</head>
|
|
|
|
<body>
|
|
<div class="container">
|
|
<header>
|
|
<div>
|
|
<h1>HNSDoH Status</h1>
|
|
<div class="meta">Handshake DNS over HTTPS/TLS</div>
|
|
</div>
|
|
<div class="meta">
|
|
Last checked: {{ last_check }}
|
|
</div>
|
|
</header>
|
|
|
|
{% if alerts or warnings %}
|
|
<div class="alerts-section">
|
|
{% for alert in alerts %}
|
|
<div class="alert-box error">{{ alert }}</div>
|
|
{% endfor %}
|
|
{% for warning in warnings %}
|
|
<div class="alert-box warning">{{ warning }}</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<h2>Node Status</h2>
|
|
<div class="node-grid">
|
|
{% for node in nodes %}
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<div>
|
|
<div class="node-name">{{ node.name }}</div>
|
|
<div class="node-location">{{ node.location }}</div>
|
|
</div>
|
|
<div class="node-ip">{{ node.ip }}</div>
|
|
</div>
|
|
|
|
<div class="status-list">
|
|
<div class="status-item">
|
|
<span>Plain DNS</span>
|
|
<span class="badge {{ 'up' if node.plain_dns else 'down' }}">
|
|
{{ 'UP' if node.plain_dns else 'DOWN' }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="status-item">
|
|
<span>DoH (443)</span>
|
|
<span class="badge {{ 'up' if node.doh else 'down' }}">
|
|
{{ 'UP' if node.doh else 'DOWN' }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="status-item">
|
|
<span>DoT (853)</span>
|
|
<span class="badge {{ 'up' if node.dot else 'down' }}">
|
|
{{ 'UP' if node.dot else 'DOWN' }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="status-item">
|
|
<span>Certificate</span>
|
|
<div style="text-align: right;">
|
|
<span class="badge {{ 'up' if node.cert.valid else 'down' }}">
|
|
{{ 'VALID' if node.cert.valid else 'INVALID' }}
|
|
</span>
|
|
{% if node.cert.valid %}
|
|
<div class="cert-info">Exp: {{ node.cert.expires }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<h2>30-Day History</h2>
|
|
<div class="table-container">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Node</th>
|
|
<th style="text-align: center;">Plain DNS</th>
|
|
<th style="text-align: center;">DoH</th>
|
|
<th style="text-align: center;">DoT</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for node in history.nodes %}
|
|
<tr>
|
|
<td>
|
|
<div class="node-name">{{ node.name }}</div>
|
|
<div class="node-location">{{ node.location }}</div>
|
|
</td>
|
|
{% for type in ['plain_dns', 'doh', 'dot'] %}
|
|
<td style="text-align: center;">
|
|
<div>{{ node[type].percentage }}%</div>
|
|
<div class="uptime-bar" style="margin: 4px auto 0;">
|
|
<div class="uptime-fill {% if node[type].percentage < 90 %}warn{% endif %} {% if node[type].percentage < 70 %}bad{% endif %}"
|
|
style="width: {{ node[type].percentage }}%"></div>
|
|
</div>
|
|
{% if node[type].last_down != 'never' %}
|
|
<div class="cert-info" style="text-align: center;">Last outage: {{ node[type].last_down }}</div>
|
|
{% endif %}
|
|
</td>
|
|
{% endfor %}
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="footer">
|
|
<p>Powered by <a href="https://nathan.woodburn.au">Nathan.Woodburn/</a></p>
|
|
<p><a href="/api">API Access</a></p>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
|
|
</html> |