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

Add "show fabric reachability" command. #2672

Merged
merged 1 commit into from
Feb 21, 2023
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
38 changes: 37 additions & 1 deletion scripts/fabricstat
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,33 @@ class FabricQueueStat(FabricStat):
print(tabulate(table, queuestat_header, tablefmt='simple', stralign='right'))
print()

class FabricReachability(FabricStat):
def reachability_print(self):
# Connect to database
self.db = multi_asic.connect_to_all_dbs_for_ns(self.namespace)
# Get the set of all fabric port keys
port_keys = self.db.keys(self.db.STATE_DB, FABRIC_PORT_STATUS_TABLE_PREFIX + '*')
# Create a new dictionary. The key values are the local port values
# in integer format. Only ports that have remote port data are added.
# Only ports that are "up" will be connected to a remote peer.
port_dict = {}
for port_key in port_keys:
port_data = self.db.get_all(self.db.STATE_DB, port_key)
if "REMOTE_PORT" in port_data:
port_number = int(port_key.replace("FABRIC_PORT_TABLE|PORT", ""))
port_dict.update({port_number: port_data})
# Create ordered table of port data
header = ["Local Link", "Remote Module", "Remote Link", "Status"]
body = []
for port_number in sorted(port_dict.keys()):
port_data = port_dict[port_number]
body.append((port_number, port_data["REMOTE_MOD"], \
port_data["REMOTE_PORT"], port_data["STATUS"]))
if self.namespace:
print(f"\n{self.namespace}")
print(tabulate(body, header, tablefmt='simple', stralign='right'))
return

def main():
parser = argparse.ArgumentParser(description='Display the fabric port state and counters',
formatter_class=argparse.RawTextHelpFormatter,
Expand All @@ -199,16 +226,25 @@ Examples:
""")

parser.add_argument('-q','--queue', action='store_true', help='Display fabric queue stat, otherwise port stat')
parser.add_argument('-r','--reachability', action='store_true', help='Display reachability, otherwise port stat')
parser.add_argument('-n','--namespace', default=None, help='Display fabric ports counters for specific namespace')
parser.add_argument('-e', '--errors', action='store_true', help='Display errors')

args = parser.parse_args()
queue = args.queue
reachability = args.reachability
namespace = args.namespace
errors_only = args.errors

def nsStat(ns, errors_only):
stat = FabricQueueStat(ns) if queue else FabricPortStat(ns)
if queue:
stat = FabricQueueStat(ns)
elif reachability:
stat = FabricReachability(ns)
stat.reachability_print()
return
else:
stat = FabricPortStat(ns)
cnstat_dict = stat.get_cnstat_dict()
stat.cnstat_print(cnstat_dict, errors_only)

Expand Down
12 changes: 12 additions & 0 deletions show/fabric.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ def counters():
"""Show fabric port counters"""
pass

@fabric.group(invoke_without_command=True)
@multi_asic_util.multi_asic_click_option_namespace
@click.option('-e', '--errors', is_flag=True)
def reachability(namespace, errors):
"""Show fabric reachability"""
cmd = "fabricstat -r"
if namespace is not None:
cmd += " -n {}".format(namespace)
if errors:
cmd += " -e"
clicommon.run_command(cmd)

@counters.command()
@multi_asic_util.multi_asic_click_option_namespace
@click.option('-e', '--errors', is_flag=True)
Expand Down
44 changes: 44 additions & 0 deletions tests/fabricstat_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,36 @@

"""

multi_asic_fabric_reachability = """\

asic0
Local Link Remote Module Remote Link Status
------------ --------------- ------------- --------
0 0 79 up
2 0 94 up
4 0 85 up
6 0 84 up
7 0 93 up

asic1
Local Link Remote Module Remote Link Status
------------ --------------- ------------- --------
0 0 69 up
4 0 75 up
"""

multi_asic_fabric_reachability_asic0 = """\

asic0
Local Link Remote Module Remote Link Status
------------ --------------- ------------- --------
0 0 79 up
2 0 94 up
4 0 85 up
6 0 84 up
7 0 93 up
"""

class TestFabricStat(object):
@classmethod
def setup_class(cls):
Expand Down Expand Up @@ -163,6 +193,20 @@ def test_multi_show_fabric_counters_queue_asic(self):
assert return_code == 0
assert result == multi_asic_fabric_counters_queue_asic0

def test_multi_show_fabric_reachability(self):
return_code, result = get_result_and_return_code('fabricstat -r')
print("return_code: {}".format(return_code))
print("result = {}".format(result))
assert return_code == 0
assert result == multi_asic_fabric_reachability

def test_multi_show_fabric_reachability_asic(self):
return_code, result = get_result_and_return_code('fabricstat -r -n asic0')
print("return_code: {}".format(return_code))
print("result = {}".format(result))
assert return_code == 0
assert result == multi_asic_fabric_reachability_asic0

@classmethod
def teardown_class(cls):
print("TEARDOWN")
Expand Down