Home > Arista > How hard to make a Network Search app in Python. Can a newbie do it?

How hard to make a Network Search app in Python. Can a newbie do it?

Yes, definitely! It will not be a glorified web or desktop app but it can be run on any terminal/shell if python3 is installed.

This post is for IT professionals who maintain and troubleshoot multiple network devices throughout the day and looking to find ways to make their job easier by automating boring stuff with python.

If you don’t have an in house network monitoring, configuration manager and automation tool in your network you are probably having to login network devices manually to check/search logs, configs, IPs, mac addresses.

What if you could search your network configs, logs for a keyword on all the devices without having to log in manually. This would save you a lot of time when you need to check something quickly on multiple devices.

This script has great examples about :

  • How to work with text files in python.
  • How to read parse strings from a file.
  • Using netmiko library and sending multiple commands to multiple network devices.
  • Looping a function until we want to stop the loop.
  • How to calculate the time it took to run the script.
  • And more.

Let’s get to work. This python3 script is flexible, works for Cisco Nexus, Arista and Juniper devices. If you are new to python, don’t be scared, I left lots of comments in the code so you can see the purpose of each line.

import re    # to find and replace characters 
from netmiko import ConnectHandler   # to ssh and send commands to network devices
import time   # to calculate how much time it takes to run our script
import sys    # to be able to quit the script after the search

Lets define couple of variables

f = open("devices.txt", "r")  # device IPs are here
devices_str = ""               # IPs will be added here
device_type = ['juniper_junos', 'arista_eos', 'cisco_nxos'] # will need this for netmiko module 
# change the username and password as needed
username = "test"
password = "test123"

The script will import device IPs from a file called “devices.txt” which is in same directory as our code. Make sure there is only one IP on each line and lines do not start with “#”. if IPs has “#” on the same line script will ignore those IPs.

# read the IPs from the "devices.txt" file. ignore #
for line in f.readlines():
    if "#" not in line:
        devices_str = devices_str + line

f.close()
# remove and spacing and other unwanted characters. Turn all the Ips in to a list of all the IPs.  
devices_lst = ((devices_str.replace("\n", " ")).replace(",", "")).split(" ")
while ('' in devices_lst):
    devices_lst.remove('')
# here adding IPs under to 3 different list based on the title of the IPs. 
sw_arista = devices_lst[devices_lst.index('Arista_IPs') + 1:devices_lst.index('Nexus_IPs')]
sw_nexus = devices_lst[devices_lst.index('Nexus_IPs') + 1:devices_lst.index('Juniper_IPs')]
sw_juniper = devices_lst[devices_lst.index('Juniper_IPs') + 1:devices_lst.index('Cisco_IPs')]
# print all the IPs that is imported from the list
print("\n     --- Welcome to NetSearch --- \n IPs are successfully added from the file\n", sw_arista , sw_nexus, sw_juniper,)

Below is the “devices.txt” file format I used. Changing the title of IPs will cause an error when importing IPs. Because script is referring to title of IPs to know device type.

#Uncomment the lines when you are adding IPs
# Do not change anything on this file other than adding SSH IPs. Changing format may fail the script 
#
#
# enter arista ips under arista_IPs. Only one IP for each line. No space.
Arista_IPs
70.70.70.3
#
#
# enter arista ips under Nexus_IPs. Only one IP for each line. No space.
Nexus_IPs
70.70.70.1
#
#
# enter arista ips under Juniper_IPs. Only one IP for each line. No space.
Juniper_IPs
70.70.70.4
#
#
# enter arista ips under Cisco_IPs. Only one IP for each line. No space. \
Cisco_IPs
End_of_the_lst

Here is where the code starts.


invalid_input = True #this is a smart way to loop the same function until it is false. In our case, we will keep searching until we want to quit the search. pay attention below where I mention invalid_input again. 

def ssh_sw():
    search_word = input("""
NetSearch is a cool cli app to search network 
devices for a spesific word, IP or mac address.
Simply enter the keyword and press enter. 
Type "exit" to leave the app.
Note: Searching more than one word with space may not work for Cisco.  

What are you looking for: """).strip(" ")
    if search_word.strip(" ").lower() == "exit":
        print("\nThank you for using the NetSearch")
        sys.exit() # typing exit will stop the script. 
# below are all the commands that will be sent to deivices and filtered by the keyword. you can add more commands, customise to your needs. 
    arista_commands = ["sh run | i " + search_word, "Show ip route | i " + search_word,
                       "sh ip int brief | i " + search_word, "sh mac address-table | i " + search_word,
                       "Show ip arp | i " + search_word, "Show ip mroute | i " + search_word, ]
    cisco_commands = ["sh run | i " + search_word, "Show ip route | i " + search_word,
                      "sh ip int brief | i " + search_word, "sh mac address-table | i " + search_word,
                      "Show ip arp | i " + search_word, "Show ip mroute | i " + search_word, ]
    juniper_commands = ["run show configuration | display set | match " + search_word,
                        "run show arp | match " + search_word,
                        "run show ethernet-switching table | match " + search_word]
    start_time = time.time()  # timer starts here
    for device in device_type:
#netmiko connects to devices and execute the commands. You can easly add another If stetament for another device type. 
        if device == 'arista_eos':
            for ar_ip in sw_arista:
                arista_login = {'device_type': 'ariinvalid_inputsta_eos', 'host': ar_ip, 'username': username,
                                'password': password, }
                ar_connect = ConnectHandler(**arista_login)
                output = ar_connect.send_config_set(arista_commands)
                print("\n" + ar_ip + "\n" + output)
        if device == 'cisco_nxos':
            for nx_ip in sw_nexus:
                nexus_login = {'device_type': 'cisco_nxos', 'host': nx_ip, 'username': username, 'password': password, }
                nx_connect = ConnectHandler(**nexus_login)
                output = nx_connect.send_config_set(cisco_commands)
                print("\n" + nx_ip + "\n" + output)
        if device == 'juniper_junos':
            for jn_ip in sw_juniper:
                juniper_login = {'device_type': 'juniper_junos', 'host': jn_ip, 'username': username,
                                 'password': password, }
                jn_connect = ConnectHandler(**juniper_login)
                output = jn_connect.send_config_set(juniper_commands)
                print("\n" + jn_ip + "\n" + output)
    print("--- Completed in %s seconds ---" % (time.time() - start_time))
    invalid_input = False  # stop funtion

while invalid_input:  # loop the function until invalid_input is False
        ssh_sw()

This is what output looks like. The search takes about 15 seconds on each device. You can add more commands in the command list and filter their output with your keyword.

--- Welcome to NetSearch ---
 IPs are successfully added from the file
 ['70.70.70.3'] ['70.70.70.1'] ['70.70.70.4']

NetSearch is a cool cli app to search network
devices for a specific word, IP or mac address.
Simply enter the keyword and press enter.
Type "exit" to leave the app.
Note: Searching more than one word with space may not work for Cisco.

What are you looking for: 70.70.70 <==== part of the IP i am searching

70.70.70.4
configure
Entering configuration mode

{master:0}[edit]
test@SW1# run show configuration | display set | match 70.70.70
set system tacplus-server 70.70.70.10 timeout 5
set interfaces vlan unit 70 family inet address 70.70.70.4/24
run show arp | match 70.70.70
run show ethernet-switching table | match 70.70.70

{master:0}[edit]
test@SW1# run show arp | match 70.70.70
00:25:64:72:ca:95 70.70.70.10     70.70.70.10               vlan.70             none
00:15:17:0b:e8:0d 70.70.70.20     70.70.70.20               vlan.70             none

{master:0}[edit]
test@SW1# run show ethernet-switching table | match 70.70.70

{master:0}[edit]
test@SW1# exit configuration-mode
Exiting configuration mode

{master:0}
test@SW1>

70.70.70.3
config term
SW2(config)#sh run | i 70.70.70
Show ip route | i 70.70.70
sh ip int brief | i 70.70.70
sh mac address-table | i 70.70.70
Show ip arp | i 70.70.70
Show ip mroute | i 70.70.70
   ip address 70.70.70.3/24
   network 70.70.70.0/24 area 0.0.0.0
SW2(config)#Show ip route | i 70.70.70
 O      1.1.1.1/32 [110/11] via 70.70.70.1, Vlan70
 C      70.70.70.0/24 is directly connected, Vlan70
 O      192.168.1.0/24 [110/50] via 70.70.70.1, Vlan70
SW2(config)#sh ip int brief | i 70.70.70
Vlan70                 70.70.70.3/24      up         up              1500
SW2(config)#sh mac address-table | i 70.70.70
SW2(config)#Show ip arp | i 70.70.70
70.70.70.1              0  547f.ee6d.dfbc  Vlan70, Ethernet18
70.70.70.20             0  0015.170b.e80d  Vlan70, Ethernet18
SW2(config)#Show ip mroute | i 70.70.70
SW2(config)#end
SW2#

70.70.70.1
config term
Enter configuration commands, one per line.  End with CNTL/Z.
SW3(config)# sh run | i 70.70.70
Show ip route | i 70.70.70
sh ip int brief | i 70.70.70
  110 permit tcp any 70.70.70.10/24 eq tacacs
  ip address 70.70.70.1/24
sh mac address-table | i 70.70.70
  network 70.70.70.0/24 area 0.0.0.0
Show ip arp | i 70.70.70
SW3(config)# Show ip route | i 70.70.70
    *via 70.70.70.3, Vlan70, [110/50], 4d00h, ospf-10, intra
70.70.70.0/24, ubest/mbest: 1/0, attached
    *via 70.70.70.1, Vlan70, [0/0], 4w5d, direct
70.70.70.1/32, ubest/mbest: 1/0, attached
    *via 70.70.70.1, Vlan70, [0/0], 4w5d, local
SW3(config)# sh ip int brief | i 70.70.70
Show ip mroute | i 70.70.70
Vlan70               70.70.70.1      protocol-up/link-up/admin-up
SW3(config)# sh mac address-table | i 70.70.70
SW3(config)# Show ip arp | i 70.70.70
70.70.70.3      00:13:02  001c.730f.6524  Vlan70
70.70.70.10     00:13:02  0025.6472.ca95  Vlan70
70.70.70.20     00:13:02  0015.170b.e80d  Vlan70
SW3(config)# Show ip mroute | i 70.70.70
SW3(config)# end
SW3#
--- Completed in 47.62006688117981 seconds ---

This script is a great example of how useful python can be for IT professionals. You don’t have to be a software engineer to start writing python code to automate your work. Pick an easy task and start automating one task at the time.

Happy scripting…

One thought on “How hard to make a Network Search app in Python. Can a newbie do it?

Leave a Reply

Your email address will not be published. Required fields are marked *