mirror of
https://github.com/hansjone/netx.git
synced 2026-10-18 02:50:48 +08:00
MCP: add bizMonitor server, align ops/topology tools, harden CLI exec
- New packages/netx-bizmonitor-mcp: 8 read-only cutover/biz-state tools mirroring the netxops bizMonitor group. - Align netx-mcp (15) and netx-topology-mcp (16) with backend HTTP contracts; surface partial batch failures as tool errors. - CLI hard gate: single-line show/display only; exec job IDs, path containment, owner and ne:exec checks. - Cisco IOSv collection: stable prompt/echo handling over CR. - Remove legacy netx_api/mcp and mcp_server.py; add mcp.all.json; sync skills and docs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d8da7acb7d
commit
9085cac742
63 changed files with 3251 additions and 1092 deletions
|
|
@ -7,6 +7,7 @@ from fastapi.responses import Response
|
|||
from sqlalchemy.orm import Session
|
||||
|
||||
from .auth_deps import AuthContext, require_user
|
||||
from .auth_scopes import has_scope
|
||||
from .auth_service import write_audit
|
||||
from .db import get_db
|
||||
from .device_types import SUPPORTED_VENDORS
|
||||
|
|
@ -275,6 +276,10 @@ def api_create_exec_job(
|
|||
|
||||
uid, uname = _actor(ctx)
|
||||
payload = body.model_dump(exclude_none=True)
|
||||
if not has_scope(ctx.scopes, "ne:exec"):
|
||||
raise HTTPException(status_code=403, detail={"error": "insufficient_scope", "required": ["ne:exec"]})
|
||||
if not uid:
|
||||
raise HTTPException(status_code=401, detail={"error": "job_owner_required"})
|
||||
is_batch = bool(
|
||||
payload.get("targets")
|
||||
or payload.get("ne_ids")
|
||||
|
|
@ -330,7 +335,7 @@ def api_create_exec_job(
|
|||
)
|
||||
return out
|
||||
|
||||
ack = start_ne_exec_job(kind=kind, arguments=payload, runner=_runner)
|
||||
ack = start_ne_exec_job(kind=kind, arguments=payload, owner_user_id=uid, runner=_runner)
|
||||
write_audit(
|
||||
db,
|
||||
action="ne.exec_job_start",
|
||||
|
|
@ -349,9 +354,16 @@ def api_get_exec_job(
|
|||
job_id: str,
|
||||
ctx: Annotated[AuthContext, Depends(require_user)],
|
||||
):
|
||||
"""Poll a background exec job started via POST /exec-jobs."""
|
||||
_ = ctx
|
||||
return get_ne_exec_job(job_id)
|
||||
"""Poll own jobs; admins (role or admin:users scope) may read any job."""
|
||||
if not has_scope(ctx.scopes, "ne:exec"):
|
||||
raise HTTPException(status_code=403, detail={"error": "insufficient_scope", "required": ["ne:exec"]})
|
||||
uid, _ = _actor(ctx)
|
||||
is_admin = ctx.user.role == "admin" or has_scope(ctx.scopes, "admin:users")
|
||||
out = get_ne_exec_job(job_id, user_id=uid, is_admin=is_admin)
|
||||
if out.get("error_code") in {"job_forbidden", "invalid_job_id", "job_id_required"}:
|
||||
status = 403 if out["error_code"] == "job_forbidden" else 400
|
||||
raise HTTPException(status_code=status, detail=out)
|
||||
return out
|
||||
|
||||
|
||||
@router.post("/connect-test")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue