2026-03-01 23:03:18 -05:00
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html lang="en">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
<title>{% block title %}GANDALF{% endblock %}</title>
|
|
|
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
feat: terminal aesthetic rewrite + link debug page
- Full dark terminal aesthetic (Pulse/TinkerTickets style):
- #0a0a0a background, #00ff41 green, #ffb000 amber, #00ffff cyan
- CRT scanline overlay, phosphor glow, ASCII corner pseudoelements
- Bracket-notation badges [CRITICAL], monospace font throughout
- style.css, base.html, index.html, suppressions.html all rewritten
- New Link Debug page (/links, /api/links):
- Per-host, per-interface cards with speed/duplex/port type/auto-neg
- Traffic bars (TX cyan, RX green) with rate labels
- Error/drop counters, carrier change history
- SFP/DOM optical panel: vendor, temp, voltage, bias, TX/RX power dBm bars
- RX-TX delta shown; color-coded warn/crit thresholds
- Auto-refresh every 60s, anchor-jump to #hostname
- LinkStatsCollector in monitor.py:
- SSHes to each host (one connection, all ifaces batched)
- Parses ethtool + ethtool -m (SFP DOM) output
- Merges with Prometheus traffic/error/carrier metrics
- Stores as link_stats in monitor_state table
- config.json: added ssh section for ethtool collection
- app.js: terminal chip style consistency (uppercase, ● bullet)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 12:43:11 -05:00
|
|
|
<header class="header">
|
|
|
|
|
<div class="header-left">
|
|
|
|
|
<div class="header-brand">
|
|
|
|
|
<span class="header-title">GANDALF</span>
|
|
|
|
|
<span class="header-sub">Network Monitor // LotusGuild</span>
|
|
|
|
|
</div>
|
|
|
|
|
<nav class="header-nav">
|
|
|
|
|
<a href="{{ url_for('index') }}"
|
|
|
|
|
class="nav-link {% if request.endpoint == 'index' %}active{% endif %}">
|
|
|
|
|
Dashboard
|
|
|
|
|
</a>
|
|
|
|
|
<a href="{{ url_for('links_page') }}"
|
|
|
|
|
class="nav-link {% if request.endpoint == 'links_page' %}active{% endif %}">
|
|
|
|
|
Link Debug
|
|
|
|
|
</a>
|
feat: inspector page, link debug enhancements, security hardening
- Add /inspector page: visual model-accurate switch chassis diagrams
(USF5P, USL8A, US24PRO, USPPDUP, USMINI), clickable port blocks
with color coding (green=up, amber=PoE, cyan=uplink, grey=down),
detail panel with stats/PoE/LLDP, LLDP-based path debug side-by-side
- Link Debug: port number badges (#N), LLDP neighbor line, PoE class/max,
collapsible host/switch panels with sessionStorage persistence
- monitor.py: collect LLDP neighbor map + PoE class/max/mode per switch
port; PulseClient uses requests.Session() for HTTP keep-alive; add
shlex.quote() around interface names (defense-in-depth)
- Security: suppress buttons use data-* attrs + delegated click handler
instead of inline onclick with Jinja2 variable interpolation; remove
| safe filter from user-controlled fields in suppressions.html;
setDuration() takes explicit el param instead of implicit event global
- db.py: thread-local connection reuse with ping(reconnect=True) to
avoid a new TCP handshake per query
- .gitignore: add config.json (contains credentials), __pycache__
- README: full rewrite covering architecture, all 4 pages, alert logic,
config reference, deployment, troubleshooting, security notes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-03 15:39:48 -05:00
|
|
|
<a href="{{ url_for('inspector') }}"
|
|
|
|
|
class="nav-link {% if request.endpoint == 'inspector' %}active{% endif %}">
|
|
|
|
|
Inspector
|
|
|
|
|
</a>
|
feat: terminal aesthetic rewrite + link debug page
- Full dark terminal aesthetic (Pulse/TinkerTickets style):
- #0a0a0a background, #00ff41 green, #ffb000 amber, #00ffff cyan
- CRT scanline overlay, phosphor glow, ASCII corner pseudoelements
- Bracket-notation badges [CRITICAL], monospace font throughout
- style.css, base.html, index.html, suppressions.html all rewritten
- New Link Debug page (/links, /api/links):
- Per-host, per-interface cards with speed/duplex/port type/auto-neg
- Traffic bars (TX cyan, RX green) with rate labels
- Error/drop counters, carrier change history
- SFP/DOM optical panel: vendor, temp, voltage, bias, TX/RX power dBm bars
- RX-TX delta shown; color-coded warn/crit thresholds
- Auto-refresh every 60s, anchor-jump to #hostname
- LinkStatsCollector in monitor.py:
- SSHes to each host (one connection, all ifaces batched)
- Parses ethtool + ethtool -m (SFP DOM) output
- Merges with Prometheus traffic/error/carrier metrics
- Stores as link_stats in monitor_state table
- config.json: added ssh section for ethtool collection
- app.js: terminal chip style consistency (uppercase, ● bullet)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 12:43:11 -05:00
|
|
|
<a href="{{ url_for('suppressions_page') }}"
|
|
|
|
|
class="nav-link {% if request.endpoint == 'suppressions_page' %}active{% endif %}">
|
|
|
|
|
Suppressions
|
|
|
|
|
</a>
|
|
|
|
|
</nav>
|
2026-03-01 23:03:18 -05:00
|
|
|
</div>
|
feat: terminal aesthetic rewrite + link debug page
- Full dark terminal aesthetic (Pulse/TinkerTickets style):
- #0a0a0a background, #00ff41 green, #ffb000 amber, #00ffff cyan
- CRT scanline overlay, phosphor glow, ASCII corner pseudoelements
- Bracket-notation badges [CRITICAL], monospace font throughout
- style.css, base.html, index.html, suppressions.html all rewritten
- New Link Debug page (/links, /api/links):
- Per-host, per-interface cards with speed/duplex/port type/auto-neg
- Traffic bars (TX cyan, RX green) with rate labels
- Error/drop counters, carrier change history
- SFP/DOM optical panel: vendor, temp, voltage, bias, TX/RX power dBm bars
- RX-TX delta shown; color-coded warn/crit thresholds
- Auto-refresh every 60s, anchor-jump to #hostname
- LinkStatsCollector in monitor.py:
- SSHes to each host (one connection, all ifaces batched)
- Parses ethtool + ethtool -m (SFP DOM) output
- Merges with Prometheus traffic/error/carrier metrics
- Stores as link_stats in monitor_state table
- config.json: added ssh section for ethtool collection
- app.js: terminal chip style consistency (uppercase, ● bullet)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 12:43:11 -05:00
|
|
|
<div class="header-right">
|
|
|
|
|
<span class="header-user">{{ user.name or user.username }}</span>
|
2026-03-01 23:03:18 -05:00
|
|
|
</div>
|
feat: terminal aesthetic rewrite + link debug page
- Full dark terminal aesthetic (Pulse/TinkerTickets style):
- #0a0a0a background, #00ff41 green, #ffb000 amber, #00ffff cyan
- CRT scanline overlay, phosphor glow, ASCII corner pseudoelements
- Bracket-notation badges [CRITICAL], monospace font throughout
- style.css, base.html, index.html, suppressions.html all rewritten
- New Link Debug page (/links, /api/links):
- Per-host, per-interface cards with speed/duplex/port type/auto-neg
- Traffic bars (TX cyan, RX green) with rate labels
- Error/drop counters, carrier change history
- SFP/DOM optical panel: vendor, temp, voltage, bias, TX/RX power dBm bars
- RX-TX delta shown; color-coded warn/crit thresholds
- Auto-refresh every 60s, anchor-jump to #hostname
- LinkStatsCollector in monitor.py:
- SSHes to each host (one connection, all ifaces batched)
- Parses ethtool + ethtool -m (SFP DOM) output
- Merges with Prometheus traffic/error/carrier metrics
- Stores as link_stats in monitor_state table
- config.json: added ssh section for ethtool collection
- app.js: terminal chip style consistency (uppercase, ● bullet)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 12:43:11 -05:00
|
|
|
</header>
|
2026-03-01 23:03:18 -05:00
|
|
|
|
|
|
|
|
<main class="main">
|
|
|
|
|
{% block content %}{% endblock %}
|
|
|
|
|
</main>
|
|
|
|
|
|
2026-03-14 14:31:57 -04:00
|
|
|
<script>
|
|
|
|
|
const GANDALF_CONFIG = {
|
|
|
|
|
ticket_web_url: "{{ config.get('ticket_api', {}).get('web_url', 'http://t.lotusguild.org/ticket/') }}"
|
|
|
|
|
};
|
|
|
|
|
</script>
|
2026-03-01 23:03:18 -05:00
|
|
|
<script src="{{ url_for('static', filename='app.js') }}"></script>
|
|
|
|
|
{% block scripts %}{% endblock %}
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|