-
Notifications
You must be signed in to change notification settings - Fork 55
/
RoutingTable.py
126 lines (88 loc) · 3.33 KB
/
RoutingTable.py
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#Copyright (C) 2014 Matt Oswalt (http://keepingitclassless.net/)
'''
RoutingTable.py
This is an example of a script that could be written to gather
information from NX-API. Here, we pull the contents of the routing
table and place them into custom objects to be used elsewhere.
'''
from nxapi_utils import NXAPI, xmltodict
#TODO: There may be additional options for other route types
class Prefix(object):
'''A class to define a route prefix'''
def __init__(self):
self.ipprefix = ''
self.ucast_nhops = ''
self.mcast_nhops = ''
self.attached = False
self.nexthops = []
class NextHop(object):
'''
A class to define a next-hop route. Meant to
be used in an array within the Prefix class
'''
def __init__(self):
self.ipnexthop = ''
self.ifname = ''
self.uptime = ''
self.pref = 0
self.metric = 0
self.clientname = ''
self.hoptype = ''
self.ubest = True
def process_nexthop(next_hop):
'''Processes nexthop data structure'''
if not 'ipnexthop' in next_hop:
# Ignore prefixes with no next hop - not attached?
return None
nexthop_obj = NextHop()
for key, val in next_hop.iteritems():
# use setattr to set all of the object attributes
setattr(nexthop_obj, key, val)
return nexthop_obj
def process_prefix(prefix_row):
'''Processes prefix data structure'''
prefix_obj = Prefix()
for key, val in prefix_row.iteritems():
# Check for TABLE_path (nested next_hop structure)
if key == 'TABLE_path':
# Next hop is embedded in ['TABLE_path']['ROW_path']
nexthop_obj = process_nexthop(val['ROW_path'])
if not nexthop_obj == None:
prefix_obj.nexthops.append(nexthop_obj)
else:
# Swap hyphen for underscore in field names
key = key.replace('-', '_')
# use setattr to set all of the object attributes
setattr(prefix_obj, key, val)
return prefix_obj
def get_routes(url='', username='', password=''):
'''
Retrieves a collection of route entries from the FIB
of an NXAPI-enabled switch
'''
thisnxapi = NXAPI()
thisnxapi.set_target_url(url)
thisnxapi.set_username(username)
thisnxapi.set_password(password)
thisnxapi.set_msg_type('cli_show')
thisnxapi.set_cmd('show ip route')
returndata = thisnxapi.send_req()
#print returnData[1] #Uncomment to print the entire XML return
doc = xmltodict.parse(returndata[1])
#TODO: need to make more dynamic, for VRFs and IPv6 address families
prefixtable = doc['ins_api']['outputs']['output']['body']['TABLE_vrf'] \
['ROW_vrf']['TABLE_addrf']['ROW_addrf']['TABLE_prefix']
for key in prefixtable:
docsub = prefixtable[key]
routes = []
for prefix_row in docsub: #executes once for every prefix
this_prefix = process_prefix(prefix_row)
routes.append(this_prefix)
# Print out routes
for route in routes:
print "The route to ", route.ipprefix, " has ", \
len(route.nexthops), " next-hop solutions"
for nexthop in route.nexthops:
print "via ", nexthop.ipnexthop, "out of", nexthop.ifname
if __name__ == '__main__':
get_routes('http://10.2.1.8/ins', 'admin', 'Cisco.com')