[Python Patterns] Working with the SolarWinds Orion SDK to get VLAN info from a Cisco device.
If you use SolarWinds, this script is for you.
If you have your SolarWinds NCM making nice little backups of your Cisco configs you can use this script as a starter for many projects. This script uses the SolarWinds Orion SDK and a nifty module called CiscoConfParse to pull the data from a backed up config to get a VLAN from an interface.
Once you have a SolarWinds API user setup you'd give the script an IP of your router and it should pull back the VLAN info on an interface if you do that sort of thing.
# get_vlan_info.py from SolarWinds NCM
#
# Parses the VLAN from interfaces in a Cisco config stored in SolarWinds
#
# You will need a API user setup in SolarWinds for access
#
# How to use
# python get_vlan_info.py -i 10.0.0.1
import argparse
from ciscoconfparse import CiscoConfParse
import json
from netaddr import IPAddress
from orionsdk import SwisClient
import os
import requests
import sys
def main(**kwargs):
# Get IP from args
ip_addr = kwargs['ip_addr']
# Disable SSL check because SW reasons
requests.packages.urllib3.disable_warnings()
# Connect to SWIS
NPM_SERVER = 'solarwinds_instance_ip'
USERNAME = 'the_api_user'
PASSWORD = 'super_secret_password'
swis = SwisClient(NPM_SERVER, USERNAME, PASSWORD)
# Get NODE.ID from SolarWinds
# TODO wrap this in a try/catch at some point
query_result = swis.query(
"SELECT ip.NodeID, ip.Node.Caption, ip.IPAddress, "
"ip.SubnetMask, ip.Node.Vendor, ip.Node.MachineType "
"FROM Orion.NodeIPAddresses ip WHERE ip.Node.caption"
" IS NOT null and IPAddress = '{}'".format(ip_addr)
)
# print(query_result)
if query_result['results'] != []:
node_id = query_result['results'][0]['NodeID']
# print(node_id)
else:
print("FAIL, No Device Found!")
return {}
# Download node configuration from NCM
query = '''
SELECT TOP 1 C.NodeID AS NcmNodeId, C.NodeProperties.CoreNodeId,
C.DownloadTime, C.ConfigType, C.Config
FROM NCM.ConfigArchive C
WHERE C.NodeProperties.CoreNodeID = @orionnodeid_par
ORDER BY C.DownloadTime DESC
'''
params = {
'orionnodeid_par': node_id
}
# TODO wrap this in a try/catch at some point
query_results = swis.query(query, **params)
# print(query_results)
if query_results['results'] != []:
last_config = query_results['results'][0]['Config']
# print(last_config)
else:
print("FAIL, No Device Config Found!")
return {}
# Write the config out to text as CiscoConfParse expects a real config file
# or a bunch of lines of config data, weird.
# TODO wrap this in a try/catch at some point
with open('cisco.txt', 'w') as f:
f.write(last_config)
f.close()
# Parse the config
parse = CiscoConfParse('cisco.txt', syntax='ios')
# print(parse)
# Clean up after ourselves
os.remove('cisco.txt')
vlan = ''
helper_list = []
cidr_out = ''
# Parse out all interfaces
all_int = parse.find_objects(r"^interface")
# Iterate over the objects
for obj in all_int:
if obj.re_search_children(r"{}\b".format(ip_addr)):
# This should be our interface with the vlan
# print(obj.text)
vlan = obj.text.split('Vlan')[1]
# print(vlan)
# OK got vlan, now lets get the children
for child in obj.children:
if 'helper-address' in child.text:
# print("HELPER {}".format(child.text))
helper_list.append(child.text.split(' ')[3])
elif 'ip address' in child.text:
# print("IP ADDRESS INFO: {}".format(child.text))
sub_net = child.text.split(' ')[4]
gateway = child.text.split(' ')[3]
sub_net_bits = IPAddress(sub_net).netmask_bits()
cidr_out = "{}/{}".format(gateway, sub_net_bits)
d = {
"vlan": vlan,
"ip_helpers": helper_list,
"subnet": cidr_out
}
print(d)
return d
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument(
'-i',
dest='ip_addr',
help='Enter the ip address',
required=True
)
args = parser.parse_args()
# Convert the argparse.Namespace to a dictionary: vars(args)
arg_dict = vars(args)
# pass dictionary to main
main(**arg_dict)
sys.exit(0)
My blog posts tagged with "Python Patterns" are designed to be a quick look reference for some Python code snippets I use a lot. They are written to be a quick starting point for future projects so I do not need to type as much.