ktbyers / netmiko

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

Script to change cisco interface based on find/replace #580

Closed jsb515 closed 5 years ago

jsb515 commented 7 years ago

I'm trying to write a script that will change auth order for mab and dot1x on interfaces that have the auth order incorrectly. For example if Fa1/0/1 has the auth order mab dot1x but needs to be auth order dot1x mab. Having trouble figuring out how to do this with configparser to do a find replace type method or using ansible. Any help or examples to help get me on right track would be appreciated.

ktbyers commented 7 years ago

Can you show me a more detailed example, i.e. the relevant interfaces section and order that you want to change (with one interface right and one interface wrong).

jsb515 commented 7 years ago

an example interface would look like this

interface FastEthernet1/0/1 description DATA PORT switchport access vlan 100 switchport mode access no logging event link-status authentication control-direction in authentication event fail action next-method authentication event server dead action authorize vlan 100 authentication event server dead action authorize voice authentication event server alive action reinitialize authentication host-mode multi-auth authentication open authentication order mab dot1x This would be the before and the setting we want to change. authentication order dot1x mab This should be the after when the change is made. authentication priority dot1x mab authentication port-control auto authentication periodic authentication timer reauthenticate server authentication violation restrict mab snmp trap mac-notification change added snmp trap mac-notification change removed dot1x pae authenticator dot1x timeout tx-period 10 spanning-tree portfast spanning-tree bpduguard enable

ktbyers commented 7 years ago

And you want to do this in Ansible or Python (or don't care which)?

jsb515 commented 7 years ago

doesn't matter to me :)

ktbyers commented 7 years ago

@jsb515 For a given switch do you know which interfaces need this configuration applied (not which ones are wrong), but all of the interfaces that should have:

interface x
  authentication order mab dot1x 
  authentication order dot1x mab 
jsb515 commented 7 years ago

Usually fa1/0/1 -24 or to 48 and some switches are gi1/0/1 - 24 or 48

That's why I was curious if it can search all int for the mab dot1x first if found change to dot1x mab because one int might be an uplink and not need the dot1x mab

ktbyers commented 7 years ago

@jsb515 This does most of the heavy lifting:

#!/usr/bin/env python
from netmiko import ConnectHandler
from getpass import getpass
from ciscoconfparse import CiscoConfParse

device = { 
    'device_type': 'cisco_ios',
    'ip': '10.10.10.70',
    'username': 'pyclass',
    'password': getpass(),
} 

net_connect = ConnectHandler(**device)
net_connect.enable()
#print(net_connect.find_prompt())

run_config = net_connect.send_command("show run")
run_config = run_config.splitlines()
#cisco_cfg = CiscoConfParse(run_config)
cisco_cfg = CiscoConfParse("cisco.cfg")
config_obj = cisco_cfg.find_objects_w_all_children(parentspec=r"^interface",
                                                  childspec=[r"authentication order dot1x mab",
                                                             r"authentication order mab dot1x"])
for parent in config_obj:
    print(parent.text)
    mab_line = parent.re_search_children(r"authentication order mab dot1x")[0].linenum
    dot1x_line = parent.re_search_children(r"authentication order dot1x mab")[0].linenum
    # Check if mab_line comes later
    if mab_line > dot1x_line:
        print("Found")
        print(parent.text)

Note, I was testing it with a file named cisco.cfg, but I also included some code to show you what it would look if grabbing from running-config using Netmiko.

This finds the interfaces that have the condition you specified. You could then use Netmiko's send_config_set() to execute a change on that interface to correct the order.

jsb515 commented 7 years ago

Awesome! I gave it a shot this morning and it did not print anything for the "found" when looking for mab dot1x. I did uncomment the line for parsing the (sh_run) and then commented out the line below for ("cisco.cfg") since it was looking on the switch and not from a file. I also added in for it to send a terminal length 0 to make sure it wasn't just getting half the config from the show run.

ktbyers commented 7 years ago

@jsb515 I would start by testing it just using a static file on the local system (i.e. save the running config to a local system).

I tested the above code using the interface description you gave above and one port with mab first; the other with dot1x first.

pourmirza commented 6 years ago

Hi @ktbyers ,

Can I use cisco_cfg.find_objects to find interfaces with a missing config. For example , all interfaces that don't have "switchport mode access" config. Also, what is the best way to save the running config to a local system and use it later. I use following script to export the running-config but I am not sure if this is the right way:

run_output = net_connect.send_command("show run") run_config = run_output.splitlines() with open('run-config.txt', 'w') as f: f.write(str(run_config))

langcblt commented 3 years ago

I got stuck with this same issue [FATAL] ciscoconfparse could not open error. I was able to use the ciscoconfparse module to loop thru several config files (text), parse the configs in a folder and output the result. When I I added some additional configs into the same folder, it gave me the [FATAL] ciscoconfparse could not open error. I have no luck so far researching online and finding a solution. if you know why please advise