Introduction
Hello all.
It’s been some time now that I have started learning about network automation/programming through the Cisco DevNet channel, learning about NetDevOps, CICD and all those magical notions, presented by various incredible people on the Cisco Devnet Team.
Automation with Network Devices is not new to me. I have been experimenting for a long time, trying to pilot Telnet sessions at first and then SSH sessions through various languages.
First it was TCL and Expect, a long time ago, probably around 2006-2007. I used an Excel worksheet where all our Wan Devices IP Addresses were stored for our branches, added VBA code to extract the IP for the given Device from the respective cell, as well as some other details, and then started the session by calling the TCL/Expect scripts with those as arguments. I remember changing password for all the devices in the Wan in a few minutes as an example of those benefits but I also had other uses such as automating fault checks to be used by members of our staff that didn’t have admin access to the Network Devices. One detail: The routers involved in these were not all Cisco. Most were IBM models 😉
Then I started using Perl for it. First using Perl to modify Smokeping plugins (essentially Perl code) so they could get latency numbers for the path from one Cisco Device to another (testing intermediate paths) and then straight through Perl scripts used to get Performance Data from Cisco Network Devices that SNMP could not provide (such as MLS Queues stats) and graphing them.
The matching for the responses was a little risky. With TCL it was awful. You could pretty much automate issuing commands either for showing info on screen or configuration but I had no way to extract information. Also at times the buffers didn’t play well and your connection could get dangerous..
With Pearl it was really better. Pearl was really fast and provided ways to match exactly what you wanted for prompts and such as well as to extract information and use it further (like in those graphs I mentioned). However everything needed to be build from scratch and it was difficult to share code with anyone else..
Cisco DevNet and other magical words
So this is where Cisco DevNet comes in. Starting at Cisco Live in Berlin a few years ago, I came across a zone that allowed for some clever self paced labs to be done by those attended. I was looking for the self paced labs for Networking, got disappointed from the lab subjects and turned my attention to what else was available close by.. and I saw the DevNet Zone! (I don’t even remember if it was called that at the time)..
I don’t really need to explain what Cisco DevNet is. They have done very well for themselves in the past few years and continue to do better. Also, if you are reading this post, chances are that you came here because of your interest in DevNet and network automation/programming. So before I put up my small example of code, I will throw in my viewpoint on what makes Cisco DevNet so important for Network Automation.
Cisco’s people (probably only a few at first) realized at some point that all their efforts for people to write applications for the Network, were not getting through. The existing developers didn’t know enough or understand enough about the network or how applications use it, in order to conceive and create network applications. Network automation didn’t even come into the picture..
So a new way to look at things was needed. Something to draw in the people that do understand the network. The engineers themselves. Also a common platform , a common reference point was necessary. Something to be used as both a source of knowledge and tools of the trade, but also a place of gathering for the people interested to share knowledge and help each other.
It grew. A lot! For people who are following some of it, it’s like we are seeing Cisco DevNet people build bases on the moon! At the same time we are finding it difficult to explain to other network engineers and IT people around us what is going on (“What moon????!!!”).
Get on the DevNet Express!
So they went further and organized local training events. And created streaming content! And Webinars! And Media Channels! And Infrastructure for you to test things for free (the DevNet Sandbox)! And there is no stopping those great people, all gifted, all very enthousiastic, all reachable and ready to share, coupled with a great Community Manager to bring a human face to all of this, reach you and help you find a starting point.
Why am I talking about it? Small Project
Well I have been trying to get on this train, with some success.. I have followed some training from Webinars and a Local Event (DevNet Express Athens 2018), I have of course done the Cisco Live content in place and highly recommend it, I have subscribed to Kirk Byers excellent email class about Python and Netmiko and I am following quite a few experts in the field.
However it all really starts when you get behind the screen and start tapping code on the keyboard. So what can we automate?
A lot of people have written excellent posts about it. I will not trouble you with it, but I do intend to come back to the post and provide some links to urls and people that do have things to say on the matter.
I started with procedures that are already standardized in my workplace but were never automated. In other words we did have a series of commands and things to do on paper or in word files but have to copy/paste them or type them anew if the need to used them arises. So I automated those.
Then I started chasing around for things we do a lot and could gain some time from automating them but could also perhaps outsource the execution of those repetitive tasks to other teams, without handing over to them the admin access for our network equipment. I could go on and on but I won’t.
So this is a script that will automate our efforts to locate mac addresses on a campus lan fast, when our help desk teams connects workstations to access ports that are usually on a dummy vlan (a vlan with no L3 access to anywhere) and wants us to grant them network access. That involved locating the access switch and the access port that the workstation has connected to and changing the access vlan.
This part of the code is written in Python and handles the locating the mac address part. Up to this point, it’s usefull for the network admins, gaining some time to complete what they already know how to do by themselves. I do intend to to provide a web based access to this tool in order for the Help Desk people to be able to run it themselves without giving them network equipment access.
Obviously the script depends largely on the local infrastructure and has to be adjusted before it can be used elsewhere. It basically starts on a core switch where the mac address will show up when connected anywhere on the campus Lan. It then follows the mac address through CDP until the final access switch is found where the address is shown on the mac address table as type STATIC. It uses regular expressions to do a few things like checking for the mac address input, locating the info from the mac address table (vlan, port, address type) and also some info from the cdp neighbour command (neighbour ip address and platform). It also checks for connection failure and the event that the mac address is not found anywhere. I am sure you can add things on your own and provide improvements. It’s just an idea, I am sure a lot can do a lot better. So here is the code. I changed some initial data for confidentiality issues. I don’t have a problem sharing some platform info as they will soon be replaced:
from netmiko import ConnectHandler, ssh_exception
from paramiko.ssh_exception import SSHException
from datetime import datetime
from getpass import getpass
import os
import subprocess
import re
import sys
print("Mac Search at KK\n")
print("We are not handling access points, if you get an error, please call noc")
#### Ask for mac address ###########
mcaddress = input('mac address: ').strip()
#print (mcaddress)
macpt = re.compile(r"[a-f0-9]{4,4}\.[a-f0-9]{4,4}\.[a-f0-9]{4,4}")
checkmac = macpt.search(mcaddress)
if checkmac == None:
print("Mac address not given or not in correct format!")
print("Example: xxxx.yyyy.zzzz with Cisco notation, chars in a-f and numbers in 0-9 ranges")
sys.exit(1)
#### Ask for starting switch ip address ###########
startswitchip = input('switch to start from: ').strip()
ippt = re.compile(r"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}")
checkip = ippt.search(startswitchip)
if checkip == None:
print("IP address not given or not in correct format!")
print("Example: 0-255.0-255.0-255.0-255 with IPv4 ranges")
sys.exit(1)
user = input('username:')
passwd = getpass()
ipaddress = startswitchip
platform = "6509"
addresstype = "dynamic"
vlanid = ""
while ("STATIC" not in addresstype) and ("static" not in addresstype):
if "2950" not in platform:
contype = "cisco_ios_ssh"
cmdstring = "sh mac address-table | in " + mcaddress
if "6509" in platform:
portpt = re.compile(r"\s+(?P<vlanid>\S+)\s+\S+\s+(?P<addresstype>\S+)\s+\S+\s+\S+\s+(?P<port>\S+)")
else:
portpt = re.compile(r"\s+(?P<vlanid>\S+)\s+\S+\s+(?P<addresstype>\S+)\s+(?P<port>\S+)")
else:
contype = "cisco_ios_telnet"
cmdstring = "sh mac-address-table | in " + mcaddress
portpt = re.compile(r"\s+(?P<vlanid>\S+)\s+\S+\s+(?P<addresstype>\S+)\s+(?P<port>\S+)")
swcon = {
'device_type': contype,
'ip': ipaddress,
'username': user,
'password': passwd,
}
try:
net_connect = ConnectHandler(**swcon)
except SSHException:
print ("can't connect to last device")
sys.exit(1)
except ssh_exception.NetMikoTimeoutException:
print(" SSH Timed out")
sys.exit(1)
except ssh_exception.NetMikoAuthenticationException:
print("Invalid Credentials: ", ipaddress)
sys.exit(1)
output = net_connect.send_command_timing(cmdstring).strip("*")
findport = portpt.search(output)
if findport == None:
print("Address not found")
addresstype = "STATIC"
net_connect.disconnect()
break
portfound = findport.group('port')
addresstype = findport.group('addresstype')
vlanid = findport.group('vlanid')
print ()
print ("Mac port:", portfound)
print ("Address Type:", addresstype)
if ("dynamic" not in addresstype) and ("DYNAMIC" not in addresstype):
print("\nWe found it!")
#output = net_connect.send_command_timing("sh run int " + portfound +"\n")
print ("Mac port:", portfound, "on vlan", vlanid, "at", ipaddress)
else:
print("\nIt's on another switch, we need to look further through", portfound)
cmdstring = "sh cdp neighbors " + portfound +" detail"
output = net_connect.send_command_timing(cmdstring)
######### Find ip address and plaform for CDP Neighbor ################
ippt = re.compile(r"\s+IP address:\s+(?P<ipaddress>\d+\.+\d+\.\d+\.\d+)")
platformpt = re.compile(r"Platform: cisco WS-C(?P<platform>\w+)")
findaddress = ippt.search(output)
findplatform = platformpt.search(output)
ipaddress = findaddress.group('ipaddress')
platform = findplatform.group('platform')
print ("Next Neightbor IP Address:", ipaddress)
print ("Next Neighbor Platform:", platform)
net_connect.disconnect()
print ('done testing')
So that’s about it. I will come back to complete this with explanations and links. But it works. Just modify it for your use case or get an idea for something else. I won’t be at the Cisco Live Europe 2019 but hope for next year. If you go there, don’t forget to go by the Cisco DevNet Zone early on, get your hands on the keyboard and talk to people around you!
Script explanation
To be filled
People to know in Devnet + some links
Community Manager:
Silvia K. Spiva : https://twitter.com/silviakspiva
Hank Preston : https://twitter.com/hfpreston
Stuart Clark : https://twitter.com/bigevilbeard (https://blogs.cisco.com/developer/plan_test_deploy , https://blogs.cisco.com/developer/nornir-python-automation-framework , https://blogs.cisco.com/developer/network-configuration-template )
John McDonough : https://twitter.com/johnamcdonough
Kareem Iskander : https://twitter.com/Kareem_isk (https://t.co/oTV49pUR1a Kareem Iskander shows you how the #DevNet Zone is built, and why content is top of mind every month of the year.)
Andrian Iliesiu : https://twitter.com/aidevnet (https://blogs.cisco.com/developer/from-pampered-customer-to-devnet-zone-builder-is-this-you )
Kirk Byers: @kirkbyers https://pynet.twb-tech.com/blog/automation/netmiko.html Kirk is the creator of Netmiko and works on a number of projects including Napalm and Nornir. He is truly and automation expert. I am following his email course.
Dmitry Figol: @dmfigol Dmitry is a network programmability expert and streamer.
Jason Gooley: @Jason_Gooley Jason is an author of a Cisco Press book for network programmability
Links
To be filled.
JT