Skip to content

Commit e949f31

Browse files
vdahiya12yxieca
authored andcommitted
[show] add support for gRPC show commands for active-active (#2629)
Signed-off-by: vaibhav-dahiya [email protected] This PR adds support for show mux hwmode muxdirection as well as show mux grpc muxdirection to show the state of gRPC connected to the SoCs for 'active-active' acble type vdahiya@sonic:~$ show mux grpc muxdirection Port Direction Presence PeerDirection ConnectivityState --------- ----------- ---------- --------------- ------------------- Ethernet0 active False active READY vdahiya@sonic:~$ vdahiya@sonic:~$ show mux grpc muxdirection --json { "HWMODE": { "Ethernet0": { "Direction": "active", "Presence": "False", "PeerDirection": "active", "ConnectivityState": "READY" } } } What I did Added support for the commands. How I did it How to verify it UT and running the changes on Testbed
1 parent 7772392 commit e949f31

File tree

3 files changed

+492
-34
lines changed

3 files changed

+492
-34
lines changed

show/muxcable.py

+287-34
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,21 @@
3636
VENDOR_MODEL_REGEX = re.compile(r"CAC\w{3}321P2P\w{2}MS")
3737

3838

39+
def get_asic_index_for_port(port):
40+
asic_index = None
41+
if platform_sfputil is not None:
42+
asic_index = platform_sfputil_helper.get_asic_id_for_logical_port(port)
43+
if asic_index is None:
44+
# TODO this import is only for unit test purposes, and should be removed once sonic_platform_base
45+
# is fully mocked
46+
import sonic_platform_base.sonic_sfp.sfputilhelper
47+
asic_index = sonic_platform_base.sonic_sfp.sfputilhelper.SfpUtilHelper().get_asic_id_for_logical_port(port)
48+
if asic_index is None:
49+
port_name = platform_sfputil_helper.get_interface_alias(port, db)
50+
click.echo("Got invalid asic index for port {}, cant retreive mux status".format(port_name))
51+
return 0
52+
return asic_index
53+
3954
def db_connect(db_name, namespace=EMPTY_NAMESPACE):
4055
return swsscommon.DBConnector(db_name, REDIS_TIMEOUT_MSECS, True, namespace)
4156

@@ -1239,6 +1254,67 @@ def get_hwmode_mux_direction_port(db, port):
12391254
return res_dict
12401255

12411256

1257+
def create_active_active_mux_direction_json_result(result, port, db):
1258+
1259+
port = platform_sfputil_helper.get_interface_alias(port, db)
1260+
result["HWMODE"][port] = {}
1261+
res_dict = get_grpc_cached_version_mux_direction_per_port(db, port)
1262+
result["HWMODE"][port]["Direction"] = res_dict["self_mux_direction"]
1263+
result["HWMODE"][port]["Presence"] = res_dict["presence"]
1264+
result["HWMODE"][port]["PeerDirection"] = res_dict["peer_mux_direction"]
1265+
result["HWMODE"][port]["ConnectivityState"] = res_dict["grpc_connection_status"]
1266+
1267+
rc = res_dict["rc"]
1268+
1269+
return rc
1270+
1271+
def create_active_standby_mux_direction_json_result(result, port, db):
1272+
1273+
res_dict = get_hwmode_mux_direction_port(db, port)
1274+
port = platform_sfputil_helper.get_interface_alias(port, db)
1275+
result["HWMODE"][port] = {}
1276+
result["HWMODE"][port]["Direction"] = res_dict[1]
1277+
result["HWMODE"][port]["Presence"] = res_dict[2]
1278+
1279+
rc = res_dict[0]
1280+
1281+
return rc
1282+
1283+
def create_active_active_mux_direction_result(body, port, db):
1284+
1285+
res_dict = get_grpc_cached_version_mux_direction_per_port(db, port)
1286+
temp_list = []
1287+
port = platform_sfputil_helper.get_interface_alias(port, db)
1288+
temp_list.append(port)
1289+
temp_list.append(res_dict["self_mux_direction"])
1290+
temp_list.append(res_dict["presence"])
1291+
temp_list.append(res_dict["peer_mux_direction"])
1292+
temp_list.append(res_dict["grpc_connection_status"])
1293+
body.append(temp_list)
1294+
1295+
rc = res_dict["rc"]
1296+
1297+
return rc
1298+
1299+
def create_active_standby_mux_direction_result(body, port, db):
1300+
1301+
res_dict = get_hwmode_mux_direction_port(db, port)
1302+
1303+
temp_list = []
1304+
port = platform_sfputil_helper.get_interface_alias(port, db)
1305+
temp_list.append(port)
1306+
temp_list.append(res_dict[1])
1307+
temp_list.append(res_dict[2])
1308+
body.append(temp_list)
1309+
1310+
rc = res_dict[0]
1311+
1312+
delete_all_keys_in_db_table("APPL_DB", "XCVRD_SHOW_HWMODE_DIR_CMD")
1313+
delete_all_keys_in_db_table("STATE_DB", "XCVRD_SHOW_HWMODE_DIR_RSP")
1314+
delete_all_keys_in_db_table("STATE_DB", "XCVRD_SHOW_HWMODE_DIR_RES")
1315+
1316+
return rc
1317+
12421318
@muxcable.group(cls=clicommon.AbbreviationGroup)
12431319
def hwmode():
12441320
"""Shows the muxcable hardware information directly"""
@@ -1247,39 +1323,52 @@ def hwmode():
12471323

12481324
@hwmode.command()
12491325
@click.argument('port', metavar='<port_name>', required=False, default=None)
1326+
@click.option('--json', 'json_output', required=False, is_flag=True, type=click.BOOL, help="display the output in json format")
12501327
@clicommon.pass_db
1251-
def muxdirection(db, port):
1328+
def muxdirection(db, port, json_output):
12521329
"""Shows the current direction of the muxcable {active/standy}"""
12531330

12541331
port = platform_sfputil_helper.get_interface_name(port, db)
12551332

12561333
delete_all_keys_in_db_table("APPL_DB", "XCVRD_SHOW_HWMODE_DIR_CMD")
12571334
delete_all_keys_in_db_table("STATE_DB", "XCVRD_SHOW_HWMODE_DIR_RSP")
12581335
delete_all_keys_in_db_table("STATE_DB", "XCVRD_SHOW_HWMODE_DIR_RES")
1336+
per_npu_configdb = {}
12591337

1260-
if port is not None:
1338+
namespaces = multi_asic.get_front_end_namespaces()
1339+
for namespace in namespaces:
1340+
asic_id = multi_asic.get_asic_index_from_namespace(namespace)
12611341

1342+
per_npu_configdb[asic_id] = ConfigDBConnector(use_unix_socket_path=False, namespace=namespace)
1343+
per_npu_configdb[asic_id].connect()
1344+
1345+
if port is not None:
1346+
1347+
asic_index = get_asic_index_for_port(port)
1348+
cable_type = get_optional_value_for_key_in_config_tbl(per_npu_configdb[asic_index], port, "cable_type", "MUX_CABLE")
12621349
if check_port_in_mux_cable_table(port) == False:
12631350
click.echo("Not Y-cable port")
12641351
return CONFIG_FAIL
12651352

1266-
res_dict = get_hwmode_mux_direction_port(db, port)
1267-
1268-
body = []
1269-
temp_list = []
1270-
headers = ['Port', 'Direction', 'Presence']
1271-
port = platform_sfputil_helper.get_interface_alias(port, db)
1272-
temp_list.append(port)
1273-
temp_list.append(res_dict[1])
1274-
temp_list.append(res_dict[2])
1275-
body.append(temp_list)
1276-
1277-
rc = res_dict[0]
1278-
click.echo(tabulate(body, headers=headers))
1353+
if json_output:
1354+
result = {}
1355+
result ["HWMODE"] = {}
1356+
if cable_type == "active-active":
1357+
rc = create_active_active_mux_direction_json_result(result, port, db)
1358+
else:
1359+
rc = False
1360+
rc = create_active_standby_mux_direction_json_result(result, port, db)
1361+
click.echo("{}".format(json.dumps(result, indent=4)))
12791362

1280-
delete_all_keys_in_db_table("APPL_DB", "XCVRD_SHOW_HWMODE_DIR_CMD")
1281-
delete_all_keys_in_db_table("STATE_DB", "XCVRD_SHOW_HWMODE_DIR_RSP")
1282-
delete_all_keys_in_db_table("STATE_DB", "XCVRD_SHOW_HWMODE_DIR_RES")
1363+
else:
1364+
body = []
1365+
if cable_type == "active-active":
1366+
headers = ['Port', 'Direction', 'Presence', 'PeerDirection', 'ConnectivityState']
1367+
rc = create_active_active_mux_direction_result(body, port, db)
1368+
else:
1369+
rc = create_active_standby_mux_direction_result(body, port, db)
1370+
headers = ['Port', 'Direction', 'Presence']
1371+
click.echo(tabulate(body, headers=headers))
12831372

12841373
return rc
12851374

@@ -1289,8 +1378,12 @@ def muxdirection(db, port):
12891378

12901379
rc_exit = True
12911380
body = []
1381+
active_active = False
1382+
if json_output:
1383+
result = {}
1384+
result ["HWMODE"] = {}
12921385

1293-
for port in logical_port_list:
1386+
for port in natsorted(logical_port_list):
12941387

12951388
if platform_sfputil is not None:
12961389
physical_port_list = platform_sfputil_helper.logical_port_name_to_physical_port_list(port)
@@ -1316,26 +1409,37 @@ def muxdirection(db, port):
13161409
if port != logical_port_list_per_port[0]:
13171410
continue
13181411

1319-
temp_list = []
1412+
1413+
asic_index = get_asic_index_for_port(port)
1414+
cable_type = get_optional_value_for_key_in_config_tbl(per_npu_configdb[asic_index], port, "cable_type", "MUX_CABLE")
1415+
if json_output:
1416+
if cable_type == "active-active":
1417+
rc = create_active_active_mux_direction_json_result(result, port, db)
1418+
active_active = True
1419+
else:
1420+
rc = create_active_standby_mux_direction_json_result(result, port, db)
13201421

1321-
res_dict = get_hwmode_mux_direction_port(db, port)
1422+
else:
1423+
if cable_type == 'active-active':
1424+
rc = create_active_active_mux_direction_result(body, port, db)
1425+
active_active = True
1426+
else:
1427+
rc = create_active_standby_mux_direction_result(body, port, db)
1428+
if rc != 0:
1429+
rc_exit = False
13221430

1323-
port = platform_sfputil_helper.get_interface_alias(port, db)
1324-
temp_list.append(port)
1325-
temp_list.append(res_dict[1])
1326-
temp_list.append(res_dict[2])
1327-
body.append(temp_list)
1328-
rc = res_dict[0]
1329-
if rc != 0:
1330-
rc_exit = False
13311431

1332-
headers = ['Port', 'Direction', 'Presence']
13331432

1334-
click.echo(tabulate(body, headers=headers))
1433+
if json_output:
1434+
click.echo("{}".format(json.dumps(result, indent=4)))
1435+
else:
1436+
if active_active:
1437+
1438+
headers = ['Port', 'Direction', 'Presence', 'PeerDirection', 'ConnectivityState']
1439+
else:
1440+
headers = ['Port', 'Direction', 'Presence']
1441+
click.echo(tabulate(body, headers=headers))
13351442

1336-
delete_all_keys_in_db_table("APPL_DB", "XCVRD_SHOW_HWMODE_DIR_CMD")
1337-
delete_all_keys_in_db_table("STATE_DB", "XCVRD_SHOW_HWMODE_DIR_RSP")
1338-
delete_all_keys_in_db_table("STATE_DB", "XCVRD_SHOW_HWMODE_DIR_RES")
13391443
if rc_exit == False:
13401444
sys.exit(EXIT_FAIL)
13411445

@@ -2003,3 +2107,152 @@ def tunnel_route(db, port, json_output):
20032107
click.echo(tabulate(print_data, headers=headers))
20042108

20052109
sys.exit(STATUS_SUCCESSFUL)
2110+
2111+
2112+
def get_grpc_cached_version_mux_direction_per_port(db, port):
2113+
2114+
2115+
state_db = {}
2116+
mux_info_dict = {}
2117+
mux_info_full_dict = {}
2118+
trans_info_full_dict = {}
2119+
mux_info_dict["rc"] = False
2120+
2121+
# Getting all front asic namespace and correspding config and state DB connector
2122+
2123+
namespaces = multi_asic.get_front_end_namespaces()
2124+
for namespace in namespaces:
2125+
asic_id = multi_asic.get_asic_index_from_namespace(namespace)
2126+
state_db[asic_id] = swsscommon.SonicV2Connector(use_unix_socket_path=False, namespace=namespace)
2127+
state_db[asic_id].connect(state_db[asic_id].STATE_DB)
2128+
2129+
if platform_sfputil is not None:
2130+
asic_index = platform_sfputil_helper.get_asic_id_for_logical_port(port)
2131+
2132+
if asic_index is None:
2133+
# TODO this import is only for unit test purposes, and should be removed once sonic_platform_base
2134+
# is fully mocked
2135+
import sonic_platform_base.sonic_sfp.sfputilhelper
2136+
asic_index = sonic_platform_base.sonic_sfp.sfputilhelper.SfpUtilHelper().get_asic_id_for_logical_port(port)
2137+
if asic_index is None:
2138+
click.echo("Got invalid asic index for port {}, cant retrieve mux cable table entries".format(port))
2139+
return mux_info_dict
2140+
2141+
2142+
mux_info_full_dict[asic_index] = state_db[asic_index].get_all(
2143+
state_db[asic_index].STATE_DB, 'MUX_CABLE_INFO|{}'.format(port))
2144+
trans_info_full_dict[asic_index] = state_db[asic_index].get_all(
2145+
state_db[asic_index].STATE_DB, 'TRANSCEIVER_STATUS|{}'.format(port))
2146+
2147+
res_dir = {}
2148+
res_dir = mux_info_full_dict[asic_index]
2149+
mux_info_dict["self_mux_direction"] = res_dir.get("self_mux_direction", None)
2150+
mux_info_dict["peer_mux_direction"] = res_dir.get("peer_mux_direction", None)
2151+
mux_info_dict["grpc_connection_status"] = res_dir.get("grpc_connection_status", None)
2152+
2153+
trans_dir = {}
2154+
trans_dir = trans_info_full_dict[asic_index]
2155+
2156+
status = trans_dir.get("status", "0")
2157+
presence = "True" if status == "1" else "False"
2158+
2159+
mux_info_dict["presence"] = presence
2160+
2161+
mux_info_dict["rc"] = True
2162+
2163+
return mux_info_dict
2164+
2165+
2166+
@muxcable.group(cls=clicommon.AbbreviationGroup)
2167+
def grpc():
2168+
"""Shows the muxcable hardware information directly"""
2169+
pass
2170+
2171+
2172+
@grpc.command()
2173+
@click.argument('port', metavar='<port_name>', required=False, default=None)
2174+
@click.option('--json', 'json_output', required=False, is_flag=True, type=click.BOOL, help="display the output in json format")
2175+
@clicommon.pass_db
2176+
def muxdirection(db, port, json_output):
2177+
"""Shows the current direction of the FPGA facing port on Tx Side {active/standy}"""
2178+
2179+
port = platform_sfputil_helper.get_interface_name(port, db)
2180+
2181+
2182+
if port is not None:
2183+
2184+
if check_port_in_mux_cable_table(port) == False:
2185+
click.echo("Not Y-cable port")
2186+
return CONFIG_FAIL
2187+
2188+
if json_output:
2189+
result = {}
2190+
result ["HWMODE"] = {}
2191+
rc = create_active_active_mux_direction_json_result(result, port, db)
2192+
click.echo("{}".format(json.dumps(result, indent=4)))
2193+
2194+
else:
2195+
body = []
2196+
2197+
headers = ['Port', 'Direction', 'Presence', 'PeerDirection', 'ConnectivityState']
2198+
rc = create_active_active_mux_direction_result(body, port, db)
2199+
click.echo(tabulate(body, headers=headers))
2200+
2201+
return rc
2202+
2203+
else:
2204+
2205+
2206+
logical_port_list = platform_sfputil_helper.get_logical_list()
2207+
2208+
rc_exit = True
2209+
body = []
2210+
if json_output:
2211+
result = {}
2212+
result ["HWMODE"] = {}
2213+
2214+
for port in natsorted(logical_port_list):
2215+
2216+
if platform_sfputil is not None:
2217+
physical_port_list = platform_sfputil_helper.logical_port_name_to_physical_port_list(port)
2218+
2219+
if not isinstance(physical_port_list, list):
2220+
continue
2221+
if len(physical_port_list) != 1:
2222+
continue
2223+
2224+
if not check_port_in_mux_cable_table(port):
2225+
continue
2226+
2227+
physical_port = physical_port_list[0]
2228+
logical_port_list_for_physical_port = platform_sfputil_helper.get_physical_to_logical()
2229+
2230+
logical_port_list_per_port = logical_port_list_for_physical_port.get(physical_port, None)
2231+
2232+
""" This check is required for checking whether or not this logical port is the one which is
2233+
actually mapped to physical port and by convention it is always the first port.
2234+
TODO: this should be removed with more logic to check which logical port maps to actual physical port
2235+
being used"""
2236+
2237+
if port != logical_port_list_per_port[0]:
2238+
continue
2239+
2240+
if json_output:
2241+
rc = create_active_active_mux_direction_json_result(result, port, db)
2242+
else:
2243+
rc = create_active_active_mux_direction_result(body, port, db)
2244+
2245+
if rc != True:
2246+
rc_exit = False
2247+
2248+
if json_output:
2249+
click.echo("{}".format(json.dumps(result, indent=4)))
2250+
else:
2251+
headers = ['Port', 'Direction', 'Presence', 'PeerDirection', 'ConnectivityState']
2252+
2253+
click.echo(tabulate(body, headers=headers))
2254+
2255+
if rc_exit == False:
2256+
sys.exit(EXIT_FAIL)
2257+
2258+

0 commit comments

Comments
 (0)