6
6
import switchdb
7
7
8
8
9
+
9
10
def loadDevices ():
10
11
"""
11
12
Load device inventory from config.yml
12
13
"""
13
14
print ("Loading devices from config file..." )
14
- with open ("config.yml" , 'r' ) as config :
15
+ with open ("config.yml" , "r" ) as config :
15
16
devicelist = yaml .full_load (config )
16
- return devicelist [' Devices' ]
17
+ return devicelist [" Devices" ]
17
18
18
19
19
20
def connectToDevice (deviceconfig ):
@@ -22,19 +23,19 @@ def connectToDevice(deviceconfig):
22
23
"""
23
24
print ("Loading device configuration..." )
24
25
device = {}
25
- device [' host' ] = deviceconfig [' address' ]
26
- device [' auth_username' ] = deviceconfig [' username' ]
27
- device [' auth_password' ] = deviceconfig [' password' ]
28
- device [' auth_strict_key' ] = False
29
- device [' timeout_socket' ] = 10
30
- device [' timeout_ops' ] = 10
26
+ device [" host" ] = deviceconfig [" address" ]
27
+ device [" auth_username" ] = deviceconfig [" username" ]
28
+ device [" auth_password" ] = deviceconfig [" password" ]
29
+ device [" auth_strict_key" ] = False
30
+ device [" timeout_socket" ] = 10
31
+ device [" timeout_ops" ] = 10
31
32
try :
32
- device [' port' ] = deviceconfig [' port' ]
33
+ device [" port" ] = deviceconfig [" port" ]
33
34
except KeyError :
34
35
pass
35
- if deviceconfig [' type' ] == ' ios-xe' :
36
+ if deviceconfig [" type" ] == " ios-xe" :
36
37
conn = IOSXEDriver (** device )
37
- elif deviceconfig [' type' ] == ' nx-os' :
38
+ elif deviceconfig [" type" ] == " nx-os" :
38
39
conn = NXOSDriver (** device )
39
40
try :
40
41
print (f"Attempting connection to { device ['host' ]} " )
@@ -62,70 +63,79 @@ def getInterfaceInfo(device):
62
63
# Parse raw CLI using Genie
63
64
intdata = resp .genie_parse_output ()
64
65
interfaceStats = {
65
- ' total_port' : 0 ,
66
- ' up_port' : 0 ,
67
- ' down_port' : 0 ,
68
- ' disabled_port' : 0 ,
69
- ' intop10m' : 0 ,
70
- ' intop100m' : 0 ,
71
- ' intop1g' : 0 ,
72
- ' intop10g' : 0 ,
73
- ' intop25g' : 0 ,
74
- ' intop40g' : 0 ,
75
- ' intop100g' : 0 ,
76
- ' intmedcop' : 0 ,
77
- ' intmedsfp' : 0 ,
78
- ' intmedvirtual' : 0
66
+ " total_port" : 0 ,
67
+ " up_port" : 0 ,
68
+ " down_port" : 0 ,
69
+ " disabled_port" : 0 ,
70
+ " intop10m" : 0 ,
71
+ " intop100m" : 0 ,
72
+ " intop1g" : 0 ,
73
+ " intop10g" : 0 ,
74
+ " intop25g" : 0 ,
75
+ " intop40g" : 0 ,
76
+ " intop100g" : 0 ,
77
+ " intmedcop" : 0 ,
78
+ " intmedsfp" : 0 ,
79
+ " intmedvirtual" : 0 ,
79
80
}
81
+ # Init dict for detailed interface operational stat collection
82
+ intDetailed = {}
80
83
# Process each interface
81
84
for iface in intdata :
82
85
# Skip VLAN / PortChannel Interfaces
83
- if ' Ethernet' not in iface :
84
- print (f' found non-ethernet interface: { iface } ' )
86
+ if " Ethernet" not in iface :
87
+ print (f" found non-ethernet interface: { iface } " )
85
88
continue
86
- if ' GigabitEthernet0/0' in iface :
87
- print (f' found management interface: { iface } ' )
89
+ if " GigabitEthernet0/0" in iface :
90
+ print (f" found management interface: { iface } " )
88
91
continue
89
92
print (f"Working on interface { iface } " )
93
+ # Collect detailed interface stats (name, oper status, description, MAC)
94
+ intDetailed [iface ] = {}
95
+ intDetailed [iface ]["oper_status" ] = intdata [iface ]["oper_status" ]
96
+ intDetailed [iface ]["description" ] = intdata [iface ]["description" ]
97
+ intDetailed [iface ]["phys_addr" ] = intdata [iface ]["phys_address" ]
98
+ intDetailed [iface ]["oper_speed" ] = intdata [iface ]["port_speed" ]
99
+ intDetailed [iface ]["oper_duplex" ] = intdata [iface ]["duplex_mode" ]
90
100
# Count all Ethernet interfaces
91
- interfaceStats [' total_port' ] += 1
101
+ interfaceStats [" total_port" ] += 1
92
102
# Count admin-down interfaces
93
- if not intdata [iface ][' enabled' ]:
94
- interfaceStats [' disabled_port' ] += 1
103
+ if not intdata [iface ][" enabled" ]:
104
+ interfaceStats [" disabled_port" ] += 1
95
105
# Count 'not connected' interfaces
96
- elif intdata [iface ][' enabled' ] and intdata [iface ][' oper_status' ] == ' down' :
97
- interfaceStats [' down_port' ] += 1
106
+ elif intdata [iface ][" enabled" ] and intdata [iface ][" oper_status" ] == " down" :
107
+ interfaceStats [" down_port" ] += 1
98
108
# Count up / connected interfaces - Then collect current speeds
99
- elif intdata [iface ][' enabled' ] and intdata [iface ][' oper_status' ] == 'up' :
100
- interfaceStats [' up_port' ] += 1
101
- speed = intdata [iface ][' bandwidth' ]
109
+ elif intdata [iface ][" enabled" ] and intdata [iface ][" oper_status" ] == "up" :
110
+ interfaceStats [" up_port" ] += 1
111
+ speed = intdata [iface ][" bandwidth" ]
102
112
if speed == 10_000 :
103
- interfaceStats [' intop10m' ] += 1
113
+ interfaceStats [" intop10m" ] += 1
104
114
if speed == 100_000 :
105
- interfaceStats [' intop100m' ] += 1
115
+ interfaceStats [" intop100m" ] += 1
106
116
if speed == 1_000_000 :
107
- interfaceStats [' intop1g' ] += 1
117
+ interfaceStats [" intop1g" ] += 1
108
118
if speed == 10_000_000 :
109
- interfaceStats [' intop10g' ] += 1
119
+ interfaceStats [" intop10g" ] += 1
110
120
if speed == 25_000_000 :
111
- interfaceStats [' intop25g' ] += 1
121
+ interfaceStats [" intop25g" ] += 1
112
122
if speed == 40_000_000 :
113
- interfaceStats [' intop40g' ] += 1
123
+ interfaceStats [" intop40g" ] += 1
114
124
if speed == 100_000_000 :
115
- interfaceStats [' intop100g' ] += 1
125
+ interfaceStats [" intop100g" ] += 1
116
126
# Count number of interfaces by media type
117
127
try :
118
- media = intdata [iface ][' media_type' ]
119
- if ' 1000BaseTX' in media :
120
- interfaceStats [' intmedcop' ] += 1
121
- elif ' Virtual' in media :
122
- interfaceStats [' intmedvirtual' ] += 1
128
+ media = intdata [iface ][" media_type" ]
129
+ if " 1000BaseTX" in media :
130
+ interfaceStats [" intmedcop" ] += 1
131
+ elif " Virtual" in media :
132
+ interfaceStats [" intmedvirtual" ] += 1
123
133
else :
124
- interfaceStats [' intmedsfp' ] += 1
134
+ interfaceStats [" intmedsfp" ] += 1
125
135
except KeyError :
126
- interfaceStats [' intmedsfp' ] += 1
136
+ interfaceStats [" intmedsfp" ] += 1
127
137
# When complete - return int stats list
128
- return interfaceStats
138
+ return interfaceStats , intDetailed
129
139
130
140
131
141
def save_raw_output (data ):
@@ -134,10 +144,10 @@ def save_raw_output(data):
134
144
output is stored.
135
145
"""
136
146
# Create local directory to store raw output
137
- if not os .path .exists (' raw_output' ):
138
- os .makedirs (' raw_output' )
147
+ if not os .path .exists (" raw_output" ):
148
+ os .makedirs (" raw_output" )
139
149
# Dump port information to file
140
- with open (f' raw_output/{ system_serial } .txt' , 'w' ) as a :
150
+ with open (f" raw_output/{ system_serial } .txt" , "w" ) as a :
141
151
a .write (data .result )
142
152
143
153
@@ -150,11 +160,11 @@ def getSystemInfoXE(device):
150
160
resp = device .send_command ("show version" )
151
161
parsed = resp .genie_parse_output ()
152
162
sysinfo = {}
153
- sysinfo [' serial' ] = parsed [' version' ][ ' chassis_sn' ]
154
- sysinfo [' model' ] = parsed [' version' ][ ' chassis' ]
155
- sysinfo [' sw_ver' ] = parsed [' version' ][ ' version' ]
163
+ sysinfo [" serial" ] = parsed [" version" ][ " chassis_sn" ]
164
+ sysinfo [" model" ] = parsed [" version" ][ " chassis" ]
165
+ sysinfo [" sw_ver" ] = parsed [" version" ][ " version" ]
156
166
global system_serial
157
- system_serial = sysinfo [' serial' ]
167
+ system_serial = sysinfo [" serial" ]
158
168
return sysinfo
159
169
160
170
@@ -167,11 +177,11 @@ def getSystemInfoNX(device):
167
177
resp = device .send_command ("show version" )
168
178
parsed = resp .genie_parse_output ()
169
179
sysinfo = {}
170
- sysinfo [' serial' ] = parsed [' platform' ][ ' hardware' ][ ' processor_board_id' ]
171
- sysinfo [' model' ] = parsed [' platform' ][ ' hardware' ][ ' model' ]
172
- sysinfo [' sw_ver' ] = parsed [' platform' ][ ' software' ][ ' system_version' ]
180
+ sysinfo [" serial" ] = parsed [" platform" ][ " hardware" ][ " processor_board_id" ]
181
+ sysinfo [" model" ] = parsed [" platform" ][ " hardware" ][ " model" ]
182
+ sysinfo [" sw_ver" ] = parsed [" platform" ][ " software" ][ " system_version" ]
173
183
global system_serial
174
- system_serial = sysinfo [' serial' ]
184
+ system_serial = sysinfo [" serial" ]
175
185
return sysinfo
176
186
177
187
@@ -185,7 +195,7 @@ def addDeviceToDB(devicelist):
185
195
# Compare between new config file - see what should be added/removed
186
196
curswitches = swDB .getAllSummary ()
187
197
currentSwitches = [row [3 ] for row in curswitches ]
188
- newSwitches = [devicelist [switch ][' address' ] for switch in devicelist ]
198
+ newSwitches = [devicelist [switch ][" address" ] for switch in devicelist ]
189
199
swRemove = set (currentSwitches ).difference (newSwitches )
190
200
swAdd = set (newSwitches ).difference (currentSwitches )
191
201
# If switches to remove, purge from the database
@@ -197,7 +207,7 @@ def addDeviceToDB(devicelist):
197
207
198
208
print ("Adding devices to DB..." )
199
209
for switch in devicelist :
200
- switchIP = devicelist [switch ][' address' ]
210
+ switchIP = devicelist [switch ][" address" ]
201
211
if switchIP in swAdd :
202
212
print (f"Adding switch ({ switch } / { switchIP } ) to DB..." )
203
213
swDB .addSwitch (str (switch ), str (switchIP ))
@@ -206,7 +216,7 @@ def addDeviceToDB(devicelist):
206
216
swDB .close ()
207
217
208
218
209
- def updateDB (device , ip , sysinfo , portinfo ):
219
+ def updateDB (device , ip , sysinfo , portinfo , detailedinfo ):
210
220
"""
211
221
Insert new system & port information
212
222
into the database
@@ -216,6 +226,8 @@ def updateDB(device, ip, sysinfo, portinfo):
216
226
swDB .updateSysInfo (device , ip , sysinfo )
217
227
print (f"Updating port info for { device } in DB..." )
218
228
swDB .updatePorts (device , ip , portinfo )
229
+ print (f"Updating detailed port info for { device } in DB..." )
230
+ swDB .updateInterfaceDetails (device , ip , sysinfo , detailedinfo )
219
231
swDB .close ()
220
232
221
233
@@ -250,7 +262,7 @@ def run():
250
262
# Iterate through each device for processing
251
263
for device in devicelist :
252
264
dev = device
253
- ip = devicelist [device ][' address' ]
265
+ ip = devicelist [device ][" address" ]
254
266
# Open device connection
255
267
devcon = connectToDevice (devicelist [device ])
256
268
if devcon :
@@ -260,13 +272,14 @@ def run():
260
272
sysinfo = getSystemInfoXE (devcon )
261
273
if type (devcon ) == NXOSDriver :
262
274
sysinfo = getSystemInfoNX (devcon )
263
- portinfo = getInterfaceInfo (devcon )
275
+ portinfo , detailedinfo = getInterfaceInfo (devcon )
264
276
except Exception as e :
265
- print (f' ERROR: { e } ' )
277
+ print (f" ERROR: { e } " )
266
278
updateCheckStatus (device , ip , False )
267
279
continue
268
280
# Update database with new info
269
- updateDB (dev , ip , sysinfo , portinfo )
281
+ updateDB (dev , ip , sysinfo , portinfo , detailedinfo )
282
+ # Update database with interface detail info
270
283
# Update if check succeeeded
271
284
updateCheckStatus (dev , ip , True )
272
285
else :
@@ -276,5 +289,5 @@ def run():
276
289
updateLastRun ()
277
290
278
291
279
- if __name__ == ' __main__' :
292
+ if __name__ == " __main__" :
280
293
run ()
0 commit comments