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:
@@ -12,7 +12,6 @@ const addZone = QuickModal({
|
||||
validate: (b) => !b.name ? 'Zone name required' : null,
|
||||
successMsg: 'Zone created',
|
||||
},
|
||||
refresh: 'firewall',
|
||||
});
|
||||
|
||||
export default definePage({
|
||||
@@ -25,8 +24,8 @@ export default definePage({
|
||||
const guard = renderGuard(state.firewall, 'Zones', 'Firewall zones', state.firewall.data?.zones);
|
||||
if (guard) return guard;
|
||||
|
||||
const zones = state.firewall.data?.zones?.available || [];
|
||||
const activeZones = state.firewall.data?.zones?.active || {};
|
||||
const zones = Object.keys(state.firewall.data?.zones || {});
|
||||
const activeZones = state.firewall.data?.active_zones || {};
|
||||
const zoneDetails = {};
|
||||
for (const name of zones) {
|
||||
const activeIfaces = activeZones[name];
|
||||
@@ -67,24 +66,32 @@ export default definePage({
|
||||
selected: ifacesArr,
|
||||
fieldKey: 'interfaces',
|
||||
successMsg: 'Interfaces updated',
|
||||
refresh: 'firewall',
|
||||
})()}>Interfaces</button>
|
||||
<button class="btn btn-sm btn-outline"
|
||||
onClick=${() => MultiSelectModal({
|
||||
title: 'Services: ' + name,
|
||||
url: '/api/firewall/zones/' + enc(name) + '/services',
|
||||
options: state.firewall.data?.services || [],
|
||||
options: state.firewall.data?.available_services || [],
|
||||
selected: svcsArr,
|
||||
fieldKey: 'services',
|
||||
successMsg: 'Services updated',
|
||||
refresh: 'firewall',
|
||||
confirm: (b) => {
|
||||
const svcs = (b && b.services) || [];
|
||||
const isDefault = name === state.firewall.data?.default_zone;
|
||||
if (isDefault && !svcs.includes('https') && !svcs.includes('ssh')) {
|
||||
return 'This removes both HTTPS and SSH from the default zone ' +
|
||||
"'" + name + "'. Management access and remote recovery " +
|
||||
'through this zone will be blocked until you reach the ' +
|
||||
'appliance via console or another route.\n\nRemove them anyway?';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
})()}>Services</button>
|
||||
<${ConfirmDelete}
|
||||
url=${'/api/firewall/zones/' + enc(name)}
|
||||
deleteKey=${name}
|
||||
message=${'Delete zone ' + name + '?'}
|
||||
success=${'Zone ' + name + ' deleted'}
|
||||
refresh="firewall"
|
||||
label="Delete" />
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
Reference in New Issue
Block a user