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

support show interface commands for multi ASIC platforms #1006

Merged
merged 7 commits into from
Aug 21, 2020
Merged
Show file tree
Hide file tree
Changes from 6 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
310 changes: 146 additions & 164 deletions scripts/intfutil

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,12 @@
],
package_data={
'show': ['aliases.ini'],
'tests': ['acl_input/*', 'mock_tables/*.py', 'mock_tables/*.json', 'filter_fdb_input/*']
'tests': ['acl_input/*',
'mock_tables/*.py',
'mock_tables/*.json',
'mock_tables/asic0/*.json',
'mock_tables/asic1/*.json',
'filter_fdb_input/*']
},
scripts=[
'scripts/aclshow',
Expand Down
63 changes: 39 additions & 24 deletions show/interfaces/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@
from natsort import natsorted
from tabulate import tabulate

from sonic_py_common import multi_asic
import utilities_common.cli as clicommon
import utilities_common.multi_asic as multi_asic_util
import portchannel

def try_convert_interfacename_from_alias(ctx, db, interfacename):
def try_convert_interfacename_from_alias(ctx, interfacename):
"""try to convert interface name from alias"""

if clicommon.get_interface_naming_mode() == "alias":
alias = interfacename
interfacename = clicommon.InterfaceAliasConverter(db).alias_to_name(alias)
interfacename = clicommon.InterfaceAliasConverter().alias_to_name(alias)
# TODO: ideally alias_to_name should return None when it cannot find
# the port name for the alias
if interfacename == alias:
Expand All @@ -31,19 +33,19 @@ def interfaces():
# 'alias' subcommand ("show interfaces alias")
@interfaces.command()
@click.argument('interfacename', required=False)
@clicommon.pass_db
def alias(db, interfacename):
@multi_asic_util.multi_asic_click_options
def alias(interfacename, namespace, display):
"""Show Interface Name/Alias Mapping"""

ctx = click.get_current_context()

port_dict = db.cfgdb.get_table("PORT")
port_dict = multi_asic.get_port_table(namespace=namespace)

header = ['Name', 'Alias']
body = []

if interfacename is not None:
interfacename = try_convert_interfacename_from_alias(ctx, db, interfacename)
interfacename = try_convert_interfacename_from_alias(ctx, interfacename)

# If we're given an interface name, output name and alias for that interface only
if interfacename in port_dict.keys():
Expand All @@ -56,6 +58,10 @@ def alias(db, interfacename):
else:
# Output name and alias for all interfaces
for port_name in natsorted(port_dict.keys()):
if ((display == multi_asic_util.constants.DISPLAY_EXTERNAL) and
('role' in port_dict[port_name]) and
(port_dict[port_name]['role'] is multi_asic.INTERNAL_PORT)):
continue
if 'alias' in port_dict[port_name]:
body.append([port_name, port_dict[port_name]['alias']])
else:
Expand All @@ -65,19 +71,25 @@ def alias(db, interfacename):

@interfaces.command()
@click.argument('interfacename', required=False)
@multi_asic_util.multi_asic_click_options
@click.option('--verbose', is_flag=True, help="Enable verbose output")
@clicommon.pass_db
def description(db, interfacename, verbose):
def description(interfacename, namespace, display, verbose):
"""Show interface status, protocol and description"""

ctx = click.get_current_context()

cmd = "intfutil description"
cmd = "intfutil -c description"

#ignore the display option when interface name is passed
if interfacename is not None:
interfacename = try_convert_interfacename_from_alias(ctx, db, interfacename)
interfacename = try_convert_interfacename_from_alias(ctx, interfacename)

cmd += " {}".format(interfacename)
cmd += " -i {}".format(interfacename)
else:
cmd += " -d {}".format(display)

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

clicommon.run_command(cmd, display_cmd=verbose)

Expand All @@ -91,19 +103,24 @@ def naming_mode(verbose):

@interfaces.command()
@click.argument('interfacename', required=False)
@multi_asic_util.multi_asic_click_options
@click.option('--verbose', is_flag=True, help="Enable verbose output")
@clicommon.pass_db
def status(db, interfacename, verbose):
def status(interfacename, namespace, display, verbose):
"""Show Interface status information"""

ctx = click.get_current_context()

cmd = "intfutil status"
cmd = "intfutil -c status"

if interfacename is not None:
interfacename = try_convert_interfacename_from_alias(ctx, db, interfacename)
interfacename = try_convert_interfacename_from_alias(ctx, interfacename)

cmd += " {}".format(interfacename)
cmd += " -i {}".format(interfacename)
else:
cmd += " -d {}".format(display)

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

clicommon.run_command(cmd, display_cmd=verbose)

Expand Down Expand Up @@ -225,7 +242,7 @@ def expected(db, interfacename):
for port in natsorted(neighbor_dict.keys()):
temp_port = port
if clicommon.get_interface_naming_mode() == "alias":
port = clicommon.InterfaceAliasConverter(db).name_to_alias(port)
port = clicommon.InterfaceAliasConverter().name_to_alias(port)
neighbor_dict[port] = neighbor_dict.pop(temp_port)
device2interface_dict[neighbor_dict[port]['name']] = {'localPort': port, 'neighborPort': neighbor_dict[port]['port']}

Expand Down Expand Up @@ -268,8 +285,7 @@ def transceiver():
@click.argument('interfacename', required=False)
@click.option('-d', '--dom', 'dump_dom', is_flag=True, help="Also display Digital Optical Monitoring (DOM) data")
@click.option('--verbose', is_flag=True, help="Enable verbose output")
@clicommon.pass_db
def eeprom(db, interfacename, dump_dom, verbose):
def eeprom(interfacename, dump_dom, verbose):
"""Show interface transceiver EEPROM information"""

ctx = click.get_current_context()
Expand All @@ -280,7 +296,7 @@ def eeprom(db, interfacename, dump_dom, verbose):
cmd += " --dom"

if interfacename is not None:
interfacename = try_convert_interfacename_from_alias(ctx, db, interfacename)
interfacename = try_convert_interfacename_from_alias(ctx, interfacename)

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

Expand All @@ -289,16 +305,15 @@ def eeprom(db, interfacename, dump_dom, verbose):
@transceiver.command()
@click.argument('interfacename', required=False)
@click.option('--verbose', is_flag=True, help="Enable verbose output")
@clicommon.pass_db
def lpmode(db, interfacename, verbose):
def lpmode(interfacename, verbose):
"""Show interface transceiver low-power mode status"""

ctx = click.get_current_context()

cmd = "sudo sfputil show lpmode"

if interfacename is not None:
interfacename = try_convert_interfacename_from_alias(ctx, db, interfacename)
interfacename = try_convert_interfacename_from_alias(ctx, interfacename)

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

Expand All @@ -316,7 +331,7 @@ def presence(db, interfacename, verbose):
cmd = "sfpshow presence"

if interfacename is not None:
interfacename = try_convert_interfacename_from_alias(ctx, db, interfacename)
interfacename = try_convert_interfacename_from_alias(ctx, interfacename)

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

Expand Down
6 changes: 3 additions & 3 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ def subinterfaces():
@click.option('--verbose', is_flag=True, help="Enable verbose output")
def status(subinterfacename, verbose):
"""Show sub port interface status information"""
cmd = "intfutil status "
cmd = "intfutil -c status"

if subinterfacename is not None:
sub_intf_sep_idx = subinterfacename.find(VLAN_SUB_INTERFACE_SEPARATOR)
Expand All @@ -479,9 +479,9 @@ def status(subinterfacename, verbose):
if clicommon.get_interface_naming_mode() == "alias":
subinterfacename = iface_alias_converter.alias_to_name(subinterfacename)

cmd += subinterfacename
cmd += " -i {}".format(subinterfacename)
else:
cmd += "subport"
cmd += " -i subport"
run_command(cmd, display_cmd=verbose)

#
Expand Down
16 changes: 8 additions & 8 deletions tests/intfutil_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"""

show_interface_description_Ethernet0_verbose_output="""\
Running command: intfutil description Ethernet0
Running command: intfutil -c description -i Ethernet0
Interface Oper Admin Alias Description
----------- ------ ------- --------- --------------------
Ethernet0 down up Ethernet0 ARISTA01T2:Ethernet1
Expand Down Expand Up @@ -83,7 +83,7 @@ def test_intf_status(self):
assert result.output == show_interface_status_output

# Test 'intfutil status'
output = subprocess.check_output('intfutil status', stderr=subprocess.STDOUT, shell=True)
output = subprocess.check_output('intfutil -c status', stderr=subprocess.STDOUT, shell=True)
print(output)
assert result.output == show_interface_status_output

Expand All @@ -93,7 +93,7 @@ def test_intf_status_verbose(self):
assert result.exit_code == 0
print(result.exit_code)
print(result.output)
expected_output = "Running command: intfutil status"
expected_output = "Running command: intfutil -c status -d all"
assert result.output.split('\n')[0] == expected_output

def test_intf_status_Ethernet32(self):
Expand Down Expand Up @@ -164,15 +164,15 @@ def test_subintf_status(self):
self.assertEqual(result.output.strip(), expected_output)

# Test 'intfutil status subport'
output = subprocess.check_output('intfutil status subport', stderr=subprocess.STDOUT, shell=True)
output = subprocess.check_output('intfutil -c status -i subport', stderr=subprocess.STDOUT, shell=True)
print >> sys.stderr, output
self.assertEqual(output.strip(), expected_output)

# Test 'show subinterfaces status --verbose'
def test_subintf_status_verbose(self):
result = self.runner.invoke(show.cli.commands["subinterfaces"].commands["status"], ["--verbose"])
print >> sys.stderr, result.output
expected_output = "Command: intfutil status subport"
expected_output = "Command: intfutil -c status -i subport"
self.assertEqual(result.output.split('\n')[0], expected_output)


Expand All @@ -189,15 +189,15 @@ def test_single_subintf_status(self):
self.assertEqual(result.output.strip(), expected_output)

# Test 'intfutil status Ethernet0.10'
output = subprocess.check_output('intfutil status Ethernet0.10', stderr=subprocess.STDOUT, shell=True)
output = subprocess.check_output('intfutil -c status -i Ethernet0.10', stderr=subprocess.STDOUT, shell=True)
print >> sys.stderr, output
self.assertEqual(output.strip(), expected_output)

# Test '--verbose' status of single sub interface
def test_single_subintf_status_verbose(self):
result = self.runner.invoke(show.cli.commands["subinterfaces"].commands["status"], ["Ethernet0.10", "--verbose"])
print >> sys.stderr, result.output
expected_output = "Command: intfutil status Ethernet0.10"
expected_output = "Command: intfutil -c status -i Ethernet0.10"
self.assertEqual(result.output.split('\n')[0], expected_output)


Expand All @@ -222,7 +222,7 @@ def test_single_subintf_status_alias_mode_verbose(self):

result = self.runner.invoke(show.cli.commands["subinterfaces"].commands["status"], ["etp1.10", "--verbose"])
print >> sys.stderr, result.output
expected_output = "Command: intfutil status Ethernet0.10"
expected_output = "Command: intfutil -c status -i Ethernet0.10"
self.assertEqual(result.output.split('\n')[0], expected_output)

os.environ["SONIC_CLI_IFACE_MODE"] = "default"
Expand Down
Empty file.
72 changes: 72 additions & 0 deletions tests/mock_tables/asic0/appl_db.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"PORT_TABLE:Ethernet0": {
"lanes": "33,34,35,36",
"description": "ARISTA01T2:Ethernet3/1/1",
"pfc_asym": "off",
"mtu": "9100",
"alias": "Ethernet1/1",
"oper_status": "up",
"admin_status": "up",
"role": "Ext",
"speed": "40000",
"asic_port_name": "Eth0-ASIC0"
},
"PORT_TABLE:Ethernet4": {
"oper_status": "up",
"lanes": "29,30,31,32",
"description": "ARISTA01T2:Ethernet3/2/1",
"pfc_asym": "off",
"mtu": "9100",
"alias": "Ethernet1/2",
"admin_status": "up",
"role": "Ext",
"speed": "40000",
"asic_port_name": "Eth1-ASIC0"
},
"PORT_TABLE:Ethernet-BP0": {
"oper_status": "up",
"lanes": "93,94,95,96",
"description": "ASIC1:Eth0-ASIC1",
"pfc_asym": "off",
"mtu": "9100",
"alias": "Ethernet-BP0",
"admin_status": "up",
"role": "Int",
"speed": "40000",
"asic_port_name": "Eth16-ASIC0"
},
"PORT_TABLE:Ethernet-BP4": {
"oper_status": "up",
"lanes": "97,98,99,100",
"description": "ASIC1:Eth1-ASIC1",
"pfc_asym": "off",
"mtu": "9100",
"alias": "Ethernet-BP4",
"admin_status": "up",
"role": "Int",
"speed": "40000",
"asic_port_name": "Eth17-ASIC0"
},
"LAG_MEMBER_TABLE:PortChannel1002:Ethernet0": {
"status": "disabled"
},
"LAG_MEMBER_TABLE:PortChannel1002:Ethernet4": {
"status": "enabled"
},
"LAG_MEMBER_TABLE:PortChannel4001:Ethernet-BP0": {
"status": "enabled"
},
"LAG_MEMBER_TABLE:PortChannel4001:Ethernet-BP4": {
"status": "enabled"
},
"LAG_TABLE:PortChannel1002": {
"admin_status": "up",
"mtu": "9100",
"oper_status": "up"
},
"LAG_TABLE:PortChannel4001": {
"admin_status": "up",
"mtu": "9100",
"oper_status": "up"
}
}
6 changes: 6 additions & 0 deletions tests/mock_tables/asic0/asic_db.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"ASIC_STATE:SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000": {
"SAI_SWITCH_ATTR_INIT_SWITCH": "true",
"SAI_SWITCH_ATTR_SRC_MAC_ADDRESS": "DE:AD:BE:EF:CA:FE"
}
}
Loading