feat: read-only Blackwall TUI dashboard (Phase 1) #253
No reviewers
Labels
No labels
bug
deploy
documentation
duplicate
enhancement
good first issue
help wanted
invalid
pull-request
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
femboy/blackwall!253
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/blackwall-tui-dashboard"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Phase 1 of the Blackwall TUI dashboard: a read-only, Blackwall-themed
(
ratatui, red-on-black) terminal dashboard over the existing read controlAPI and the Prometheus
:9100endpoint. No write/mutating endpoint isintroduced or called anywhere in this change.
New crates:
crates/blackwall-client— pure async read-only data layer shared by theTUI now and the web GUI later (Phase 2, separate plan): a Prometheus
text-exposition parser (
parse_prometheus/MetricsSnapshot), typed views(
bgp_peers,throughput,armed,deception_sessions), anApiClientover
/v1/mitigations/rtbh,/v1/sessions,/v1/detections(decodingstraight into
blackwall_api::dtotypes — no redefined DTOs), and aMetricsClientthat scrapes and parses the metrics endpoint.bin/blackwall-tui— the dashboard binary: a single-sourcetheme.rspalette (bg
#0a0000, blackwall red#ff1e2d, dim ember#8b0f16, hot#ff6b6b), anAppStatewith per-source (metrics vs. API) stalenesstracking, five render-tested panels (header/throughput/peerings/rtbh/
sessions), and an async refresh loop (metrics ~1.5s, entities ~5s;
q/Esc/Ctrl-Cto quit).One metrics addition (
crates/blackwall-flow,bin/blackwalld):blackwall_flow_sampled_bytes_total/blackwall_flow_sampled_packets_total— two new counters fed by the existing sFlow sample-decode path, extrapolated
from each sample's sampling rate, so the TUI can derive bps/pps via a delta
over time. New metric families only; nothing existing renamed or removed.
Notable deviations from the original plan (flagged, not silent)
6-value FSM.
bin/blackwalld/src/metrics.rsemitsblackwall_bgp_session_stateas a single unlabeled gauge with values{0,1,2}(Idle/Connecting/Established) — Blackwall runs exactly oneupstream BGP session, not a multi-peer table, and the metrics renderer
(
blackwall_metrics::Metric) has no label support at all.views::BgpStatedecodes against that reality (
0/1/2→Idle/Connect/Established) andbgp_peersfalls back to a"upstream"peer name when nopeerlabel ispresent (always, today). The fuller FSM variants (
Active/OpenSent/OpenConfirm) and labeled multi-peer decoding are kept working and testedfor forward compatibility, but are unreachable against the current
exporter. See the doc comment in
crates/blackwall-client/src/views.rs.Deserialize/Cloneadded toRtbhDto/DetectionDto/SessionDtoincrates/blackwall-api/src/dto.rs(previouslySerialize-only). Requiredfor
blackwall-clientto decode API responses straight into the shared DTOtypes per the plan's own constraint ("reuse
blackwall_api::dtotypes —do not redefine DTOs"); otherwise that constraint is unsatisfiable. Purely
additive derives, no behavior change.
crates/blackwall-flow's counters live on the existingCollectorMetricsstruct (not a new
FlowMetricstype the plan assumed) — that's the typethat's actually threaded through the collector and the metrics endpoint
today.
Cargo.toml'smembersalready globscrates/*/bin/*, so both newcrates are picked up automatically; no explicit
membersentries wereneeded (the eBPF crate's
excludeis untouched).blackwall-client/src/{api,http}.rs,blackwall-tui/src/main.rs) are excluded from the coverage gate the waythe repo actually does this — a filename pattern in
scripts/coverage.sh'sEXCLUDEregex (matchingbin/blackwalld/src/api.rs,flow/src/collector_net.rs, etc.) — ratherthan a
#[cfg(not(coverage))]attribute, which isn't a mechanism this repodefines anywhere.
Verification
From the worktree root, with a local Postgres up (
docker compose up -d,DATABASE_URLset — required forblackwall-state's DB-backed tests, sameas CI):
cargo test --workspace— 903 tests passed, 0 failedcargo clippy --workspace --all-targets -- --deny warnings— cleancargo fmt --all -- --check— cleanbash scripts/coverage.sh— 96.24% line coverage (gate: ≥90%)8e767b48987dbc8056ae