@php
// Threshold tone for gauges/bars: >=90 offline, >=75 warning, else online.
$tone = fn (int $v): string => $v >= 90 ? 'offline' : ($v >= 75 ? 'warning' : 'online');
$barColor = ['online' => 'bg-online', 'warning' => 'bg-warning', 'offline' => 'bg-offline'];
$statusLabel = ['online' => 'Online', 'warning' => 'Warnung', 'offline' => 'Offline'][$server->status] ?? ucfirst($server->status);
$specs = $server->specs ?? [];
$cores = $specs['cores'] ?? null;
$ramGb = $specs['ram_gb'] ?? null;
$diskGb = $specs['disk_gb'] ?? null;
$ramUsed = $ramGb !== null ? round((float) $ramGb * $server->mem / 100, 1) : null;
$diskUsed = $diskGb !== null ? (int) round((float) $diskGb * $server->disk / 100) : null;
$specRows = [
['Architektur', $specs['arch'] ?? '—'],
['Kernel', $specs['kernel'] ?? '—'],
['Virtualisierung', $specs['virt'] ?? '—'],
['Kerne', $cores ?? '—'],
['RAM', $ramGb !== null ? $ramGb.' GB' : '—'],
['Disk', $diskGb !== null ? $diskGb.' GB' : '—'],
];
// Detected OS tooling (populated once the live profile loads).
if (! empty($os)) {
$pm = ($os['packageManager'] ?? 'none') !== 'none' ? $os['packageManager'] : '—';
$fw = ($os['firewallTool'] ?? 'none') !== 'none' ? $os['firewallTool'] : '—';
$specRows[] = ['System', $os['familyLabel'] ?? '—'];
$specRows[] = ['Paketverwaltung', $pm];
$specRows[] = ['Firewall', $fw];
}
$vitals = [
['label' => 'CPU', 'icon' => 'cpu', 'val' => (int) $server->cpu, 'sub' => ($loadAvg > 0 ? 'Last '.number_format($loadAvg, 2).' · ' : '').($cores ? $cores.' Kerne' : '—')],
['label' => 'RAM', 'icon' => 'activity', 'val' => (int) $server->mem, 'sub' => $ramUsed !== null ? $ramUsed.' / '.$ramGb.' GB' : '—'],
['label' => 'Disk', 'icon' => 'server', 'val' => (int) $server->disk, 'sub' => $diskUsed !== null ? $diskUsed.' / '.$diskGb.' GB' : '—'],
];
@endphp
Zurück zur Flotte
{{-- Hero header --}}
$server->status === 'online',
'border-warning/30 bg-warning/10 text-warning' => $server->status === 'warning',
'border-offline/30 bg-offline/10 text-offline' => $server->status === 'offline',
])>
{{ $server->name }}
{{ $statusLabel }}
{{ $server->hostname }}
·
{{ $server->ip }}
·
{{ $server->os }}
·
Uptime {{ $server->uptime ?: '—' }}
·
zuletzt {{ optional($server->last_seen_at)->diffForHumans() ?? '—' }}
System-Updates
Dateien
@if ($ready && ! $connected)
Keine Live-Verbindung — gezeigt werden die zuletzt gespeicherten Werte. Zugang/Erreichbarkeit prüfen.
@endif
{{-- SSH-Zugang (Credential) --}}
@php
$cred = $server->credential;
$credStatus = $cred ? ($cred->disabled ? 'offline' : 'online') : null;
$credStatusLabel = $cred ? ($cred->disabled ? 'Gesperrt' : 'Aktiv') : null;
$credAuthLabel = $cred ? ($cred->auth_type === 'key' ? 'SSH-Key' : 'Passwort') : null;
@endphp
@if ($cred)
! $cred->disabled,
'border-offline/30 bg-offline/10 text-offline' => $cred->disabled,
])>
{{ $cred->name ?: $cred->username }}
{{ $credStatusLabel }}
{{ $credAuthLabel }}
{{ $cred->username }} @{{ $server->ip }}
Bearbeiten
{{ $cred->disabled ? 'Entsperren' : 'Sperren' }}
Löschen
@else
Kein Zugang hinterlegt
Ohne SSH-Zugang ist keine Live-Steuerung möglich.
Zugang hinterlegen
@endif
{{-- Vitals: live gauges, full width, dense --}}
@foreach ($vitals as $v)
{{ $v['label'] }}
{{ $v['sub'] }}
@endforeach
@if ($ready)
{{-- Spezifikationen + Sicherheit --}}
@foreach ($specRows as [$key, $val])
{{ $key }}
{{ $val }}
@endforeach
@foreach ($hardening as $check)
@php $supported = $check['supported'] ?? true; @endphp
{{-- One calm state signal: a lock glyph (geschlossen = sicher, offen = offen);
unsupported items render muted with a German reason and no toggle. --}}
$supported && $check['secure'],
'border-warning/25 bg-warning/10 text-warning' => $supported && ! $check['secure'],
'border-line bg-raised text-ink-4' => ! $supported,
])>
{{ $check['label'] }}
@if ($supported)
$check['secure'],
'text-warning' => ! $check['secure'],
])>{{ $check['secure'] ? 'sicher' : 'offen' }}
@else
n. v.
@endif
{{ $supported ? $check['detail'] : $check['reason'] }}
@if ($supported)
@if ($check['key'] === 'fail2ban')
@endif
{{-- Toggle: secondary to make secure, quiet ghost to loosen. --}}
{{ $check['featureOn'] ? 'Deaktivieren' : 'Aktivieren' }}
@endif
@endforeach
{{-- Firewall-Regeln --}}
@php
$fw = $firewall ?? [];
$fwTool = $fw['tool'] ?? 'ufw';
$fwToolLabel = $fwTool === 'firewalld' ? 'firewalld' : 'UFW';
$fwSupported = $fw['supported'] ?? false;
$fwInstalled = $fw['installed'] ?? false;
$fwActive = $fw['active'] ?? false;
$fwManageable = $fw['manageable'] ?? false;
$fwReadOnly = $fw['readOnly'] ?? false;
$fwReadError = $fw['readError'] ?? false;
$fwRules = $fw['rules'] ?? [];
$fwDefaults = $fw['defaults'] ?? [];
$actTone = ['ALLOW' => 'online', 'LIMIT' => 'warning', 'DENY' => 'offline', 'REJECT' => 'offline'];
@endphp
@if ($fwSupported && $fwManageable)
Regel
@endif
@if (! $fwSupported)
{{ $fw['reason'] ?? 'Firewall-Verwaltung ist auf diesem System nicht verfügbar.' }}
@elseif ($fwReadError)
Firewall-Status konnte nicht gelesen werden (Verbindung/Rechte). Bitte später erneut laden.
@elseif (! $fwInstalled)
{{ $fwToolLabel }} ist nicht installiert.
Aktivieren
@elseif ($fwTool === 'firewalld' && ! $fwActive)
firewalld ist installiert, aber inaktiv.
Aktivieren
@else
@if ($fwTool === 'ufw')
Standard
eingehend: {{ $fwDefaults['incoming'] ?? '—' }}
ausgehend: {{ $fwDefaults['outgoing'] ?? '—' }}
@else
Zone
{{ $fwDefaults['zone'] ?? '—' }}
@endif
@if ($fwReadOnly)
firewalld: nur Anzeige — Regeln bitte direkt am Server verwalten.
@endif
@forelse ($fwRules as $rule)
{{-- $ruleTone, NOT $tone: the page-level $tone is a closure used by the
gauges/Volumes panel; reusing the name here would clobber it. --}}
@php $ruleTone = $actTone[$rule['action'] ?? 'ALLOW'] ?? 'online'; @endphp
$ruleTone === 'online',
'bg-warning' => $ruleTone === 'warning',
'bg-offline' => $ruleTone === 'offline',
])>
{{ $rule['label'] ?? ($rule['to'] ?? $rule['raw']) }}
@if ($fwTool === 'ufw' && ($rule['from'] ?? '') !== '' && ! \Illuminate\Support\Str::contains($rule['from'], 'Anywhere'))
von {{ $rule['from'] }}
@endif
$ruleTone === 'online',
'text-warning' => $ruleTone === 'warning',
'text-offline' => $ruleTone === 'offline',
])>{{ strtolower($rule['action'] ?? 'allow') }}
@unless ($fwReadOnly)
@endunless
@empty
@endforelse
@endif
{{-- fail2ban-Status --}}
@php
$f2b = $fail2ban ?? [];
$f2bSupported = $f2b['supported'] ?? false;
$f2bReadError = $f2b['readError'] ?? false;
$f2bInstalled = $f2b['installed'] ?? false;
$f2bActive = $f2b['active'] ?? false;
$f2bJails = $f2b['jails'] ?? [];
$f2bIgnore = $f2b['ignoreip'] ?? [];
$f2bBanned = array_sum(array_map(fn ($j) => $j['currentlyBanned'] ?? 0, $f2bJails));
@endphp
@if ($f2bSupported && $f2bInstalled && $f2bActive)
IP sperren
@endif
@if (! $f2bSupported)
{{ $f2b['reason'] ?? 'fail2ban ist auf diesem System nicht verfügbar.' }}
@elseif ($f2bReadError)
fail2ban-Status konnte nicht gelesen werden. Bitte später erneut laden.
@elseif (! $f2bInstalled || ! $f2bActive)
fail2ban ist {{ $f2bInstalled ? 'installiert, aber inaktiv' : 'nicht installiert' }}.
Aktivieren
@else
@foreach ($f2bJails as $jail)
{{ $jail['name'] }}
($jail['currentlyBanned'] ?? 0) > 0])>gebannt: {{ $jail['currentlyBanned'] ?? 0 }}
· Fehlversuche: {{ $jail['currentlyFailed'] ?? 0 }}
@if (count($jail['bannedIps'] ?? []))
@foreach ($jail['bannedIps'] as $ip)
{{ $ip }}
Entsperren
@endforeach
@else
Keine gebannten IPs.
@endif
@endforeach
{{-- Whitelist (ignoreip) --}}
Whitelist (ignoreip)
@foreach ($f2bIgnore as $ip)
{{ $ip }}
@unless (in_array($ip, ['127.0.0.1/8', '::1'], true))
@endunless
@endforeach
Hinzufügen
@endif
{{-- Volumes + Netzwerk-Interfaces --}}
@forelse ($volumes as $vol)
@php $vt = $tone((int) $vol['used']); @endphp
{{ $vol['mount'] }}
{{ $vol['fs'] }} · {{ $vol['size'] }}
@empty
Keine Volumes gelesen.
@endforelse
Name
IP
MAC
RX
TX
@foreach ($interfaces as $if)
{{ $if['name'] }}
{{ $if['ip'] }}
{{ $if['mac'] }}
{{ $if['rx'] }}
{{ $if['tx'] }}
@endforeach
{{-- SSH-Schlüssel --}}
Schlüssel hinzufügen
@forelse ($sshKeys as $key)
{{ $key['comment'] }}
{{ $key['type'] }}
{{ $key['fingerprint'] }}
@empty
Keine autorisierten Schlüssel.
@endforelse
@else
{{-- skeletons for the SSH-loaded sections --}}
@foreach (['Spezifikationen', 'Sicherheit'] as $t)
@endforeach
@foreach (['Volumes', 'Netzwerk-Interfaces'] as $t)
@endforeach
@endif