Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support show interface commands for multi ASIC platforms #1006

Merged
merged 7 commits into from
Aug 21, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
240 changes: 125 additions & 115 deletions scripts/intfutil
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
#! /usr/bin/python

import swsssdk
import argparse
import os
from os import ttyname
import sys
import re
import types
from pprint import pprint

from tabulate import tabulate
from natsort import natsorted

import swsssdk
from swsssdk import ConfigDBConnector
from pprint import pprint
from utilities_common.constants import PORT_CHANNEL_OBJ
from utilities_common.constants import PORT_OBJ
from utilities_common.multi_asic import MultiAsic
from utilities_common.multi_asic import multi_asic_args
from utilities_common.multi_asic import run_on_all_asics
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

group imports.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in latest commit

from utilities_common.intf_filter import parse_interface_in_filter

import os

# mock the redis for unit test purposes #
try:
if os.environ["UTILITIES_UNIT_TESTING"] == "1":
Expand Down Expand Up @@ -347,7 +355,12 @@ header_stat_sub_intf = ['Sub port interface', 'Speed', 'MTU', 'Vlan', 'Admin', '

class IntfStatus(object):

def display_intf_status(self, intf_name, appl_db_keys, front_panel_ports_list, portchannel_speed_dict, appl_db_sub_intf_keys, sub_intf_list, sub_intf_only):
def display_intf_status(self):
self.get_intf_status()
sorted_table = natsorted(self.table)
print tabulate(sorted_table, header_stat if not self.sub_intf_only else header_stat_sub_intf, tablefmt="simple", stralign='right')

def generate_intf_status(self):
"""
Generate interface-status output
"""
Expand All @@ -356,108 +369,102 @@ class IntfStatus(object):
table = []
key = []

intf_fs = parse_interface_in_filter(intf_name)

intf_fs = parse_interface_in_filter(self.intf_name)
#
# Iterate through all the keys and append port's associated state to
# the result table.
#
if not sub_intf_only:
for i in appl_db_keys:
if not self.sub_intf_only:
for i in self.appl_db_keys:
key = re.split(':', i, maxsplit=1)[-1].strip()
if key in front_panel_ports_list:
if intf_name is None or key in intf_fs:
if key in self.front_panel_ports_list:
if self.multi_asic.skip_display(PORT_OBJ, key):
continue

if self.intf_name is None or key in intf_fs:
table.append((key,
appl_db_port_status_get(self.appl_db, key, PORT_LANES_STATUS),
appl_db_port_status_get(self.appl_db, key, PORT_SPEED),
appl_db_port_status_get(self.appl_db, key, PORT_MTU_STATUS),
appl_db_port_status_get(self.appl_db, key, PORT_FEC),
appl_db_port_status_get(self.appl_db, key, PORT_ALIAS),
appl_db_port_status_get(self.db, key, PORT_LANES_STATUS),
appl_db_port_status_get(self.db, key, PORT_SPEED),
appl_db_port_status_get(self.db, key, PORT_MTU_STATUS),
appl_db_port_status_get(self.db, key, PORT_FEC),
appl_db_port_status_get(self.db, key, PORT_ALIAS),
config_db_vlan_port_keys_get(self.combined_int_to_vlan_po_dict, self.front_panel_ports_list, key),
appl_db_port_status_get(self.appl_db, key, PORT_OPER_STATUS),
appl_db_port_status_get(self.appl_db, key, PORT_ADMIN_STATUS),
state_db_port_optics_get(self.state_db, key, PORT_OPTICS_TYPE),
appl_db_port_status_get(self.appl_db, key, PORT_PFC_ASYM_STATUS)))
appl_db_port_status_get(self.db, key, PORT_OPER_STATUS),
appl_db_port_status_get(self.db, key, PORT_ADMIN_STATUS),
state_db_port_optics_get(self.db, key, PORT_OPTICS_TYPE),
appl_db_port_status_get(self.db, key, PORT_PFC_ASYM_STATUS)))

for po, value in portchannel_speed_dict.iteritems():
for po, value in self.portchannel_speed_dict.iteritems():
if po:
if intf_name is None or po in intf_fs:
if self.multi_asic.skip_display(PORT_CHANNEL_OBJ, po):
continue
if self.intf_name is None or po in intf_fs:
table.append((po,
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_LANES_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_SPEED, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_MTU_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_FEC, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_ALIAS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, "vlan", self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_OPER_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_ADMIN_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_OPTICS_TYPE, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_PFC_ASYM_STATUS, self.portchannel_speed_dict)))
appl_db_portchannel_status_get(self.db, self.config_db, po, PORT_LANES_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.db, self.config_db, po, PORT_SPEED, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.db, self.config_db, po, PORT_MTU_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.db, self.config_db, po, PORT_FEC, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.db, self.config_db, po, PORT_ALIAS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.db, self.config_db, po, "vlan", self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.db, self.config_db, po, PORT_OPER_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.db, self.config_db, po, PORT_ADMIN_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.db, self.config_db, po, PORT_OPTICS_TYPE, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.db, self.config_db, po, PORT_PFC_ASYM_STATUS, self.portchannel_speed_dict)))
else:
for key in appl_db_sub_intf_keys:
for key in self.appl_db_sub_intf_keys:
sub_intf = re.split(':', key, maxsplit=1)[-1].strip()
if sub_intf in sub_intf_list:
if sub_intf in self.sub_intf_list:
table.append((sub_intf,
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_SPEED),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_MTU_STATUS),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, "vlan"),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_ADMIN_STATUS),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_OPTICS_TYPE)))

# Sorting and tabulating the result table.
sorted_table = natsorted(table)
print tabulate(sorted_table, header_stat if not sub_intf_only else header_stat_sub_intf, tablefmt="simple", stralign='right')


def __init__(self, intf_name):
appl_db_sub_intf_status_get(self.db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_SPEED),
appl_db_sub_intf_status_get(self.db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_MTU_STATUS),
appl_db_sub_intf_status_get(self.db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, "vlan"),
appl_db_sub_intf_status_get(self.db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_ADMIN_STATUS),
appl_db_sub_intf_status_get(self.db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_OPTICS_TYPE)))
return table

def __init__(self, intf_name, namespace_option, display_option):
Copy link
Contributor

@smaheshm smaheshm Jul 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move init to top?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

"""
Class constructor method
:param self:
:param intf_name: string of interface
:return:
"""
self.appl_db = db_connect_appl()
self.state_db = db_connect_state()
self.config_db = db_connect_configdb()
if self.appl_db is None:
return
if self.state_db is None:
return
if self.config_db is None:
return

sub_intf_only = False
sub_intf_name = intf_name
self.db = None
self.config_db = None
self.sub_intf_only = False
self.intf_name = intf_name
self.sub_intf_name = intf_name
self.table = []
self.multi_asic = MultiAsic(display_option, namespace_option)
if intf_name is not None:
if intf_name == SUB_PORT:
intf_name = None
sub_intf_name = None
sub_intf_only = True
self.intf_name = None
self.sub_intf_name = None
self.sub_intf_only = True
else:
sub_intf_sep_idx = intf_name.find(VLAN_SUB_INTERFACE_SEPARATOR)
if sub_intf_sep_idx != -1:
sub_intf_only = True
intf_name = intf_name[:sub_intf_sep_idx]
self.sub_intf_only = True
self.intf_name = intf_name[:sub_intf_sep_idx]

@run_on_all_asics
def get_intf_status(self):
self.front_panel_ports_list = get_frontpanel_port_list(self.config_db)
appl_db_keys = appl_db_keys_get(self.appl_db, self.front_panel_ports_list, None)
self.appl_db_keys = appl_db_keys_get(self.db, self.front_panel_ports_list, None)
self.int_to_vlan_dict = get_interface_vlan_dict(self.config_db)
self.get_raw_po_int_configdb_info = get_raw_portchannel_info(self.config_db)
self.portchannel_list = get_portchannel_list(self.get_raw_po_int_configdb_info)
self.po_int_tuple_list = create_po_int_tuple_list(self.get_raw_po_int_configdb_info)
self.po_int_dict = create_po_int_dict(self.po_int_tuple_list)
self.int_po_dict = create_int_to_portchannel_dict(self.po_int_tuple_list)
self.combined_int_to_vlan_po_dict = merge_dicts(self.int_to_vlan_dict, self.int_po_dict)
self.portchannel_speed_dict = po_speed_dict(self.po_int_dict, self.appl_db)
self.portchannel_speed_dict = po_speed_dict(self.po_int_dict, self.db)
self.portchannel_keys = self.portchannel_speed_dict.keys()

self.sub_intf_list = get_sub_port_intf_list(self.config_db)
appl_db_sub_intf_keys = appl_db_sub_intf_keys_get(self.appl_db, self.sub_intf_list, sub_intf_name)
if appl_db_keys is None:
return
self.display_intf_status(intf_name, appl_db_keys, self.front_panel_ports_list, self.portchannel_speed_dict, appl_db_sub_intf_keys, self.sub_intf_list, sub_intf_only)


self.appl_db_sub_intf_keys = appl_db_sub_intf_keys_get(self.db, self.sub_intf_list, self.sub_intf_name)
if self.appl_db_keys:
self.table += self.generate_intf_status()

# ========================== interface-description logic ==========================

Expand All @@ -467,7 +474,15 @@ header_desc = ['Interface', 'Oper', 'Admin', 'Alias', 'Description']

class IntfDescription(object):

def display_intf_description(self, appl_db_keys, front_panel_ports_list):
def display_intf_description(self):

self.get_intf_description()

# Sorting and tabulating the result table.
sorted_table = natsorted(self.table)
print tabulate(sorted_table, header_desc, tablefmt="simple", stralign='right')

def generate_intf_description(self):
"""
Generate interface-description output
"""
Expand All @@ -480,58 +495,53 @@ class IntfDescription(object):
# Iterate through all the keys and append port's associated state to
# the result table.
#
for i in appl_db_keys:
for i in self.appl_db_keys:
key = re.split(':', i, maxsplit=1)[-1].strip()
if key in front_panel_ports_list:
if key in self.front_panel_ports_list:
if self.multi_asic.skip_display(PORT_OBJ, key):
continue
table.append((key,
appl_db_port_status_get(self.appl_db, key, PORT_OPER_STATUS),
appl_db_port_status_get(self.appl_db, key, PORT_ADMIN_STATUS),
appl_db_port_status_get(self.appl_db, key, PORT_ALIAS),
appl_db_port_status_get(self.appl_db, key, PORT_DESCRIPTION)))

# Sorting and tabulating the result table.
sorted_table = natsorted(table)
print tabulate(sorted_table, header_desc, tablefmt="simple", stralign='right')
appl_db_port_status_get(self.db, key, PORT_OPER_STATUS),
appl_db_port_status_get(self.db, key, PORT_ADMIN_STATUS),
appl_db_port_status_get(self.db, key, PORT_ALIAS),
appl_db_port_status_get(self.db, key, PORT_DESCRIPTION)))
return table

def __init__(self, intf_name):
def __init__(self, intf_name, namespace_option, display_option):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move init to top?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed


self.config_db = db_connect_configdb()
self.appl_db = db_connect_appl()
if self.appl_db is None:
return
if self.config_db is None:
return
self.db = None
self.config_db = None
self.table = []
self.multi_asic = MultiAsic(display_option, namespace_option)

if intf_name is not None and intf_name == SUB_PORT:
intf_name = None
self.intf_name = None
else:
self.intf_name = intf_name

@run_on_all_asics
def get_intf_description(self):
self.front_panel_ports_list = get_frontpanel_port_list(self.config_db)
appl_db_keys = appl_db_keys_get(self.appl_db, self.front_panel_ports_list, intf_name)
if appl_db_keys is None:
return

self.display_intf_description(appl_db_keys, self.front_panel_ports_list)



def main(args):
if len(args) == 0:
print "No valid arguments provided"
return

command = args[0]
if command != "status" and command != "description":
print "No valid command provided"
return

intf_name = args[1] if len(args) == 2 else None

if command == "status":
interface_stat = IntfStatus(intf_name)
elif command == "description":
interface_desc = IntfDescription(intf_name)
self.appl_db_keys = appl_db_keys_get(self.db, self.front_panel_ports_list, self.intf_name)
if self.appl_db_keys:
self.table += self.generate_intf_description()

def main():
parser = argparse.ArgumentParser(description='Display Interface information',
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-c', '--command', type=str, help='get interface status or description', default=None)
parser.add_argument('-i', '--interface', type=str, help='interface information for specific port: Ethernet0', default=None)
parser = multi_asic_args(parser)
args = parser.parse_args()

if args.command == "status":
interface_stat = IntfStatus(args.interface, args.namespace, args.display)
interface_stat.display_intf_status()
elif args.command == "description":
interface_desc = IntfDescription(args.interface, args.namespace, args.display)
interface_desc.display_intf_description()

sys.exit(0)

if __name__ == "__main__":
main(sys.argv[1:])
main()
18 changes: 13 additions & 5 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

import mlnx

from utilities_common.multi_asic import multi_asic_click_options

# Global Variable
PLATFORM_ROOT_PATH = "/usr/share/sonic/device"
PLATFORM_JSON = 'platform.json'
Expand Down Expand Up @@ -1022,34 +1024,40 @@ def presence(interfacename, verbose):

@interfaces.command()
@click.argument('interfacename', required=False)
@multi_asic_click_options
@click.option('--verbose', is_flag=True, help="Enable verbose output")
def description(interfacename, verbose):
def description(interfacename, namespace, display, verbose):
"""Show interface status, protocol and description"""

cmd = "intfutil description"
cmd = "intfutil -c description"

if interfacename is not None:
if get_interface_mode() == "alias":
interfacename = iface_alias_converter.alias_to_name(interfacename)

cmd += " {}".format(interfacename)

namespace_option = "" if namespace is None else " -n {}".format(namespace)
cmd += " {} -d {}".format(namespace_option, display)

run_command(cmd, display_cmd=verbose)


@interfaces.command()
@click.argument('interfacename', required=False)
@multi_asic_click_options
@click.option('--verbose', is_flag=True, help="Enable verbose output")
def status(interfacename, verbose):
def status(interfacename, namespace, display, verbose):
"""Show Interface status information"""

cmd = "intfutil status"
cmd = "intfutil -c status"

if interfacename is not None:
if get_interface_mode() == "alias":
interfacename = iface_alias_converter.alias_to_name(interfacename)

cmd += " {}".format(interfacename)
namespace_option = "" if namespace is None else " -n {}".format(namespace)
cmd += " {} -d {}".format(namespace_option, display)

run_command(cmd, display_cmd=verbose)

Expand Down