9832760027
gates / gates (push) Successful in 11s
R-329. NotifyAppStartFailures emitted severity "warn". The hub accepts exactly
{info, warning, error, critical} and silently coerces anything else to "info",
which severityNotifies then drops BEFORE both legs. Banner shown, event stored,
POST 200, no mail sent. One word.
This is the second time: DiskAlertKind.Severity emitted "warn" until v0.215.0
and its own comment records that every warning-level disk alert went to nobody.
A comment recorded the lesson and nothing enforced it. The guard is now an AST
walk over the whole controller - grep cannot work here, since "warn" appears
legitimately nine times as a healthcheck status vocabulary.
The sweep found exactly one bad severity. Its limits are stated: the walk cannot
follow a variable, so all six dynamic call sites are registered by name with the
values each can take, and a new one fails the test. Two of the six were found by
the guard, not by the hand sweep before it.
Also pinned: fillwatch.Band.Severity() returns "" for BandOK, which would vanish
the same way. It is unreachable because Check() notifies only on escalation -
but that safety lives in a different function from the one that looks unsafe, so
the test asserts the consequence rather than the mapping.
app_start_failed gains a customer toggle, DEFAULT OFF, per operator ruling. The
operator is mailed either way: processOperator never consults customer prefs.
It is deliberately NOT in operatorOnlyEvents, which would make the toggle a lie.
R-386. classifyRunStates decided "the customer stopped this" from the STATE, so
every stopped stack was assumed deliberate. Measured on demo-hp: privatebin
stopped out of band, nine scans, zero events, zero banner - while the comment
beside it claimed an out-of-band stop still alerts.
DesiredState already records the answer and has exactly one writer. Stopped ->
no alarm; Running -> alarm; absent -> UNKNOWN, keep today's behaviour AND say
so. Absent stays silent deliberately: reading it as "nobody asked" would email
about every app anyone ever stopped, fleet-wide, on the first cycle after
upgrade. The gap is bounded not silent - IntentUnknown is set and the names are
logged at INFO on the heartbeat cadence. failedRestart still lifts a Stopped
intent, or F-CRIT-1 re-opens. No new DesiredState writer.
Two settings toggles each governed two alarms. "Lemez figyelmeztetes (90%+)"
also wrote disk_critical, the drive-is-FAILING alarm. Now four honest toggles;
12 became 15. A no-op save stores the existing slice verbatim, so byte identity
is by construction - without that guard the defaults case reorders, which the
red-proof caught.
Test count 1504 -> 1522. Five red-proofs, five seen failing; one passed first
time and is reported - that mutation was inert, not the test weak.
149 lines
9.2 KiB
HTML
149 lines
9.2 KiB
HTML
{{define "settings_notifications"}}
|
|
{{template "layout_start" .}}
|
|
|
|
<div class="page-header">
|
|
<h2>Beállítások — Értesítések</h2>
|
|
</div>
|
|
|
|
<!-- Section C: Notification Preferences -->
|
|
<div class="settings-card">
|
|
<h3>Értesítések</h3>
|
|
{{if .HubEnabled}}
|
|
{{if .NotificationSuccess}}<div class="alert alert-info">{{.NotificationSuccess}}</div>{{end}}
|
|
{{if .NotificationError}}<div class="alert alert-error">{{.NotificationError}}</div>{{end}}
|
|
<form method="POST" action="/settings/notifications">
|
|
{{.CSRFField}}
|
|
<div class="form-group">
|
|
<label for="notification_email">E-mail cím</label>
|
|
<input type="email" id="notification_email" name="notification_email"
|
|
value="{{with .NotificationPrefs}}{{.Email}}{{end}}"
|
|
placeholder="pelda@email.hu" class="form-control">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Hibák és figyelmeztetések:</label>
|
|
<div class="checkbox-group">
|
|
<label class="toggle">
|
|
<input type="checkbox" name="event_backup_failed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "backup_failed"}}checked{{end}}{{end}}{{end}}>
|
|
<span class="toggle-label">Biztonsági mentés sikertelen</span>
|
|
</label>
|
|
<label class="toggle">
|
|
<input type="checkbox" name="event_db_dump_failed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "db_dump_failed"}}checked{{end}}{{end}}{{end}}>
|
|
<span class="toggle-label">Adatbázis mentés sikertelen</span>
|
|
</label>
|
|
<label class="toggle">
|
|
<input type="checkbox" name="event_backup_integrity_failed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "backup_integrity_failed"}}checked{{end}}{{end}}{{end}}>
|
|
<span class="toggle-label">Mentés sérülés észlelve</span>
|
|
</label>
|
|
<label class="toggle">
|
|
<input type="checkbox" name="event_crossdrive_failed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "crossdrive_failed"}}checked{{end}}{{end}}{{end}}>
|
|
<span class="toggle-label">Másodlagos mentés sikertelen</span>
|
|
</label>
|
|
<label class="toggle">
|
|
<input type="checkbox" name="event_offbox_enlarge_blocked" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "offbox_enlarge_blocked"}}checked{{end}}{{end}}{{end}}>
|
|
<span class="toggle-label">Távoli mentés — tárhelykeret-figyelmeztetés</span>
|
|
</label>
|
|
<label class="toggle">
|
|
<input type="checkbox" name="event_disk_warning" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "disk_warning"}}checked{{end}}{{end}}{{end}}>
|
|
<span class="toggle-label">Lemez betelőben (90% felett)</span>
|
|
</label>
|
|
<label class="toggle">
|
|
<input type="checkbox" name="event_disk_critical" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "disk_critical"}}checked{{end}}{{end}}{{end}}>
|
|
<span class="toggle-label">Lemez megtelt vagy meghibásodott</span>
|
|
</label>
|
|
<label class="toggle">
|
|
<input type="checkbox" name="event_storage_disconnected" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "storage_disconnected"}}checked{{end}}{{end}}{{end}}>
|
|
<span class="toggle-label">Meghajtó leválasztva</span>
|
|
</label>
|
|
<label class="toggle">
|
|
<input type="checkbox" name="event_node_down" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "node_down"}}checked{{end}}{{end}}{{end}}>
|
|
<span class="toggle-label">Szerver nem elérhető</span>
|
|
</label>
|
|
<label class="toggle">
|
|
<input type="checkbox" name="event_health_critical" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "health_critical"}}checked{{end}}{{end}}{{end}}>
|
|
<span class="toggle-label">Rendszer állapot kritikus</span>
|
|
</label>
|
|
<label class="toggle">
|
|
<input type="checkbox" name="event_expected_backup_missed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "expected_backup_missed"}}checked{{end}}{{end}}{{end}}>
|
|
<span class="toggle-label">Elvárt fájlmentés elmaradt</span>
|
|
</label>
|
|
<label class="toggle">
|
|
<input type="checkbox" name="event_expected_dbdump_missed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "expected_dbdump_missed"}}checked{{end}}{{end}}{{end}}>
|
|
<span class="toggle-label">Elvárt adatbázismentés elmaradt</span>
|
|
</label>
|
|
<label class="toggle">
|
|
<input type="checkbox" name="event_app_start_failed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "app_start_failed"}}checked{{end}}{{end}}{{end}}>
|
|
<span class="toggle-label">Alkalmazás nem fut</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Tájékoztató:</label>
|
|
<div class="checkbox-group">
|
|
<label class="toggle">
|
|
<input type="checkbox" name="event_storage_reconnected" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "storage_reconnected"}}checked{{end}}{{end}}{{end}}>
|
|
<span class="toggle-label">Meghajtó újra csatlakoztatva</span>
|
|
</label>
|
|
<label class="toggle">
|
|
<input type="checkbox" name="event_health_recovered" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "health_recovered"}}checked{{end}}{{end}}{{end}}>
|
|
<span class="toggle-label">Rendszer állapot helyreállt</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="cooldown_hours">Értesítési szünet</label>
|
|
<div class="form-inline">
|
|
<input type="number" id="cooldown_hours" name="cooldown_hours" min="1" max="168"
|
|
value="{{with .NotificationPrefs}}{{.CooldownHours}}{{end}}"
|
|
class="form-control form-control-narrow">
|
|
<span class="form-hint">óra (azonos probléma esetén ennyi ideig nem küld újat)</span>
|
|
</div>
|
|
</div>
|
|
<div class="form-actions">
|
|
<button type="submit" class="btn btn-primary">Mentés</button>
|
|
<button type="submit" formaction="/settings/notifications/test" class="btn btn-outline">Teszt email küldése</button>
|
|
</div>
|
|
</form>
|
|
{{else}}
|
|
<div class="alert alert-info">
|
|
Az értesítések a központi rendszeren keresztül működnek, ami jelenleg nincs bekapcsolva.
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
|
|
<!-- Section: App email (SMTP relay) -->
|
|
{{if .AppEmailAvailable}}
|
|
<div class="settings-card">
|
|
<h3>Alkalmazás-email</h3>
|
|
<p class="settings-card-desc">
|
|
Az alkalmazások a Felhom-on keresztül küldhetnek emailt (pl. jelszó-visszaállítás, meghívók),
|
|
külön email-szolgáltató beállítása nélkül. A feladó címe minden alkalmazásnál a saját
|
|
<em><alkalmazás>@felhom.eu</em> címe lesz.
|
|
</p>
|
|
{{if .AppEmailSuccess}}<div class="alert alert-info">{{.AppEmailSuccess}}</div>{{end}}
|
|
{{if .AppEmailError}}<div class="alert alert-error">{{.AppEmailError}}</div>{{end}}
|
|
<form method="POST" action="/settings/app-email">
|
|
{{.CSRFField}}
|
|
<div class="form-group">
|
|
<label style="display:flex;align-items:center;gap:.5rem">
|
|
<input type="checkbox" name="app_email_enabled" value="on" {{if .AppEmailEnabled}}checked{{end}}>
|
|
Alkalmazás-email engedélyezése
|
|
</label>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="app_email_from_name">Feladó neve (opcionális)</label>
|
|
<input type="text" id="app_email_from_name" name="app_email_from_name"
|
|
value="{{.AppEmailFromName}}" placeholder="pl. a háztartás neve" class="form-control">
|
|
<span class="form-hint">Ez jelenik meg a kimenő emailek feladójaként az alkalmazás neve mellett.</span>
|
|
</div>
|
|
<div class="form-actions">
|
|
<button type="submit" class="btn btn-primary">Mentés</button>
|
|
</div>
|
|
</form>
|
|
<p class="settings-card-desc" style="margin-top:.75rem">
|
|
Bekapcsolás után az egyes alkalmazásoknál is engedélyezni kell az email-küldést (az alkalmazás oldalán).
|
|
</p>
|
|
</div>
|
|
{{end}}
|
|
{{template "layout_end" .}}
|
|
{{end}}
|