Stream WebCRT login live and unblock Huawei hop interactive connect.

Skip Huawei special_login_handler under interactive WebCRT, harden stelnet host-key auth, and echo hop/login progress into the terminal during connect.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-08-28 21:41:12 +08:00
parent 6901a7c019
commit 6ed08e24de
8 changed files with 386 additions and 67 deletions

View file

@ -280,7 +280,7 @@ class BastionConnectImplTests(unittest.TestCase):
password="bastion-pass",
timeout=unittest.mock.ANY,
)
interact.assert_called_once_with(conn, "target-user", "target-pass")
interact.assert_called_once_with(conn, "target-user", "target-pass", progress_cb=None)
class BastionInteractiveHandlerTests(unittest.TestCase):

View file

@ -32,6 +32,13 @@ class PromptDetectTests(unittest.TestCase):
self.assertFalse(cont)
self.assertTrue(save)
def test_host_key_wrapped_yn_line(self) -> None:
cont, save = _prompt_needs_host_key_confirm(
"The server is not authenticated. Continue to access it?\n[Y/N]:"
)
self.assertTrue(cont)
self.assertFalse(save)
def test_password_change_not_host_key(self) -> None:
cont, save = _prompt_needs_host_key_confirm("Change now? [Y/N]:")
self.assertFalse(cont)
@ -80,11 +87,14 @@ class HuaweiStelnetAuthTests(unittest.TestCase):
),
]
conn = MagicMock()
_interactive_target_auth(conn, "ipran", "secret")
seen: list[str] = []
_interactive_target_auth(conn, "ipran", "secret", progress_cb=seen.append)
self.assertEqual(
[c.args[1] for c in mock_send.call_args_list],
["ipran", "Y", "N", "secret"],
)
self.assertTrue(any("host-key continue" in p for p in seen))
self.assertTrue(any("Please input the username" in p for p in seen))
@patch("netx_api.ne_session_connect._read_channel")
@patch("netx_api.ne_session_connect._send_line")
@ -102,6 +112,9 @@ class HuaweiStelnetAuthTests(unittest.TestCase):
"Enter password:",
"<TARGET>\n",
"",
"",
"",
"",
]
conn = MagicMock()
_interactive_target_auth(conn, "ipran", "secret")