Skip to content

Commit df54138

Browse files
authored
[show] add new CLI to show tunnel route objects (sonic-net#2255)
What I did Add new CLI support to show tunnel route objects in ASIC DB. sign-off: Jing Zhang [email protected] How I did it Check if tunnel route object exists for server_ipv4, server_ipv6, soc_ipv4. If existing, print it out. If not specifying port name, print all tunnel route objects. How to verify it Added unit tests. Tested on dual testbed.
1 parent 3600639 commit df54138

File tree

3 files changed

+237
-2
lines changed

3 files changed

+237
-2
lines changed

show/muxcable.py

+135-2
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,42 @@ def create_json_dump_per_port_config(db, port_status_dict, per_npu_configdb, asi
503503
if soc_ipv4_value is not None:
504504
port_status_dict["MUX_CABLE"]["PORTS"][port_name]["SERVER"]["soc_ipv4"] = soc_ipv4_value
505505

506+
def get_tunnel_route_per_port(db, port_tunnel_route, per_npu_configdb, per_npu_appl_db, asic_id, port):
507+
508+
mux_cfg_dict = per_npu_configdb[asic_id].get_all(
509+
per_npu_configdb[asic_id].CONFIG_DB, 'MUX_CABLE|{}'.format(port))
510+
dest_names = ["server_ipv4", "server_ipv6", "soc_ipv4"]
511+
512+
for name in dest_names:
513+
dest_address = mux_cfg_dict.get(name, None)
514+
515+
if dest_address is not None:
516+
route_keys = per_npu_appl_db[asic_id].keys(
517+
per_npu_appl_db[asic_id].APPL_DB, 'TUNNEL_ROUTE_TABLE:*{}'.format(dest_address))
518+
519+
if route_keys is not None and len(route_keys):
520+
521+
port_tunnel_route["TUNNEL_ROUTE"][port] = port_tunnel_route["TUNNEL_ROUTE"].get(port, {})
522+
port_tunnel_route["TUNNEL_ROUTE"][port][name] = {}
523+
port_tunnel_route["TUNNEL_ROUTE"][port][name]['DEST'] = dest_address
524+
525+
def create_json_dump_per_port_tunnel_route(db, port_tunnel_route, per_npu_configdb, per_npu_appl_db, asic_id, port):
526+
527+
get_tunnel_route_per_port(db, port_tunnel_route, per_npu_configdb, per_npu_appl_db, asic_id, port)
528+
529+
def create_table_dump_per_port_tunnel_route(db, print_data, per_npu_configdb, per_npu_appl_db, asic_id, port):
530+
531+
port_tunnel_route = {}
532+
port_tunnel_route["TUNNEL_ROUTE"] = {}
533+
get_tunnel_route_per_port(db, port_tunnel_route, per_npu_configdb, per_npu_appl_db, asic_id, port)
534+
535+
for port, route in port_tunnel_route["TUNNEL_ROUTE"].items():
536+
for dest_name, values in route.items():
537+
print_line = []
538+
print_line.append(port)
539+
print_line.append(dest_name)
540+
print_line.append(values['DEST'])
541+
print_data.append(print_line)
506542

507543
@muxcable.command()
508544
@click.argument('port', required=False, default=None)
@@ -558,8 +594,8 @@ def status(db, port, json_output):
558594
click.echo("Got invalid asic index for port {}, cant retreive mux status".format(port_name))
559595
sys.exit(STATUS_FAIL)
560596

561-
muxcable_info_dict[asic_index] = per_npu_appl_db[asic_id].get_all(
562-
per_npu_appl_db[asic_id].APPL_DB, 'MUX_CABLE_TABLE:{}'.format(port))
597+
muxcable_info_dict[asic_index] = per_npu_appl_db[asic_index].get_all(
598+
per_npu_appl_db[asic_index].APPL_DB, 'MUX_CABLE_TABLE:{}'.format(port))
563599
muxcable_grpc_dict[asic_index] = per_npu_statedb[asic_index].get_all(
564600
per_npu_statedb[asic_index].STATE_DB, 'MUX_CABLE_TABLE|{}'.format(port))
565601
muxcable_health_dict[asic_index] = per_npu_statedb[asic_index].get_all(
@@ -1751,3 +1787,100 @@ def packetloss(db, port, json_output):
17511787

17521788
click.echo(tabulate(print_count, headers=count_headers))
17531789
click.echo(tabulate(print_event, headers=event_headers))
1790+
1791+
@muxcable.command()
1792+
@click.argument('port', metavar='<port_name>', required=False, default=None)
1793+
@click.option('--json', 'json_output', required=False, is_flag=True, type=click.BOOL, help="display the output in json format")
1794+
@clicommon.pass_db
1795+
def tunnel_route(db, port, json_output):
1796+
"""show muxcable tunnel-route <port_name>"""
1797+
1798+
port = platform_sfputil_helper.get_interface_name(port, db)
1799+
1800+
per_npu_appl_db = {}
1801+
per_npu_configdb = {}
1802+
mux_tbl_keys = {}
1803+
1804+
namespaces = multi_asic.get_front_end_namespaces()
1805+
for namespace in namespaces:
1806+
asic_id = multi_asic.get_asic_index_from_namespace(namespace)
1807+
1808+
per_npu_appl_db[asic_id] = swsscommon.SonicV2Connector(use_unix_socket_path=False, namespace=namespace)
1809+
per_npu_appl_db[asic_id].connect(per_npu_appl_db[asic_id].APPL_DB)
1810+
1811+
per_npu_configdb[asic_id] = swsscommon.SonicV2Connector(use_unix_socket_path=False, namespace=namespace)
1812+
per_npu_configdb[asic_id].connect(per_npu_configdb[asic_id].CONFIG_DB)
1813+
1814+
mux_tbl_keys[asic_id] = per_npu_configdb[asic_id].keys(
1815+
per_npu_configdb[asic_id].CONFIG_DB, "MUX_CABLE|*")
1816+
1817+
if port is not None:
1818+
1819+
logical_port_list = platform_sfputil_helper.get_logical_list()
1820+
1821+
if port not in logical_port_list:
1822+
port_name = platform_sfputil_helper.get_interface_alias(port, db)
1823+
click.echo(("ERR: Not a valid logical port for dualtor firmware {}".format(port_name)))
1824+
sys.exit(CONFIG_FAIL)
1825+
1826+
asic_index = None
1827+
if platform_sfputil is not None:
1828+
asic_index = platform_sfputil_helper.get_asic_id_for_logical_port(port)
1829+
if asic_index is None:
1830+
# TODO this import is only for unit test purposes, and should be removed once sonic_platform_base
1831+
# is fully mocked
1832+
import sonic_platform_base.sonic_sfp.sfputilhelper
1833+
asic_index = sonic_platform_base.sonic_sfp.sfputilhelper.SfpUtilHelper().get_asic_id_for_logical_port(port)
1834+
if asic_index is None:
1835+
port_name = platform_sfputil_helper.get_interface_alias(port, db)
1836+
click.echo("Got invalid asic index for port {}, cant retreive tunnel route info".format(port_name))
1837+
sys.exit(STATUS_FAIL)
1838+
1839+
if mux_tbl_keys[asic_index] is not None and "MUX_CABLE|{}".format(port) in mux_tbl_keys[asic_index]:
1840+
if json_output:
1841+
port_tunnel_route = {}
1842+
port_tunnel_route["TUNNEL_ROUTE"] = {}
1843+
1844+
create_json_dump_per_port_tunnel_route(db, port_tunnel_route, per_npu_configdb, per_npu_appl_db, asic_index, port)
1845+
1846+
click.echo("{}".format(json.dumps(port_tunnel_route, indent=4)))
1847+
1848+
else:
1849+
print_data = []
1850+
1851+
create_table_dump_per_port_tunnel_route(db, print_data, per_npu_configdb, per_npu_appl_db, asic_index, port)
1852+
1853+
headers = ['PORT', 'DEST_TYPE', 'DEST_ADDRESS']
1854+
1855+
click.echo(tabulate(print_data, headers=headers))
1856+
else:
1857+
click.echo("this is not a valid port present on dualToR".format(port))
1858+
sys.exit(STATUS_FAIL)
1859+
1860+
else:
1861+
if json_output:
1862+
port_tunnel_route = {}
1863+
port_tunnel_route["TUNNEL_ROUTE"] = {}
1864+
for namespace in namespaces:
1865+
asic_id = multi_asic.get_asic_index_from_namespace(namespace)
1866+
for key in natsorted(mux_tbl_keys[asic_id]):
1867+
port = key.split("|")[1]
1868+
1869+
create_json_dump_per_port_tunnel_route(db, port_tunnel_route, per_npu_configdb, per_npu_appl_db, asic_id, port)
1870+
1871+
click.echo("{}".format(json.dumps(port_tunnel_route, indent=4)))
1872+
else:
1873+
print_data = []
1874+
1875+
for namespace in namespaces:
1876+
asic_id = multi_asic.get_asic_index_from_namespace(namespace)
1877+
for key in natsorted(mux_tbl_keys[asic_id]):
1878+
port = key.split("|")[1]
1879+
1880+
create_table_dump_per_port_tunnel_route(db, print_data, per_npu_configdb, per_npu_appl_db, asic_id, port)
1881+
1882+
headers = ['PORT', 'DEST_TYPE', 'DEST_ADDRESS']
1883+
1884+
click.echo(tabulate(print_data, headers=headers))
1885+
1886+
sys.exit(STATUS_SUCCESSFUL)

tests/mock_tables/appl_db.json

+6
Original file line numberDiff line numberDiff line change
@@ -281,5 +281,11 @@
281281
},
282282
"MUX_CABLE_TABLE:Ethernet12": {
283283
"state": "active"
284+
},
285+
"TUNNEL_ROUTE_TABLE:10.2.1.1": {
286+
"alias": "Vlan1000"
287+
},
288+
"TUNNEL_ROUTE_TABLE:10.3.1.1": {
289+
"alias": "Vlan1000"
284290
}
285291
}

tests/muxcable_test.py

+96
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,48 @@
477477
}
478478
"""
479479

480+
show_muxcable_tunnel_route_expected_output_json="""\
481+
{
482+
"TUNNEL_ROUTE": {
483+
"Ethernet0": {
484+
"server_ipv4": {
485+
"DEST": "10.2.1.1"
486+
}
487+
},
488+
"Ethernet4": {
489+
"server_ipv4": {
490+
"DEST": "10.3.1.1"
491+
}
492+
}
493+
}
494+
}
495+
"""
496+
497+
show_muxcable_tunnel_route_expected_output="""\
498+
PORT DEST_TYPE DEST_ADDRESS
499+
--------- ----------- --------------
500+
Ethernet0 server_ipv4 10.2.1.1
501+
Ethernet4 server_ipv4 10.3.1.1
502+
"""
503+
504+
show_muxcable_tunnel_route_expected_output_port_json="""\
505+
{
506+
"TUNNEL_ROUTE": {
507+
"Ethernet0": {
508+
"server_ipv4": {
509+
"DEST": "10.2.1.1"
510+
}
511+
}
512+
}
513+
}
514+
"""
515+
516+
show_muxcable_tunnel_route_expected_port_output="""\
517+
PORT DEST_TYPE DEST_ADDRESS
518+
--------- ----------- --------------
519+
Ethernet0 server_ipv4 10.2.1.1
520+
"""
521+
480522
class TestMuxcable(object):
481523
@classmethod
482524
def setup_class(cls):
@@ -2113,6 +2155,60 @@ def test_show_muxcable_packetloss_port_json(self):
21132155
assert result.exit_code == 0
21142156
assert result.output == show_muxcable_packetloss_expected_output_json
21152157

2158+
@mock.patch('utilities_common.platform_sfputil_helper.get_logical_list', mock.MagicMock(return_value=["Ethernet0", "Ethernet12"]))
2159+
@mock.patch('utilities_common.platform_sfputil_helper.get_asic_id_for_logical_port', mock.MagicMock(return_value=0))
2160+
@mock.patch('show.muxcable.platform_sfputil', mock.MagicMock(return_value={0: ["Ethernet12", "Ethernet0"]}))
2161+
@mock.patch('utilities_common.platform_sfputil_helper.logical_port_name_to_physical_port_list', mock.MagicMock(return_value=[0]))
2162+
def test_show_muxcable_tunnel_route(self):
2163+
runner = CliRunner()
2164+
db = Db()
2165+
2166+
result = runner.invoke(show.cli.commands["muxcable"].commands["tunnel-route"], obj=db)
2167+
2168+
assert result.exit_code == 0
2169+
assert result.output == show_muxcable_tunnel_route_expected_output
2170+
2171+
@mock.patch('utilities_common.platform_sfputil_helper.get_logical_list', mock.MagicMock(return_value=["Ethernet0", "Ethernet12"]))
2172+
@mock.patch('utilities_common.platform_sfputil_helper.get_asic_id_for_logical_port', mock.MagicMock(return_value=0))
2173+
@mock.patch('show.muxcable.platform_sfputil', mock.MagicMock(return_value={0: ["Ethernet12", "Ethernet0"]}))
2174+
@mock.patch('utilities_common.platform_sfputil_helper.logical_port_name_to_physical_port_list', mock.MagicMock(return_value=[0]))
2175+
def test_show_muxcable_tunnel_route_json(self):
2176+
runner = CliRunner()
2177+
db = Db()
2178+
2179+
result = runner.invoke(show.cli.commands["muxcable"].commands["tunnel-route"],
2180+
["--json"], obj=db)
2181+
2182+
assert result.exit_code == 0
2183+
assert result.output == show_muxcable_tunnel_route_expected_output_json
2184+
2185+
@mock.patch('utilities_common.platform_sfputil_helper.get_logical_list', mock.MagicMock(return_value=["Ethernet0", "Ethernet12"]))
2186+
@mock.patch('utilities_common.platform_sfputil_helper.get_asic_id_for_logical_port', mock.MagicMock(return_value=0))
2187+
@mock.patch('show.muxcable.platform_sfputil', mock.MagicMock(return_value={0: ["Ethernet12", "Ethernet0"]}))
2188+
@mock.patch('utilities_common.platform_sfputil_helper.logical_port_name_to_physical_port_list', mock.MagicMock(return_value=[0]))
2189+
def test_show_muxcable_tunnel_route_port(self):
2190+
runner = CliRunner()
2191+
db = Db()
2192+
2193+
result = runner.invoke(show.cli.commands["muxcable"].commands["tunnel-route"],
2194+
["Ethernet0"], obj=db)
2195+
2196+
assert result.exit_code == 0
2197+
assert result.output == show_muxcable_tunnel_route_expected_port_output
2198+
2199+
@mock.patch('utilities_common.platform_sfputil_helper.get_logical_list', mock.MagicMock(return_value=["Ethernet0", "Ethernet12"]))
2200+
@mock.patch('utilities_common.platform_sfputil_helper.get_asic_id_for_logical_port', mock.MagicMock(return_value=0))
2201+
@mock.patch('show.muxcable.platform_sfputil', mock.MagicMock(return_value={0: ["Ethernet12", "Ethernet0"]}))
2202+
@mock.patch('utilities_common.platform_sfputil_helper.logical_port_name_to_physical_port_list', mock.MagicMock(return_value=[0]))
2203+
def test_show_muxcable_tunnel_route_json_port(self):
2204+
runner = CliRunner()
2205+
db = Db()
2206+
2207+
result = runner.invoke(show.cli.commands["muxcable"].commands["tunnel-route"],
2208+
["Ethernet0", "--json"], obj=db)
2209+
assert result.exit_code == 0
2210+
assert result.output == show_muxcable_tunnel_route_expected_output_port_json
2211+
21162212
@classmethod
21172213
def teardown_class(cls):
21182214
os.environ['UTILITIES_UNIT_TESTING'] = "0"

0 commit comments

Comments
 (0)