ktbyers / netmiko

Multi-vendor library to simplify Paramiko SSH connections to network devices
MIT License
3.55k stars 1.3k forks source link

OSError: Search pattern never detected in send_command_expect #1229

Closed amarbaranwal closed 5 years ago

amarbaranwal commented 5 years ago

I am trying to automate below steps using netmiko APIs over UCS Fabric Interconnect Switches, where script is expected to login first on the Virtual Device IP - device_ip and then execute "connect nxos a" to access Active node and "connect nxos b" for Standby Node.

Below is the snippet of manual execution: sshpass -p $PASSWORDCFG ssh -oStrictHostKeyChecking=no -l $USER device_ip Cisco UCS 6200 Series Fabric Interconnect Cisco Nexus Operating System (NX-OS) Software .... AAN-FI01-A# AAN-FI01-A# connect nxos a <== CLI to execute Cisco Nexus Operating System (NX-OS) Software ... AAN-FI01-A(nxos)# <== Active Node mode, where prompt changes

log snippet from script executed in debug mode: INFO: Connected (version 2.0, client OpenSSH_6.2) INFO: Auth banner: b'Cisco UCS 6200 Series Fabric Interconnect\n' INFO: Authentication (password) successful! INFO: Successfully logged into AAN-FI01-A(10.15.4.100)

/home/PROD-USA/amardkum/IoT-NetEng/monitor_device_UpTime_and_SerialNumber.py(195)get_serial_numbers() -> if uname == "admin": (Pdb) n /home/PROD-USA/amardkum/IoT-NetEng/monitor_device_UpTime_and_SerialNumber.py(196)get_serial_numbers() -> output_a = net_connect.send_command("connect nxos a") (Pdb) s --Call-- /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1187)send_command() -> def send_command( (Pdb) s /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1231)send_command() -> loop_delay = 0.2 (Pdb) n /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1235)send_command() -> delay_factor = self.select_delay_factor(delay_factor) (Pdb) n /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1236)send_command() -> if delay_factor == 1 and max_loops == 500: (Pdb) delay_factor 1 (Pdb) n /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1238)send_command() -> max_loops = int(self.timeout / loop_delay) (Pdb) n /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1241)send_command() -> if expect_string is None: (Pdb) timeout ** NameError: name 'timeout' is not defined (Pdb) self.timeout 100 (Pdb) n /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1242)send_command() -> if auto_find_prompt: (Pdb) n /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1243)send_command() -> try: (Pdb) n /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1244)send_command() -> prompt = self.find_prompt(delay_factor=delay_factor) (Pdb) n /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1249)send_command() -> search_pattern = re.escape(prompt.strip()) (Pdb) prompt 'AAN-FI01-A#' (Pdb) n /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1253)send_command() -> if normalize: (Pdb) prompt 'AAN-FI01-A#' (Pdb) n /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1254)send_command() -> command_string = self.normalize_cmd(command_string) (Pdb) command_string 'connect nxos a' (Pdb) n ... /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1279)send_command() -> output, search_pattern (Pdb) n /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1282)send_command() -> if re.search(search_pattern, output): (Pdb) output 'connect nxos a\r\nCisco Nexus Operating System (NX-OS) Software\r\nTAC support: http://www.cisco.com/tac\r\nCopyright (c) 2002-2017, Cisco Systems, Inc. All rights reserved.\r\nThe copyrights to certain works contained in this software are\r\nowned by other third parties and used and distributed under\r\nlicense. Certain components of this software are licensed under\r\nthe GNU General Public License (GPL) version 2.0 or the GNU\r\nLesser General Public License (LGPL) Version 2.1. A copy of each\r\nsuch license is available at\r\nhttp://www.opensource.org/licenses/gpl-2.0.php and\r\nhttp://www.opensource.org/licenses/lgpl-2.1.php\r\n\rAAN-FI01-A(nxos)# ' (Pdb) search_pattern 'AAN\-FI01\-A\#' (Pdb) n /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1290)send_command() -> time.sleep(delay_factor loop_delay) (Pdb) n /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1291)send_command() -> i += 1 (Pdb) n /usr/lib/python3.6/site-packages/netmiko/base_connection.py(1266)send_command() -> while i <= max_loops: (Pdb) i 7 (Pdb) max_loops 500 (Pdb) c ERROR: Hit OSError for 10.15.4.100 - Search pattern never detected in send_command_expect: AAN-FI01-A#

amarbaranwal commented 5 years ago

I can see that, due to mismatch in expected pattern, it's failing. Is there an option/solution to handle this situation?

carlmontanari commented 5 years ago

You are maybe looking for set_base_prompt -- in this example my hostname starts as "3560CX":

>>> conn.send_config_set(['hostname SOMETHING'])

'config term\nEnter configuration commands, one per line.  End with CNTL/Z.\n3560CX(config)#hostname SOMETHING\nSOMETHING(config)#end\nSOMETHING#'
>>>
>>> conn.base_prompt
'3560CX'
>>> conn.set_base_prompt()
'SOMETHING'
>>> conn.base_prompt
'SOMETHING'
>>> conn.send_config_set(['hostname 3560CX'])
'config term\nEnter configuration commands, one per line.  End with CNTL/Z.\nSOMETHING(config)#hostname 3560CX\n3560CX(config)#end\n3560CX#'
>>> conn.set_base_prompt()
'3560CX'
>>> conn.base_prompt
'3560CX'
>>>

You should be able to connect, connect to 'nxos a', then reset the base prompt. See also: #1226 which is similar. Let us know if that helps!

amarbaranwal commented 5 years ago

Hi Carl, thank you for your comment. I tried with "set_base_prompt()" but that didn't help. Exception is hit with execution of "send_command("connect nxos a")" itself. Below is the sequence of prompt change: 053119 12:14:12:INFO: Successfully logged into DXB-FI01-A(10.13.4.100) 053119 12:14:12:INFO: Find Prompt before 'connect nxos a': DXB-FI01-A# 053119 12:14:12:INFO: Base Prompt before 'connect nxos a': DXB-FI01-A

executing net_connect.send_command("connect nxos a")

053119 12:15:53:INFO: Find Prompt after hitting exception: DXB-FI01-A(nxos)# 053119 12:15:53:INFO: Base Prompt after hitting exception: DXB-FI01-A 053119 12:15:53:INFO: Hit issue with 'connect nxos a'

After executing net_connect.send_command("connect nxos a") it hangs for approx 100 secs. and hits exception concluding - 'Search pattern never detected in send_command_expect: DXB-FI01-A#'. With execution of "connect nxos a", the value of "find_prompt()" has changed. However, the code expects the previously recorded prompt.

I checked the code flow of "send_command()" where the expected pattern is stored before write_channel(command_string) and same is being used for lookup after execution.

As of now, I am accepting the exception and passing on. But that is costing me 100 seconds of wait time against one such CLI.

ktbyers commented 5 years ago

Try:

net_connect.send_command_timing("connect nxos a")

And then execute set_base_prompt() after that.

Another option is:

net_connect.send_command("connect nxos a", expect_string=r"#")

Note, by default send_command is going to search for part of the current prompt which is why your command fails. The _timing method doesn't look for a pattern it is entirely delay based. Adding the expect_string argument changes the pattern that is looked for.

amarbaranwal commented 5 years ago

Hi Kirk, "expect_string" option did help. My mistake that I overlooked the available option with "send_command()" method. Thanks a lot, Amar

ghost commented 4 years ago

Please someone help me with this issue Code:

from netmiko import ConnectHandler from getpass import getpass import time from datetime import datetime start_time = datetime.now() start = time.time() host = input('Enter ip address: ') device = {'device_type': 'cisco_asa', 'host': host, 'username':'reuben', 'password':'cisco', 'port': '22', 'secret': 'cisco', 'verbose': True}

net_connect = ConnectHandler(**device) cmd = 'copy disk0:ospf7.txt disk0:ospf12.txt'

expect_string = (r'Source filename', r'Destination filename')

output = net_connect.send_command(cmd) if 'Source filename' in output: output += net_connect.send_command('\n') if 'Destination filename' in output: output += net_connect.send_command('\n')

output += net_connect.send_command('\n', '\n', expect_string=r'#', delay_factor=2)

print(output)

output = net_connect.send_command('show int ip brie')

print(output)

Error:

C:\network_automation_2\venv\Scripts\python.exe C:/network_automation_2/testing_commands_netmiko.py Enter ip address: 10.7.250.54 SSH connection established to 10.7.250.54:22 Interactive SSH session established Traceback (most recent call last): File "C:/network_automation_2/testing_commands_netmiko.py", line 19, in output = net_connect.send_command(cmd) File "C:\network_automation_2\venv\lib\site-packages\netmiko\cisco\cisco_asa_ssh.py", line 61, in send_command output = super(CiscoAsaSSH, self).send_command(*args, **kwargs) File "C:\network_automation_2\venv\lib\site-packages\netmiko\base_connection.py", line 1337, in send_command search_pattern OSError: Search pattern never detected in send_command_expect: LABASA1#

Process finished with exit code 1

sachin0987 commented 2 years ago

Hi Kirk, "expect_string" option did help. My mistake that I overlooked the available option with "send_command()" method. Thanks a lot, Amar

Hey , can you please help us with the solution?

ktbyers commented 2 years ago

@sachin0987 It is best if you open a new issue and include your failing code (simplified to just what fails) and the exception stack trace. The issue here is closed.