hmm
This commit is contained in:
105
packages/system/nebula-ui/templates/index.html
Normal file
105
packages/system/nebula-ui/templates/index.html
Normal file
@@ -0,0 +1,105 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<h1>Network Overview</h1>
|
||||
|
||||
{% if stats is none %}
|
||||
<div class="card">
|
||||
<div class="no-data">
|
||||
Could not reach the Nebula stats endpoint at <code class="mono">{{ request.app.state.stats_url if request.app.state is defined else "configured URL" }}</code>.
|
||||
Make sure <code class="mono">stats.enabled</code> and <code class="mono">stats.listen</code> are set in your Nebula config.
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
|
||||
{# ── top-level counters ── #}
|
||||
{% set meta = stats.get("meta", {}) %}
|
||||
{% set network = stats.get("network", {}) %}
|
||||
|
||||
<div class="stat-grid">
|
||||
<div class="stat-box">
|
||||
<div class="label">Nebula Version</div>
|
||||
<div class="value" style="font-size:15px; padding-top:4px;">{{ meta.get("version", "—") }}</div>
|
||||
</div>
|
||||
{% set peers = hostmap.get("Hosts", {}) if hostmap else {} %}
|
||||
<div class="stat-box">
|
||||
<div class="label">Active Peers</div>
|
||||
<div class="value">{{ peers | length }}</div>
|
||||
</div>
|
||||
{% set counters = stats.get("counters", {}) %}
|
||||
<div class="stat-box">
|
||||
<div class="label">Tx Bytes</div>
|
||||
<div class="value">{{ "{:,}".format(counters.get("send_bytes", 0)) }}</div>
|
||||
</div>
|
||||
<div class="stat-box">
|
||||
<div class="label">Rx Bytes</div>
|
||||
<div class="value">{{ "{:,}".format(counters.get("recv_bytes", 0)) }}</div>
|
||||
</div>
|
||||
<div class="stat-box">
|
||||
<div class="label">Tx Packets</div>
|
||||
<div class="value">{{ "{:,}".format(counters.get("send_packets", 0)) }}</div>
|
||||
</div>
|
||||
<div class="stat-box">
|
||||
<div class="label">Rx Packets</div>
|
||||
<div class="value">{{ "{:,}".format(counters.get("recv_packets", 0)) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# ── raw stats JSON ── #}
|
||||
<details style="margin-bottom:20px;">
|
||||
<summary>Raw stats JSON</summary>
|
||||
<pre>{{ stats | tojson(indent=2) }}</pre>
|
||||
</details>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{# ── hostmap ── #}
|
||||
<div class="card">
|
||||
<h2>Peer Hostmap</h2>
|
||||
{% if hostmap is none %}
|
||||
<div class="no-data">Hostmap unavailable — stats endpoint not reachable.</div>
|
||||
{% else %}
|
||||
{% set hosts = hostmap.get("Hosts", {}) %}
|
||||
{% if not hosts %}
|
||||
<div class="no-data">No peers connected.</div>
|
||||
{% else %}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Overlay IP</th>
|
||||
<th>Remote Addrs</th>
|
||||
<th>Index</th>
|
||||
<th>Relay?</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for overlay_ip, host in hosts.items() %}
|
||||
<tr>
|
||||
<td class="mono">{{ overlay_ip }}</td>
|
||||
<td>
|
||||
{% for addr in host.get("RemoteAddrs", []) %}
|
||||
<span class="mono badge badge-gray" style="margin-right:4px;">{{ addr }}</span>
|
||||
{% else %}
|
||||
<span class="badge badge-gray">none</span>
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="mono">{{ host.get("LocalIndex", "—") }}</td>
|
||||
<td>
|
||||
{% if host.get("Relay") %}
|
||||
<span class="badge badge-blue">relay</span>
|
||||
{% else %}
|
||||
<span class="badge badge-gray">no</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
<details style="margin-top:16px;">
|
||||
<summary>Raw hostmap JSON</summary>
|
||||
<pre>{{ hostmap | tojson(indent=2) }}</pre>
|
||||
</details>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user