Jump to content
  • entries
    9
  • comments
    3
  • views
    2,861

A taste of python automation in networking

BSpendlove

2,051 views

A few personal projects I've been working on, mainly just putting together a load of useful functions in python along with the netmiko library to pull specific data from Cisco IOS devices (mainly ISRs and Catalyst, not been designed for Nexus, ASAs, other vendors yet etc..)

 

I've mainly been testing some open source IPAM solutions such as netbox and PHPIPAM to see if I can do some neat little tricks and I've created a few things for both solutions on the side of my job because I want to expand my programming knowledge (have been doing a lot of python + c# lately)

 

Here is a basic example to connect to a cisco switch, pull the data into a kind of JSON format to be used when creating a new vlan using Netbox's API + python API module. (Beware, I'm also using a module that I have on github over at https://github.com/BSpendlove/BCPTools (follow the readme to install the library and use some of the basic functions I use in this netbox example)

 

from pprint import pprint
from netbox import NetBox
from BCPTools.BCPTFunctions import bcp_create_session
from BCPTools.BCPTFunctions import bcp_show_vlans

#Cisco Switch connection details for Netmiko/BCPTools

conn = {
    'device_type': 'cisco_ios',
    'ip': '192.168.1.109',
    'username': 'hume',
    'password': 'cisco',
    'secret': 'cisco'
}

##---------------------- NETBOX API Login details ------------------------------##
myToken = 'mytoken123mytoken123mytoken123mytoken123'
api_login = NetBox(host='192.168.1.9', port=80, use_ssl=False, auth_token=myToken)
##------------------------------------------------------------------------------##

class bcp_vlan_functions(object):
	def create_vlan_group(self, netbox, name, slug, checkExists=True):
		if checkExists == True:

			vlan_group = netbox.ipam.get_vlan_groups(name=name)

			if not vlan_group:
				results = netbox.ipam.create_vlan_group(name=name, slug=slug)
				return results

			if name in vlan_group[0]['name']:
				print(name.lower() + " has already been configured as a VLAN Group... checkExist must be False if you would like to create a duplicate VLAN Group...")
				print("Local Database ID for vlan group: {0} is {1}\n".format(name,str(vlan_group[0]['id'])))

			else:
				results = netbox.ipam.create_vlan_group(name=name,slug=slug)
				return results

		else:
			print("Create vlan function without simple duplication...\n")
			results = netbox.ipam.create_vlan_group(name=name,slug=slug)
			return results

	def create_vlan(self, netbox, name, vlanid, groupid):
		vlan_check = netbox.ipam.get_vlans(name=name)

		if not vlan_check:
			results = netbox.ipam.create_vlan(vlan_name=name,vid=vlanid,group=groupid)
			print("VLAN{0} ({1}) has been created...\n".format(vlanid, name))
			return results

		if name in vlan_check[0]['name']:
			if not vlan_check[0]['group']:
				print("VLAN{0} exists in the Netbox Database although is not registered with VLAN Group: {1}... Have not performed any action...\n".format(vlanid, groupid))
				#netbox.ipam.create_vlan(vlan_name=name,vid=vlanid,group=groupid)
			elif groupid ==  vlan_check[0]['group']['id']:
				print("VLAN{0} ({1}) is already configured in VLAN Group: {2}\n".format(vlanid, name, vlan_check[0]['group']['name']))

	def get_vlan_group(self, netbox, vlanname):
		#Try to use either id or name to filter through VLAN groups, obviously ID is better if you have duplicate vlan group names, but with some common practice, you shouldn't configure 2 sites with the same 'VLAN group name'!!!
		return netbox.ipam.get_vlan_groups(name=vlanname)

	def save_vlans_to_netbox(self, netbox, groupname):
		session = bcp_create_session(conn)
		vlans = bcp_show_vlans(session)

		vlangroup = self.get_vlan_group(netbox, groupname)

		if not vlangroup:
			print("VLAN Group {0} can not be found...".format(groupname))
		else:
			vlangroupid = vlangroup[0]['id']

			for vlan in vlans:
				self.create_vlan(netbox, vlan['name'], vlan['vlan_id'],vlangroupid)

bcp_vlan_functions().create_vlan_group(api_login,"PYTHON-TEST-NETBOX","python-test-netbox")
bcp_vlan_functions().save_vlans_to_netbox(api_login, "PYTHON-TEST-NETBOX")

For example, I have a switch at 192.168.1.109 with the following as the 'show vlan' output:

W17BS-SW01#show vlan

VLAN Name                             Status    Ports
---- -------------------------------- --------- -------------------------------
1    default                          active    Fa1/0/1, Fa1/0/2, Fa1/0/3
                                                Fa1/0/4, Fa1/0/6, Fa1/0/7
                                                Fa1/0/8, Fa1/0/9, Fa1/0/10
                                                Fa1/0/11, Fa1/0/12, Fa1/0/13
                                                Fa1/0/14, Fa1/0/15, Fa1/0/16
                                                Fa1/0/17, Fa1/0/18, Fa1/0/19
                                                Fa1/0/20, Fa1/0/21, Fa1/0/22
                                                Fa1/0/23, Fa1/0/24, Gi1/0/1
                                                Gi1/0/2
10   IT                               active    Fa1/0/5
20   ACCOUNTS                         active
30   SALES                            active
40   HR                               active
50   INTERNAL                         active
100  CAMERAS                          active
101  GUEST-WIFI                       active

I've amended some interfaces to go in the other vlans so now my function from my BCPTools library on github will return this data as:

Spoiler

show vlan - filtered with textfsm logic (regex filtering etc... on a template)

 

and now from the Netbox point of view:

image.png.9952fd7d62b4fb8e36c2d79553845d99.png

after running the netbox function I've created to pull the vlans from a cisco switch, and then use the API to create these vlans in the VLAN group called 'Python-test-netbox':

(virtualenvironment) brandon@ubuntu:~/brandon_scripts/NETBOX_API_EXAMPLES$ python3 netbox_cisco_switch_vlans.py
python-test-netbox has already been configured as a VLAN Group... checkExist must be False if you would like to create a duplicate VLAN Group...
Local Database ID for vlan group: PYTHON-TEST-NETBOX is 7

VLAN1 (default) has been created...
VLAN10 (IT) has been created...
VLAN20 (ACCOUNTS) has been created...
VLAN30 (SALES) has been created...
VLAN40 (HR) has been created...
VLAN50 (INTERNAL) has been created...
VLAN100 (CAMERAS) has been created...
VLAN101 (GUEST-WIFI) has been created...
VLAN1002 (fddi-default) has been created...
VLAN1003 (token-ring-default) has been created...
VLAN1004 (fddinet-default) has been created...
VLAN1005 (trnet-default) has been created...

(obviously filtering out VLAN1 and 1002-1005 would be best but this is a just a quick dirty function to show some basics with python automation and networking/inventory purposes)

 

image.png.3b82ac837e9e0084ec753975a895fb19.png

0 Comments

There are no comments to display.

×