33import swsssdk
44import sys
55import re
6+ import types
67from tabulate import tabulate
78from natsort import natsorted
8-
9+ from swsssdk import ConfigDBConnector
10+ from pprint import pprint
911
1012
1113# ========================== Common interface-utils logic ==========================
@@ -23,42 +25,84 @@ PORT_DESCRIPTION = "description"
2325PORT_OPTICS_TYPE = "type"
2426PORT_PFC_ASYM_STATUS = "pfc_asym"
2527
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+
2674
2775def db_connect_appl ():
2876 appl_db = swsssdk .SonicV2Connector (host = '127.0.0.1' )
2977 if appl_db is None :
3078 return None
31-
3279 appl_db .connect (appl_db .APPL_DB )
33-
3480 return appl_db
3581
3682
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+ """
3987 if intf_name is None :
4088 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 )
4391 else :
4492 return None
45-
4693 return appl_db_keys
4794
4895
4996def appl_db_port_status_get (appl_db , intf_name , status_type ):
5097 """
5198 Get the port status
5299 """
53-
54100 full_table_id = PORT_STATUS_TABLE_PREFIX + intf_name
55101 status = appl_db .get (appl_db .APPL_DB , full_table_id , status_type )
56102 if status is None :
57103 return "N/A"
58-
59104 if status_type == PORT_SPEED and status != "N/A" :
60105 status = '{}G' .format (status [:- 3 ])
61-
62106 return status
63107
64108
@@ -83,13 +127,153 @@ def state_db_port_optics_get(state_db, intf_name, type):
83127 return "N/A"
84128 return optics_type
85129
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+
86270# ========================== interface-status logic ==========================
87271
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' ]
89273
90274class IntfStatus (object ):
91275
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 ):
93277 """
94278 Generate interface-status output
95279 """
@@ -104,34 +288,65 @@ class IntfStatus(object):
104288 #
105289 for i in appl_db_keys :
106290 key = re .split (':' , i , maxsplit = 1 )[- 1 ].strip ()
107- if key and key . startswith ( 'Ethernet' ) :
291+ if key in front_panel_ports_list :
108292 table .append ((key ,
109293 appl_db_port_status_get (self .appl_db , key , PORT_LANES_STATUS ),
110294 appl_db_port_status_get (self .appl_db , key , PORT_SPEED ),
111295 appl_db_port_status_get (self .appl_db , key , PORT_MTU_STATUS ),
112296 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 ),
113298 appl_db_port_status_get (self .appl_db , key , PORT_OPER_STATUS ),
114299 appl_db_port_status_get (self .appl_db , key , PORT_ADMIN_STATUS ),
115300 state_db_port_optics_get (self .state_db , key , PORT_OPTICS_TYPE ),
116301 appl_db_port_status_get (self .appl_db , key , PORT_PFC_ASYM_STATUS )))
117-
118302 # 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+
119316 sorted_table = natsorted (table )
120317 print tabulate (sorted_table , header_stat , tablefmt = "simple" , stralign = 'right' )
121318
122319
123320 def __init__ (self , intf_name ):
124-
321+ """
322+ Class constructor method
323+ :param self:
324+ :param intf_name: string of interface
325+ :return:
326+ """
125327 self .appl_db = db_connect_appl ()
126328 self .state_db = db_connect_state ()
329+ self .config_db = db_connect_configdb ()
127330 if self .appl_db is None :
128331 return
129332 if self .state_db is None :
130333 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 ()
132347 if appl_db_keys is None :
133348 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 )
135350
136351
137352
@@ -143,7 +358,7 @@ header_desc = ['Interface', 'Oper', 'Admin', 'Alias', 'Description']
143358
144359class IntfDescription (object ):
145360
146- def display_intf_description (self , appl_db_keys ):
361+ def display_intf_description (self , appl_db_keys , front_panel_ports_list ):
147362 """
148363 Generate interface-description output
149364 """
@@ -158,7 +373,7 @@ class IntfDescription(object):
158373 #
159374 for i in appl_db_keys :
160375 key = re .split (':' , i , maxsplit = 1 )[- 1 ].strip ()
161- if key and key . startswith ( 'Ethernet' ) :
376+ if key in front_panel_ports_list :
162377 table .append ((key ,
163378 appl_db_port_status_get (self .appl_db , key , PORT_OPER_STATUS ),
164379 appl_db_port_status_get (self .appl_db , key , PORT_ADMIN_STATUS ),
@@ -171,15 +386,18 @@ class IntfDescription(object):
171386
172387 def __init__ (self , intf_name ):
173388
389+ self .config_db = db_connect_configdb ()
174390 self .appl_db = db_connect_appl ()
175391 if self .appl_db is None :
176392 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 )
179397 if appl_db_keys is None :
180398 return
181399
182- self .display_intf_description (appl_db_keys )
400+ self .display_intf_description (appl_db_keys , self . front_panel_ports_list )
183401
184402
185403
0 commit comments