Quelltext des aktuellen Standes
<?php
$this->layout('layouts/main', [
'page_title' => 'Nicht mehr gefundene VMs',
'current_route' => 'vms',
'full_width' => true,
]);
$vms = $vms ?? [];
$canManage = $can_manage ?? false;
$view = $this;
/** Wie lange eine VM schon vermisst wird, in ganzen Tagen. */
$tageSeit = static function (?string $zeitpunkt): ?int {
if ($zeitpunkt === null || $zeitpunkt === '') {
return null;
}
$ts = strtotime($zeitpunkt);
return $ts !== false ? (int)floor((time() - $ts) / 86400) : null;
};
?>
<div>
<div class="content-header">
<div>
<h1><?= $this->te('Nicht mehr gefundene VMs') ?></h1>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/"><?= $this->te('Home') ?></a></li>
<li class="breadcrumb-item"><a href="/vms"><?= $this->te('Virtualisierung') ?></a></li>
<li class="breadcrumb-item active"><?= $this->te('Nicht mehr gefunden') ?></li>
</ol>
</div>
<div class="content-header-actions">
<a href="/vms" class="btn btn-default"><?= $this->te('« Zur Übersicht') ?></a>
</div>
</div>
<div class="page-body">
<div class="alert alert-info">
<?= $this->te('Diese VMs hat der Hypervisor beim letzten Abgleich nicht mehr gemeldet. Der Abgleich löscht nichts von selbst – er hält nur fest, seit wann eine VM fehlt. Taucht eine VM wieder auf, verschwindet die Kennzeichnung beim nächsten Abgleich von allein. Erst danach lohnt das Aufräumen: Eine nur kurz abgeschaltete oder migrierte VM wäre sonst voreilig gelöscht.') ?>
</div>
<?php if (empty($vms)): ?>
<div class="empty-state">
<i class="fas fa-check-circle"></i>
<p><?= $this->te('Alle VMs werden vom jeweiligen Hypervisor gemeldet. Nichts aufzuräumen.') ?></p>
</div>
<?php else: ?>
<form method="POST" action="/vms/missing/cleanup"
onsubmit="return vmlBestaetigen(this);">
<input type="hidden" name="_csrf" value="<?= $view->e($view->csrf()) ?>">
<div class="table-wrapper">
<table class="data-table">
<thead>
<tr>
<?php if ($canManage): ?>
<th scope="col" style="width:2.5rem;">
<input type="checkbox" onclick="vmlAlle(this)" title="<?= $this->te('Alle auswählen') ?>">
</th>
<?php endif; ?>
<th scope="col"><?= $this->te('Name') ?></th>
<th scope="col"><?= $this->te('Host') ?></th>
<th scope="col"><?= $this->te('Vermisst seit') ?></th>
<th scope="col"><?= $this->te('IP-Adresse') ?></th>
<th scope="col"><?= $this->te('Zuletzt gesehen') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($vms as $vm): ?>
<?php $tage = $tageSeit($vm['missing_since'] ?? null); ?>
<tr>
<?php if ($canManage): ?>
<td>
<input type="checkbox" name="vm_ids[]" value="<?= (int)$vm['id'] ?>" class="vml-pick">
</td>
<?php endif; ?>
<td>
<a href="/vms/<?= (int)$vm['id'] ?>" class="table-link"><?= $view->e($vm['name']) ?></a>
<?php if (!empty($vm['purpose'])): ?>
<div class="text-muted" style="font-size:.75rem;"><?= $view->e($vm['purpose']) ?></div>
<?php endif; ?>
</td>
<td class="text-muted">
<?php if (!empty($vm['host_id'])): ?>
<a href="/vms/hosts/<?= (int)$vm['host_id'] ?>" class="table-link"><?= $view->e($vm['host_name'] ?? '—') ?></a>
<?php else: ?>—<?php endif; ?>
</td>
<td>
<span class="status-pill <?= ($tage ?? 0) >= 7 ? 'status-pill--danger' : 'status-pill--warning' ?>">
<?= $tage === null ? '—' : ($tage === 0 ? 'heute' : $tage . ' Tag(e)') ?>
</span>
<div class="text-muted" style="font-size:.75rem;">
<?= !empty($vm['missing_since']) ? $view->e(date('d.m.Y H:i', strtotime((string)$vm['missing_since']))) : '' ?>
</div>
</td>
<td class="text-muted"><?= $view->e($vm['ip_address'] ?: '—') ?></td>
<td class="text-muted">
<?= !empty($vm['last_sync_at']) ? $view->e(date('d.m.Y H:i', strtotime((string)$vm['last_sync_at']))) : '—' ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php if ($canManage): ?>
<p style="margin-top:1rem;">
<button type="submit" class="btn btn-danger">
<i class="fas fa-trash"></i> <?= $this->te('Ausgewählte löschen') ?>
</button>
<span class="form-hint" style="margin-left:.5rem;">
<?= $this->te('Löscht die VM in OpenNIT – nicht auf dem Hypervisor. Jede Löschung steht im Audit-Log.') ?>
</span>
</p>
<?php endif; ?>
</form>
<?php endif; ?>
</div>
</div>
<script>
function vmlAlle(kopf) {
document.querySelectorAll('.vml-pick').forEach(function (el) { el.checked = kopf.checked; });
}
function vmlBestaetigen(form) {
var anzahl = form.querySelectorAll('.vml-pick:checked').length;
if (anzahl === 0) {
alert('Bitte mindestens eine VM auswählen.');
return false;
}
return confirm(anzahl + ' VM(s) in OpenNIT löschen? Auf dem Hypervisor ändert sich nichts.');
}
</script>