push
This commit is contained in:
87
templates/devices/edit.html
Normal file
87
templates/devices/edit.html
Normal file
@@ -0,0 +1,87 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Edit device - {{ device.name }} - MikroMon{% endblock %}
|
||||
{% block content %}
|
||||
<div class="d-flex align-items-center justify-content-between mb-3 flex-wrap gap-2">
|
||||
<div>
|
||||
<h1 class="h3 mb-0">Edit device</h1>
|
||||
<div class="text-muted">{{ device.name }} ({{ device.host }})</div>
|
||||
</div>
|
||||
<a class="btn btn-outline-secondary" href="{{ url_for('devices.view', device_id=device.id) }}"><i class="fa-solid fa-arrow-left me-1"></i>Back</a>
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-lg-7">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<form method="post" novalidate>
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12">
|
||||
<label class="form-label">Name</label>
|
||||
{{ form.name(class_="form-control") }}
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Host</label>
|
||||
{{ form.host(class_="form-control") }}
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-6">
|
||||
<label class="form-label">REST port</label>
|
||||
{{ form.rest_port(class_="form-control") }}
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<label class="form-label">REST base path</label>
|
||||
{{ form.rest_base_path(class_="form-control") }}
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-6">
|
||||
<label class="form-label">Username</label>
|
||||
{{ form.username(class_="form-control") }}
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<label class="form-label">Password</label>
|
||||
{{ form.password(class_="form-control", placeholder="Leave blank to keep unchanged") }}
|
||||
<div class="form-text">Leave blank to keep the current password.</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="form-check">
|
||||
{{ form.allow_insecure_tls(class_="form-check-input") }}
|
||||
<label class="form-check-label">Allow insecure TLS (self-signed)</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="form-check">
|
||||
{{ form.ssh_enabled(class_="form-check-input", id="sshEnabled") }}
|
||||
<label class="form-check-label" for="sshEnabled">Enable SSH connector</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<label class="form-label">SSH port</label>
|
||||
{{ form.ssh_port(class_="form-control") }}
|
||||
<div class="form-text">Used only when SSH is enabled.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-3">
|
||||
<button class="btn btn-primary" type="submit"><i class="fa-solid fa-floppy-disk me-1"></i>Save changes</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-5">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<div class="fw-semibold mb-2"><i class="fa-solid fa-circle-info me-2"></i>Notes</div>
|
||||
<ul class="small mb-0">
|
||||
<li>Changing credentials updates the encrypted secret stored in the database.</li>
|
||||
<li>If REST fails, verify host/port/path and TLS setting.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
32
templates/devices/index.html
Normal file
32
templates/devices/index.html
Normal file
@@ -0,0 +1,32 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Devices - MikroMon{% endblock %}
|
||||
{% block content %}
|
||||
<div class="d-flex align-items-center justify-content-between mb-3">
|
||||
<div>
|
||||
<h1 class="h3 mb-0">Devices</h1>
|
||||
<div class="text-muted">Routers / hosts to monitor.</div>
|
||||
</div>
|
||||
<a class="btn btn-primary" href="{{ url_for('devices.new') }}"><i class="fa-solid fa-plus me-1"></i>Add device</a>
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
{% for d in devices %}
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="card shadow-sm h-100">
|
||||
<div class="card-body">
|
||||
<div class="fw-semibold">{{ d.name }}</div>
|
||||
<div class="text-muted small">{{ d.host }}</div>
|
||||
{% if d.last_error %}
|
||||
<div class="mt-2 alert alert-warning py-2 px-3 mb-0 small"><i class="fa-solid fa-triangle-exclamation me-1"></i>{{ d.last_error }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="card-footer bg-white border-0 pt-0 pb-3 px-3">
|
||||
<a class="btn btn-outline-primary btn-sm" href="{{ url_for('devices.view', device_id=d.id) }}"><i class="fa-solid fa-eye me-1"></i>Details</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-12"><div class="alert alert-info mb-0">No devices.</div></div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
87
templates/devices/new.html
Normal file
87
templates/devices/new.html
Normal file
@@ -0,0 +1,87 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}New device - MikroMon{% endblock %}
|
||||
{% block content %}
|
||||
<div class="d-flex align-items-center justify-content-between mb-3 flex-wrap gap-2">
|
||||
<div>
|
||||
<h1 class="h3 mb-0">Add device</h1>
|
||||
<div class="text-muted">Configure REST/SSH access.</div>
|
||||
</div>
|
||||
<a class="btn btn-outline-secondary" href="{{ url_for('devices.index') }}"><i class="fa-solid fa-arrow-left me-1"></i>Back</a>
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-lg-7">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<form method="post" novalidate>
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12">
|
||||
<label class="form-label">Name</label>
|
||||
{{ form.name(class_="form-control", placeholder="e.g. MikroTik RB4011") }}
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Host</label>
|
||||
{{ form.host(class_="form-control", placeholder="192.168.1.1 or router.example.com") }}
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-6">
|
||||
<label class="form-label">REST port</label>
|
||||
{{ form.rest_port(class_="form-control") }}
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<label class="form-label">REST base path</label>
|
||||
{{ form.rest_base_path(class_="form-control", placeholder="/rest") }}
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-6">
|
||||
<label class="form-label">Username</label>
|
||||
{{ form.username(class_="form-control") }}
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<label class="form-label">Password</label>
|
||||
{{ form.password(class_="form-control", placeholder="••••••••") }}
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="form-check">
|
||||
{{ form.allow_insecure_tls(class_="form-check-input") }}
|
||||
<label class="form-check-label">Allow insecure TLS (self-signed)</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="form-check">
|
||||
{{ form.ssh_enabled(class_="form-check-input", id="sshEnabled") }}
|
||||
<label class="form-check-label" for="sshEnabled">Enable SSH connector</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<label class="form-label">SSH port</label>
|
||||
{{ form.ssh_port(class_="form-control") }}
|
||||
<div class="form-text">Used only when SSH is enabled.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-3">
|
||||
<button class="btn btn-primary" type="submit"><i class="fa-solid fa-plus me-1"></i>Save</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-5">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<div class="fw-semibold mb-2"><i class="fa-solid fa-circle-info me-2"></i>Tips</div>
|
||||
<ul class="small mb-0">
|
||||
<li>REST uses the MikroTik API (<code>/rest</code>).</li>
|
||||
<li>If you use a self-signed cert, enable insecure TLS.</li>
|
||||
<li>SSH is optional (e.g. for commands/reads).</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
78
templates/devices/view.html
Normal file
78
templates/devices/view.html
Normal file
@@ -0,0 +1,78 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ device.name }} - Device - MikroMon{% endblock %}
|
||||
{% block content %}
|
||||
<div class="d-flex align-items-start justify-content-between mb-3 flex-wrap gap-2">
|
||||
<div>
|
||||
<h1 class="h3 mb-0">{{ device.name }}</h1>
|
||||
<div class="text-muted">{{ device.host }}</div>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<a class="btn btn-outline-secondary" href="{{ url_for('devices.index') }}"><i class="fa-solid fa-arrow-left me-1"></i>Back</a>
|
||||
<a class="btn btn-outline-primary" href="{{ url_for('devices.edit', device_id=device.id) }}"><i class="fa-solid fa-pen-to-square me-1"></i>Edit</a>
|
||||
<form method="post" action="{{ url_for('devices.delete', device_id=device.id) }}" onsubmit="return confirm('Delete this device?');">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<button class="btn btn-outline-danger" type="submit"><i class="fa-solid fa-trash me-1"></i>Delete</button>
|
||||
</form>
|
||||
<button class="btn btn-primary" id="btnTest"><i class="fa-solid fa-plug-circle-check me-1"></i>Test REST</button>
|
||||
<button class="btn btn-outline-primary" id="btnDiscover"><i class="fa-solid fa-magnifying-glass me-1"></i>Discover</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-lg-5">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<div class="fw-semibold mb-2"><i class="fa-solid fa-server me-2"></i>Configuration</div>
|
||||
<dl class="row mb-0 small">
|
||||
<dt class="col-5 text-muted">REST</dt><dd class="col-7">{{ device.host }}:{{ device.rest_port }}{{ device.rest_base_path }}</dd>
|
||||
<dt class="col-5 text-muted">TLS</dt><dd class="col-7">{{ 'insecure' if device.allow_insecure_tls else 'strict' }}</dd>
|
||||
<dt class="col-5 text-muted">SSH</dt><dd class="col-7">{{ 'enabled' if device.ssh_enabled else 'disabled' }}{% if device.ssh_enabled %} ({{ device.ssh_port }}){% endif %}</dd>
|
||||
<dt class="col-5 text-muted">Last error</dt><dd class="col-7">{{ device.last_error or '-' }}</dd>
|
||||
<dt class="col-5 text-muted">Created</dt><dd class="col-7">{{ device.created_at }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-7">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<div class="fw-semibold mb-2"><i class="fa-solid fa-terminal me-2"></i>Result</div>
|
||||
<pre class="bg-light border rounded p-3 mb-0" style="min-height: 240px" id="out">{}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
(function(){
|
||||
const out = document.getElementById('out');
|
||||
const csrf = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';
|
||||
function show(obj){ out.textContent = JSON.stringify(obj, null, 2); }
|
||||
async function postJson(url){
|
||||
const res = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type':'application/json', 'X-CSRFToken': csrf },
|
||||
body: JSON.stringify({})
|
||||
});
|
||||
let data = null;
|
||||
try { data = await res.json(); } catch(e) { data = { ok:false, error:'Invalid JSON response' }; }
|
||||
if(!res.ok) return { ok:false, ...data };
|
||||
return data;
|
||||
}
|
||||
document.getElementById('btnTest')?.addEventListener('click', async ()=>{
|
||||
show({loading:true});
|
||||
const data = await postJson("{{ url_for('devices.test', device_id=device.id) }}");
|
||||
show(data);
|
||||
});
|
||||
document.getElementById('btnDiscover')?.addEventListener('click', async ()=>{
|
||||
show({loading:true});
|
||||
const res = await fetch("{{ url_for('devices.discover', device_id=device.id) }}");
|
||||
const data = await res.json();
|
||||
show(data);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user