mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-08-27 12:30:13 +03:00
feat: Add batch link_ids to link_delete/link_reset, fields filter to link_list
This commit is contained in:
parent
d6c362b3f0
commit
be69670333
@ -612,10 +612,16 @@ async def link_create(
|
||||
@mcp.tool()
|
||||
async def link_delete(
|
||||
project_id: Annotated[str, Field(description="UUID of the project")],
|
||||
link_id: Annotated[str, Field(description="UUID of the link to delete")],
|
||||
link_id: Annotated[str | None, Field(description="Link UUID (single mode)")] = None,
|
||||
link_ids: Annotated[list[str] | None, Field(description="Batch mode: [\"uuid1\",\"uuid2\"] — delete multiple links in parallel")] = None,
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Delete a link from a project."""
|
||||
return await asyncio.to_thread(_run_handler_sync, delete_link_handler, {"project_id": project_id, "link_id": link_id})
|
||||
"""Delete one or more links from a project."""
|
||||
params = {"project_id": project_id}
|
||||
if link_ids:
|
||||
params["link_ids"] = link_ids
|
||||
else:
|
||||
params["link_id"] = link_id
|
||||
return await asyncio.to_thread(_run_handler_sync, delete_link_handler, params)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
@ -909,9 +915,10 @@ async def node_links(
|
||||
@mcp.tool()
|
||||
async def link_reset(
|
||||
project_id: Annotated[str, Field(description="UUID of the project")],
|
||||
link_id: Annotated[str, Field(description="UUID of the link")],
|
||||
link_id: Annotated[str | None, Field(description="Link UUID (single mode)")] = None,
|
||||
link_ids: Annotated[list[str] | None, Field(description="Batch mode: [\"uuid1\",\"uuid2\"] — reset multiple links in parallel")] = None,
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Reset a link by tearing down the underlying UDP connection and recreating it.
|
||||
"""Reset one or more links by tearing down and recreating the UDP connection.
|
||||
|
||||
Use cases:
|
||||
- Clear accumulated packet errors/drops from the link's UDP connection
|
||||
@ -920,9 +927,12 @@ async def link_reset(
|
||||
|
||||
Filters are preserved but their internal application state resets.
|
||||
"""
|
||||
return await asyncio.to_thread(_run_handler_sync, reset_link_handler, {
|
||||
"project_id": project_id, "link_id": link_id,
|
||||
})
|
||||
params = {"project_id": project_id}
|
||||
if link_ids:
|
||||
params["link_ids"] = link_ids
|
||||
else:
|
||||
params["link_id"] = link_id
|
||||
return await asyncio.to_thread(_run_handler_sync, reset_link_handler, params)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
|
||||
@ -137,9 +137,24 @@ def create_link_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) -> dic
|
||||
|
||||
def delete_link_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) -> dict[str, Any]:
|
||||
project_id = params.get("project_id")
|
||||
if not project_id:
|
||||
return {"error": "project_id is required"}
|
||||
link_ids = params.get("link_ids")
|
||||
if link_ids:
|
||||
if not isinstance(link_ids, list):
|
||||
return {"error": "link_ids must be a list"}
|
||||
conn = _get_connector(gns3_ctx)
|
||||
def _del(lid):
|
||||
try:
|
||||
conn.http_call("delete", f"{conn.base_url}/projects/{project_id}/links/{lid}")
|
||||
return {"link_id": lid, "status": "deleted"}
|
||||
except Exception as e:
|
||||
return {"link_id": lid, "status": "error", "error": str(e)}
|
||||
with ThreadPoolExecutor(max_workers=min(len(link_ids), BATCH_MAX_WORKERS)) as pool:
|
||||
return list(pool.map(_del, link_ids))
|
||||
link_id = params.get("link_id")
|
||||
if not project_id or not link_id:
|
||||
return {"error": "project_id and link_id are required"}
|
||||
if not link_id:
|
||||
return {"error": "link_id or link_ids is required"}
|
||||
conn = _get_connector(gns3_ctx)
|
||||
conn.http_call("delete", f"{conn.base_url}/projects/{project_id}/links/{link_id}")
|
||||
return {"message": f"Link {link_id} deleted", "link_id": link_id}
|
||||
@ -167,9 +182,25 @@ def update_link_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) -> dic
|
||||
|
||||
def reset_link_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) -> dict[str, Any]:
|
||||
project_id = params.get("project_id")
|
||||
if not project_id:
|
||||
return {"error": "project_id is required"}
|
||||
link_ids = params.get("link_ids")
|
||||
if link_ids:
|
||||
if not isinstance(link_ids, list):
|
||||
return {"error": "link_ids must be a list"}
|
||||
conn = _get_connector(gns3_ctx)
|
||||
def _rst(lid):
|
||||
try:
|
||||
url = f"{conn.base_url}/projects/{project_id}/links/{lid}/reset"
|
||||
r = conn.http_call("post", url).json()
|
||||
return {"link_id": lid, "status": "reset", "link": r}
|
||||
except Exception as e:
|
||||
return {"link_id": lid, "status": "error", "error": str(e)}
|
||||
with ThreadPoolExecutor(max_workers=min(len(link_ids), BATCH_MAX_WORKERS)) as pool:
|
||||
return list(pool.map(_rst, link_ids))
|
||||
link_id = params.get("link_id")
|
||||
if not project_id or not link_id:
|
||||
return {"error": "project_id and link_id are required"}
|
||||
if not link_id:
|
||||
return {"error": "link_id or link_ids is required"}
|
||||
conn = _get_connector(gns3_ctx)
|
||||
url = f"{conn.base_url}/projects/{project_id}/links/{link_id}/reset"
|
||||
result = conn.http_call("post", url).json()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user