netmiko: Huawei special_login_handler is not logging in successfully

The system information is as follows:

  1. netmiko version: 4.0
  2. python 3.10
  3. window 11

error_print:

Traceback (most recent call last):
  File "E:\web_API\test.py", line 11, in <module>
    app.net_ssh_proxy(switch_json = switch_json, commands=commands)
  File "E:\web_API\app.py", line 25, in net_ssh_proxy
    with ConnectHandler(**device_info, sock=sock) as net_connect:
  File "E:\venv_02\lib\site-packages\netmiko\ssh_dispatcher.py", line 344, in ConnectHandler
    return ConnectionClass(*args, **kwargs)
  File "E:\venv_02\lib\site-packages\netmiko\base_connection.py", line 434, in __init__
    self._open()
  File "E:\venv_02\lib\site-packages\netmiko\base_connection.py", line 439, in _open
    self.establish_connection()
  File "E:\venv_02\lib\site-packages\netmiko\base_connection.py", line 1092, in establish_connection
    self.special_login_handler()
  File "E:\venv_02\lib\site-packages\netmiko\huawei\huawei.py", line 105, in special_login_handler
    output = self.read_until_pattern(password_change_prompt)
  File "E:\venv_02\lib\site-packages\netmiko\base_connection.py", line 631, in read_until_pattern
    raise ReadException(msg)
netmiko.exceptions.ReadException: Unable to successfully split output based on pattern:
pattern=((Change now|Please choose))|([\]>]\s*$)
output='\nInfo: The max number of VTY users is 21, the number of current VTY users online is 2, and total number of terminal users online is 2.\n      The current login time is 2022-03-28 15:55:30+08:00.\n<xxxx_hostname>'
results=['\nInfo: The max number of VTY users is 21, the number of current VTY users online is 2, and total number of terminal users online is 2.\n      The current login time is 2022-03-28 15:55:30+08:00.\n<xxxx_hostname', None, None, '>', '']

test instanse 2. python 3.10 3. window 11 Netmiko 3.4.0 Release

out_print

no problem

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 52 (26 by maintainers)

Commits related to this issue

Most upvoted comments

The reason for Huawei telnet trouble netmiko.exceptions.ReadException: Unable to successfully split output based on pattern is that pattern (]\s*$|>\s*$|(Change now|Please choose 'YES' or 'NO').+) contains nested group (nested parentheses). To fix this issue, changes of source code needed.

Details:

  1. In this string: https://github.com/ktbyers/netmiko/blob/f3b5da244e6ce1e5fd7bd89fd36b090e854828b4/netmiko/huawei/huawei.py#L132 combined_pattern created - i mean this pattern (]\s*$|>\s*$|(Change now|Please choose 'YES' or 'NO').+)
  2. Then created combined_pattern passes to read_until_pattern method here https://github.com/ktbyers/netmiko/blob/f3b5da244e6ce1e5fd7bd89fd36b090e854828b4/netmiko/huawei/huawei.py#L155
  3. Bad thing happend here: https://github.com/ktbyers/netmiko/blob/f3b5da244e6ce1e5fd7bd89fd36b090e854828b4/netmiko/base_connection.py#L636 After splitting, we got result list of length = 4, and this is the reason for ReadException here: https://github.com/ktbyers/netmiko/blob/f3b5da244e6ce1e5fd7bd89fd36b090e854828b4/netmiko/base_connection.py#L645
  4. And the reason of len(result) = 4 is that combined_pattern has nested parentheses here:
(]\s*$|>\s*$|(Change now|Please choose 'YES' or 'NO').+)
             ^                                      ^

@Toxic-Waste- you can try to edit file /home/<snip>/.local/lib/python3.10/site-packages/netmiko/huawei/huawei.py on line 131 change this:

password_change_prompt = r"(Change now|Please choose 'YES' or 'NO').+"

to this:

password_change_prompt = r"Change now|Please choose 'YES' or 'NO'"

But you must understand that:

  • it is not good to change package’s code directly like that
  • it can cause unexpected error in another place
  • this is just a dirty quick fix that worked for my case

@ktbyers I can try to analize side effects of proposed changes and craft Pull Request if you like. But if you think that PR is redundant, please let me know. Thanks!

@ktbyers Yes, i see.

import re
from netmiko import ConnectHandler
host = input('Input Dest host: ')

device = {
    'device_type': 'huawei_telnet',
    'ip':   host,
    'username': 'login',
    'password': 'pass',
    'port' : 23,
    'verbose': True,
    'session_log': f'{host}.log'
}

net_connect = ConnectHandler(**device)
pip3 list | grep netmiko
netmiko                      4.1.0

I can confirm the issue using Netmiko 4.0.0 (latest pip release together with Python 3.10.4) using device_type = 'huawei'.

With the Netmiko 3.4.0 release everything works fine. Also, it doesn’t seem to make any difference whether the password change prompt is displayed or not (see both tracebacks below).

netmiko.exceptions.ReadException: Unable to successfully split output based on pattern:
pattern=((Change now|Please choose))|([\]>]\s*$)
output='\nWarning: The password will expire in 11 days.\nThe password needs to be changed. Change now? [Y/N]: '
results=['\nWarning: The password will expire in 11 days.\nThe password needs to be changed. ', 'Change now', 'Change now', None, '? [Y/N]: ']
netmiko.exceptions.ReadException: Unable to successfully split output based on pattern:
pattern=((Change now|Please choose))|([\]>]\s*$)
output='\nInfo: Current mode: Monitor (automatically making switching decisions).\nWarning: The intelligent upgrade function is disabled. Log in to the web platform and enable this function.\n  -----------------------------------------------------------------------------     \n  User last login information:     [...]      \n  -----------------------------------------------------------------------------\n<AC6508>'
results=['\nInfo: Current mode: Monitor (automatically making switching decisions).\nWarning: The intelligent upgrade function is disabled. Log in to the web platform and enable this function.\n  -----------------------------------------------------------------------------     \n  User last login information:     [...]    \n  -----------------------------------------------------------------------------\n<AC6508', None, None, '>', '']

After spending some time investigating the issue I found out that the pattern matching logic in read_until_pattern expects the pattern to split exactly in 3 parts (using re.split), see base_connection.py#L579 for reference. Seems this change was introduced during some fundamental changes to the channel reading logic in in https://github.com/ktbyers/netmiko/commit/793100dcfd76d3eb5089ba4cd27c99e3c3c0f886.

I have proposed a fix and documented some more info in #2719.