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 <noreply@anthropic.com>
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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."
|
||||
},
|
||||
|
||||
@@ -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."
|
||||
},
|
||||
|
||||
@@ -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<string, string> = {
|
||||
public_http: 'HTTP In',
|
||||
public_https: 'HTTPS In',
|
||||
mgmt_https: 'Management',
|
||||
}
|
||||
|
||||
// eg_backend_<id> → friendly name lookup for HAProxy stats display.
|
||||
const backendIdToName = useMemo(() => {
|
||||
const m = new Map<number, string>()
|
||||
@@ -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) => (
|
||||
<div key={f.name} style={{ fontSize: 12, color: '#334155' }}>
|
||||
<Space size={6} wrap>
|
||||
<code style={{ fontSize: 11 }}>{f.name}</code>
|
||||
<code style={{ fontSize: 11 }}>{HA_FRONTEND_LABELS[f.name] ?? f.name}</code>
|
||||
<Text type="secondary" style={{ fontSize: 11 }}>
|
||||
{f.sessions} sess
|
||||
{f.req_rate > 0 ? ` · ${f.req_rate}/s` : ''}
|
||||
@@ -650,14 +661,23 @@ export default function DashboardPage() {
|
||||
<Col xs={24} md={12} xl={8}>
|
||||
<Card size="small" title={<><SafetyCertificateOutlined /> {t('dashboard.sslCard.title')}</>} className="h-100">
|
||||
<Statistic title={t('dashboard.sslCard.total')} value={(tlsCerts.data ?? []).length} />
|
||||
{certsSoon.length > 0 ? (
|
||||
{certsExpired.length > 0 && (
|
||||
<Alert
|
||||
style={{ marginTop: 8 }}
|
||||
type="error"
|
||||
showIcon
|
||||
message={t('dashboard.sslCard.certExpired', { count: certsExpired.length })}
|
||||
/>
|
||||
)}
|
||||
{certsSoon.length > 0 && (
|
||||
<Alert
|
||||
style={{ marginTop: 8 }}
|
||||
type="warning"
|
||||
showIcon
|
||||
message={t('dashboard.sslCard.expiringSoon', { count: certsSoon.length })}
|
||||
/>
|
||||
) : (
|
||||
)}
|
||||
{certsExpired.length === 0 && certsSoon.length === 0 && (
|
||||
<div style={{ marginTop: 8, fontSize: 12, color: '#64748B' }}>
|
||||
{t('dashboard.sslCard.allFresh')}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user