Python Scripting on a Cisco Nexus 7k

A few days ago I stumbled upon the python interpreter on the Nexus platform. It got me to tinkering.

In the past, I have had a requirement to grab a list of all of the interfaces on a box, the IP’s, and the masks. The interfaces and IP’s can easily be obtained from a show ip int br, and using column select to grab the relevant columns (hold down Alt when you are selecting in putty, if you didn’t know that before then go try it!). Getting the subnet masks for those is a little less trivial though.

As a side note, in the past I’ve used this:

sh ip int | i is up|Internet add

This works, but you have to mess a little to strip out just the bits you want (not a lot of work with a decent text editor though, I admit).

Anyway, more just to see if I could, I wrote a python script to extract the structured dictionary response from a “show ip interface” and parse out the relevant pieces and print them into a fixed width table, under the columns ‘Name’,’IP’,’CIDR’,’Mask’,’Admin’,’Link’,’Protocol’.

If you drop the script into bootflash:scripts/, then type “source ?” into the CLI, you’ll see that it’s available as a command. You can even set up a command alias so that you can access it quicker.

I’ve put the code on gitlab at:¬†https://gitlab.com/geekynick/nexus-python

And here it is too:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/usr/bin/env python
import sys, re
 
# color escape sequences
color_red="\x1b[31;01m"
color_green="\x1b[00;32m"
color_blue="\x1b[34;01m"
color_normal="\x1b[00m"
 
def nxos_help_string(args):
    # display online help (if asked for) for NX-OS' "source" command 
    # either in config mode or at the exec prompt, if users type "source <script> ?" then help_string appears
	# CREDIT: https://github.com/datacenter
    nb_args = len(args)
    if nb_args > 1:
        help_string = color_green + "Version of show ip int br, including subnet masks. No arguments required." + color_normal
        m = re.match('__cli_script.*help', args[1])
        if m:
                # user entered "source ?" with no parameters: display script help
                if args[1] == "__cli_script_help":
                    print help_string
                    exit(0)
                # argument help
                argv = args[2:]
                # dont count last arg if it was partial help (no-space-question-mark)
                if args[1] == "__cli_script_args_help_partial":
                    argv = argv[:-1]
                nb_args = len(argv)
                # only file name provided: use man-page style help
                print "__man_page"
                print help_string
                exit(0)
 
def calcDottedNetmask(mask):
    #Converts a CIDR number into a dotted netmask - i.e. 24 returns 255.255.255.0
	#CREDIT: http://stackoverflow.com/questions/819355/how-can-i-check-if-an-ip-is-in-a-network-in-python
    bits = 0
    for i in xrange(32-mask,32):
        bits |= (1 << i)
    return "%d.%d.%d.%d" % ((bits & 0xff000000) >> 24, (bits & 0xff0000) >> 16, (bits & 0xff00) >> 8 , (bits & 0xff))
 
#main
 
#Return the help if nexus called it (i.e. source ?)
nxos_help_string(sys.argv)
 
#Grab the interfaces as structured data
interfaces = clid("show ip interface")
 
#Count the interfaces
intcount = 0
for key in interfaces.keys():
  if 'intf-name' in key:
    intcount += 1
 
#Define a fixed width table
table = '{:<25}{:<15}{:<5}{:<16}{:<10}{:<10}{:<10}'
 
#Print table headers
print table.format('Name','IP','CIDR','Mask','Admin','Link','Protocol')
 
#Loop the interfaces, grab the relevant bits and print each row
for x in range(1,intcount+1):
  name = interfaces['TABLE_intf/intf-name/'+str(x)]
  ip = interfaces['TABLE_intf/prefix/'+str(x)]
  cidr = interfaces['TABLE_intf/masklen/'+str(x)]
  mask = calcDottedNetmask(int(cidr))
  admin = interfaces['TABLE_intf/admin-state/'+str(x)]
  link = interfaces['TABLE_intf/link-state/'+str(x)]
  protocol = interfaces['TABLE_intf/proto-state/'+str(x)]
  print table.format(name,ip,cidr,mask,admin,link,protocol)
Posted in Cisco, Scripting, Uncategorized.

3 Comments

  1. Pingback: Message Digest #1 – Sk1f3r's Notes

  2. Hello Nick! I have a few questions prior to try your script:
    After saving the script into bootflash:scripts/ the name of the program appear as a command?
    This can be run just with the name of the program or with the normal “python name.py”

  3. Hi Adan,

    Yeah, you just type “source ?” and it will give you context sensitive help saying how to run it. So it will be “source scriptname” for example.

    Nick.

Leave a Reply