clusev/app
boban 265136fc42 Metric history fix, service-failure audit trail, alert channels + secret-retarget hardening
Metric history: the per-minute sampler (clusev:sample-metrics) now reads
cpu/mem/disk from the `servers` DB row — the same source the live gauges read,
shared via MariaDB — instead of a cross-container Redis cache the poller may
not share in prod. It gates on last_seen_at freshness (skip offline/unpolled)
and keeps `load` as a best-effort cache read. History now fills whenever the
gauges have data, independent of the cache driver or container split — the
prod detail page no longer shows "Noch keine Verlaufsdaten" after hours.

Service-action failures are persisted: a failed systemctl start/stop/restart
writes a red service.<op>.failed AuditEvent with the FULL systemctl reason in
meta['output'] (mb_scrub-ed, 4000-cap), shown expandable in the audit log — a
truncated, ephemeral toast is no longer the only trace. The failure toast is a
short pointer to the audit log, level=error, and error toasts now linger 9s.

Alert delivery: a warning banner appears on the alerts page when NO channel
would reach anyone (no SMTP + no safe webhook + no Gotify). A new Gotify push
channel (server URL + encrypted app token) posts title/message/priority with
the token in X-Gotify-Key; a self-hosted LAN Gotify is allowed (scheme-checked,
not private-range-blocked like the SSRF-guarded webhooks) — a real push when a
service goes down, no e-mail needed.

Secret-retarget hardening (Codex-found class): changing a target while leaving
its secret blank could send the OLD secret to the NEW endpoint. Closed for the
Gotify token, the SMTP password (save + test-send + the runtime mailer), and
the host-terminal SSH credential (username/port change) — each drops/forbids
the stale secret before the new target is stored. Setting::uncached() reads the
security-sensitive keys DB-direct so a cache-repopulation race can't re-pair an
old secret with a new target. Three Codex rounds, clean; 778 tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 22:21:54 +02:00
..
Console/Commands Metric history fix, service-failure audit trail, alert channels + secret-retarget hardening 2026-07-08 22:21:54 +02:00
Enums feat(rbac): role enum + column + gates foundation (admin>operator>viewer) 2026-07-05 00:42:16 +02:00
Events fix(blade): garbled header on every signed-in page + private metrics channel (v0.4.1) 2026-06-14 08:34:07 +02:00
Exceptions perf/cleanup: one SSH round-trip for Docker, drop dead i18n, dedupe row 2026-07-06 20:06:27 +02:00
Http fix(ui): sidebar alert/threat badges update at once, not up to 60s late 2026-07-06 20:22:51 +02:00
Jobs feat: scaffold — Dockerized Laravel 13 + Livewire 3 + Tailwind 4 + Reverb 2026-06-12 00:31:50 +02:00
Livewire Metric history fix, service-failure audit trail, alert channels + secret-retarget hardening 2026-07-08 22:21:54 +02:00
Mail fix(alerts): fresh mailer at queue time (poller!) + branded HTML alert e-mail 2026-07-06 21:14:52 +02:00
Models Metric history fix, service-failure audit trail, alert channels + secret-retarget hardening 2026-07-08 22:21:54 +02:00
Notifications fix(security): constant-time password-reset (flatten account-enumeration timing) 2026-06-15 19:16:30 +02:00
Providers fix(alerts): fresh mailer at queue time (poller!) + branded HTML alert e-mail 2026-07-06 21:14:52 +02:00
Rules feat(auth): ValidIpOrCidr validation rule 2026-06-20 17:42:06 +02:00
Services Metric history fix, service-failure audit trail, alert channels + secret-retarget hardening 2026-07-08 22:21:54 +02:00
Support Metric history fix, service-failure audit trail, alert channels + secret-retarget hardening 2026-07-08 22:21:54 +02:00