Repository navigation
Add NetDevOps automation toolkit: Python SDK + CLI, in-app Automation tab, CI gate - #1
Conversation
…ab, CI gate - automation/ package: typed NetSimClient SDK, Typer CLI, Jinja2 config templating, render->push->validate pipeline, declarative network definitions - in-app Automation tab: config-as-code, intended-state validation, drift detection, copy-as-Python, OSPF demo loader - examples/automation/provision_and_verify.py end-to-end demo - .github/workflows/netdevops.yml: render->push->validate CI gate - tests/test_automation_toolkit.py (6 tests); 197 passing total Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The in-app seeded Jinja template (AUTO_TPL_DEFAULT) omitted the per-block 'exit' lines, so 'Render & push' failed with '% Invalid input' when entering a second interface / the OSPF block (NetSim's CLI requires leaving a config sub-mode before entering another). Matches automation/templates/router.j2. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Automation tab — end-to-end test resultsTested the new Automation/NetDevOps tab through the browser against the exact PR-branch code (local Result: T1 demo provision ✓ · T2 validate 100/100 (healthy) & 25/100 (broken) ✓ · T3 render & push ✓ (after fix) · T4 drift detection ✓ · T5 copy-as-Python ✓ 🔧 Bug found & fixed: Render & push emitted % Invalid inputThe in-app default Jinja template ( Fixed by adding T1 — Load OSPF demoCanvas shows PC1–R1–R2–PC2 (4 devices, 3 links); status "Provisioned PC1–R1=OSPF=R2–PC2 via automation push." T2 — Intended-state validation (healthy + adversarial)
T4 — Drift detectionSave baseline → T5 — Copy as PythonEmits a runnable SDK snippet ( Tested by Devin — session: https://app.devin.ai/sessions/850f5eff01f640b9b3f6079509dce508 |
Summary
Adds a network-automation / NetDevOps layer on top of NetSim so the project visibly demonstrates Python network automation (config-as-code, validation, drift) — not just a clickable simulator. The engine already exposed an automation surface (
app/engine/automation.py: Jinja-style templating, intent↔CLI, snapshot/drift, Batfish-style validation) wired to REST endpoints, but there was no SDK, no CLI, no CI, and no UI for it. This PR fills that gap; no engine behavior changes.The whole network is described as one declarative file (
automation/labs/two_router_ospf.yaml— topology + per-device vars + intended-state assertions) and a single command deploys and verifies it: a real OSPF adjacency between R1/R2 and validated cross-subnet reachability (PC1↔PC2), 8/8 assertions passing.What's added
1. Python SDK + CLI (
automation/)client.NetSimClient— typed, stdlib-only (urllib) REST SDK, one method per primitive (apply_lab,push_config,render,snapshot,drift,validate,get_intent, …).netdevops.py— therender_configs → topology_spec → deploy_and_verifypipeline. Configs render with real Jinja2 (templates/router.j2,host.j2) from per-devicevars, then push;deploy_and_verifyreturns(report, ok)whereokrequires clean topology + clean pushes + all assertions passing.cli.py— Typer CLI:render | deploy | validate | drift | intent.deployexits non-zero on failure, so it doubles as a CI gate.2. In-app Automation tab (
app/static/index.html+app.js)/api/automation/*endpoints: config-as-code (template + vars → render / render&push), intended-state Validate (PASS/FAIL + score), drift (snapshot baseline → diff), a "Copy as Python" button that emits an equivalent SDK script, and a one-click "Load OSPF demo" that provisions PC1–R1=OSPF=R2–PC2 so the tab is immediately usable in the live demo.3. NetDevOps CI (
.github/workflows/netdevops.yml)automation.cli deploy …then the example script (render → push → validate → drift), failing the build on any misconfiguration. Existingci.ymlnow also installsautomation/requirements.txt.4. Tests + docs
tests/test_automation_toolkit.py(6 tests: pure render/spec/report functions + full pipeline against an in-thread uvicorn server, drift, intent). 197 tests pass (was 191).examples/automation/provision_and_verify.py+ README; README gains a "Network automation (NetDevOps)" section, a CI badge, and SEO keywords.Dependency note
automation/requirements.txtpinstyper==0.12.5andclick==8.1.7— newer Click (8.2+) changedmake_metavar()'s signature and breaks Typer 0.12.5. App runtime deps (requirements.txt) are untouched; these are tooling-only.Verified locally
python -m automation.cli deploy automation/labs/two_router_ospf.yaml→validation: 8/8 passed (score 100/100), exit 0.python -m pytest -q→ 197 passed.