Files
nexus/modules/kea/pages/edit.php
Lars Gebhardt-Kusche d6f09326f4
All checks were successful
Deploy / deploy-staging (push) Successful in 6s
Deploy / deploy-production (push) Has been skipped
dsfdsf
2026-04-24 23:54:04 +02:00

267 lines
11 KiB
PHP

<?php
use App\Database;
use App\Repository\KeaHostMetadataRepository;
use App\Repository\KeaHostRepository;
$module = modules()->get('kea');
$settings = modules()->settings('kea');
$fallback = $module['db_defaults'] ?? [];
$metadataFallback = is_array($module['metadata_db_defaults'] ?? null) ? $module['metadata_db_defaults'] : [];
$metadataConfig = is_array($settings['metadata_db'] ?? null)
? array_replace($metadataFallback, $settings['metadata_db'])
: $metadataFallback;
$source = (string)($_GET['source'] ?? $_POST['source'] ?? 'reservation');
$source = $source === 'lease' ? 'lease' : 'reservation';
$id = (int)($_GET['id'] ?? $_POST['id'] ?? 0);
$error = null;
$notice = null;
$host = null;
$metadataRepo = null;
$groups = [];
$availableIpsByGroup = [];
$checks = [];
$hostKey = '';
try {
$pdo = modules()->modulePdo('kea', $fallback);
if (empty($metadataConfig['driver']) || empty($metadataConfig['dbname'])) {
throw new RuntimeException('Nexus DHCP Zusatzdatenbank ist nicht konfiguriert.');
}
$metadataRepo = new KeaHostMetadataRepository(Database::createFromArray($metadataConfig));
$metadataRepo->ensureSchema();
$groups = $metadataRepo->listGroups();
$repo = new KeaHostRepository($pdo, $metadataRepo);
$host = $repo->findDisplayByKey($source, $id);
if (!$host) {
throw new RuntimeException('KEA Eintrag wurde nicht gefunden.');
}
$hostKey = $source . ':' . (string)($host['host_id'] ?? $id);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = (string)($_POST['action'] ?? 'save_metadata');
if ($action === 'dns_lookup') {
$ip = (string)($host['ipv4_address'] ?? '');
$hostname = trim((string)($host['metadata']['device_name'] ?? $host['hostname'] ?? ''));
$reverse = $ip !== '' ? gethostbyaddr($ip) : '';
$forward = $hostname !== '' ? gethostbyname($hostname) : '';
$success = ($reverse !== '' && $reverse !== $ip) || ($forward !== '' && $forward !== $hostname);
$metadataRepo->saveCheck($hostKey, 'dns', $success ? 'success' : 'warning', [
'ip' => $ip,
'hostname' => $hostname,
'reverse' => $reverse,
'forward' => $forward,
]);
$notice = $success ? 'DNS-Pruefung gespeichert.' : 'DNS-Pruefung gespeichert, aber kein eindeutiger Name gefunden.';
} else {
$metadata = [
'real_name' => $_POST['real_name'] ?? '',
'device_name' => $_POST['device_name'] ?? '',
'owner' => $_POST['owner'] ?? '',
'location' => $_POST['location'] ?? '',
'device_type' => $_POST['device_type'] ?? '',
'group_name' => $_POST['group_name'] ?? '',
'desired_ip' => $_POST['desired_ip'] ?? '',
'notes' => $_POST['notes'] ?? '',
'tags' => [],
];
$desiredIp = trim((string)$metadata['desired_ip']);
if ($desiredIp !== '') {
$newHostId = $repo->reserveDisplayEntry($host, $desiredIp, $metadata);
$source = 'reservation';
$id = $newHostId;
$notice = 'Zusatzdaten gespeichert und KEA-Reservierung gesetzt.';
} else {
$metadataRepo->saveForHost(
$id,
(string)($host['dhcp_identifier'] ?? ''),
(string)($host['ipv4_address'] ?? ''),
$metadata
);
$notice = 'Zusatzdaten gespeichert.';
}
}
$host = $repo->findDisplayByKey($source, $id) ?: $host;
$hostKey = $source . ':' . (string)($host['host_id'] ?? $id);
}
$usedIps = array_diff(
array_merge($repo->usedIpAddresses(), $metadataRepo->desiredIps()),
[(string)($host['ipv4_address'] ?? ''), (string)($host['metadata']['desired_ip'] ?? '')]
);
$availableIpsByGroup = $metadataRepo->availableIpsByGroup($usedIps);
$checks = $metadataRepo->latestChecks([$hostKey])[$hostKey] ?? [];
} catch (Throwable $e) {
$error = $e->getMessage();
}
$metadata = is_array($host['metadata'] ?? null) ? $host['metadata'] : [];
$selectedGroup = (string)($metadata['group_name'] ?? '');
$selectedIp = (string)($metadata['desired_ip'] ?? '');
?>
<?= module_shell_header('kea', [
'title' => 'KEA Eintrag bearbeiten',
]) ?>
<div class="module-flow kea-page">
<section class="module-box">
<div class="module-box-head">
<div>
<h2 class="module-box-title">KEA Eintrag bearbeiten</h2>
<p>Zusatzdaten werden separat von der KEA-Datenbank gespeichert.</p>
</div>
<div class="setup-actions">
<a class="module-button module-button--secondary" href="/module/kea/groups">Gruppen verwalten</a>
<a class="module-button module-button--secondary" href="/module/kea">Zurueck</a>
</div>
</div>
</section>
<?php if ($error): ?>
<div class="kea-message kea-message--error" role="alert">
<strong>Fehler</strong>
<p><?= e($error) ?></p>
</div>
<?php elseif ($host): ?>
<?php if ($notice): ?>
<div class="kea-message kea-message--success">
<?= e($notice) ?>
</div>
<?php endif; ?>
<section class="module-box kea-panel">
<div class="module-box-head kea-panel__head">
<div>
<span class="pill"><?= ($source === 'lease') ? 'Lease' : 'Reservierung' ?></span>
<h2 class="module-box-title"><?= e((string)($host['hostname'] ?: 'Unbekannt')) ?></h2>
<p class="muted">
IP <?= e((string)($host['ipv4_address'] ?? '')) ?> · MAC <?= e((string)($host['dhcp_identifier'] ?? '')) ?>
</p>
</div>
</div>
<form method="post" class="kea-edit-form">
<input type="hidden" name="action" value="save_metadata">
<input type="hidden" name="source" value="<?= e($source) ?>">
<input type="hidden" name="id" value="<?= e((string)$id) ?>">
<label class="setup-field">
<span>Echter Name</span>
<input type="text" name="real_name" value="<?= e((string)($metadata['real_name'] ?? '')) ?>">
</label>
<label class="setup-field">
<span>Gerätename</span>
<input type="text" name="device_name" value="<?= e((string)($metadata['device_name'] ?? '')) ?>">
</label>
<label class="setup-field">
<span>Besitzer</span>
<input type="text" name="owner" value="<?= e((string)($metadata['owner'] ?? '')) ?>">
</label>
<label class="setup-field">
<span>Standort</span>
<input type="text" name="location" value="<?= e((string)($metadata['location'] ?? '')) ?>">
</label>
<label class="setup-field">
<span>Gerätetyp</span>
<input type="text" name="device_type" value="<?= e((string)($metadata['device_type'] ?? '')) ?>">
</label>
<label class="setup-field">
<span>Gruppe</span>
<select name="group_name" data-kea-group-select>
<option value="">Bitte waehlen</option>
<?php foreach ($groups as $group): ?>
<option value="<?= e($group) ?>" <?= $selectedGroup === $group ? 'selected' : '' ?>><?= e($group) ?></option>
<?php endforeach; ?>
</select>
<?php if ($groups === []): ?>
<small class="muted">Noch keine Gruppen definiert. Oeffne zuerst Gruppen verwalten.</small>
<?php endif; ?>
</label>
<label class="setup-field">
<span>Feste IP</span>
<select name="desired_ip" data-kea-ip-select data-selected-ip="<?= e($selectedIp) ?>">
<option value="">Erst Gruppe waehlen</option>
</select>
<small class="muted">Es werden nur freie IPs aus dem IP-Bereich der gewaehlten Gruppe angeboten.</small>
</label>
<label class="setup-field kea-edit-form__wide">
<span>Notizen</span>
<textarea name="notes" rows="4"><?= e((string)($metadata['notes'] ?? '')) ?></textarea>
</label>
<div class="setup-actions kea-edit-form__wide">
<button class="cta-button" type="submit">Speichern</button>
<a class="nav-link" href="/module/kea">Abbrechen</a>
</div>
</form>
</section>
<section class="module-box kea-panel">
<div class="module-box-head kea-panel__head">
<div>
<span class="pill">Pruefungen</span>
<h2 class="module-box-title">Gerätechecks</h2>
<p class="muted">Pruefergebnisse werden in der Nexus-DHCP-Datenbank gespeichert und koennen spaeter fuer Reports genutzt werden.</p>
</div>
</div>
<div class="kea-check-grid">
<div class="kea-check-card">
<h4>DNS / Hostname</h4>
<?php $dnsCheck = $checks['dns'] ?? null; ?>
<?php if ($dnsCheck): ?>
<?php $dnsResult = json_decode((string)($dnsCheck['result_json'] ?? '{}'), true) ?: []; ?>
<p class="muted">Status: <?= e((string)($dnsCheck['status'] ?? '')) ?> · <?= e((string)($dnsCheck['checked_at'] ?? '')) ?></p>
<p class="mono">Reverse: <?= e((string)($dnsResult['reverse'] ?? '-')) ?></p>
<p class="mono">Forward: <?= e((string)($dnsResult['forward'] ?? '-')) ?></p>
<?php else: ?>
<p class="muted">Noch keine DNS-Pruefung gespeichert.</p>
<?php endif; ?>
<form method="post" class="setup-actions">
<input type="hidden" name="action" value="dns_lookup">
<input type="hidden" name="source" value="<?= e($source) ?>">
<input type="hidden" name="id" value="<?= e((string)$id) ?>">
<button class="nav-link" type="submit">DNS jetzt pruefen</button>
</form>
</div>
<div class="kea-check-card">
<h4>Login-Erkennung</h4>
<p class="muted">Vorbereitet fuer spaetere HTTP/Port-Erkennung. Noch nicht automatisch aktiv, damit keine ungewollten Scans laufen.</p>
</div>
</div>
</section>
<script>
(() => {
const ipsByGroup = <?= json_encode($availableIpsByGroup, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ?>;
const groupSelect = document.querySelector('[data-kea-group-select]');
const ipSelect = document.querySelector('[data-kea-ip-select]');
if (!groupSelect || !ipSelect) {
return;
}
const selectedIp = ipSelect.dataset.selectedIp || '';
const renderIps = () => {
const ips = ipsByGroup[groupSelect.value] || [];
ipSelect.innerHTML = '';
const empty = document.createElement('option');
empty.value = '';
empty.textContent = groupSelect.value ? 'Keine feste IP' : 'Erst Gruppe waehlen';
ipSelect.appendChild(empty);
if (selectedIp && !ips.includes(selectedIp)) {
ips.unshift(selectedIp);
}
for (const ip of ips) {
const option = document.createElement('option');
option.value = ip;
option.textContent = ip;
option.selected = ip === selectedIp;
ipSelect.appendChild(option);
}
};
groupSelect.addEventListener('change', renderIps);
renderIps();
})();
</script>
<?php endif; ?>
</div>
<?= module_shell_footer() ?>