Press J to jump to the feed. Press question mark to learn the rest of the keyboard shortcuts
47
Posted byMeow 馃悎馃悎Meow 馃惐馃惐 Meow Meow馃嵑馃悎馃惐Meow A+!12 months ago
Archived

Print("A Python Post")

Python keeps coming up again and again in various networking discussions since people are always debating exactly how much automation stuff you should learn as you get more senior.

Let's kick the tires with python a bit to see what all the fuss is about. We won't go very deep into explaining things so this will be more of a show and tell type deal.

Python is baked into most Linux and Mac OSs by default, typically you will find 2.7 in the wild since python 3 makes some changes that people are reluctant to adopt so you will find many 2 vs 3 debates about the subject. Windows doesn't have python baked in so you will need to install it online if you want to use that to follow along. I personally like anaconda's package.

Python also has a package manager call pip that can be used to install various addons. I'll install pip and also ipython which is a awesome python sense I love.

root@Home01:~# apt-get install python-pip ipython -y
Reading package lists... Done
Building dependency tree
Reading state information... Done

Once pip is installed we can add more functionality into python by installing modules, I'll install the netaddr module which lets us do some IP operations.

[root@Fedora-S01 ~]# pip install netaddr  
Collecting netaddr
  Downloading netaddr-0.7.19-py2.py3-none-any.whl (1.6MB)
    100% |鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅| 1.6MB 885kB/s 
Installing collected packages: netaddr
Successfully installed netaddr-0.7.19

Python can be run in two modes, an interactive mode where we pop into a python shell and can type commands line by line as needed or a non-interactive mode where we will write up the full script to be run. Typically we will just use the interactive mode for testing things out and will mostly run script files.

For now we will open up ipython and play around a bit, I like ipython more than the traditional shell because it adds features like tab completion for commands and some other neat things. It is supported on all platforms.

[root@Fedora-S01 ~]# ipython
Python 2.7.13 (default, May 10 2017, 20:04:28) 
Type "copyright", "credits" or "license" for more information.

IPython 5.3.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: 

It is a bit of tradition in the programming world to have your first script be "hello world", lets try this out in the shell.

In [1]: print "Hello World"
Hello World

To write a script file, we make a file called helloworld.py and then we can call it with the python command and pointing to the file.

[root@Fedora-S01 ~]# cat helloworld.py print "Hello World" [root@Fedora-S01 ~]# python helloworld.py Hello World

If you don't want to have to use the python command to run scripts then you need to make sure your script starts with #!/bin/env python so the script can find the python interpreter.

[root@Fedora-S01 ~]# cat helloworld.py 
#!/bin/env python
print "Hello World"

In linux we need to set the file to be a executable and we can run it.

[root@Fedora-S01 ~]# chmod u+x helloworld.py   
 
[root@Fedora-S01 ~]# ./helloworld.py         
Hello World

To play with our netaddr module we first need to import it into python. When we use this method we need to prepend all the functions with netaddr to test this out we will make a variable called IP and use the netaddr.IPAddress function to examine an IP address.

[root@Fedora-S01 ~]# ipython              

In [1]: import netaddr

In [2]: ip = netaddr.IPAddress('192.168.77.100')

In [3]: ip.version
Out[3]: 4

In [4]: ip.bin
Out[4]: '0b11000000101010000100110101100100'

We can also change the name of the module we need to call by using the as keyword, then we can call the functions by using CAT instead. This time we will use the IPNetwork function to figure out the subnet mask.

In [12]: import netaddr as CAT

In [13]: net = CAT.IPNetwork('192.168.77.0/23')

In [14]: net.netmask
Out[14]: IPAddress('255.255.254.0')

Lastly if you don't want to call the module every time we can directly import the commands so we can directly call the functions.

In [15]: from netaddr import *

In [16]: newnet = IPNetwork('192.168.88.0/12')

In [17]: newnet.netmask
Out[17]: IPAddress('255.240.0.0')

If you need to brush up on what a module can do you can use the help command to pull up the module's help file.

In [15]: help(net)


Help on IPNetwork in module netaddr.ip object:

class IPNetwork(BaseIP, IPListMixin)
 |  An IPv4 or IPv6 network or subnet.
 |  
 |  A combination of an IP address and a network mask.
 |  
 |  Accepts CIDR and several related variants :
 |  
 |  a) Standard CIDR::
 |  
 |      x.x.x.x/y -> 192.0.2.0/24
 |      x::/y -> fe80::/10
 |  
 |  b) Hybrid CIDR format (netmask address instead of prefix), where 'y'        address represent a valid netmask::
 |  
 |      x.x.x.x/y.y.y.y -> 192.0.2.0/255.255.255.0
 |      x::/y:: -> fe80::/ffc0::
 |  
 |  c) ACL hybrid CIDR format (hostmask address instead of prefix like        Cisco's ACL bitmasks), where 'y' address represent a valid netmask::
 |  
 |      x.x.x.x/y.y.y.y -> 192.0.2.0/0.0.0.255
 |      x::/y:: -> fe80::/3f:ffff:ffff:ffff:ffff:ffff:ffff:ffff
 |  
 |  d) Abbreviated CIDR format (as of netaddr 0.7.x this requires the        optional constructor argument ``implicit_prefix=True``)::
 |  
 |      x       -> 192
 |      x/y     -> 10/8
 |      x.x/y   -> 192.168/16
 |      x.x.x/y -> 192.168.0/24
 |  
 |      which are equivalent to::
 |  
 |      x.0.0.0/y   -> 192.0.0.0/24
 |      x.0.0.0/y   -> 10.0.0.0/8
 |      x.x.0.0/y   -> 192.168.0.0/16
 |      x.x.x.0/y   -> 192.168.0.0/24

Another highly useful thing is using loops to run through a bunch of data, lets use netaddr to return all the IPs in a /28 subnet.

In [27]: for ip in IPNetwork('172.10.9.230/28'):
    ...:     print ip
    ...:     
    ...:     
172.10.9.224
172.10.9.225
172.10.9.226
172.10.9.227
172.10.9.228
172.10.9.229
172.10.9.230
172.10.9.231
172.10.9.232
172.10.9.233
172.10.9.234
172.10.9.235
172.10.9.236
172.10.9.237
172.10.9.238
172.10.9.239

Get on with the Cisco!

Let's close out this intro to python by showing off a simple python script that will collect show ip interface brief from a few routers.

First we will import netmiko which is a good Cisco friendly ssh module for python

#!/bin/env python

from netmiko import ConnectHandler

Next we will tell netmiko how to connect to each router, there are quite a few different ways we can do it but I'll make a dictionary that contains the various connection parameters for each device. BTW you can use # to make comments to explain what you are doing in your code, it is a good idea to make notes as you go so you understand your code later or so other people can follow your logic.

#Add Device Info

R01 = {
    'device_type': 'cisco_ios',
    'ip': '10.10.21.101',
    'username': 'admin',
    'password': 'meowcat',
    'secret': 'meowcat',
    'verbose': False,
}

R02 = {
    'device_type': 'cisco_ios',
    'ip': '10.10.21.102',
    'username': 'admin',
    'password': 'meowcat',
    'secret': 'meowcat',
    'verbose': False,
}

R03 = {
    'device_type': 'cisco_ios',
    'ip': '10.10.21.103',
    'username': 'admin',
    'password': 'meowcat',
    'secret': 'meowcat',
    'verbose': False,
}

Once they are all made I will group them all in to a variable we can call.

#Make Varible for routers
all_routers = [R01,R02,R03]

Then we simply make a loop that connects to each device and runs the show ip int brief command then displays the output in a pretty way.

#Loop to collect "show ip int brief" and display it

for router in all_routers:
	net_connect = ConnectHandler(**router)
	output = net_connect.send_command("show ip interface brief")
	print "\n **************** {0} ************".format(router['ip'])
	print output
	print "**************** END ****************\n"

Output

Here is what things look like when we are done. Something like this could be useful if you need to collect info across several different devices.

python "C:\Users\the-packet-thrower\cisco.py"
 **************** 10.10.21.101 ************

Interface              IP-Address      OK? Method Status                Protocol

GigabitEthernet1       10.10.21.101    YES DHCP   up                    up      

GigabitEthernet2       unassigned      YES NVRAM  up                    up      

GigabitEthernet2.12    10.1.2.1        YES manual up                    up      

GigabitEthernet3       unassigned      YES NVRAM  administratively down down    

Loopback0              192.168.254.1   YES manual up                    up      

**************** END ****************

 **************** 10.10.21.102 ************

Interface              IP-Address      OK? Method Status                Protocol

GigabitEthernet1       10.10.21.102    YES DHCP   up                    up      

GigabitEthernet2       unassigned      YES unset  up                    up      

GigabitEthernet2.12    10.1.2.2        YES manual up                    up      

GigabitEthernet2.23    10.2.3.2        YES manual up                    up      

Loopback0              192.168.254.2   YES manual up                    up      

**************** END ****************

 **************** 10.10.21.103 ************

Interface              IP-Address      OK? Method Status                Protocol

GigabitEthernet1       10.10.21.103    YES DHCP   up                    up      

GigabitEthernet2       unassigned      YES unset  up                    up      

GigabitEthernet2.23    10.2.3.3        YES manual up                    up      

GigabitEthernet2.34    10.3.4.3        YES manual up                    up      

Loopback0              192.168.254.3   YES manual up                    up      

**************** END ****************
9 comments
91% Upvoted
This thread is archived
New comments cannot be posted and votes cannot be cast
level 1

This is awesome! I've been using Expect scripts to accomplish similar things, but I have a feeling that this might be more elegant and powerful.

Can't wait to try it.

level 1
Comment deleted12 months ago
level 2
Meow 馃悎馃悎Meow 馃惐馃惐 Meow Meow馃嵑馃悎馃惐Meow A+!Original Poster1 point12 months ago

Someone read ahead of the class :)

level 1
Comment deleted12 months ago
level 2
Meow 馃悎馃悎Meow 馃惐馃惐 Meow Meow馃嵑馃悎馃惐Meow A+!Original Poster1 point12 months ago

I did a coupe of his courses, good stuff

level 1

Love it! Thanks u/the-packet-thrower

level 1
CCNA1 point12 months ago

Cool beans

level 1

Great Post! I'd love to see more SDN-related posts in the future (even if just at a high-level without being language-specific).

level 1

Going to try this tomorrow! Do you have any VIRL examples with physical L2 support or Wan connectivity support out there? I'm having trouble with VIRL talking to my home lab.

level 1

Su instead of sudo? Running as root?! Blasphemy! /nerd jokes

In all seriousness, this post is awesome. If CCNA/certs in general weren't such resume boosters I'd probably be studying stuff Cumulus and other SDN stuff, polishing up on my Linux and Python skills, and trying to write posts like this ;-). I for one wouldn't mind seeing more like this in the future.

level 2
Meow 馃悎馃悎Meow 馃惐馃惐 Meow Meow馃嵑馃悎馃惐Meow A+!Original Poster3 points12 months ago

Real men run as root everywhere!

Community Details

34.1k

Subscribers

232

Online

Create Post
r/ccna Rules
1.
No posting of illegal materials
2.
No posting of braindumps
3.
Be courteous and helpful
4.
Don't ask others to complete your labs
Cookies help us deliver our Services. By using our Services or clicking I agree, you agree to our use of cookies.Learn More.