status: cancel-all reverts pending changes to last applied config
- lib.common.revert_to_applied(): restore a config file from its
_last_applied_config snapshot (stamped hash); no baseline -> skip with
reason, file untouched
- firewall config_apply now stamps the applied baseline like the other
subsystems; GET /firewall/config and the state collector strip the
internal _last_applied_* keys
- POST /status/cancel-all + /api/status/cancel-all: revert pending
subsystems, {cancelled, skipped, errors}, partial-failure safe
- dashboard: "Cancel All Changes" button with confirm modal
(CancelConfirm, reuses the pending-changes modal rows); the pending
changes card is hidden entirely when nothing is pending
- tests: revert_to_applied, status_cancel_all, firewall stamping/meta
stripping, /api/status/cancel-all route, node tests for CancelConfirm;
firewall _config_apply tests no longer write the real repo config
- docs: api.md, state-model.md, config.md, hoover.md
This commit is contained in:
@@ -55,6 +55,29 @@ def stamp_applied(cfg: dict[str, Any]) -> dict[str, Any]:
|
||||
return cfg
|
||||
|
||||
|
||||
def revert_to_applied(path: Path) -> tuple[bool, str]:
|
||||
"""Restore the config file at *path* to its last-applied snapshot.
|
||||
|
||||
Reads the raw file, and when it records a ``_last_applied_config``
|
||||
snapshot, rewrites the file from that snapshot (stamped with a fresh
|
||||
hash so the pending check reports the config as up to date).
|
||||
|
||||
Args:
|
||||
path: Path to the config JSON file to revert.
|
||||
|
||||
Returns:
|
||||
Tuple ``(True, "")`` when the file was restored, or
|
||||
``(False, reason)`` when it could not be (missing file or no
|
||||
recorded baseline — i.e. the config was never applied).
|
||||
"""
|
||||
cfg = load_json(path)
|
||||
snap = cfg.get(_LAST_APPLIED_CONFIG_KEY)
|
||||
if not isinstance(snap, dict):
|
||||
return False, "No baseline recorded (never applied)"
|
||||
save_json(path, stamp_applied(deepcopy(snap)))
|
||||
return True, ""
|
||||
|
||||
|
||||
def deep_diff(old: Any, new: Any, prefix: str = "") -> list[dict[str, Any]]:
|
||||
"""Return a list of field-level changes between two configurations.
|
||||
|
||||
@@ -284,6 +307,7 @@ __all__ = [
|
||||
"ensure_dirs",
|
||||
"get_interface_ip",
|
||||
"load_json",
|
||||
"revert_to_applied",
|
||||
"run",
|
||||
"run_proc",
|
||||
"save_json",
|
||||
|
||||
Reference in New Issue
Block a user