refactor: daemon collectors, thin webui proxies, pure config reads
- move state collectors from lib/state.py to daemon/collectors/ (7 modules, registration side-effect; daemon/server.py imports the package before the first populate()) - webui/api: new daemon_route() decorator factory in common.py collapses the try/except daemon-proxy boilerplate in all 8 blueprints (rules/params/body/transform keep responses identical) - firewall: interface-coverage invariant — config is the source of truth for zone interfaces (absent key = empty, no hands-off zones); pure validate_coverage() enforced at save (400) and apply (409, force: true overrides), top-level `unmanaged` exemption - lib: get_config() reads are now pure (no dir creation or writes); new lib/bootstrap.py creates runtime dirs and persists the one-shot nginx legacy migration at daemon start, after system_import (lib.nginx.migrate_config_file) - lib/common: compute_pending() apply-bookkeeping helper - daemon: emit_and_refresh() handler helper; refresh_state(bump=) so /status/refresh no longer bumps versions (poll/mutation only) - acme: move --log last so acme.sh never treats a real arg as the log-file argument - docs: AGENTS.md, config.md, state-model.md, api.md updated; HARDEN.md dropped (plan implemented); apply-confirm force wording Tests: 917 passed; ruff check + format clean.
This commit is contained in:
+15
-8
@@ -24,10 +24,14 @@ return annotation references them.
|
||||
differs from the recorded hash; `status.pending_diff` lists the field
|
||||
changes since that snapshot. All apply operations (including firewall
|
||||
`config_apply`) re-stamp the baseline. These bookkeeping keys are
|
||||
internal and stripped from every state/API config payload. Canceling
|
||||
pending changes (`POST /api/status/cancel-all`) restores a pending
|
||||
config file from its snapshot; a subsystem with no recorded baseline
|
||||
(never applied) is reported as skipped, not reset.
|
||||
internal and stripped from every state/API config payload. Canceling
|
||||
pending changes (`POST /api/status/cancel-all`) restores a pending
|
||||
config file from its snapshot; a subsystem with no recorded baseline
|
||||
(never applied) is reported as skipped, not reset. Apply-all and
|
||||
cancel-all both decide from this last-poll state (an edit saved within
|
||||
the last poll interval may not yet be flagged), and cancel reverts only
|
||||
the declarative config file — live drift (e.g. manual `firewall-cmd`)
|
||||
survives a cancel.
|
||||
|
||||
## State shape summary
|
||||
|
||||
@@ -62,10 +66,13 @@ Top-level `FirewallState`:
|
||||
// firewalld service XML definitions
|
||||
// (lib/firewall.py get_service_descriptions,
|
||||
// cached per process)
|
||||
uncovered_interfaces: [str], // network-config interfaces (excluding
|
||||
// lo/wg*) not in any live zone —
|
||||
// advisory coverage warning; empty =
|
||||
// fully covered; NOT counted in pending
|
||||
uncovered_interfaces: [str], // network-config interfaces (excluding
|
||||
// lo/wg*) not in any LIVE zone — a
|
||||
// live-drift advisory (config may still
|
||||
// cover them); distinct from the
|
||||
// config-based interface-coverage
|
||||
// invariant (docs/config.md); NOT
|
||||
// counted in pending
|
||||
zones: {zone: zoneDict}, // --list-all-zones; hyphenated keys,
|
||||
// may carry "sources", "ports",
|
||||
// "protocols", "forward-ports", "ics",
|
||||
|
||||
Reference in New Issue
Block a user