From 9a39ddfcc7c469bf1a5aa774258921f13ab35064 Mon Sep 17 00:00:00 2001 From: oliver Date: Fri, 5 Jun 2026 16:14:59 +0800 Subject: [PATCH] feat(ne-exec): allow ping and ping6 on managed NE CLI path Co-authored-by: Cursor --- netx_api/ne_exec.py | 4 ++-- packages/netx-mcp/src/netx_mcp/http_tools.py | 2 +- tests/test_ne_exec.py | 9 ++++++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/netx_api/ne_exec.py b/netx_api/ne_exec.py index a42138d..7f10407 100644 --- a/netx_api/ne_exec.py +++ b/netx_api/ne_exec.py @@ -30,8 +30,8 @@ _BLOCKED_RE = re.compile( r")" ) -# Only vendor read-only query verbs (Cisco show / Huawei-ZTE display). -_ALLOWED_PREFIX_RE = re.compile(r"(?i)^(show\s|display\s)") +# Read-only CLI: show/display plus ping reachability checks. +_ALLOWED_PREFIX_RE = re.compile(r"(?i)^(show\s|display\s|ping\s|ping6\s)") # Unicode / C1 line separators that can smuggle a second CLI after a show prefix. _FORBIDDEN_LINE_SEPARATORS = ("\u2028", "\u2029", "\x85", "\x0b", "\x0c") diff --git a/packages/netx-mcp/src/netx_mcp/http_tools.py b/packages/netx-mcp/src/netx_mcp/http_tools.py index 85b431c..ed4d620 100644 --- a/packages/netx-mcp/src/netx_mcp/http_tools.py +++ b/packages/netx-mcp/src/netx_mcp/http_tools.py @@ -391,7 +391,7 @@ HTTP_MCP_TOOLS: list[dict[str, Any]] = [ }, { "name": "execManagedNe", - "description": "Run read-only CLI on a managed NE via netx (show/display only; max 5 commands).", + "description": "Run read-only CLI on a managed NE via netx (show/display/ping; max 5 commands).", "inputSchema": { "type": "object", "properties": { diff --git a/tests/test_ne_exec.py b/tests/test_ne_exec.py index a5f0836..474dd84 100644 --- a/tests/test_ne_exec.py +++ b/tests/test_ne_exec.py @@ -15,10 +15,13 @@ class NeExecValidationTests(unittest.TestCase): def test_allows_display(self) -> None: _validate_command("display interface brief") - def test_blocks_ping_and_other_non_show_display(self) -> None: + def test_allows_ping(self) -> None: + _validate_command("ping 192.168.0.1") + _validate_command("ping6 2001::1") + _validate_command("PING 10.0.0.1 vrf MGMT") + + def test_blocks_non_allowed_prefix(self) -> None: for cmd in ( - "ping 192.168.0.1", - "ping6 2001::1", "get system info", "traceroute 192.168.0.1", "tracert 192.168.0.1",