0a18b94d84
- Flask + SQLite web app with user authentication - Zone management: create/delete zones, edit raw zone files - Record management: add/delete A/AAAA/CNAME/MX/TXT/NS/PTR/SRV/CAA records - Service control: start/stop/restart/reload BIND via systemctl/rndc - Configuration editor: edit named.conf.options/local with syntax validation - DNS query testing: online dig tool - Audit log: all operations logged with user/timestamp - BIND9 backend, listening on port 53
126 lines
5.4 KiB
HTML
126 lines
5.4 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}仪表盘 - DNS 管理{% endblock %}
|
|
{% block content %}
|
|
<div class="dashboard">
|
|
<div class="stats-grid">
|
|
<div class="stat-card">
|
|
<div class="stat-icon {% if status.active %}stat-ok{% else %}stat-err{% endif %}">●</div>
|
|
<div class="stat-info">
|
|
<div class="stat-label">BIND 服务</div>
|
|
<div class="stat-value {% if status.active %}text-ok{% else %}text-err{% endif %}">
|
|
{{ status.status | upper }}
|
|
</div>
|
|
<div class="stat-sub">开机自启: {{ '是' if status.enabled else '否' }}</div>
|
|
</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-icon">🌍</div>
|
|
<div class="stat-info">
|
|
<div class="stat-label">域名数量</div>
|
|
<div class="stat-value">{{ zone_count }}</div>
|
|
</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-icon">📋</div>
|
|
<div class="stat-info">
|
|
<div class="stat-label">记录总数</div>
|
|
<div class="stat-value">{{ total_records }}</div>
|
|
</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-icon">⚙️</div>
|
|
<div class="stat-info">
|
|
<div class="stat-label">BIND 版本</div>
|
|
<div class="stat-value-small">{{ version[:40] }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="dashboard-grid">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h2>服务控制</h2>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="service-controls">
|
|
<a href="{{ url_for('service_control', action='start') }}" class="btn btn-success" onclick="return confirm('启动 BIND 服务?')">▶ 启动</a>
|
|
<a href="{{ url_for('service_control', action='stop') }}" class="btn btn-warning" onclick="return confirm('停止 BIND 服务?')">⏹ 停止</a>
|
|
<a href="{{ url_for('service_control', action='restart') }}" class="btn btn-info" onclick="return confirm('重启 BIND 服务?')">🔄 重启</a>
|
|
<a href="{{ url_for('service_control', action='reload') }}" class="btn btn-primary" onclick="return confirm('重载 BIND 配置?')">🔁 重载配置</a>
|
|
</div>
|
|
<div class="service-note">
|
|
<p>📝 <strong>提示:</strong> BIND 监听标准 53 端口,可直接用 <code>dig a.wxj.aa</code> 查询。</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h2>域名概览</h2>
|
|
<a href="{{ url_for('zone_create') }}" class="btn btn-primary btn-sm">+ 添加域名</a>
|
|
</div>
|
|
<div class="card-body">
|
|
{% if zones %}
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>域名</th>
|
|
<th>类型</th>
|
|
<th>记录数</th>
|
|
<th>操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for z in zones %}
|
|
<tr>
|
|
<td><a href="{{ url_for('zone_detail', zone_name=z.name) }}"><strong>{{ z.name }}</strong></a></td>
|
|
<td><span class="badge">{{ z.type }}</span></td>
|
|
<td>{{ z.record_count }}</td>
|
|
<td>
|
|
<a href="{{ url_for('zone_detail', zone_name=z.name) }}" class="btn-sm btn-primary">管理</a>
|
|
<a href="{{ url_for('zone_raw', zone_name=z.name) }}" class="btn-sm btn-info">原始文件</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
{% else %}
|
|
<div class="empty-state">
|
|
<p>还没有任何域名</p>
|
|
<a href="{{ url_for('zone_create') }}" class="btn btn-primary">+ 创建第一个域名</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h2>最近操作</h2>
|
|
<a href="{{ url_for('logs') }}" class="btn-sm btn-info">查看全部</a>
|
|
</div>
|
|
<div class="card-body">
|
|
{% if recent_logs %}
|
|
<table class="table">
|
|
<thead>
|
|
<tr><th>时间</th><th>用户</th><th>操作</th><th>详情</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for log in recent_logs %}
|
|
<tr>
|
|
<td class="text-mono">{{ log.timestamp.strftime('%Y-%m-%d %H:%M:%S') }}</td>
|
|
<td>{{ log.user }}</td>
|
|
<td>{{ log.action }}</td>
|
|
<td class="text-mono text-sm">{{ log.detail }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
{% else %}
|
|
<p class="text-muted">暂无操作记录</p>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|