3
3
import swsssdk
4
4
import sys
5
5
import re
6
+ import types
6
7
from tabulate import tabulate
7
8
from natsort import natsorted
8
-
9
+ from swsssdk import ConfigDBConnector
10
+ from pprint import pprint
9
11
10
12
11
13
# ========================== Common interface-utils logic ==========================
@@ -23,42 +25,84 @@ PORT_DESCRIPTION = "description"
23
25
PORT_OPTICS_TYPE = "type"
24
26
PORT_PFC_ASYM_STATUS = "pfc_asym"
25
27
28
+ def db_connect_configdb ():
29
+ """
30
+ Connect to configdb
31
+ """
32
+ config_db = ConfigDBConnector ()
33
+ if config_db is None :
34
+ return None
35
+ config_db .connect ()
36
+ return config_db
37
+
38
+ def get_frontpanel_port_list (config_db ):
39
+ ports_dict = config_db .get_table ('PORT' )
40
+ front_panel_ports_list = []
41
+ for port in ports_dict .iterkeys ():
42
+ front_panel_ports_list .append (port )
43
+ return front_panel_ports_list
44
+
45
+
46
+ def get_interface_vlan_dict (config_db ):
47
+ """
48
+ Get info from REDIS ConfigDB and create interface to vlan mapping
49
+ """
50
+ get_int_vlan_configdb_info = config_db .get_table ('VLAN_MEMBER' )
51
+ int_list = []
52
+ vlan_list = []
53
+ for line in get_int_vlan_configdb_info :
54
+ vlan_number = line [0 ]
55
+ interface = line [1 ]
56
+ int_list .append (interface )
57
+ vlan_list .append (vlan_number )
58
+ int_to_vlan_dict = dict (zip (int_list , vlan_list ))
59
+ return int_to_vlan_dict
60
+
61
+
62
+ def config_db_vlan_port_keys_get (int_to_vlan_dict , front_panel_ports_list , intf_name ):
63
+ """
64
+ Get interface vlan value and return it.
65
+ """
66
+ vlan = "routed"
67
+ if intf_name in front_panel_ports_list :
68
+ if intf_name in int_to_vlan_dict .keys ():
69
+ vlan = int_to_vlan_dict [intf_name ]
70
+ if "Vlan" in vlan :
71
+ vlan = "trunk"
72
+ return vlan
73
+
26
74
27
75
def db_connect_appl ():
28
76
appl_db = swsssdk .SonicV2Connector (host = '127.0.0.1' )
29
77
if appl_db is None :
30
78
return None
31
-
32
79
appl_db .connect (appl_db .APPL_DB )
33
-
34
80
return appl_db
35
81
36
82
37
- def appl_db_keys_get (appl_db , intf_name ):
38
-
83
+ def appl_db_keys_get (appl_db , front_panel_ports_list , intf_name ):
84
+ """
85
+ Get APPL_DB Keys
86
+ """
39
87
if intf_name is None :
40
88
appl_db_keys = appl_db .keys (appl_db .APPL_DB , "PORT_TABLE:*" )
41
- elif intf_name . startswith ( 'Ethernet' ) :
42
- appl_db_keys = appl_db .keys (appl_db .APPL_DB , "PORT_TABLE:%s" % intf_name )
89
+ elif intf_name in front_panel_ports_list :
90
+ appl_db_keys = db .keys (appl_db .APPL_DB , "PORT_TABLE:%s" % intf_name )
43
91
else :
44
92
return None
45
-
46
93
return appl_db_keys
47
94
48
95
49
96
def appl_db_port_status_get (appl_db , intf_name , status_type ):
50
97
"""
51
98
Get the port status
52
99
"""
53
-
54
100
full_table_id = PORT_STATUS_TABLE_PREFIX + intf_name
55
101
status = appl_db .get (appl_db .APPL_DB , full_table_id , status_type )
56
102
if status is None :
57
103
return "N/A"
58
-
59
104
if status_type == PORT_SPEED and status != "N/A" :
60
105
status = '{}G' .format (status [:- 3 ])
61
-
62
106
return status
63
107
64
108
@@ -83,13 +127,153 @@ def state_db_port_optics_get(state_db, intf_name, type):
83
127
return "N/A"
84
128
return optics_type
85
129
130
+ def merge_dicts (x ,y ):
131
+ # store a copy of x, but overwrite with y's values where applicable
132
+ merged = dict (x ,** y )
133
+ xkeys = x .keys ()
134
+ # if the value of merged[key] was overwritten with y[key]'s value
135
+ # then we need to put back any missing x[key] values
136
+ for key in xkeys :
137
+ # if this key is a dictionary, recurse
138
+ if type (x [key ]) is types .DictType and y .has_key (key ):
139
+ merged [key ] = merge (x [key ],y [key ])
140
+ return merged
141
+
142
+ def tuple_to_dict (tup , new_dict ):
143
+ """
144
+ From a tuple create a dictionary that uses the first item in the tuple as a key
145
+ and the 2nd item in the tuple as a value.
146
+ """
147
+ for a , b in tup :
148
+ new_dict .setdefault (a , []).append (b )
149
+ return new_dict
150
+
151
+
152
+ def get_raw_portchannel_info (config_db ):
153
+ """
154
+ This function uses the redis config_db as input and gets the "PORTCHANNEL_MEMBER" table
155
+ create
156
+ >>> get_po_int_configdb_info = get_portchannel_info(config_db)
157
+ >>> pprint(get_po_int_configdb_info)
158
+ {('PortChannel0001', 'Ethernet108'): {},
159
+ ('PortChannel0001', 'Ethernet112'): {},
160
+ ('PortChannel0002', 'Ethernet116'): {},
161
+ ('PortChannel0003', 'Ethernet120'): {},
162
+ ('PortChannel0004', 'Ethernet124'): {}}
163
+ This function returns a dictionary with the key being portchannels and interface tuple.
164
+ """
165
+ get_raw_po_int_configdb_info = config_db .get_table ('PORTCHANNEL_MEMBER' )
166
+ return get_raw_po_int_configdb_info # Return a dictionary with the key being the portchannel and interface
167
+
168
+ def get_portchannel_list (get_raw_po_int_configdb_info ):
169
+ """
170
+ >>> portchannel_list = get_portchannel_list(get_raw_po_int_configdb_info)
171
+ >>> pprint(portchannel_list)
172
+ ['PortChannel0001', 'PortChannel0002', 'PortChannel0003', 'PortChannel0004']
173
+ >>>
174
+ """
175
+ portchannel_list = []
176
+ for po in get_raw_po_int_configdb_info :
177
+ portchannel = po [0 ]
178
+ if portchannel not in portchannel_list :
179
+ portchannel_list .append (portchannel )
180
+ portchannel = portchannel_list .sort ()
181
+ return portchannel_list
182
+
183
+ def create_po_int_tuple_list (get_raw_po_int_configdb_info ):
184
+ """
185
+ >>> po_int_tuple = get_raw_po_int_configdb_info.keys()
186
+ >>> pprint(po_int_tuple_list)
187
+ [('PortChannel0001', 'Ethernet108'),
188
+ ('PortChannel0002', 'Ethernet116'),
189
+ ('PortChannel0004', 'Ethernet124'),
190
+ ('PortChannel0003', 'Ethernet120'),
191
+ ('PortChannel0001', 'Ethernet112')]
192
+ >>>
193
+ """
194
+ po_int_tuple_list = get_raw_po_int_configdb_info .keys ()
195
+ return po_int_tuple_list
196
+
197
+ def create_po_int_dict (po_int_tuple_list ):
198
+ """
199
+ This function takes the portchannel to interface tuple
200
+ and converts that into a portchannel to interface dictionary
201
+ with the portchannels as the key and the interfaces as the values.
202
+ """
203
+ temp_dict = {}
204
+ po_int_dict = tuple_to_dict (po_int_tuple_list , temp_dict )
205
+ return po_int_dict
206
+
207
+ def create_int_to_portchannel_dict (po_int_tuple_list ):
208
+ """
209
+ This function takes the portchannel to interface tuple
210
+ and converts that into an interface to portchannel dictionary
211
+ with the interfaces as the key and the portchannels as the values.
212
+ """
213
+ int_po_dict = {}
214
+ for po , intf in po_int_tuple_list :
215
+ int_po_dict .setdefault (intf , po )
216
+ return int_po_dict
217
+
218
+ def po_speed_dict (po_int_dict , appl_db ):
219
+ """
220
+ This function takes the portchannel to interface dictionary
221
+ and the appl_db and then creates a portchannel to speed
222
+ dictionary.
223
+ """
224
+ if po_int_dict :
225
+ po_list = []
226
+ for key , value in po_int_dict .iteritems ():
227
+ agg_speed_list = []
228
+ po_list .append (key )
229
+ if len (value ) == 1 :
230
+ interface_speed = appl_db .get (appl_db .APPL_DB , "PORT_TABLE:" + value [0 ], "speed" )
231
+ interface_speed = '{}G' .format (interface_speed [:- 3 ])
232
+ po_list .append (interface_speed )
233
+ elif len (value ) > 1 :
234
+ for intf in value :
235
+ temp_speed = appl_db .get (appl_db .APPL_DB , "PORT_TABLE:" + intf , "speed" )
236
+ temp_speed = int (temp_speed )
237
+ agg_speed_list .append (temp_speed )
238
+ interface_speed = sum (agg_speed_list )
239
+ interface_speed = str (interface_speed )
240
+ interface_speed = '{}G' .format (interface_speed [:- 3 ])
241
+ po_list .append (interface_speed )
242
+ po_speed_dict = dict (po_list [i :i + 2 ] for i in range (0 , len (po_list ), 2 ))
243
+ return po_speed_dict
244
+ else :
245
+ po_speed_dict = {}
246
+ return po_speed_dict
247
+
248
+ def appl_db_portchannel_status_get (appl_db , config_db , po_name , status_type , portchannel_speed_dict ):
249
+ """
250
+ Get the port status
251
+ """
252
+ full_table_id = "LAG_TABLE:" + po_name
253
+ po_table_id = "PORTCHANNEL|" + po_name
254
+ #print(full_table_id)
255
+ if status_type == "speed" :
256
+ status = portchannel_speed_dict [po_name ]
257
+ return status
258
+ if status_type == "vlan" :
259
+ status = "routed"
260
+ return status
261
+ if status_type == "mtu" :
262
+ status = config_db .get (config_db .CONFIG_DB , po_table_id , status_type )
263
+ return status
264
+ status = appl_db .get (appl_db .APPL_DB , full_table_id , status_type )
265
+ #print(status)
266
+ if status is None :
267
+ return "N/A"
268
+ return status
269
+
86
270
# ========================== interface-status logic ==========================
87
271
88
- header_stat = ['Interface' , 'Lanes' , 'Speed' , 'MTU' , 'Alias' , 'Oper' , 'Admin' , 'Type' , 'Asym PFC' ]
272
+ header_stat = ['Interface' , 'Lanes' , 'Speed' , 'MTU' , 'Alias' , 'Vlan' , ' Oper' , 'Admin' , 'Type' , 'Asym PFC' ]
89
273
90
274
class IntfStatus (object ):
91
275
92
- def display_intf_status (self , appl_db_keys ):
276
+ def display_intf_status (self , appl_db_keys , front_panel_ports_list , portchannel_speed_dict ):
93
277
"""
94
278
Generate interface-status output
95
279
"""
@@ -104,34 +288,65 @@ class IntfStatus(object):
104
288
#
105
289
for i in appl_db_keys :
106
290
key = re .split (':' , i , maxsplit = 1 )[- 1 ].strip ()
107
- if key and key . startswith ( 'Ethernet' ) :
291
+ if key in front_panel_ports_list :
108
292
table .append ((key ,
109
293
appl_db_port_status_get (self .appl_db , key , PORT_LANES_STATUS ),
110
294
appl_db_port_status_get (self .appl_db , key , PORT_SPEED ),
111
295
appl_db_port_status_get (self .appl_db , key , PORT_MTU_STATUS ),
112
296
appl_db_port_status_get (self .appl_db , key , PORT_ALIAS ),
297
+ config_db_vlan_port_keys_get (self .combined_int_to_vlan_po_dict , self .front_panel_ports_list , key ),
113
298
appl_db_port_status_get (self .appl_db , key , PORT_OPER_STATUS ),
114
299
appl_db_port_status_get (self .appl_db , key , PORT_ADMIN_STATUS ),
115
300
state_db_port_optics_get (self .state_db , key , PORT_OPTICS_TYPE ),
116
301
appl_db_port_status_get (self .appl_db , key , PORT_PFC_ASYM_STATUS )))
117
-
118
302
# Sorting and tabulating the result table.
303
+ for po , value in portchannel_speed_dict .iteritems ():
304
+ if po :
305
+ table .append ((po ,
306
+ appl_db_portchannel_status_get (self .appl_db , self .config_db , po , PORT_LANES_STATUS , self .portchannel_speed_dict ),
307
+ appl_db_portchannel_status_get (self .appl_db , self .config_db , po , PORT_SPEED , self .portchannel_speed_dict ),
308
+ appl_db_portchannel_status_get (self .appl_db , self .config_db , po , PORT_MTU_STATUS , self .portchannel_speed_dict ),
309
+ appl_db_portchannel_status_get (self .appl_db , self .config_db , po , PORT_ALIAS , self .portchannel_speed_dict ),
310
+ appl_db_portchannel_status_get (self .appl_db , self .config_db , po , "vlan" , self .portchannel_speed_dict ),
311
+ appl_db_portchannel_status_get (self .appl_db , self .config_db , po , PORT_OPER_STATUS , self .portchannel_speed_dict ),
312
+ appl_db_portchannel_status_get (self .appl_db , self .config_db , po , PORT_ADMIN_STATUS , self .portchannel_speed_dict ),
313
+ appl_db_portchannel_status_get (self .appl_db , self .config_db , po , PORT_OPTICS_TYPE , self .portchannel_speed_dict ),
314
+ appl_db_portchannel_status_get (self .appl_db , self .config_db , po , PORT_PFC_ASYM_STATUS , self .portchannel_speed_dict )))
315
+
119
316
sorted_table = natsorted (table )
120
317
print tabulate (sorted_table , header_stat , tablefmt = "simple" , stralign = 'right' )
121
318
122
319
123
320
def __init__ (self , intf_name ):
124
-
321
+ """
322
+ Class constructor method
323
+ :param self:
324
+ :param intf_name: string of interface
325
+ :return:
326
+ """
125
327
self .appl_db = db_connect_appl ()
126
328
self .state_db = db_connect_state ()
329
+ self .config_db = db_connect_configdb ()
127
330
if self .appl_db is None :
128
331
return
129
332
if self .state_db is None :
130
333
return
131
- appl_db_keys = appl_db_keys_get (self .appl_db , intf_name )
334
+ if self .config_db is None :
335
+ return
336
+ self .front_panel_ports_list = get_frontpanel_port_list (self .config_db )
337
+ appl_db_keys = appl_db_keys_get (self .appl_db , self .front_panel_ports_list , intf_name )
338
+ self .int_to_vlan_dict = get_interface_vlan_dict (self .config_db )
339
+ self .get_raw_po_int_configdb_info = get_raw_portchannel_info (self .config_db )
340
+ self .portchannel_list = get_portchannel_list (self .get_raw_po_int_configdb_info )
341
+ self .po_int_tuple_list = create_po_int_tuple_list (self .get_raw_po_int_configdb_info )
342
+ self .po_int_dict = create_po_int_dict (self .po_int_tuple_list )
343
+ self .int_po_dict = create_int_to_portchannel_dict (self .po_int_tuple_list )
344
+ self .combined_int_to_vlan_po_dict = merge_dicts (self .int_to_vlan_dict , self .int_po_dict )
345
+ self .portchannel_speed_dict = po_speed_dict (self .po_int_dict , self .appl_db )
346
+ self .portchannel_keys = self .portchannel_speed_dict .keys ()
132
347
if appl_db_keys is None :
133
348
return
134
- self .display_intf_status (appl_db_keys )
349
+ self .display_intf_status (appl_db_keys , self . front_panel_ports_list , self . portchannel_speed_dict )
135
350
136
351
137
352
@@ -143,7 +358,7 @@ header_desc = ['Interface', 'Oper', 'Admin', 'Alias', 'Description']
143
358
144
359
class IntfDescription (object ):
145
360
146
- def display_intf_description (self , appl_db_keys ):
361
+ def display_intf_description (self , appl_db_keys , front_panel_ports_list ):
147
362
"""
148
363
Generate interface-description output
149
364
"""
@@ -158,7 +373,7 @@ class IntfDescription(object):
158
373
#
159
374
for i in appl_db_keys :
160
375
key = re .split (':' , i , maxsplit = 1 )[- 1 ].strip ()
161
- if key and key . startswith ( 'Ethernet' ) :
376
+ if key in front_panel_ports_list :
162
377
table .append ((key ,
163
378
appl_db_port_status_get (self .appl_db , key , PORT_OPER_STATUS ),
164
379
appl_db_port_status_get (self .appl_db , key , PORT_ADMIN_STATUS ),
@@ -171,15 +386,18 @@ class IntfDescription(object):
171
386
172
387
def __init__ (self , intf_name ):
173
388
389
+ self .config_db = db_connect_configdb ()
174
390
self .appl_db = db_connect_appl ()
175
391
if self .appl_db is None :
176
392
return
177
-
178
- appl_db_keys = appl_db_keys_get (self .appl_db , intf_name )
393
+ if self .config_db is None :
394
+ return
395
+ self .front_panel_ports_list = get_frontpanel_port_list (self .config_db )
396
+ appl_db_keys = appl_db_keys_get (self .appl_db , self .front_panel_ports_list , intf_name )
179
397
if appl_db_keys is None :
180
398
return
181
399
182
- self .display_intf_description (appl_db_keys )
400
+ self .display_intf_description (appl_db_keys , self . front_panel_ports_list )
183
401
184
402
185
403
0 commit comments