Python - how to make decision based on a failed command (netmiko and try-except-else)

Viewed 122

I am trying to create a test program which will log to Cisco ASA firewalls and collect some data. I run into a challenge. Some firewalls are single context some are multi-context, but connection is made on admin IP address to all of them. Once connected there is a command "changeto system" which will only be successful on multi-context firewalls. I was thinking to use try-except-else ....

    conn = ConnectHandler(device_type= "cisco_asa", ip=host[1],  username=u[host[3]], password=p[host[3]], secret=p[host[3]])
    print(conn.find_prompt())
    try:
        output4 = conn.send_command(cmd_system)
    except:
        # not a multi-context firewall
        for cmd in cmd_list_asa:
                CONTEXT_OUTPUT = open(chgnr + '__' + host[0] + '_' + d[cmd]+ '_' + testtype , "a")
                info = ("running .... " + host[0] + "......." + cmd)
                runcommand(info, cmd, CONTEXT_OUTPUT)
                CONTEXT_OUTPUT.close()
    else:
        #multi-context firewall
        #collect SYSTEM context data
        for cmd in cmd_list_asa:
                CONTEXT_OUTPUT = open(chgnr + '__' + host[0] + '_system_' + d[cmd]+ '_' + testtype , "a")
                info = ("running .... " + host[0] + "_system......." + cmd)
                runcommand(info, cmd, CONTEXT_OUTPUT)
                CONTEXT_OUTPUT.close()
        #create context list and collect data
        output3 = conn.send_command(cmd_contextlist)
        list = re.findall("\"(.*?)\"",output3)
        for fw in list:
            cmd_change = ("changeto context " + fw)
            output = conn.send_command(cmd_change)
            for cmd in cmd_list_asa:
                CONTEXT_OUTPUT = open(chgnr + '__' + host[0] + '_' + fw + '__' + d[cmd]+ '_' + testtype , "a")
                info = ("running .... " + host[0] + "_" + fw + "......." + cmd)
                runcommand(info, cmd, CONTEXT_OUTPUT)
                CONTEXT_OUTPUT.close()

the CONTEXT_OUTPUT is just a fancy way of dynamically generating filename. testype to differentiate between multiple runs and finally all what runcommand does it sends the command...conn.send_command(cmd).

As per my expectation if output4 command fails the except section should be executed if is successful should jump to the else section, but apparently even those firewalls which are not multicontext will run through the else section and skip except.

1 Answers

After talking with my colleague I realized my mistake. Try-expect is for python error handling. When the command fails it still returns an output

...admin> changeto system
                                      ^
ERROR: % Invalid input detected at '^' marker.
ERROR: Command authorization failed

...that output has to be assessed so instead of try-expect-else it should be a if-else...

 ....
   output4 = conn.send_command(cmd_system)
        if "ERROR" in output4: 
            # not a multi-context firewall
            for cmd in cmd_list_asa:
                    CONTEXT_OUTPUT = open(chgnr + '__' + host[0] + '_' + d[cmd]+ '_' + testtype , "a")
                    info = ("running .... " + host[0] + "......." + cmd)
                    runcommand(info, cmd, CONTEXT_OUTPUT)
                    CONTEXT_OUTPUT.close()
        else:
            #multi-context firewall
            #collect SYSTEM context data
            for cmd in cmd_list_asa:
....
Related