ktbyers / netmiko

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

net_connect.commit() on cisco ASR9K router (6.1.3) hangs and throw this error back #1171

Closed jayt007 closed 4 years ago

jayt007 commented 5 years ago

I have a python code to load configuration file via ftp on to Cisco ASR9K router and when i commit with net_connect.commit() it just hangs and throw this exception and exit. But i see the config is actually commited on to the device. I tried delay_factor 2 and 4 with the command with no luck.

Please note i wipe out the config via console (using netmiko) before i load the full config via ftp. So the prompt wouldn't have a hostname, i dont know thats the issue here.

Traceback (most recent call last): File "ssh_loadconfigviaftp_iosxr.py", line 100, in main(sys.argv[1:]) File "ssh_loadconfigviaftp_iosxr.py", line 80, in main net_connect.commit() File "/usr/local/lib/python3.7/site-packages/netmiko/cisco/cisco_xr_ssh.py", line 103, in commit delay_factor=delay_factor, File "/usr/local/lib/python3.7/site-packages/netmiko/base_connection.py", line 1320, in send_command_expect return self.send_command(*args, **kwargs) File "/usr/local/lib/python3.7/site-packages/netmiko/base_connection.py", line 1295, in send_command search_pattern OSError: Search pattern never detected in send_command_expect: RP/0/RSP0/CPU0:ios(config)#

OzNetNerd commented 5 years ago

Can you please post your whole script?

jayt007 commented 5 years ago
# JT - load configuration files via ftp (ssh connection)

from netmiko import ConnectHandler
import sys
import getopt
import time
from datetime import datetime

def main(argv):

    try:
        opts, args = getopt.getopt(argv, 'hd:', ['device=', 'ftpconfigfile='])
    except getopt.GetoptError:
        print('ssh_loadconfig_iosxr.py -d <device_ip> --ftpconfigfile <ftp_configuration_file_path>')
        print('e.g. ftpconfigfile: ftp://10.186.192.193/asr9k_v0.6/complete/asr9006c_full.config.cfg')
        sys.exit(2)

    for opt, arg in opts:
        if opt == '-h':
            print('ssh_loadconfig_iosxr.py -d <device_ip> --ftpconfigfile <ftp_configuration_file_path>')
            print('e.g. ftpconfigfile: ftp://10.186.192.193/asr9k_v0.6/complete/asr9006c_full.config.cfg')
        elif opt in ('-d', '--device'):
            device_ip = arg
        elif opt == '--ftpconfigfile':
            ftpconfigfile = arg

    print('\n\nConnecting to device {}...\n'.format(device_ip))

    cisco_xr = {
        'device_type': 'cisco_xr',
        'host': device_ip,
        'username': 'cisco',
        'password': 'cisco',
        'use_keys': 'False',
        'allow_agent': 'False'
    }

    net_connect = ConnectHandler(**cisco_xr)
    output = net_connect.find_prompt()
    print(output)

    net_connect.write_channel('configure t' + '\n')
    output = net_connect.read_channel()
    # if 'config:' not in output:
    #     raise ValueError("Exec prompt not found")
    print(output)

    output = net_connect.find_prompt()
    print(output)

    Tstart = datetime.now()

    print("\nLoading configuration file via ftp...")
    output = net_connect.send_command_timing("load " + ftpconfigfile + ' ' + "vrf MGMT", strip_command=False, strip_prompt=False)
    time.sleep(3)

    if "Source username" in output:
        output += net_connect.send_command_timing("theivendramoorthy", strip_command=False, strip_prompt=False)

    if "Source password" in output:
        output += net_connect.send_command_timing("NetDesign", strip_command=False, strip_prompt=False)

    Tend = datetime.now()
    Tdiff = Tend - Tstart

    print(output)

    if 'Loading' and 'bytes parsed in' in output:
        print ('\nConfiguration loaded...')
        print ('\nTime taken to load the configuration = {}'.format(str(Tdiff)))

        if 'Syntax/Authorization errors in one or more commands' in output:
            output += net_connect.send_command("show configuration failed load detail")
            print(output)

        else:
            print ('\nCommit configuration...\n')
            net_connect.write_channel('end' + '\r')
            net_connect.commit()
            # net_connect.write_channel('commit' + '\r')
            # time.sleep(40)

            output = net_connect.read_channel()
            print(output)

            if 'Failed to commit one or more configuration items' in output:
                output = net_connect.send_command("show configuration failed inheritance")
            print(output)

    elif 'Loading' not in output:
        print('\nLoad configuration failed...!!')

    if 'RSP' in output:
        print ('\nAborting connection with {}...'.format(device_ip))
        net_connect.disconnect()

if __name__ == "__main__":
    main(sys.argv[1:])
jayt007 commented 5 years ago

Hi Will,

I am learning Python so apologies if its not in a good shape. I've tried the below as an alternative to net_connect.commit() and it works fine. But i am having issues with the time given for the commit before the disconnect. I wonder net_connect.commit() would handle is better.

   # net_connect.write_channel('commit' + '\r')
   # time.sleep(40)

Thanks, Jay

ktbyers commented 5 years ago

@jaytmoorthy How long does the commit() take for this change if you are doing it manually? Can you enable the session_log and see what it shows?

    cisco_xr = {
        'device_type': 'cisco_xr',
        'host': device_ip,
        'username': 'cisco',
        'password': 'cisco',
        'use_keys': 'False',
        'allow_agent': 'False',
        'session_log': 'my_session.txt',         # This file will be created
    }
jayt007 commented 5 years ago

@ktbyers i think it takes around 10 - 12 seconds (for a 12K config file). Logs below as you suggested... i gave 40 seconds before the disconnect(). If i dont give enough time i see partial configurations committed to the device.

It would be good if i could detect when the commit is completed and disconnect imediately rather than waiting for the timeout (the only thing ASR IOS XR display is the time - e.g. Wed Apr 24 21:44:22.711 UTC once the commit is completed).

RP/0/RSP0/CPU0:ios#configure t

Wed Apr 24 21:44:04.758 UTC RP/0/RSP0/CPU0:ios(config)#

RP/0/RSP0/CPU0:ios(config)#load ftp://10.186.192.193/asr9k_v0.7/complete/asr9001f_config_full.cfg vrf MGMT

Source username: [anonymous]?theivendramoorthy

Source password: Loading.. 12829 bytes parsed in 2 sec (6404)bytes/sec RP/0/RSP0/CPU0:ios(config)#commit

Wed Apr 24 21:44:22.711 UTC RP/0/RSP0/CPU0:asr9001f(config)#

RP/0/RSP0/CPU0:asr9001f(config)#end

RP/0/RSP0/CPU0:asr9001f#

RP/0/RSP0/CPU0:asr9001f#exit

carlmontanari commented 4 years ago

Since this has been sitting for a bit I'm going to go ahead and close it.

If this is still an issue please feel free to reopen and we can try to pick it back up. If you do chose to reopen: If you replace a config w/out modifying the hostname does that work (assuming appropriate delay factor)? Sounds like maybe that is/was part/all of the issue perhaps.