-
Notifications
You must be signed in to change notification settings - Fork 661
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enhancement of 'show' commands and addition of 'debug', and 'undebug'… (
#113) - added script to get interface status. - added few subcommands under "show interfaces" command. - enhanced "show process" to get all processes sorted by CPU & memory. - added "show services" command to get all the running process from all the dockers. - added "show vlan" command. - enhanced multiple subcommands under - added debug', and 'undebug' CLI utilities.
- Loading branch information
Showing
10 changed files
with
469 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
_debug_completion() { | ||
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \ | ||
COMP_CWORD=$COMP_CWORD \ | ||
_DEBUG_COMPLETE=complete $1 ) ) | ||
return 0 | ||
} | ||
|
||
complete -F _debug_completion -o default debug; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
_undebug_completion() { | ||
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \ | ||
COMP_CWORD=$COMP_CWORD \ | ||
_UNDEBUG_COMPLETE=complete $1 ) ) | ||
return 0 | ||
} | ||
|
||
complete -F _undebug_completion -o default undebug; |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[aliases] | ||
running-configuration=runningconfiguration | ||
running-config=runningconfiguration | ||
startup-configuration=startupconfiguration | ||
startup-config=startupconfiguration |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
#! /usr/bin/python -u | ||
# date: 07/12/17 | ||
|
||
import click | ||
import os | ||
import subprocess | ||
from click_default_group import DefaultGroup | ||
|
||
try: | ||
import ConfigParser as configparser | ||
except ImportError: | ||
import configparser | ||
|
||
|
||
# This is from the aliases example: | ||
# https://github.com/pallets/click/blob/57c6f09611fc47ca80db0bd010f05998b3c0aa95/examples/aliases/aliases.py | ||
class Config(object): | ||
"""Object to hold CLI config""" | ||
|
||
def __init__(self): | ||
self.path = os.getcwd() | ||
self.aliases = {} | ||
|
||
def read_config(self, filename): | ||
parser = configparser.RawConfigParser() | ||
parser.read([filename]) | ||
try: | ||
self.aliases.update(parser.items('aliases')) | ||
except configparser.NoSectionError: | ||
pass | ||
|
||
|
||
# Global Config object | ||
_config = None | ||
|
||
|
||
# This aliased group has been modified from click examples to inherit from DefaultGroup instead of click.Group. | ||
# DefaultFroup is a superclass of click.Group which calls a default subcommand instead of showing | ||
# a help message if no subcommand is passed | ||
class AliasedGroup(DefaultGroup): | ||
"""This subclass of a DefaultGroup supports looking up aliases in a config | ||
file and with a bit of magic. | ||
""" | ||
|
||
def get_command(self, ctx, cmd_name): | ||
global _config | ||
|
||
# If we haven't instantiated our global config, do it now and load current config | ||
if _config is None: | ||
_config = Config() | ||
|
||
# Load our config file | ||
cfg_file = os.path.join(os.path.dirname(__file__), 'aliases.ini') | ||
_config.read_config(cfg_file) | ||
|
||
# Try to get builtin commands as normal | ||
rv = click.Group.get_command(self, ctx, cmd_name) | ||
if rv is not None: | ||
return rv | ||
|
||
# No builtin found. Look up an explicit command alias in the config | ||
if cmd_name in _config.aliases: | ||
actual_cmd = _config.aliases[cmd_name] | ||
return click.Group.get_command(self, ctx, actual_cmd) | ||
|
||
# Alternative option: if we did not find an explicit alias we | ||
# allow automatic abbreviation of the command. "status" for | ||
# instance will match "st". We only allow that however if | ||
# there is only one command. | ||
matches = [x for x in self.list_commands(ctx) | ||
if x.lower().startswith(cmd_name.lower())] | ||
if not matches: | ||
# No command name matched. Issue Default command. | ||
ctx.arg0 = cmd_name | ||
cmd_name = self.default_cmd_name | ||
return DefaultGroup.get_command(self, ctx, cmd_name) | ||
elif len(matches) == 1: | ||
return DefaultGroup.get_command(self, ctx, matches[0]) | ||
ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) | ||
|
||
|
||
def run_command(command, pager=False): | ||
if pager is True: | ||
click.echo(click.style("Command: ", fg='cyan') + click.style(command, fg='green')) | ||
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) | ||
click.echo_via_pager(p.stdout.read()) | ||
else: | ||
click.echo(click.style("Command: ", fg='cyan') + click.style(command, fg='green')) | ||
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) | ||
click.echo(p.stdout.read()) | ||
|
||
|
||
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help', '-?']) | ||
|
||
|
||
# | ||
# 'cli' group (root group) ### | ||
# | ||
|
||
@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) | ||
def cli(): | ||
"""SONiC command line - 'debug' command""" | ||
pass | ||
|
||
# | ||
# 'bgp' group ### | ||
# | ||
|
||
@cli.group(cls=AliasedGroup, default_if_no_args=True) | ||
def bgp(): | ||
"""debug bgp on """ | ||
pass | ||
|
||
@bgp.command(default=True) | ||
def default(): | ||
command = 'sudo vtysh -c "debug bgp"' | ||
run_command(command) | ||
|
||
@bgp.command() | ||
def events(): | ||
"""debug bgp events on """ | ||
command = 'sudo vtysh -c "debug bgp events"' | ||
run_command(command) | ||
|
||
@bgp.command() | ||
def updates(): | ||
"""debug bgp events on """ | ||
command = 'sudo vtysh -c "debug bgp updates"' | ||
run_command(command) | ||
|
||
if __name__ == '__main__': | ||
cli() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#!/usr/bin/env python | ||
import swsssdk | ||
import sys | ||
import re | ||
from tabulate import tabulate | ||
header = ['Iface', 'LANES', 'ALIAS', 'OPER', 'ADMIN', 'MTU'] | ||
|
||
|
||
PORT_STATUS_TABLE_PREFIX = "PORT_TABLE:" | ||
PORT_LANES_STATUS_FIELD = "lanes" | ||
PORT_ALIAS_STATUS_FIELD = "alias" | ||
PORT_OPER_STATUS_FIELD = "oper_status" | ||
PORT_ADMIN_STATUS_FIELD = "admin_status" | ||
PORT_MTU_STATUS_FIELD = "mtu" | ||
|
||
class Intstat(object): | ||
table = [] | ||
|
||
def get_port_status(self, port_name, status_type): | ||
""" | ||
Get the port status | ||
""" | ||
full_table_id = PORT_STATUS_TABLE_PREFIX + port_name | ||
status = self.db.get(self.db.APPL_DB, full_table_id, status_type) | ||
if status is None: | ||
return "N/A" | ||
else: | ||
return status | ||
|
||
def __init__(self): | ||
self.db = swsssdk.SonicV2Connector(host='127.0.0.1') | ||
self.db.connect(self.db.APPL_DB) | ||
a = self.db.keys(self.db.APPL_DB) | ||
#print(a) | ||
tables = self.db.keys(self.db.APPL_DB, "PORT_TABLE:*") | ||
i = {} | ||
table = [] | ||
key = [] | ||
#print tabulate(header, tablefmt='simple', stralign='right') | ||
for i in tables: | ||
key = re.split(':', i, maxsplit=1)[-1].strip() | ||
if key: | ||
table.append((key, self.get_port_status(key, PORT_LANES_STATUS_FIELD), self.get_port_status(key, PORT_ALIAS_STATUS_FIELD), self.get_port_status(key, PORT_OPER_STATUS_FIELD), self.get_port_status(key, PORT_ADMIN_STATUS_FIELD), self.get_port_status(key, PORT_MTU_STATUS_FIELD))) | ||
print tabulate(table, header, tablefmt="simple", stralign='right') | ||
|
||
|
||
def main(): | ||
interface_stat = Intstat() | ||
|
||
# Now decide what information to display | ||
sys.exit(0) | ||
|
||
if __name__ == "__main__": | ||
main() |
Oops, something went wrong.