mirror of
https://github.com/Av0idD4rk/firegex.git
synced 2026-10-23 14:31:00 +00:00
Expose 28 tools with shared REST operations, role-scoped bearer authentication, revisions, durable retries, snapshots, jobs and timed rollback. Add Docker verification harnesses and setup/workflow documentation in docs/mcp.md and inst.md. Validated with 330 unit tests, two consecutive 25-case MCP/import runs, and restart recovery; the full upstream regression run remains incomplete.
61 lines
2.5 KiB
Python
61 lines
2.5 KiB
Python
"""Two-phase probe driven by the Docker runner around a real backend restart."""
|
|
import asyncio
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import sys
|
|
import time
|
|
import uuid
|
|
|
|
sys.path.insert(0, "/test/backend")
|
|
sys.path.insert(0, "/test/tests")
|
|
from integration.test_mcp import connect, call, options, read_service
|
|
from mcp_api.store import Store
|
|
|
|
STATE = Path("/tmp/firegex-mcp-restart.json")
|
|
URL = "http://127.0.0.1:4444/"
|
|
|
|
|
|
async def prepare():
|
|
store = Store(os.environ["FIREGEX_MCP_TEST_DB"])
|
|
store.open()
|
|
credential = store.token_create("restart-probe", "admin", 1)
|
|
store.close()
|
|
async with connect(URL, credential) as client:
|
|
name = "restart-" + uuid.uuid4().hex[:12]
|
|
spec = {"name": name, "addresses": [{"ip_int": "127.0.0.1", "port": 23456}]}
|
|
opts = options()
|
|
service = await call(client, "fgx_service_apply", spec=spec, options=opts)
|
|
before = (await call(client, "fgx_firewall_get"))["data"]
|
|
change = await call(client, "fgx_firewall_apply",
|
|
patch={"settings": {"allow_icmp": not before["settings"]["allow_icmp"]}},
|
|
options=options(before["revision"], confirm_within_seconds=5))
|
|
STATE.write_text(json.dumps({"credential": credential, "service": service, "spec": spec,
|
|
"options": opts, "revision": before["revision"], "change_id": change["change"]["id"]}))
|
|
STATE.chmod(0o600)
|
|
print("Prepared an unconfirmed change and a retry receipt", flush=True)
|
|
|
|
|
|
async def verify():
|
|
saved = json.loads(STATE.read_text())
|
|
async with connect(URL, saved["credential"]) as client:
|
|
change = await call(client, "fgx_change_get", change_id=saved["change_id"])
|
|
assert change["data"]["status"] == "rolled_back", change
|
|
current = (await call(client, "fgx_firewall_get"))["data"]
|
|
assert current["revision"] == saved["revision"]
|
|
replay = await call(client, "fgx_service_apply", spec=saved["spec"], options=saved["options"])
|
|
assert replay["change"]["id"] == saved["service"]["change"]["id"]
|
|
sid = replay["data"]["service_id"]
|
|
current = await read_service(client, sid)
|
|
await call(client, "fgx_service_delete", service=sid, options=options(current["revision"]))
|
|
store = Store(os.environ["FIREGEX_MCP_TEST_DB"])
|
|
store.open()
|
|
store.token_revoke(saved["credential"]["id"])
|
|
store.close()
|
|
STATE.unlink()
|
|
print("PASS: expired lease recovered and identical request replayed after restart", flush=True)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(prepare() if sys.argv[1] == "prepare" else verify())
|