ws: migrate push stream to data streaming
- daemon: send full snapshot on connect; versions/tick now carry the full state of one subsystem (subsystem + data); no legacy updated/subsystems payloads; refresh_state and POST /status/refresh broadcast per-subsystem versions with data - client: modelSet() patches models in place; onMessage/topic refresh retired; 3s initial-load fallback via new POST /api/status/refresh - schema: lib/schema.py TypedDicts + hoover/schema.js defaults + docs/state-model.md as single source of truth for state shapes - system: poll at 1s, volatile metrics registered, dashboard uses a dedicated system model (status model removed) - firewall: refuse to strip both https and ssh from the default zone (409, force override via UI confirm); set_zone_services persists services to the declarative config; collector exposes default_zone - UI: pages migrate to flat state shapes; post-mutation modelFetch refreshes removed (WS delta covers it) - tests: ws snapshot/delta/broadcast, refresh-state, schema types, model-set/js ws handler and reconnect fallback
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/** WireGuard page — tunnel & peer management. */
|
||||
import { html, PageHeader, Badge, StatusDot, Empty, Table, ServiceStatus, renderGuard, esc, enc, $val, apiFetch, toast, openModal, closeModal, formModal, definePage, getModel, modelFetch, ActionButton, ActionCell, ConfirmDelete, MonoText, ActionGroup, QuickModal, downloadBlob, formAction, ApplyConfirm, qrSVG, csvToArr } from '/static/hoover/index.js';
|
||||
import { html, PageHeader, Badge, StatusDot, Empty, Table, ServiceStatus, renderGuard, esc, enc, $val, apiFetch, toast, openModal, closeModal, formModal, definePage, getModel, ActionButton, ActionCell, ConfirmDelete, MonoText, ActionGroup, QuickModal, downloadBlob, formAction, ApplyConfirm, qrSVG, csvToArr } from '/static/hoover/index.js';
|
||||
|
||||
/* ── LAN detection helper ────────────────────────────────────── */
|
||||
function getLanSubnets() {
|
||||
@@ -76,7 +76,6 @@ const addPeer = QuickModal({
|
||||
!b.access_class ? 'Access Class is required' : null,
|
||||
successMsg: 'Peer added',
|
||||
},
|
||||
refresh: 'wireguard',
|
||||
postRender: (inner, data) => {
|
||||
const presetEl = document.getElementById('wg-allowed-preset');
|
||||
if (presetEl) {
|
||||
@@ -256,7 +255,7 @@ function settingsModal(wireguardData, state) {
|
||||
if (!resp.ok) throw resp.error || 'Failed to save';
|
||||
toast('Settings saved', 'success');
|
||||
closeModal(idx);
|
||||
modelFetch('wireguard');
|
||||
// No modelFetch — WS delta updates the wireguard model.
|
||||
}),
|
||||
},
|
||||
],
|
||||
@@ -291,7 +290,6 @@ const addClass = QuickModal({
|
||||
!b.listen_port ? 'Listen port is required' : null,
|
||||
successMsg: 'Class added',
|
||||
},
|
||||
refresh: 'wireguard',
|
||||
postRender: (inner) => {
|
||||
const sel = document.getElementById('wc-lan');
|
||||
if (sel) {
|
||||
@@ -330,7 +328,7 @@ function editClassModal(key, cls, peerCount) {
|
||||
if (!resp.ok) throw resp.error || 'Failed';
|
||||
toast('Class updated', 'success');
|
||||
closeModal(idx);
|
||||
modelFetch('wireguard');
|
||||
// No modelFetch — WS delta updates the wireguard model.
|
||||
}),
|
||||
},
|
||||
],
|
||||
@@ -374,17 +372,17 @@ function renderAccessClasses(config, status) {
|
||||
<td>
|
||||
${!hasKeys
|
||||
? html`<${ActionButton} url=${'/api/wireguard/classes/keys/' + enc(k)} label="Keys"
|
||||
cls="btn btn-sm btn-warning" successMsg=${'Keys generated for ' + esc(k)} refresh="wireguard" />`
|
||||
cls="btn btn-sm btn-warning" successMsg=${'Keys generated for ' + esc(k)} />`
|
||||
: ''}
|
||||
<button class="btn btn-sm btn-outline" onClick=${() => editClassModal(k, v, pCount)}>Edit</button>
|
||||
<${ActionButton} url=${'/api/wireguard/classes/' + enc(k) + '/' + (isUp ? 'down' : 'up')}
|
||||
cls="btn btn-sm btn-outline" labelOn="Stop" labelOff="Start" condition=${isUp}
|
||||
successMsg=${isUp ? 'Tunnel stopped' : 'Tunnel started'} refresh="wireguard" />
|
||||
successMsg=${isUp ? 'Tunnel stopped' : 'Tunnel started'} />
|
||||
${(pCount > 0)
|
||||
? html`<button class="btn btn-sm btn-outline" disabled title="Peers reference this class">Delete</button>`
|
||||
: html`<${ConfirmDelete} url=${'/api/wireguard/classes'} body=${{ key: k }}
|
||||
deleteKey=${k} message=${'Delete access class ' + esc(k) + '?'} success="Class deleted"
|
||||
refresh="wireguard" label="Delete" />`}
|
||||
label="Delete" />`}
|
||||
</td>
|
||||
</tr>`;
|
||||
});
|
||||
@@ -469,7 +467,6 @@ export default definePage({
|
||||
removeUrl=${'/api/wireguard/peers/' + enc(p.name)}
|
||||
removeMessage=${'Remove peer ' + p.name + '?'}
|
||||
removeSuccess="Peer removed"
|
||||
removeRefresh="wireguard"
|
||||
deleteKey=${p.name} />
|
||||
</tr>`;
|
||||
});
|
||||
@@ -492,12 +489,12 @@ export default definePage({
|
||||
<div class="d-flex justify-content-between">
|
||||
<span>Subnet: ${esc(v.subnet || '-')}</span>
|
||||
<span>LAN: ${v.lan_access ? 'Yes' : 'No'}</span>
|
||||
<span>Keys: ${classHasKeys(v) ? 'Ready' : html`<${ActionButton} url=${'/api/wireguard/classes/keys/' + enc(k)} label="Generate" cls="btn btn-xs btn-warning" successMsg=${'Keys generated'} refresh="wireguard" />`}</span>
|
||||
<span>Keys: ${classHasKeys(v) ? 'Ready' : html`<${ActionButton} url=${'/api/wireguard/classes/keys/' + enc(k)} label="Generate" cls="btn btn-xs btn-warning" successMsg=${'Keys generated'} />`}</span>
|
||||
</div>
|
||||
<div style="margin-top: 4px;">
|
||||
<${ActionButton} url=${'/api/wireguard/classes/' + enc(k) + '/' + (isUp ? 'down' : 'up')}
|
||||
cls="btn btn-xs btn-outline" labelOn="Stop" labelOff="Start" condition=${isUp}
|
||||
successMsg=${isUp ? 'Stopped' : 'Started'} refresh="wireguard" />
|
||||
successMsg=${isUp ? 'Stopped' : 'Started'} />
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
@@ -512,12 +509,10 @@ export default definePage({
|
||||
url: '/api/wireguard/' + (isUp ? 'down' : 'up'),
|
||||
labelOn: 'Stop All', labelOff: 'Start All', condition: isUp,
|
||||
successMsg: 'Tunnel ' + (isUp ? 'stopped' : 'started'),
|
||||
refresh: 'wireguard',
|
||||
}),
|
||||
ApplyConfirm({
|
||||
pending: st.pending_changes || false,
|
||||
successMsg: 'WireGuard applied',
|
||||
refresh: ['wireguard', 'firewall'],
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user