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

show subinterfaces status #642

Merged
merged 20 commits into from
Nov 5, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
7e2d955
Add sub port interface to intfutil status
wendani Sep 12, 2019
80714f0
Format change
wendani Sep 12, 2019
b50f09e
Hook 'intfutil status' with show subinterfaces status
wendani Sep 12, 2019
cf1b51c
Add 'intfutil status subport' to show only the status of sub port int…
wendani Sep 12, 2019
b6a4ac7
Hook 'intfutil status subport' with 'show subinterfaces status'
wendani Sep 12, 2019
7c45d13
Support intfutil status <sub_port_intf_name>
wendani Sep 12, 2019
360a5c9
Add alias naming mode support
wendani Sep 13, 2019
367b768
Merge remote-tracking branch 'origin/master' into sub_intf_show_master
wendani Sep 18, 2019
7e16f02
Address comments
wendani Sep 26, 2019
926286d
Address comment: concatenate command line, and validate input
wendani Sep 26, 2019
80293ce
Address comment: keep show interface status intact
wendani Oct 16, 2019
2dd02bc
Merge remote-tracking branch 'origin/master' into sub_intf_show_master
wendani Nov 2, 2019
f0faf8f
Add unit test for show interfaces status / intfutil status
wendani Nov 2, 2019
03bc156
Add unit test for 'show interfaces status --verbose'
wendani Nov 4, 2019
9969e55
Add unit test for 'show subinterfaces status' / 'intfutil status subp…
wendani Nov 4, 2019
bc946e0
Add unit test for 'show subinterfaces status --verbose'
wendani Nov 4, 2019
3a288e4
Add unit test for single sub interface status show
wendani Nov 4, 2019
9b3c711
Add unit test for '--verbose' single sub interface status show
wendani Nov 4, 2019
972e0f5
Add unit test for showing status of single sub interface in alias nam…
wendani Nov 4, 2019
94f0936
Add unit test for '--verbose' status of single sub interface in alias…
wendani Nov 4, 2019
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
165 changes: 136 additions & 29 deletions scripts/intfutil
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ PORT_DESCRIPTION = "description"
PORT_OPTICS_TYPE = "type"
PORT_PFC_ASYM_STATUS = "pfc_asym"

VLAN_SUB_INTERFACE_SEPARATOR = "."
VLAN_SUB_INTERFACE_TYPE = "dot1q-encapsulation"
wendani marked this conversation as resolved.
Show resolved Hide resolved

SUB_PORT = "subport"

def db_connect_configdb():
"""
Connect to configdb
Expand All @@ -43,6 +48,15 @@ def get_frontpanel_port_list(config_db):
return front_panel_ports_list


def get_sub_port_intf_list(config_db):
sub_intf_dict = config_db.get_table('VLAN_SUB_INTERFACE')
sub_intf_list = []
for sub_intf in sub_intf_dict.keys():
if isinstance(sub_intf, basestring):
sub_intf_list.append(sub_intf)
return sub_intf_list


def get_interface_vlan_dict(config_db):
"""
Get info from REDIS ConfigDB and create interface to vlan mapping
Expand Down Expand Up @@ -93,6 +107,23 @@ def appl_db_keys_get(appl_db, front_panel_ports_list, intf_name):
return appl_db_keys


def appl_db_sub_intf_keys_get(appl_db, sub_intf_list, sub_intf_name):
"""
Get APPL_DB sub port interface keys
"""
if sub_intf_name is None:
appl_db_sub_intf_keys = []
appl_db_intf_keys = appl_db.keys(appl_db.APPL_DB, "INTF_TABLE:*")
for appl_db_intf_key in appl_db_intf_keys:
if re.split(':', appl_db_intf_key, maxsplit=1)[-1].strip() in sub_intf_list:
appl_db_sub_intf_keys.append(appl_db_intf_key)
elif sub_intf_name in sub_intf_list:
appl_db_sub_intf_keys = appl_db.keys(appl_db.APPL_DB, "INTF_TABLE:%s" % sub_intf_name)
else:
return []
return appl_db_sub_intf_keys


def appl_db_port_status_get(appl_db, intf_name, status_type):
"""
Get the port status
Expand Down Expand Up @@ -267,13 +298,42 @@ def appl_db_portchannel_status_get(appl_db, config_db, po_name, status_type, por
return "N/A"
return status

def appl_db_sub_intf_status_get(appl_db, config_db, front_panel_ports_list, portchannel_speed_dict, sub_intf_name, status_type):
sub_intf_sep_idx = sub_intf_name.find(VLAN_SUB_INTERFACE_SEPARATOR)
if sub_intf_sep_idx != -1:
parent_port_name = sub_intf_name[:sub_intf_sep_idx]
vlan_id = sub_intf_name[sub_intf_sep_idx + 1:]

full_intf_table_name = "INTF_TABLE" + ":" + sub_intf_name

if status_type == "vlan":
return vlan_id

if status_type == "admin_status":
status = appl_db.get(appl_db.APPL_DB, full_intf_table_name, status_type)
return status if status is not None else "N/A"

if status_type == "type":
return VLAN_SUB_INTERFACE_TYPE

if status_type == "mtu" or status_type == "speed":
if parent_port_name in front_panel_ports_list:
return appl_db_port_status_get(appl_db, parent_port_name, status_type)
elif parent_port_name in portchannel_speed_dict.keys():
return appl_db_portchannel_status_get(appl_db, config_db, parent_port_name, status_type, portchannel_speed_dict)
else:
return "N/A"

return "N/A"

# ========================== interface-status logic ==========================

header_stat = ['Interface', 'Lanes', 'Speed', 'MTU', 'Alias', 'Vlan', 'Oper', 'Admin', 'Type', 'Asym PFC']
header_stat_sub_intf = ['Sub port interface', 'Speed', 'MTU', 'Vlan', 'Admin', 'Type']
wendani marked this conversation as resolved.
Show resolved Hide resolved

class IntfStatus(object):

def display_intf_status(self, appl_db_keys, front_panel_ports_list, portchannel_speed_dict):
def display_intf_status(self, appl_db_keys, front_panel_ports_list, portchannel_speed_dict, appl_db_sub_intf_keys, sub_intf_list, sub_intf_only):
"""
Generate interface-status output
"""
Expand All @@ -286,35 +346,61 @@ class IntfStatus(object):
# Iterate through all the keys and append port's associated state to
# the result table.
#
for i in appl_db_keys:
key = re.split(':', i, maxsplit=1)[-1].strip()
if key in front_panel_ports_list:
table.append((key,
appl_db_port_status_get(self.appl_db, key, PORT_LANES_STATUS),
appl_db_port_status_get(self.appl_db, key, PORT_SPEED),
appl_db_port_status_get(self.appl_db, key, PORT_MTU_STATUS),
appl_db_port_status_get(self.appl_db, key, PORT_ALIAS),
config_db_vlan_port_keys_get(self.combined_int_to_vlan_po_dict, self.front_panel_ports_list, key),
appl_db_port_status_get(self.appl_db, key, PORT_OPER_STATUS),
appl_db_port_status_get(self.appl_db, key, PORT_ADMIN_STATUS),
state_db_port_optics_get(self.state_db, key, PORT_OPTICS_TYPE),
appl_db_port_status_get(self.appl_db, key, PORT_PFC_ASYM_STATUS)))
# Sorting and tabulating the result table.
for po, value in portchannel_speed_dict.iteritems():
if po:
table.append((po,
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_LANES_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_SPEED, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_MTU_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_ALIAS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, "vlan", self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_OPER_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_ADMIN_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_OPTICS_TYPE, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_PFC_ASYM_STATUS, self.portchannel_speed_dict)))
if not sub_intf_only:
for i in appl_db_keys:
key = re.split(':', i, maxsplit=1)[-1].strip()
if key in front_panel_ports_list:
table.append((key,
appl_db_port_status_get(self.appl_db, key, PORT_LANES_STATUS),
appl_db_port_status_get(self.appl_db, key, PORT_SPEED),
appl_db_port_status_get(self.appl_db, key, PORT_MTU_STATUS),
appl_db_port_status_get(self.appl_db, key, PORT_ALIAS),
config_db_vlan_port_keys_get(self.combined_int_to_vlan_po_dict, self.front_panel_ports_list, key),
appl_db_port_status_get(self.appl_db, key, PORT_OPER_STATUS),
appl_db_port_status_get(self.appl_db, key, PORT_ADMIN_STATUS),
state_db_port_optics_get(self.state_db, key, PORT_OPTICS_TYPE),
appl_db_port_status_get(self.appl_db, key, PORT_PFC_ASYM_STATUS)))

for po, value in portchannel_speed_dict.iteritems():
if po:
table.append((po,
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_LANES_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_SPEED, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_MTU_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_ALIAS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, "vlan", self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_OPER_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_ADMIN_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_OPTICS_TYPE, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_PFC_ASYM_STATUS, self.portchannel_speed_dict)))

for key in appl_db_sub_intf_keys:
sub_intf = re.split(':', key, maxsplit=1)[-1].strip()
if sub_intf in sub_intf_list:
table.append((sub_intf,
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_LANES_STATUS),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_SPEED),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_MTU_STATUS),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_ALIAS),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, "vlan"),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_OPER_STATUS),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_ADMIN_STATUS),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_OPTICS_TYPE),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_PFC_ASYM_STATUS)))
else:
for key in appl_db_sub_intf_keys:
sub_intf = re.split(':', key, maxsplit=1)[-1].strip()
if sub_intf in sub_intf_list:
table.append((sub_intf,
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_SPEED),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_MTU_STATUS),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, "vlan"),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_ADMIN_STATUS),
appl_db_sub_intf_status_get(self.appl_db, self.config_db, self.front_panel_ports_list, self.portchannel_speed_dict, sub_intf, PORT_OPTICS_TYPE)))

# Sorting and tabulating the result table.
sorted_table = natsorted(table)
print tabulate(sorted_table, header_stat, tablefmt="simple", stralign='right')
print tabulate(sorted_table, header_stat if not sub_intf_only else header_stat_sub_intf, tablefmt="simple", stralign='right')


def __init__(self, intf_name):
Expand All @@ -333,6 +419,20 @@ class IntfStatus(object):
return
if self.config_db is None:
return

sub_intf_only = False
sub_intf_name = intf_name
if intf_name is not None:
if intf_name == SUB_PORT:
intf_name = None
sub_intf_name = None
sub_intf_only = True
else:
sub_intf_sep_idx = intf_name.find(VLAN_SUB_INTERFACE_SEPARATOR)
if sub_intf_sep_idx != -1:
sub_intf_only = True
intf_name = intf_name[:sub_intf_sep_idx]

self.front_panel_ports_list = get_frontpanel_port_list(self.config_db)
appl_db_keys = appl_db_keys_get(self.appl_db, self.front_panel_ports_list, intf_name)
self.int_to_vlan_dict = get_interface_vlan_dict(self.config_db)
Expand All @@ -344,9 +444,12 @@ class IntfStatus(object):
self.combined_int_to_vlan_po_dict = merge_dicts(self.int_to_vlan_dict, self.int_po_dict)
self.portchannel_speed_dict = po_speed_dict(self.po_int_dict, self.appl_db)
self.portchannel_keys = self.portchannel_speed_dict.keys()

self.sub_intf_list = get_sub_port_intf_list(self.config_db)
appl_db_sub_intf_keys = appl_db_sub_intf_keys_get(self.appl_db, self.sub_intf_list, sub_intf_name)
if appl_db_keys is None:
return
self.display_intf_status(appl_db_keys, self.front_panel_ports_list, self.portchannel_speed_dict)
self.display_intf_status(appl_db_keys, self.front_panel_ports_list, self.portchannel_speed_dict, appl_db_sub_intf_keys, self.sub_intf_list, sub_intf_only)



Expand Down Expand Up @@ -392,6 +495,10 @@ class IntfDescription(object):
return
if self.config_db is None:
return

if intf_name is not None and intf_name == SUB_PORT:
intf_name = None

self.front_panel_ports_list = get_frontpanel_port_list(self.config_db)
appl_db_keys = appl_db_keys_get(self.appl_db, self.front_panel_ports_list, intf_name)
if appl_db_keys is None:
Expand Down
53 changes: 49 additions & 4 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen'

VLAN_SUB_INTERFACE_SEPARATOR = '.'

try:
# noinspection PyPep8Naming
import ConfigParser as configparser
Expand Down Expand Up @@ -74,25 +76,42 @@ def name_to_alias(self, interface_name):
"""Return vendor interface alias if SONiC
interface name is given as argument
"""
vlan_id = ''
sub_intf_sep_idx = -1
if interface_name is not None:
sub_intf_sep_idx = interface_name.find(VLAN_SUB_INTERFACE_SEPARATOR)
if sub_intf_sep_idx != -1:
vlan_id = interface_name[sub_intf_sep_idx + 1:]
# interface_name holds the parent port name
interface_name = interface_name[:sub_intf_sep_idx]

for port_name in self.port_dict.keys():
if interface_name == port_name:
return self.port_dict[port_name]['alias']
return self.port_dict[port_name]['alias'] if sub_intf_sep_idx == -1 \
else self.port_dict[port_name]['alias'] + VLAN_SUB_INTERFACE_SEPARATOR + vlan_id

# interface_name not in port_dict. Just return interface_name
return interface_name
return interface_name if sub_intf_sep_idx == -1 else interface_name + VLAN_SUB_INTERFACE_SEPARATOR + vlan_id

def alias_to_name(self, interface_alias):
"""Return SONiC interface name if vendor
port alias is given as argument
"""
vlan_id = ''
sub_intf_sep_idx = -1
if interface_alias is not None:
sub_intf_sep_idx = interface_alias.find(VLAN_SUB_INTERFACE_SEPARATOR)
if sub_intf_sep_idx != -1:
vlan_id = interface_alias[sub_intf_sep_idx + 1:]
# interface_alias holds the parent port alias
interface_alias = interface_alias[:sub_intf_sep_idx]

for port_name in self.port_dict.keys():
if interface_alias == self.port_dict[port_name]['alias']:
return port_name
return port_name if sub_intf_sep_idx == -1 else port_name + VLAN_SUB_INTERFACE_SEPARATOR + vlan_id

# interface_alias not in port_dict. Just return interface_alias
return interface_alias
return interface_alias if sub_intf_sep_idx == -1 else interface_alias + VLAN_SUB_INTERFACE_SEPARATOR + vlan_id


# Global Config object
Expand Down Expand Up @@ -661,6 +680,32 @@ def portchannel(verbose):
cmd = "sudo teamshow"
run_command(cmd, display_cmd=verbose)

#
# 'subinterfaces' group ("show subinterfaces ...")
#

@cli.group(cls=AliasedGroup, default_if_no_args=False)
def subinterfaces():
"""Show details of the sub port interfaces"""
pass

# 'subinterfaces' subcommand ("show subinterfaces status")
@subinterfaces.command()
@click.argument('subinterfacename', type=str, required=False)
@click.option('--verbose', is_flag=True, help="Enable verbose output")
def status(subinterfacename, verbose):
"""Show sub port interface status information"""
cmd = "intfutil status"

if subinterfacename is not None:
if get_interface_mode() == "alias":
subinterfacename = iface_alias_converter.alias_to_name(subinterfacename)

cmd += " {}".format(subinterfacename)
wendani marked this conversation as resolved.
Show resolved Hide resolved
else:
cmd += " subport"
run_command(cmd, display_cmd=verbose)

#
# 'pfc' group ("show pfc ...")
#
Expand Down