This reference documents the Python modules that make up the Azazel control plane. The intent is to provide enough context for operators to extend or mock the behaviour during testing.
Azazel-Edge now uses the Azazel-Zero style unified Textual TUI.
The legacy azctl/menu modular implementation was removed.
azctl/tui_zero.py
azctl/tui_zero_textual.py
- CLI:
python3 -m azctl.cli menu - Internally,
azctl.cli.cmd_menu()callsazctl.tui_zero.run_menu()
- Loads state from
runtime/ui_snapshot.jsonwhen available. - Falls back to
python3 -m azctl.cli status --json. - Menu actions map to mode events:
stage_open->portalreprobe->shieldcontain->lockdown
textual(required for menu TUI)rich(status/TUI rendering helpers used elsewhere)
State(name: str, description: str = "")Event(name: str, severity: int = 0)Transition(source, target, condition, action=None)StateMachine(initial_state, config_path=None, window_size=5)provides:add_transition(transition)– register a new transition.dispatch(event)– evaluate transitions from the current state.reset()– return to the initial state and clear score history.summary()– dictionary suitable for API responses.get_thresholds()– read shield/lockdown thresholds and unlock timers fromazazel.yaml.get_actions_preset()– fetch the delay/shape/block preset for the current mode.apply_score(severity)– update the moving-average score window, transition to the correct mode, and return evaluation metadata.
ScoreEvaluator computes cumulative severity and provides classify(score)
which returns normal, guarded, elevated, or critical.
DelayAction, ShapeAction, BlockAction, and RedirectAction derive from the
common Action interface and expose plan(target) iterators. Each yields
ActionResult objects that describe tc/nftables commands without executing
side-effects.
SuricataTail and CanaryTail read JSON logs from disk and emit Event
instances. They are intentionally deterministic, easing unit test coverage.
APIServer is a minimal dispatcher used by future HTTP front-ends. The bundled
handler add_health_route(version) returns a HealthResponse dataclass.
build_machine() wires the portal/shield/lockdown states. load_events(path)
loads YAML describing synthetic events. main(argv) powers the systemd service
by feeding events into AzazelDaemon, which applies score-based decisions and
writes decisions.log entries containing the chosen mode and action presets.
The controller exposes a minimal HTTP interface for supervised overrides. A
POST request to /v1/mode with a JSON body such as { "mode": "shield" }
will transition the daemon to the requested state. The handler immediately
applies the corresponding preset from azazel.yaml (delay, shaping rate, and
block flag) and records the outcome to decisions.log alongside operator
metadata. Preset values are documented in the operations guide's
mode action table.
scripts/suricata_generate.pyrenders the Suricata YAML template.scripts/nft_apply.shandscripts/tc_reset.shmanage enforcement tools.scripts/sanity_check.shprints warnings if dependent services are inactive.scripts/rollback.shremoves installed assets.scripts/resolve_allowlist.pyresolves medical FQDNs to CIDRs and writes the lockdown nftables allowlist used by the generated template.