OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

zone_show.php

9 KB
<?php $this->layout('layouts/main', [
    'page_title'    => 'DNS-Zone',
    'current_route' => 'dns',
    'full_width'    => true,
]); ?>
<?php
$zone        = $zone        ?? [];
$records     = $records     ?? [];
$typeCounts  = $type_counts ?? [];
$filterQ     = $filter_q    ?? '';
$filterType  = $filter_type ?? '';
$zoneId      = (int)($zone['id'] ?? 0);
?>
<div class="page-body">
    <div class="content-header">
        <div>
            <h1><?= $this->e($zone['name'] ?? '') ?></h1>
            <ol class="breadcrumb">
                <li class="breadcrumb-item"><a href="/"><?= $this->te('Home') ?></a></li>
                <li class="breadcrumb-item"><a href="/dns">DNS</a></li>
                <li class="breadcrumb-item active"><?= $this->e($zone['name'] ?? '') ?></li>
            </ol>
        </div>
        <?php if (!empty($can_manage)): ?>
        <div>
            <form action="/dns/zones/<?= $zoneId ?>" method="POST" style="display:inline;">
                <input type="hidden" name="_csrf"   value="<?= $this->csrf() ?>">
                <input type="hidden" name="_method" value="DELETE">
                <button type="button" class="btn btn-sm btn-danger"
                        onclick="itConfirmSubmit(this, 'Zone entfernen?', 'Die Zone „<?= $this->e(addslashes((string)($zone['name'] ?? ''))) ?>“ wird mit allen Records und ihrem Änderungsverlauf aus OpenNIT entfernt. Der DNS-Server selbst bleibt unberührt – meldet ein Agent die Zone erneut, taucht sie wieder auf.', 'Entfernen')">
                    <i class="fas fa-trash"></i> <?= $this->te('Zone entfernen') ?>
                </button>
            </form>
        </div>
        <?php endif; ?>
    </div>

    <!-- Zonen-Metadaten -->
    <section class="detail-card" style="margin-bottom:1.25rem;">
        <div class="detail-card-body" style="display:flex;flex-wrap:wrap;gap:2rem;">
            <div><div style="font-size:.75rem;color:var(--gray-500);text-transform:uppercase;"><?= $this->te('Typ') ?></div><div style="font-weight:600;"><?= $this->e($zone['zone_type'] ?: '–') ?></div></div>
            <div><div style="font-size:.75rem;color:var(--gray-500);text-transform:uppercase;"><?= $this->te('DNS-Server') ?></div><div style="font-weight:600;"><?= $this->e($zone['dns_server'] ?: '–') ?></div></div>
            <div><div style="font-size:.75rem;color:var(--gray-500);text-transform:uppercase;"><?= $this->te('AD-integriert') ?></div><div style="font-weight:600;"><?= !empty($zone['is_ad_integrated']) ? 'Ja' : 'Nein' ?></div></div>
            <div><div style="font-size:.75rem;color:var(--gray-500);text-transform:uppercase;"><?= $this->te('Reverse-Zone') ?></div><div style="font-weight:600;"><?= !empty($zone['is_reverse']) ? 'Ja' : 'Nein' ?></div></div>
            <div><div style="font-size:.75rem;color:var(--gray-500);text-transform:uppercase;"><?= $this->te('Records') ?></div><div style="font-weight:600;"><?= (int)($zone['record_count'] ?? 0) ?></div></div>
            <div><div style="font-size:.75rem;color:var(--gray-500);text-transform:uppercase;"><?= $this->te('Letzter Sync') ?></div><div style="font-weight:600;"><?= !empty($zone['last_synced_at']) ? $this->e(date('d.m.Y H:i', strtotime($zone['last_synced_at']))) : '–' ?></div></div>
        </div>
    </section>

    <!-- Filter -->
    <div class="card card-outline card-primary">
    <div class="filter-card-body">
        <form method="get" action="/dns/zones/<?= $zoneId ?>" style="display:flex;gap:.5rem;flex-wrap:wrap;align-items:center;">
            <input type="search" name="q" value="<?= $this->e($filterQ) ?>" class="form-control form-control-sm" placeholder="<?= $this->te('Record suchen…') ?>" autocomplete="off" style="max-width:240px;">
            <select name="type" class="form-control form-control-sm" style="max-width:160px;">
                <option value=""><?= $this->te('Alle Typen') ?></option>
                <?php foreach ($typeCounts as $t => $c): ?>
                    <option value="<?= $this->e($t) ?>" <?= $filterType === $t ? 'selected' : '' ?>><?= $this->e($t) ?> (<?= (int)$c ?>)</option>
                <?php endforeach; ?>
            </select>
            <button type="submit" class="btn btn-sm btn-primary"><?= $this->te('Filtern') ?></button>
            <?php if ($filterQ !== '' || $filterType !== ''): ?><a href="/dns/zones/<?= $zoneId ?>" class="btn btn-sm btn-default"><?= $this->te('Zurücksetzen') ?></a><?php endif; ?>
        </form>
        <a href="/dns" class="btn btn-sm btn-default" style="margin-left:auto;"><?= $this->te('&laquo; Alle Zonen') ?></a>
    </div>
    </div>

    <!-- Records -->
    <?php if (empty($records)): ?>
        <div class="empty-state">
            <span class="empty-icon"><i class="fas fa-search"></i></span>
            <strong><?= $this->te(($filterQ !== '' || $filterType !== '') ? 'Keine Records für den Filter' : 'Keine Records') ?></strong>
        </div>
    <?php else: ?>
        <div class="table-wrapper">
            <table class="data-table">
                <thead><tr><th scope="col"><?= $this->te('Name') ?></th><th scope="col"><?= $this->te('Typ') ?></th><th scope="col"><?= $this->te('Daten') ?></th><th scope="col"><?= $this->t('TTL') ?></th></tr></thead>
                <tbody>
                <?php foreach ($records as $r): ?>
                    <tr>
                        <td style="font-family:monospace;"><?= $this->e($r['name']) ?></td>
                        <td><span class="badge"><?= $this->e($r['type']) ?></span></td>
                        <td style="font-family:monospace;word-break:break-all;"><?= $this->e($r['data'] ?? '') ?></td>
                        <td style="color:var(--gray-500);"><?= $r['ttl'] !== null ? (int)$r['ttl'] : '–' ?></td>
                    </tr>
                <?php endforeach; ?>
                </tbody>
            </table>
        </div>
    <?php endif; ?>

    <?php
    $changes     = $changes      ?? [];
    $historyDays = (int)($history_days ?? 0);
    $artLabel    = ['added' => 'Hinzugefügt', 'changed' => 'Geändert', 'removed' => 'Entfernt'];
    $artPill     = ['added' => 'status-pill--success', 'changed' => 'status-pill--warning', 'removed' => 'status-pill--danger'];
    ?>
    <h2 style="margin-top:2rem;font-size:1.05rem;"><?= $this->te('Änderungen') ?></h2>
    <?php if (empty($changes)): ?>
        <div class="empty-state">
            <span class="empty-icon"><i class="fas fa-history"></i></span>
            <strong><?= $this->te('Noch keine Änderungen aufgezeichnet') ?></strong>
            <p><?= $this->te('Der Verlauf beginnt mit dem zweiten Import dieser Zone &ndash; der erste legt den Ausgangsstand fest.') ?></p>
        </div>
    <?php else: ?>
        <div class="table-wrapper">
            <table class="data-table">
                <thead><tr><th scope="col"><?= $this->te('Zeitpunkt') ?></th><th scope="col"><?= $this->te('Art') ?></th><th scope="col"><?= $this->te('Name') ?></th><th scope="col"><?= $this->te('Typ') ?></th><th scope="col"><?= $this->te('Vorher') ?></th><th scope="col"><?= $this->te('Nachher') ?></th></tr></thead>
                <tbody>
                <?php foreach ($changes as $c): ?>
                    <tr>
                        <td style="white-space:nowrap;color:var(--gray-500);">
                            <?= $this->e(date('d.m.Y H:i', strtotime((string)$c['changed_at']))) ?>
                        </td>
                        <td>
                            <span class="status-pill <?= $artPill[$c['change_type']] ?? 'status-pill--neutral' ?>">
                                <?= $artLabel[$c['change_type']] ?? $this->e($c['change_type']) ?>
                            </span>
                        </td>
                        <td style="font-family:monospace;"><?= $this->e($c['record_name']) ?></td>
                        <td><span class="badge"><?= $this->e($c['record_type']) ?></span></td>
                        <td style="font-family:monospace;word-break:break-all;color:var(--gray-500);">
                            <?= $c['old_data'] !== null ? $this->e($c['old_data']) : '&mdash;' ?>
                            <?php if ($c['old_ttl'] !== null && $c['old_ttl'] !== $c['new_ttl']): ?>
                                <small><?= $this->t('(TTL') ?> <?= (int)$c['old_ttl'] ?>)</small>
                            <?php endif; ?>
                        </td>
                        <td style="font-family:monospace;word-break:break-all;">
                            <?= $c['new_data'] !== null ? $this->e($c['new_data']) : '&mdash;' ?>
                            <?php if ($c['new_ttl'] !== null && $c['old_ttl'] !== $c['new_ttl']): ?>
                                <small><?= $this->t('(TTL') ?> <?= (int)$c['new_ttl'] ?>)</small>
                            <?php endif; ?>
                        </td>
                    </tr>
                <?php endforeach; ?>
                </tbody>
            </table>
        </div>
        <small class="form-hint" style="display:block;margin-top:.5rem;">
            <?php if ($historyDays > 0): ?>
                <?= $this->t('Der Verlauf wird {tage} Tage aufbewahrt.', ['tage' => $this->e($historyDays)]) ?>
            <?php else: ?>
                <?= $this->te('Der Verlauf wird unbegrenzt aufbewahrt.') ?>
            <?php endif; ?>
            <?= $this->t('Aufgezeichnet wird, was sich zwischen zwei Importen unterscheidet &ndash; nicht, wer die Änderung am DNS-Server vorgenommen hat.') ?>
        </small>
    <?php endif; ?>
</div>
<?php if (!empty($can_manage)): ?><?= $this->partial('confirm_modal') ?><?php endif; ?>