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

[201911] Multi asic platform config interface portchannel, show transceiver #1087

Merged
merged 5 commits into from
Sep 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
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
346 changes: 223 additions & 123 deletions config/main.py

Large diffs are not rendered by default.

18 changes: 14 additions & 4 deletions scripts/portconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ portconfig is the utility to show and change ECN configuration

usage: portconfig [-h] [-v] [-s] [-f] [-m] [-p PROFILE] [-gmin GREEN_MIN]
[-gmax GREEN_MAX] [-ymin YELLOW_MIN] [-ymax YELLOW_MAX]
[-rmin RED_MIN] [-rmax RED_MAX] [-vv]
[-rmin RED_MIN] [-rmax RED_MAX] [-vv] [-n namespace]

optional arguments:
-h --help show this help message and exit
Expand All @@ -14,6 +14,7 @@ optional arguments:
-s --speed port speed in Mbits
-f --fec port fec mode
-m --mtu port mtu in bytes
-n --namesapce Namespace name
"""
from __future__ import print_function

Expand All @@ -32,12 +33,16 @@ class portconfig(object):
"""
Process aclstat
"""
def __init__(self, verbose, port):
def __init__(self, verbose, port, namespace):
self.verbose = verbose

# Set up db connections
self.db = swsssdk.ConfigDBConnector()
if namespace is None:
self.db = swsssdk.ConfigDBConnector()
else:
self.db = swsssdk.ConfigDBConnector(use_unix_socket_path=True, namespace=namespace)
self.db.connect()

# check whether table for this port exists
port_tables = self.db.get_table(PORT_TABLE_NAME)
if not port_tables.has_key(port):
Expand Down Expand Up @@ -74,10 +79,15 @@ def main():
parser.add_argument('-f', '--fec', type=str, help='port fec mode value in (none, rs, fc)', default=None)
parser.add_argument('-m', '--mtu', type=int, help='port mtu value in bytes', default=None)
parser.add_argument('-vv', '--verbose', action='store_true', help='Verbose output', default=False)
parser.add_argument('-n', '--namespace', metavar='namespace details', type = str, required = False,
help = 'The asic namespace whose DB instance we need to connect', default=None)
args = parser.parse_args()

if args.namespace is not None:
swsssdk.SonicDBConfig.load_sonic_global_db_config(namespace=args.namespace)

try:
port = portconfig(args.verbose, args.port)
port = portconfig(args.verbose, args.port, args.namespace)
if args.list:
port.list_params(args.port)
elif args.speed or args.fec or args.mtu:
Expand Down
113 changes: 78 additions & 35 deletions scripts/sfpshow
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ import operator
import os

from natsort import natsorted
from swsssdk import SonicV2Connector, port_util
from tabulate import tabulate

from utilities_common import multi_asic as multi_asic_util
from sonic_py_common.interface import front_panel_prefix, backplane_prefix
from sonic_py_common import multi_asic

# Mock the redis for unit test purposes #
try:
if os.environ["UTILITIES_UNIT_TESTING"] == "1":
Expand All @@ -23,6 +26,9 @@ try:
sys.path.insert(0, modules_path)
sys.path.insert(0, test_path)
import mock_tables.dbconnector
if os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] == "multi_asic":
import mock_tables.mock_multi_asic
mock_tables.dbconnector.load_namespace_config()
except KeyError:
pass

Expand Down Expand Up @@ -128,18 +134,27 @@ dom_value_unit_map = {'rx1power': 'dBm', 'rx2power': 'dBm',
'tx3power': 'dBm', 'tx4power': 'dBm',
'temperature': 'C', 'voltage': 'Volts'}

def display_invalid_intf_eeprom(intf_name):
output = intf_name + ': ' + 'SFP EEPROM Not detected' + '\n'
click.echo(output)

def display_invalid_intf_presence(intf_name):
header = ['Port', 'Presence']
port_table = []
port_table.append((intf_name, 'Not present'))
click.echo(tabulate(port_table, header))

class SFPShow(object):

def __init__(self):
def __init__(self, intf_name, namespace_option, dump_dom=False):
super(SFPShow,self).__init__()
self.adb = SonicV2Connector(host="127.0.0.1")
self.adb.connect(self.adb.APPL_DB)

self.sdb = SonicV2Connector(host="127.0.0.1")
self.sdb.connect(self.sdb.STATE_DB)
return
self.db = None
self.config_db = None
self.intf_name = intf_name
self.dump_dom = dump_dom
self.table = []
self.output = ''
self.multi_asic = multi_asic_util.MultiAsic(namespace_option=namespace_option)

# Convert dict values to cli output string
def format_dict_value_to_string(self, sorted_key_table,
Expand Down Expand Up @@ -293,53 +308,61 @@ class SFPShow(object):

return out_put

def display_eeprom(self, interfacename, dump_dom):
@multi_asic_util.run_on_multi_asic
def get_eeprom(self):
out_put = ''

if interfacename is not None:
presence = self.sdb.exists(self.sdb.STATE_DB, 'TRANSCEIVER_INFO|{}'.format(interfacename))
if self.intf_name is not None:
presence = self.db.exists(self.db.STATE_DB, 'TRANSCEIVER_INFO|{}'.format(self.intf_name))
if presence:
out_put = self.convert_interface_sfp_info_to_cli_output_string(self.sdb, interfacename, dump_dom)
out_put = self.convert_interface_sfp_info_to_cli_output_string(self.db, self.intf_name, self.dump_dom)
else:
out_put = out_put + interfacename + ': ' + 'SFP EEPROM Not detected' + '\n'
out_put = out_put + self.intf_name + ': ' + 'SFP EEPROM Not detected' + '\n'
else:
port_table_keys = self.adb.keys(self.adb.APPL_DB, "PORT_TABLE:*")
port_table_keys = self.db.keys(self.db.APPL_DB, "PORT_TABLE:*")
sorted_table_keys = natsorted(port_table_keys)
for i in sorted_table_keys:
interface = re.split(':', i, maxsplit=1)[-1].strip()
if interface and interface.startswith('Ethernet'):
presence = self.sdb.exists(self.sdb.STATE_DB, 'TRANSCEIVER_INFO|{}'.format(interface))
if interface and interface.startswith(front_panel_prefix()) and not interface.startswith(backplane_prefix()):
presence = self.db.exists(self.db.STATE_DB, 'TRANSCEIVER_INFO|{}'.format(interface))
if presence:
out_put = out_put + self.convert_interface_sfp_info_to_cli_output_string(self.sdb, interface, dump_dom)
out_put = out_put + self.convert_interface_sfp_info_to_cli_output_string(self.db, interface, self.dump_dom)
else:
out_put = out_put + interface + ': ' + 'SFP EEPROM Not detected' + '\n'

out_put = out_put + '\n'
out_put = out_put + '\n'

print out_put
self.output += out_put

def display_presence(self, interfacename):
@multi_asic_util.run_on_multi_asic
def get_presence(self):
port_table = []
header = ['Port', 'Presence']

if interfacename is not None:
presence = self.sdb.exists(self.sdb.STATE_DB, 'TRANSCEIVER_INFO|{}'.format(interfacename))
if self.intf_name is not None:
presence = self.db.exists(self.db.STATE_DB, 'TRANSCEIVER_INFO|{}'.format(self.intf_name))
if presence:
port_table.append((interfacename, 'Present'))
port_table.append((self.intf_name, 'Present'))
else:
port_table.append((interfacename, 'Not present'))
port_table.append((self.intf_name, 'Not present'))
else:
port_table_keys = self.adb.keys(self.adb.APPL_DB, "PORT_TABLE:*")
port_table_keys = self.db.keys(self.db.APPL_DB, "PORT_TABLE:*")
for i in port_table_keys:
key = re.split(':', i, maxsplit=1)[-1].strip()
if key and key.startswith('Ethernet'):
presence = self.sdb.exists(self.sdb.STATE_DB, 'TRANSCEIVER_INFO|{}'.format(key))
if key and key.startswith(front_panel_prefix()) and not key.startswith(backplane_prefix()):
presence = self.db.exists(self.db.STATE_DB, 'TRANSCEIVER_INFO|{}'.format(key))
if presence:
port_table.append((key,'Present'))
else:
port_table.append((key,'Not present'))

sorted_port_table = natsorted(port_table)
self.table += port_table

def display_eeprom(self):
click.echo(self.output)

def display_presence(self):
header = ['Port', 'Presence']
sorted_port_table = natsorted(self.table)
click.echo(tabulate(sorted_port_table, header))

# This is our main entrypoint - the main 'sfpshow' command
Expand All @@ -352,16 +375,36 @@ def cli():
@cli.command()
@click.option('-p', '--port', metavar='<port_name>', help="Display SFP EEPROM data for port <port_name> only")
@click.option('-d', '--dom', 'dump_dom', is_flag=True, help="Also display Digital Optical Monitoring (DOM) data")
def eeprom(port, dump_dom):
sfp = SFPShow()
sfp.display_eeprom(port, dump_dom)
@click.option('-n', '--namespace', default=None, help="Display interfaces for specific namespace")
def eeprom(port, dump_dom, namespace):
if port and multi_asic.is_multi_asic() and namespace is None:
try:
ns = multi_asic.get_namespace_for_port(port)
namespace=ns
except Exception:
display_invalid_intf_eeprom(port)
sys.exit(1)

sfp = SFPShow(port, namespace, dump_dom)
sfp.get_eeprom()
sfp.display_eeprom()

# 'presence' subcommand
@cli.command()
@click.option('-p', '--port', metavar='<port_name>', help="Display SFP presence for port <port_name> only")
def presence(port):
sfp = SFPShow()
sfp.display_presence(port)
@click.option('-n', '--namespace', default=None, help="Display interfaces for specific namespace")
def presence(port, namespace):
if port and multi_asic.is_multi_asic() and namespace is None:
try:
ns = multi_asic.get_namespace_for_port(port)
namespace=ns
except Exception:
display_invalid_intf_presence(port)
sys.exit(1)

sfp = SFPShow(port, namespace)
sfp.get_presence()
sfp.display_presence()

if __name__ == "__main__":
cli()
15 changes: 12 additions & 3 deletions sfputil/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import syslog
import types
import traceback
from sonic_py_common import device_info, multi_asic
from tabulate import tabulate
except ImportError as e:
raise ImportError("%s - required module not found" % str(e))
Expand Down Expand Up @@ -384,9 +385,17 @@ def cli():

# Load port info
try:
port_config_file_path = get_path_to_port_config_file()
platform_sfputil.read_porttab_mappings(port_config_file_path)
except Exception, e:
if multi_asic.is_multi_asic():
# For multi ASIC platforms we pass DIR of port_config_file_path and the number of asics
(platform_path, hwsku_path) = device_info.get_paths_to_platform_and_hwsku_dirs()

# Load platform module from source
platform_sfputil.read_all_porttab_mappings(hwsku_path, multi_asic.get_num_asics())
else:
# For single ASIC platforms we pass port_config_file_path and the asic_inst as 0
port_config_file_path = device_info.get_path_to_port_config_file()
platform_sfputil.read_porttab_mappings(port_config_file_path, 0)
except Exception as e:
log_error("Error reading port info (%s)" % str(e), True)
sys.exit(3)

Expand Down
15 changes: 12 additions & 3 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -735,8 +735,10 @@ def transceiver():
@transceiver.command()
@click.argument('interfacename', required=False)
@click.option('-d', '--dom', 'dump_dom', is_flag=True, help="Also display Digital Optical Monitoring (DOM) data")
@click.option('--namespace', '-n', 'namespace', default=None, show_default=True,
type=click.Choice(multi_asic_util.multi_asic_ns_choices()), help='Namespace name or all')
@click.option('--verbose', is_flag=True, help="Enable verbose output")
def eeprom(interfacename, dump_dom, verbose):
def eeprom(interfacename, dump_dom, namespace, verbose):
"""Show interface transceiver EEPROM information"""

cmd = "sfpshow eeprom"
Expand All @@ -750,8 +752,10 @@ def eeprom(interfacename, dump_dom, verbose):

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

run_command(cmd, display_cmd=verbose)
if namespace is not None:
cmd += " -n {}".format(namespace)

run_command(cmd, display_cmd=verbose)

@transceiver.command()
@click.argument('interfacename', required=False)
Expand All @@ -771,8 +775,10 @@ def lpmode(interfacename, verbose):

@transceiver.command()
@click.argument('interfacename', required=False)
@click.option('--namespace', '-n', 'namespace', default=None, show_default=True,
type=click.Choice(multi_asic_util.multi_asic_ns_choices()), help='Namespace name or all')
@click.option('--verbose', is_flag=True, help="Enable verbose output")
def presence(interfacename, verbose):
def presence(interfacename, namespace, verbose):
"""Show interface transceiver presence"""

cmd = "sfpshow presence"
Expand All @@ -783,6 +789,9 @@ def presence(interfacename, verbose):

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

if namespace is not None:
cmd += " -n {}".format(namespace)

run_command(cmd, display_cmd=verbose)


Expand Down
Loading