From 9196818f39fbf4560a6f91475f98623631360111 Mon Sep 17 00:00:00 2001 From: Syd Logan Date: Tue, 2 Jun 2020 18:59:45 -0700 Subject: [PATCH 1/8] utilities: Changes to support SONiC Gearbox Manager * add and modify command line utilities to support gearbox phy * added build time mock unit tests HLD is located at https://github.com/Azure/SONiC/blob/b817a12fd89520d3fd26bbc5897487928e7f6de7/doc/gearbox/gearbox_mgr_design.md Signed-off-by: syd.logan@broadcom.com --- scripts/gearboxutil | 275 ++++++++++++++++++ setup.py | 1 + show/main.py | 37 +++ sonic-utilities-tests/gearbox_test.py | 51 ++++ .../mock_tables/appl_db.json | 27 +- .../mock_tables/asic_db.json | 1 + .../mock_tables/asic_db2.json | 16 + .../mock_tables/dbconnector.py | 2 + 8 files changed, 409 insertions(+), 1 deletion(-) create mode 100755 scripts/gearboxutil create mode 100644 sonic-utilities-tests/gearbox_test.py create mode 100644 sonic-utilities-tests/mock_tables/asic_db2.json diff --git a/scripts/gearboxutil b/scripts/gearboxutil new file mode 100755 index 0000000000..27408742b0 --- /dev/null +++ b/scripts/gearboxutil @@ -0,0 +1,275 @@ +#! /usr/bin/python + +import swsssdk +import sys +from tabulate import tabulate +from natsort import natsorted + +import os + +# mock the redis for unit test purposes # +try: + if os.environ["UTILITIES_UNIT_TESTING"] == "1": + modules_path = os.path.join(os.path.dirname(__file__), "..") + tests_path = os.path.join(modules_path, "sonic-utilities-tests") + sys.path.insert(0, modules_path) + sys.path.insert(0, tests_path) + import mock_tables.dbconnector # required by sonic-utilities-tests +except KeyError: + pass + +# ========================== Common gearbox-utils logic ========================== + +GEARBOX_TABLE_PHY_PREFIX = "_GEARBOX_TABLE:phy:{}" +GEARBOX_TABLE_INTERFACE_PREFIX = "_GEARBOX_TABLE:interface:{}" +GEARBOX_TABLE_PORT_PREFIX = "_GEARBOX_TABLE:phy:{}:ports:{}" + +PORT_TABLE_ETHERNET_PREFIX = "PORT_TABLE:{}" + +ASIC_STATE_TABLE_PORT_PREFIX = "ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:{}" +ASIC_STATE_TABLE_SWITCH_PREFIX = "ASIC_STATE:SAI_OBJECT_TYPE_SWITCH:oid:{}" +ASIC_GEARBOX_TABLE_SWITCH_PREFIX = "ASIC_GEARBOX|MISC_SAI_SWITCH_ATTR:{}" + +PHY_NAME = "name" +PHY_ID = "phy_id" +PHY_OID = "phy_oid" +PHY_FIRMWARE_MAJOR_VERSION = "SAI_SWITCH_ATTR_FIRMWARE_MAJOR_VERSION" +PHY_LINE_LANES = "line_lanes" +PHY_SYSTEM_LANES = "system_lanes" + +PORT_OPER_STATUS = "oper_status" +PORT_ADMIN_STATUS = "admin_status" +PORT_SYSTEM_SPEED = "system_speed" +PORT_LINE_SPEED = "line_speed" + +INTF_NAME = "name" +INTF_LANES = "lanes" +INTF_SPEED = "speed" + +def get_appl_key_attr(db, key, attr, lane_count=1): + """ + Get APPL_DB key attribute + """ + + val = db.get(db.APPL_DB, key, attr) + if val is None: + return "N/A" + + if "speed" in attr: + + if val == "0": + return "N/A" + + speed = int(val[:-3]) + + if (speed % lane_count == 0): + speed = speed // lane_count + else: + return "N/A" + + val = '{}G'.format(str(speed)) + + return val + +def get_asic2_key_attr(asic_db, phy_oid, attr): + """ + Get the phy attribute + """ + + full_table_id = ASIC_GEARBOX_TABLE_SWITCH_PREFIX.format(phy_oid) + # Replace needed for mock_table unit testing + full_table_id = full_table_id.replace("ATTR:0", "ATTR:oid:0") + val = asic_db.get(asic_db.ASIC_DB2, full_table_id, attr) + if val is None: + return "N/A" + + return val + +def db_connect_asic2(): + asic_db = swsssdk.SonicV2Connector(host='127.0.0.1') + if asic_db is None: + return None + asic_db.connect(asic_db.ASIC_DB2) + return asic_db + +def db_connect_appl(): + appl_db = swsssdk.SonicV2Connector(host='127.0.0.1') + if appl_db is None: + return None + appl_db.connect(appl_db.APPL_DB) + return appl_db + +def db_connect_state(): + """ + Connect to REDIS STATE DB and get optics info + """ + state_db = swsssdk.SonicV2Connector(host='127.0.0.1') + if state_db is None: + return None + state_db.connect(state_db.STATE_DB, False) # Make one attempt only + return state_db + +def appl_db_keys_get(appl_db): + """ + Get APPL_DB Keys + """ + return appl_db.keys(appl_db.APPL_DB, GEARBOX_TABLE_PHY_PREFIX.format("*")) + +def appl_db_interface_keys_get(appl_db): + """ + Get ASIC_DB Keys + """ + return appl_db.keys(appl_db.APPL_DB, GEARBOX_TABLE_INTERFACE_PREFIX.format("*")) + +def asic2_db_keys_get(asic_db): + """ + Get ASIC_DB Keys + """ + return asic_db.keys(asic_db.ASIC_DB2, ASIC_GEARBOX_TABLE_SWITCH_PREFIX.format("*")) + +# ========================== phy-status logic ========================== + +phy_header_status = ['PHY Id', 'Name', 'Firmware'] + +class PhyStatus(object): + + def display_phy_status(self, appl_db_keys, asic_db_keys): + """ + Generate phy status output + """ + table = [] + key = [] + + for key in appl_db_keys: + if 'lanes' in key or 'ports' in key: + continue + list_items = key.split(':') + phy_id = list_items[2] + phy_oid = get_appl_key_attr(self.appl_db, GEARBOX_TABLE_PHY_PREFIX.format(phy_id), PHY_OID) + data_row = ( + phy_id, + get_appl_key_attr(self.appl_db, GEARBOX_TABLE_PHY_PREFIX.format(phy_id), PHY_NAME), + get_asic2_key_attr(self.asic_db, phy_oid, PHY_FIRMWARE_MAJOR_VERSION)) + + table.append(data_row) + + # Sorting and tabulating the result table. + sorted_table = natsorted(table) + print tabulate(sorted_table, phy_header_status, tablefmt="simple", stralign='right') + + def __init__(self): + + self.asic_db = db_connect_asic2() + self.appl_db = db_connect_appl() + + if self.asic_db is None: + return + if self.appl_db is None: + return + + appl_db_keys = appl_db_keys_get(self.appl_db) + if appl_db_keys is None: + return + + asic_db_keys = asic2_db_keys_get(self.asic_db) + if asic_db_keys is None: + return + + self.display_phy_status(appl_db_keys, asic_db_keys) + +# ========================== interface-status logic ========================== + +intf_header_status = ['PHY Id', 'Interface', 'MAC Lanes', 'MAC Lane Speed', 'PHY Lanes', 'PHY Lane Speed', 'Line Lanes', 'Line Lane Speed', 'Oper', 'Admin'] + +class InterfaceStatus(object): + + def display_intf_status(self, appl_db_keys, asic_db_keys): + """ + Generate phy status output + """ + table = [] + key = [] + + for key in appl_db_keys: + list_items = key.split(':') + index = list_items[2] + + name = get_appl_key_attr(self.appl_db, GEARBOX_TABLE_INTERFACE_PREFIX.format(index), INTF_NAME), + name = name[0] + + mac_lanes = get_appl_key_attr(self.appl_db, PORT_TABLE_ETHERNET_PREFIX.format(name), INTF_LANES) + lanes = mac_lanes.split(',') + lane_count = 0 + for lane in lanes: + lane_count += 1 + + phy_id = get_appl_key_attr(self.appl_db, GEARBOX_TABLE_INTERFACE_PREFIX.format(index), PHY_ID) + + data_row = ( + phy_id, + name, + mac_lanes, + get_appl_key_attr(self.appl_db, PORT_TABLE_ETHERNET_PREFIX.format(name), INTF_SPEED, lane_count), + get_appl_key_attr(self.appl_db, GEARBOX_TABLE_INTERFACE_PREFIX.format(index), PHY_SYSTEM_LANES), + get_appl_key_attr(self.appl_db, GEARBOX_TABLE_PORT_PREFIX.format(phy_id, index), PORT_SYSTEM_SPEED), + get_appl_key_attr(self.appl_db, GEARBOX_TABLE_INTERFACE_PREFIX.format(index), PHY_LINE_LANES), + get_appl_key_attr(self.appl_db, GEARBOX_TABLE_PORT_PREFIX.format(phy_id, index), PORT_LINE_SPEED), + get_appl_key_attr(self.appl_db, PORT_TABLE_ETHERNET_PREFIX.format(name), PORT_OPER_STATUS), + get_appl_key_attr(self.appl_db, PORT_TABLE_ETHERNET_PREFIX.format(name), PORT_ADMIN_STATUS)) + + table.append(data_row) + + # Sorting and tabulating the result table. + sorted_table = natsorted(table) + print tabulate(sorted_table, intf_header_status, tablefmt="simple", stralign='right') + + def __init__(self): + + self.asic_db = db_connect_asic2() + self.appl_db = db_connect_appl() + + if self.asic_db is None: + return + if self.appl_db is None: + return + + appl_db_keys = appl_db_interface_keys_get(self.appl_db) + if appl_db_keys is None: + return + + asic_db_keys = asic2_db_keys_get(self.asic_db) + if asic_db_keys is None: + return + + self.display_intf_status(appl_db_keys, asic_db_keys) + +def main(args): + """ + phy status + interfaces status + interfaces counters + """ + + if len(args) == 0: + print "No valid arguments provided" + return + + cmd1 = args[0] + if cmd1 != "phys" and cmd1 != "interfaces": + print "No valid command provided" + return + + cmd2 = args[1] + if cmd2 != "status" and cmd2 != "counters": + print "No valid command provided" + return + + if cmd1 == "phys" and cmd2 == "status": + PhyStatus() + elif cmd1 == "interfaces" and cmd2 == "status": + InterfaceStatus() + + sys.exit(0) + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/setup.py b/setup.py index 09e893e3f3..edffa77cd0 100644 --- a/setup.py +++ b/setup.py @@ -76,6 +76,7 @@ 'scripts/fdbclear', 'scripts/fdbshow', 'scripts/filter_fdb_entries.py', + 'scripts/gearboxutil', 'scripts/generate_dump', 'scripts/intfutil', 'scripts/intfstat', diff --git a/show/main.py b/show/main.py index f2d4df5308..5e740670ba 100755 --- a/show/main.py +++ b/show/main.py @@ -2839,6 +2839,43 @@ def pool(verbose): cmd = "sudo natconfig -p" run_command(cmd, display_cmd=verbose) +# Define GEARBOX commands only if GEARBOX is configured +app_db = SonicV2Connector(host='127.0.0.1') +app_db.connect(app_db.APPL_DB) +if app_db.keys(app_db.APPL_DB, '_GEARBOX_TABLE:phy:*'): + + @cli.group(cls=AliasedGroup) + def gearbox(): + """Show gearbox info""" + pass + + # 'phys' subcommand ("show gearbox phys") + @gearbox.group(cls=AliasedGroup) + def phys(): + """Show external PHY information""" + pass + + # 'status' subcommand ("show gearbox phys status") + @phys.command() + @click.pass_context + def status(ctx): + """Show gearbox phys status""" + run_command("gearboxutil phys status") + return + + # 'interfaces' subcommand ("show gearbox interfaces") + @gearbox.group(cls=AliasedGroup) + def interfaces(): + """Show gearbox interfaces information""" + pass + + # 'status' subcommand ("show gearbox interfaces status") + @interfaces.command() + @click.pass_context + def status(ctx): + """Show gearbox interfaces status""" + run_command("gearboxutil interfaces status") + return # 'bindings' subcommand ("show nat config bindings") @config.command() diff --git a/sonic-utilities-tests/gearbox_test.py b/sonic-utilities-tests/gearbox_test.py new file mode 100644 index 0000000000..2d0cef041e --- /dev/null +++ b/sonic-utilities-tests/gearbox_test.py @@ -0,0 +1,51 @@ +import sys +import os +from click.testing import CliRunner +from unittest import TestCase + +test_path = os.path.dirname(os.path.abspath(__file__)) +modules_path = os.path.dirname(test_path) +scripts_path = os.path.join(modules_path, "scripts") +sys.path.insert(0, test_path) +sys.path.insert(0, modules_path) + +import mock_tables.dbconnector # required by sonic-utilities-tests + +import show.main as show + +class TestGearbox(TestCase): + @classmethod + def setup_class(cls): + print("SETUP") + os.environ["PATH"] += os.pathsep + scripts_path + os.environ["UTILITIES_UNIT_TESTING"] = "1" + + def setUp(self): + self.runner = CliRunner() + + def test_gearbox_phys_status_validation(self): + result = self.runner.invoke(show.cli.commands["gearbox"].commands["phys"].commands["status"], []) + print >> sys.stderr, result.output + expected_output = ( + "PHY Id Name Firmware\n" + "-------- ------- ----------\n" + " 1 sesto-1 v0.2\n" + " 2 sesto-2 v0.3" + ) + self.assertEqual(result.output.strip(), expected_output) + + def test_gearbox_interfaces_status_validation(self): + result = self.runner.invoke(show.cli.commands["gearbox"].commands["interfaces"].commands["status"], []) + print >> sys.stderr, result.output + expected_output = ( + "PHY Id Interface MAC Lanes MAC Lane Speed PHY Lanes PHY Lane Speed Line Lanes Line Lane Speed Oper Admin\n" + "-------- ----------- --------------- ---------------- --------------- ---------------- ------------ ----------------- ------ -------\n" + " 1 Ethernet200 200,201,202,203 25G 300,301,302,303 25G 304,305 50G down up" + ) + self.assertEqual(result.output.strip(), expected_output) + + @classmethod + def teardown_class(cls): + print("TEARDOWN") + os.environ["PATH"] = os.pathsep.join(os.environ["PATH"].split(os.pathsep)[:-1]) + os.environ["UTILITIES_UNIT_TESTING"] = "0" diff --git a/sonic-utilities-tests/mock_tables/appl_db.json b/sonic-utilities-tests/mock_tables/appl_db.json index 96c071e3a2..b9ca17bd43 100644 --- a/sonic-utilities-tests/mock_tables/appl_db.json +++ b/sonic-utilities-tests/mock_tables/appl_db.json @@ -1,5 +1,6 @@ { "PORT_TABLE:Ethernet0": { + "index": "0", "lanes": "0", "alias": "Ethernet0", "description": "ARISTA01T2:Ethernet1", @@ -11,6 +12,7 @@ "admin_status": "up" }, "PORT_TABLE:Ethernet200": { + "index": "200", "lanes": "200,201,202,203", "alias": "Ethernet200", "description": "Ethernet200", @@ -18,9 +20,32 @@ "oper_status": "down", "fec": "rs", "mtu": "9100", - "pfc_asym": "off" + "pfc_asym": "off", + "admin_status": "up" }, "INTF_TABLE:Ethernet0.10": { "admin_status": "up" + }, + "_GEARBOX_TABLE:phy:1": { + "name": "sesto-1", + "phy_id": "1", + "phy_oid": "0x21000000000002" + }, + "_GEARBOX_TABLE:phy:2": { + "name": "sesto-2", + "phy_id": "2", + "phy_oid": "0x21000000000003" + }, + "_GEARBOX_TABLE:interface:200": { + "name": "Ethernet200", + "index": "200", + "line_lanes": "304,305", + "phy_id": "1", + "system_lanes": "300,301,302,303" + }, + "_GEARBOX_TABLE:phy:1:ports:200": { + "index": "200", + "line_speed": "50000", + "system_speed": "25000" } } diff --git a/sonic-utilities-tests/mock_tables/asic_db.json b/sonic-utilities-tests/mock_tables/asic_db.json index 1a769b82b5..e2364559ee 100644 --- a/sonic-utilities-tests/mock_tables/asic_db.json +++ b/sonic-utilities-tests/mock_tables/asic_db.json @@ -4,3 +4,4 @@ "SAI_SWITCH_ATTR_SRC_MAC_ADDRESS": "DE:AD:BE:EF:CA:FE" } } + diff --git a/sonic-utilities-tests/mock_tables/asic_db2.json b/sonic-utilities-tests/mock_tables/asic_db2.json new file mode 100644 index 0000000000..15c8dab838 --- /dev/null +++ b/sonic-utilities-tests/mock_tables/asic_db2.json @@ -0,0 +1,16 @@ +{ + "ASIC_GEARBOX|MISC_SAI_SWITCH_ATTR:oid:0x21000000000002": { + "SAI_SWITCH_ATTR_FIRMWARE_MAJOR_VERSION": "v0.2" + }, + "ASIC_GEARBOX|MISC_SAI_SWITCH_ATTR:oid:0x21000000000003": { + "SAI_SWITCH_ATTR_FIRMWARE_MAJOR_VERSION": "v0.3" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000002": { + "SAI_SWITCH_ATTR_INIT_SWITCH": "true", + "SAI_SWITCH_ATTR_TYPE": "SAI_SWITCH_TYPE_PHY" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000003": { + "SAI_SWITCH_ATTR_INIT_SWITCH": "true", + "SAI_SWITCH_ATTR_TYPE": "SAI_SWITCH_TYPE_PHY" + } +} \ No newline at end of file diff --git a/sonic-utilities-tests/mock_tables/dbconnector.py b/sonic-utilities-tests/mock_tables/dbconnector.py index 5a67337e6d..5bda541ca5 100644 --- a/sonic-utilities-tests/mock_tables/dbconnector.py +++ b/sonic-utilities-tests/mock_tables/dbconnector.py @@ -50,6 +50,8 @@ def __init__(self, *args, **kwargs): fname = 'config_db.json' elif db == 6: fname = 'state_db.json' + elif db == 8: + fname = 'asic_db2.json' else: raise ValueError("Invalid db") self.pubsub = MockPubSub() From 1d4b6a0138af87beed3ce4be9ee9eec18cbb513d Mon Sep 17 00:00:00 2001 From: Syd Logan Date: Thu, 4 Jun 2020 13:44:41 -0700 Subject: [PATCH 2/8] CLI enhancement, change ASIC_DB2 to APPL_DB --- scripts/gearboxutil | 62 +++---------------- .../mock_tables/appl_db.json | 6 +- .../mock_tables/asic_db2.json | 16 ----- .../mock_tables/dbconnector.py | 2 - 4 files changed, 11 insertions(+), 75 deletions(-) delete mode 100644 sonic-utilities-tests/mock_tables/asic_db2.json diff --git a/scripts/gearboxutil b/scripts/gearboxutil index 27408742b0..1607150993 100755 --- a/scripts/gearboxutil +++ b/scripts/gearboxutil @@ -26,14 +26,10 @@ GEARBOX_TABLE_PORT_PREFIX = "_GEARBOX_TABLE:phy:{}:ports:{}" PORT_TABLE_ETHERNET_PREFIX = "PORT_TABLE:{}" -ASIC_STATE_TABLE_PORT_PREFIX = "ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:{}" -ASIC_STATE_TABLE_SWITCH_PREFIX = "ASIC_STATE:SAI_OBJECT_TYPE_SWITCH:oid:{}" -ASIC_GEARBOX_TABLE_SWITCH_PREFIX = "ASIC_GEARBOX|MISC_SAI_SWITCH_ATTR:{}" - PHY_NAME = "name" PHY_ID = "phy_id" PHY_OID = "phy_oid" -PHY_FIRMWARE_MAJOR_VERSION = "SAI_SWITCH_ATTR_FIRMWARE_MAJOR_VERSION" +PHY_FIRMWARE_MAJOR_VERSION = "firmware_major_version" PHY_LINE_LANES = "line_lanes" PHY_SYSTEM_LANES = "system_lanes" @@ -71,27 +67,6 @@ def get_appl_key_attr(db, key, attr, lane_count=1): return val -def get_asic2_key_attr(asic_db, phy_oid, attr): - """ - Get the phy attribute - """ - - full_table_id = ASIC_GEARBOX_TABLE_SWITCH_PREFIX.format(phy_oid) - # Replace needed for mock_table unit testing - full_table_id = full_table_id.replace("ATTR:0", "ATTR:oid:0") - val = asic_db.get(asic_db.ASIC_DB2, full_table_id, attr) - if val is None: - return "N/A" - - return val - -def db_connect_asic2(): - asic_db = swsssdk.SonicV2Connector(host='127.0.0.1') - if asic_db is None: - return None - asic_db.connect(asic_db.ASIC_DB2) - return asic_db - def db_connect_appl(): appl_db = swsssdk.SonicV2Connector(host='127.0.0.1') if appl_db is None: @@ -117,23 +92,17 @@ def appl_db_keys_get(appl_db): def appl_db_interface_keys_get(appl_db): """ - Get ASIC_DB Keys + Get APPL_DB Keys """ return appl_db.keys(appl_db.APPL_DB, GEARBOX_TABLE_INTERFACE_PREFIX.format("*")) -def asic2_db_keys_get(asic_db): - """ - Get ASIC_DB Keys - """ - return asic_db.keys(asic_db.ASIC_DB2, ASIC_GEARBOX_TABLE_SWITCH_PREFIX.format("*")) - # ========================== phy-status logic ========================== phy_header_status = ['PHY Id', 'Name', 'Firmware'] class PhyStatus(object): - def display_phy_status(self, appl_db_keys, asic_db_keys): + def display_phy_status(self, appl_db_keys): """ Generate phy status output """ @@ -149,8 +118,7 @@ class PhyStatus(object): data_row = ( phy_id, get_appl_key_attr(self.appl_db, GEARBOX_TABLE_PHY_PREFIX.format(phy_id), PHY_NAME), - get_asic2_key_attr(self.asic_db, phy_oid, PHY_FIRMWARE_MAJOR_VERSION)) - + get_appl_key_attr(self.appl_db, GEARBOX_TABLE_PHY_PREFIX.format(phy_id), PHY_FIRMWARE_MAJOR_VERSION)) table.append(data_row) # Sorting and tabulating the result table. @@ -159,11 +127,7 @@ class PhyStatus(object): def __init__(self): - self.asic_db = db_connect_asic2() self.appl_db = db_connect_appl() - - if self.asic_db is None: - return if self.appl_db is None: return @@ -171,11 +135,7 @@ class PhyStatus(object): if appl_db_keys is None: return - asic_db_keys = asic2_db_keys_get(self.asic_db) - if asic_db_keys is None: - return - - self.display_phy_status(appl_db_keys, asic_db_keys) + self.display_phy_status(appl_db_keys) # ========================== interface-status logic ========================== @@ -183,7 +143,7 @@ intf_header_status = ['PHY Id', 'Interface', 'MAC Lanes', 'MAC Lane Speed', 'PHY class InterfaceStatus(object): - def display_intf_status(self, appl_db_keys, asic_db_keys): + def display_intf_status(self, appl_db_keys): """ Generate phy status output """ @@ -225,11 +185,7 @@ class InterfaceStatus(object): def __init__(self): - self.asic_db = db_connect_asic2() self.appl_db = db_connect_appl() - - if self.asic_db is None: - return if self.appl_db is None: return @@ -237,11 +193,7 @@ class InterfaceStatus(object): if appl_db_keys is None: return - asic_db_keys = asic2_db_keys_get(self.asic_db) - if asic_db_keys is None: - return - - self.display_intf_status(appl_db_keys, asic_db_keys) + self.display_intf_status(appl_db_keys) def main(args): """ diff --git a/sonic-utilities-tests/mock_tables/appl_db.json b/sonic-utilities-tests/mock_tables/appl_db.json index b9ca17bd43..4239cf949d 100644 --- a/sonic-utilities-tests/mock_tables/appl_db.json +++ b/sonic-utilities-tests/mock_tables/appl_db.json @@ -29,12 +29,14 @@ "_GEARBOX_TABLE:phy:1": { "name": "sesto-1", "phy_id": "1", - "phy_oid": "0x21000000000002" + "phy_oid": "0x21000000000002", + "firmware_major_version": "v0.2" }, "_GEARBOX_TABLE:phy:2": { "name": "sesto-2", "phy_id": "2", - "phy_oid": "0x21000000000003" + "phy_oid": "0x21000000000003", + "firmware_major_version": "v0.3" }, "_GEARBOX_TABLE:interface:200": { "name": "Ethernet200", diff --git a/sonic-utilities-tests/mock_tables/asic_db2.json b/sonic-utilities-tests/mock_tables/asic_db2.json deleted file mode 100644 index 15c8dab838..0000000000 --- a/sonic-utilities-tests/mock_tables/asic_db2.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "ASIC_GEARBOX|MISC_SAI_SWITCH_ATTR:oid:0x21000000000002": { - "SAI_SWITCH_ATTR_FIRMWARE_MAJOR_VERSION": "v0.2" - }, - "ASIC_GEARBOX|MISC_SAI_SWITCH_ATTR:oid:0x21000000000003": { - "SAI_SWITCH_ATTR_FIRMWARE_MAJOR_VERSION": "v0.3" - }, - "ASIC_STATE:SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000002": { - "SAI_SWITCH_ATTR_INIT_SWITCH": "true", - "SAI_SWITCH_ATTR_TYPE": "SAI_SWITCH_TYPE_PHY" - }, - "ASIC_STATE:SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000003": { - "SAI_SWITCH_ATTR_INIT_SWITCH": "true", - "SAI_SWITCH_ATTR_TYPE": "SAI_SWITCH_TYPE_PHY" - } -} \ No newline at end of file diff --git a/sonic-utilities-tests/mock_tables/dbconnector.py b/sonic-utilities-tests/mock_tables/dbconnector.py index 5bda541ca5..5a67337e6d 100644 --- a/sonic-utilities-tests/mock_tables/dbconnector.py +++ b/sonic-utilities-tests/mock_tables/dbconnector.py @@ -50,8 +50,6 @@ def __init__(self, *args, **kwargs): fname = 'config_db.json' elif db == 6: fname = 'state_db.json' - elif db == 8: - fname = 'asic_db2.json' else: raise ValueError("Invalid db") self.pubsub = MockPubSub() From 3b0071e457e4862cbf2961ac97ea0df9b884b2e4 Mon Sep 17 00:00:00 2001 From: Syd Logan Date: Thu, 4 Jun 2020 14:52:42 -0700 Subject: [PATCH 3/8] remove unused variables --- scripts/gearboxutil | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/gearboxutil b/scripts/gearboxutil index 1607150993..d5eba591d1 100755 --- a/scripts/gearboxutil +++ b/scripts/gearboxutil @@ -28,7 +28,6 @@ PORT_TABLE_ETHERNET_PREFIX = "PORT_TABLE:{}" PHY_NAME = "name" PHY_ID = "phy_id" -PHY_OID = "phy_oid" PHY_FIRMWARE_MAJOR_VERSION = "firmware_major_version" PHY_LINE_LANES = "line_lanes" PHY_SYSTEM_LANES = "system_lanes" @@ -114,7 +113,6 @@ class PhyStatus(object): continue list_items = key.split(':') phy_id = list_items[2] - phy_oid = get_appl_key_attr(self.appl_db, GEARBOX_TABLE_PHY_PREFIX.format(phy_id), PHY_OID) data_row = ( phy_id, get_appl_key_attr(self.appl_db, GEARBOX_TABLE_PHY_PREFIX.format(phy_id), PHY_NAME), From 86ef8c5702dea743c964454053fcddd2d1603b1a Mon Sep 17 00:00:00 2001 From: Syd Logan Date: Fri, 5 Jun 2020 12:34:33 -0700 Subject: [PATCH 4/8] add gearbox phy show commands --- doc/Command-Reference.md | 52 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index a6598b717e..8e7aa9001a 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -43,6 +43,8 @@ * [ECN](#ecn) * [ECN show commands](#ecn-show-commands) * [ECN config commands](#ecn-config-commands) +* [Gearbox](#gearbox) + * [Gearbox show commands](#gearbox-show-commands) * [Interfaces](#interfaces) * [Interface Show Commands](#interface-show-commands) * [Interface Config Commands](#interface-config-commands) @@ -2257,6 +2259,56 @@ The list of the WRED profile fields that are configurable is listed in the below Go Back To [Beginning of the document](#) or [Beginning of this section](#ecn) +## Gearbox + +This section explains all the Gearbox PHY show commands that are supported in SONiC. + +### Gearbox show commands +This sub-section contains the show commands that are supported for gearbox phy. + +**show gearbox interfaces status** + +This command displays information about the gearbox phy interface lanes, speeds and status. Data is displayed for both MAC side and line side of the gearbox phy + +- Usage: + ``` + show gearbox interfaces status + ``` + +- Example: + +``` +home/admin# show gearbox interfaces status + PHY Id Interface MAC Lanes MAC Lane Speed PHY Lanes PHY Lane Speed Line Lanes Line Lane Speed Oper Admin +-------- ----------- ----------- ---------------- ----------- ---------------- ------------ ----------------- ------ ------- + 1 Ethernet0 25,26,27,28 10G 200,201 20G 206 40G up up + 1 Ethernet4 29,30,31,32 10G 202,203 20G 207 40G up up + 1 Ethernet8 33,34,35,36 10G 204,205 20G 208 40G up up + + ``` + +**show gearbox phys status** + +This command displays basic information about the gearbox phys configured on the switch. + +- Usage: + ``` + show gearbox phy status + ``` + +- Example: + +``` +/home/admin# show gearbox phys status + PHY Id Name Firmware +-------- ------- ---------- + 1 sesto-1 v0.1 + + ``` + +Go Back To [Beginning of the document](#) or [Beginning of this section](#gearbox) + + ## Update Device Hostname Configuration Commands This sub-section of commands is used to change device hostname without traffic being impacted. From d11e07a5a1228202ef13a84bba852d515a7e26fe Mon Sep 17 00:00:00 2001 From: Syd Logan Date: Mon, 8 Jun 2020 14:28:21 -0700 Subject: [PATCH 5/8] validate existence of mock_table keys in tests --- scripts/gearboxutil | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/gearboxutil b/scripts/gearboxutil index d5eba591d1..4c9340669f 100755 --- a/scripts/gearboxutil +++ b/scripts/gearboxutil @@ -14,7 +14,10 @@ try: tests_path = os.path.join(modules_path, "sonic-utilities-tests") sys.path.insert(0, modules_path) sys.path.insert(0, tests_path) - import mock_tables.dbconnector # required by sonic-utilities-tests + import mock_tables.dbconnector + client = mock_tables.dbconnector.redis.StrictRedis() + if client.keys() is None: + raise Exception("Invalid mock_table keys") except KeyError: pass From fa9097f520e04dc3a0a5d8ebb3fe620137dce924 Mon Sep 17 00:00:00 2001 From: Syd Logan Date: Tue, 9 Jun 2020 14:48:59 -0700 Subject: [PATCH 6/8] fix plural command typo --- doc/Command-Reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index 8e7aa9001a..603741cadf 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -2293,7 +2293,7 @@ This command displays basic information about the gearbox phys configured on the - Usage: ``` - show gearbox phy status + show gearbox phys status ``` - Example: From 2d4109c1433fe286985d4fe9365d2565839c8213 Mon Sep 17 00:00:00 2001 From: Syd Logan Date: Tue, 9 Jun 2020 16:45:13 -0700 Subject: [PATCH 7/8] whitespace cleanups --- scripts/gearboxutil | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/gearboxutil b/scripts/gearboxutil index 4c9340669f..254d13da3f 100755 --- a/scripts/gearboxutil +++ b/scripts/gearboxutil @@ -54,7 +54,6 @@ def get_appl_key_attr(db, key, attr, lane_count=1): return "N/A" if "speed" in attr: - if val == "0": return "N/A" @@ -185,7 +184,6 @@ class InterfaceStatus(object): print tabulate(sorted_table, intf_header_status, tablefmt="simple", stralign='right') def __init__(self): - self.appl_db = db_connect_appl() if self.appl_db is None: return From 85848ae0cb9a1fa9e96a7786c74071ba2dc34c91 Mon Sep 17 00:00:00 2001 From: Syd Logan Date: Wed, 10 Jun 2020 11:20:04 -0700 Subject: [PATCH 8/8] fix more whitespace issues --- scripts/gearboxutil | 1 - sonic-utilities-tests/mock_tables/asic_db.json | 1 - 2 files changed, 2 deletions(-) diff --git a/scripts/gearboxutil b/scripts/gearboxutil index 254d13da3f..b6b2818dee 100755 --- a/scripts/gearboxutil +++ b/scripts/gearboxutil @@ -126,7 +126,6 @@ class PhyStatus(object): print tabulate(sorted_table, phy_header_status, tablefmt="simple", stralign='right') def __init__(self): - self.appl_db = db_connect_appl() if self.appl_db is None: return diff --git a/sonic-utilities-tests/mock_tables/asic_db.json b/sonic-utilities-tests/mock_tables/asic_db.json index e2364559ee..1a769b82b5 100644 --- a/sonic-utilities-tests/mock_tables/asic_db.json +++ b/sonic-utilities-tests/mock_tables/asic_db.json @@ -4,4 +4,3 @@ "SAI_SWITCH_ATTR_SRC_MAC_ADDRESS": "DE:AD:BE:EF:CA:FE" } } -