From f378771dca6d1bdacb4bb6ef771462a3bb7dcc38 Mon Sep 17 00:00:00 2001 From: Debian Date: Wed, 27 May 2026 18:51:59 +0200 Subject: [PATCH] feat(dashboard): SSL card expired/expiring split + HAProxy frontend labels Expired certs now show a red error alert ("renew immediately") instead of being silently folded into the orange "expiring soon" warning. HAProxy frontend technical names (public_http, public_https, mgmt_https) now display as human-readable labels (HTTP In, HTTPS In, Management). Co-Authored-By: Claude Sonnet 4.6 --- VERSION | 2 +- cmd/edgeguard-api/main.go | 2 +- cmd/edgeguard-ctl/main.go | 2 +- cmd/edgeguard-scheduler/main.go | 2 +- management-ui/src/i18n/locales/de/common.json | 1 + management-ui/src/i18n/locales/en/common.json | 1 + management-ui/src/pages/Dashboard/index.tsx | 28 ++++++++++++++++--- 7 files changed, 30 insertions(+), 8 deletions(-) diff --git a/VERSION b/VERSION index fdee0de..51f88d3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.118 +1.1.119 diff --git a/cmd/edgeguard-api/main.go b/cmd/edgeguard-api/main.go index f5ba407..f01d3df 100644 --- a/cmd/edgeguard-api/main.go +++ b/cmd/edgeguard-api/main.go @@ -60,7 +60,7 @@ import ( usersvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/users" ) -var version = "1.1.118" +var version = "1.1.119" func main() { addr := os.Getenv("EDGEGUARD_API_ADDR") diff --git a/cmd/edgeguard-ctl/main.go b/cmd/edgeguard-ctl/main.go index 145f487..45fdc14 100644 --- a/cmd/edgeguard-ctl/main.go +++ b/cmd/edgeguard-ctl/main.go @@ -11,7 +11,7 @@ import ( "git.netcell-it.de/projekte/edgeguard-native/internal/services/setup" ) -var version = "1.1.118" +var version = "1.1.119" const usage = `edgeguard-ctl — EdgeGuard CLI diff --git a/cmd/edgeguard-scheduler/main.go b/cmd/edgeguard-scheduler/main.go index 17e80ca..1344ce5 100644 --- a/cmd/edgeguard-scheduler/main.go +++ b/cmd/edgeguard-scheduler/main.go @@ -41,7 +41,7 @@ import ( "git.netcell-it.de/projekte/edgeguard-native/internal/services/tlscerts" ) -var version = "1.1.118" +var version = "1.1.119" const ( // renewTickInterval — how often we re-evaluate expiring certs. diff --git a/management-ui/src/i18n/locales/de/common.json b/management-ui/src/i18n/locales/de/common.json index 606e7c3..4856575 100644 --- a/management-ui/src/i18n/locales/de/common.json +++ b/management-ui/src/i18n/locales/de/common.json @@ -745,6 +745,7 @@ "sslCard": { "title": "SSL-Zertifikate", "total": "Verwaltete Zertifikate", + "certExpired": "{{count}} Zertifikat(e) abgelaufen — sofort erneuern", "expiringSoon": "{{count}} läuft bald ab (< 30 Tage)", "allFresh": "Alle Zertifikate haben > 30 Tage Restlaufzeit." }, diff --git a/management-ui/src/i18n/locales/en/common.json b/management-ui/src/i18n/locales/en/common.json index 6bb230b..0e532dc 100644 --- a/management-ui/src/i18n/locales/en/common.json +++ b/management-ui/src/i18n/locales/en/common.json @@ -745,6 +745,7 @@ "sslCard": { "title": "SSL certificates", "total": "Managed certificates", + "certExpired": "{{count}} certificate(s) expired — renew immediately", "expiringSoon": "{{count}} expiring soon (< 30 days)", "allFresh": "All certs have > 30 days remaining." }, diff --git a/management-ui/src/pages/Dashboard/index.tsx b/management-ui/src/pages/Dashboard/index.tsx index 85d866e..a33d66a 100644 --- a/management-ui/src/pages/Dashboard/index.tsx +++ b/management-ui/src/pages/Dashboard/index.tsx @@ -283,6 +283,13 @@ export default function DashboardPage() { const now = Date.now() const maintenanceDomains = (domains.data ?? []).filter(d => d.maintenance_mode) + // HAProxy frontend technical name → display label. + const HA_FRONTEND_LABELS: Record = { + public_http: 'HTTP In', + public_https: 'HTTPS In', + mgmt_https: 'Management', + } + // eg_backend_ → friendly name lookup for HAProxy stats display. const backendIdToName = useMemo(() => { const m = new Map() @@ -320,10 +327,14 @@ export default function DashboardPage() { return down })() + const certsExpired = (tlsCerts.data ?? []).filter(c => { + if (!c.not_after) return false + return new Date(c.not_after).getTime() < now + }) const certsSoon = (tlsCerts.data ?? []).filter(c => { if (!c.not_after) return false const exp = new Date(c.not_after).getTime() - return exp - now < 30 * 86_400_000 + return exp >= now && exp - now < 30 * 86_400_000 }) return ( @@ -501,7 +512,7 @@ export default function DashboardPage() { {(haproxyStats.data?.frontends ?? []).map((f) => (
- {f.name} + {HA_FRONTEND_LABELS[f.name] ?? f.name} {f.sessions} sess {f.req_rate > 0 ? ` · ${f.req_rate}/s` : ''} @@ -650,14 +661,23 @@ export default function DashboardPage() { {t('dashboard.sslCard.title')}} className="h-100"> - {certsSoon.length > 0 ? ( + {certsExpired.length > 0 && ( + + )} + {certsSoon.length > 0 && ( - ) : ( + )} + {certsExpired.length === 0 && certsSoon.length === 0 && (
{t('dashboard.sslCard.allFresh')}