Skip to content

Commit

Permalink
[show] Add bgpraw to show run all (sonic-net#2537)
Browse files Browse the repository at this point in the history
#### What I did
Add bgpraw output to `show runningconfiguration all`
```
Requirements:
1. current `show runningconfig` will print all the ConfigDB in a json format, we need to add a new key-value into the json output "bgpraw" with a long string value
2. The long string value should be the output of `vtysh -c "show run"`. It is normally multiline string, may include special characters like \". Need to make sure the escaping properly
3. We do not need to insert the key-value into ConfigDB is not existing there
4. If ConfigDB already has the key-value, we do not need to override it by vtysh command output
5. Not break multi-asic use
```
#### How I did it
Generate bgpraw output then append it to `show runnningconfiguration all`'s output
#### How to verify it
Mannual test
#### Previous command output (if the output of a command-line utility has changed)
```
admin@vlab-01:~$ show run all
{
    "ACL_TABLE": {
......
    "WRED_PROFILE": {
        "AZURE_LOSSLESS": {
            "ecn": "ecn_all",
            "green_drop_probability": "5",
            "green_max_threshold": "2097152",
            "green_min_threshold": "1048576",
            "red_drop_probability": "5",
            "red_max_threshold": "2097152",
            "red_min_threshold": "1048576",
            "wred_green_enable": "true",
            "wred_red_enable": "true",
            "wred_yellow_enable": "true",
            "yellow_drop_probability": "5",
            "yellow_max_threshold": "2097152",
            "yellow_min_threshold": "1048576"
        }
    }
}
```
#### New command output (if the output of a command-line utility has changed)
```
admin@vlab-01:~$ show run all
{
    "ACL_TABLE": {
......
    "WRED_PROFILE": {
        "AZURE_LOSSLESS": {
            "ecn": "ecn_all",
            "green_drop_probability": "5",
            "green_max_threshold": "2097152",
            "green_min_threshold": "1048576",
            "red_drop_probability": "5",
            "red_max_threshold": "2097152",
            "red_min_threshold": "1048576",
            "wred_green_enable": "true",
            "wred_red_enable": "true",
            "wred_yellow_enable": "true",
            "yellow_drop_probability": "5",
            "yellow_max_threshold": "2097152",
            "yellow_min_threshold": "1048576"
        }
    },
    "bgpraw": "Building configuration...\n\nCurrent configuration......end\n"
}
```
  • Loading branch information
wen587 authored and isabelmsft committed Mar 23, 2023
1 parent 8329518 commit 521ecfd
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
26 changes: 24 additions & 2 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from datetime import datetime
import utilities_common.constants as constants
from utilities_common.general import load_db_config
from json.decoder import JSONDecodeError

# mock the redis for unit test purposes #
try:
Expand Down Expand Up @@ -129,6 +130,10 @@ def run_command(command, display_cmd=False, return_cmd=False):
if rc != 0:
sys.exit(rc)

def get_cmd_output(cmd):
proc = subprocess.Popen(cmd, text=True, stdout=subprocess.PIPE)
return proc.communicate()[0], proc.returncode

# Lazy global class instance for SONiC interface name to alias conversion
iface_alias_converter = lazy_object_proxy.Proxy(lambda: clicommon.InterfaceAliasConverter())

Expand Down Expand Up @@ -1383,8 +1388,25 @@ def runningconfiguration():
@click.option('--verbose', is_flag=True, help="Enable verbose output")
def all(verbose):
"""Show full running configuration"""
cmd = "sonic-cfggen -d --print-data"
run_command(cmd, display_cmd=verbose)
cmd = ['sonic-cfggen', '-d', '--print-data']
stdout, rc = get_cmd_output(cmd)
if rc:
click.echo("Failed to get cmd output '{}':rc {}".format(cmd, rc))
raise click.Abort()

try:
output = json.loads(stdout)
except JSONDecodeError as e:
click.echo("Failed to load output '{}':{}".format(cmd, e))
raise click.Abort()

if not multi_asic.is_multi_asic():
bgpraw_cmd = [constants.RVTYSH_COMMAND, '-c', 'show running-config']
bgpraw, rc = get_cmd_output(bgpraw_cmd)
if rc:
bgpraw = ""
output['bgpraw'] = bgpraw
click.echo(json.dumps(output, indent=4))


# 'acl' subcommand ("show runningconfiguration acl")
Expand Down
51 changes: 51 additions & 0 deletions tests/show_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import os
import sys
import show.main as show
from click.testing import CliRunner
from unittest import mock
from unittest.mock import call, MagicMock

test_path = os.path.dirname(os.path.abspath(__file__))
modules_path = os.path.dirname(test_path)
sys.path.insert(0, test_path)
sys.path.insert(0, modules_path)


class TestShowRunAllCommands(object):
@classmethod
def setup_class(cls):
print("SETUP")
os.environ["UTILITIES_UNIT_TESTING"] = "1"

def test_show_runningconfiguration_all_json_loads_failure(self):
def get_cmd_output_side_effect(*args, **kwargs):
return "", 0
with mock.patch('show.main.get_cmd_output',
mock.MagicMock(side_effect=get_cmd_output_side_effect)) as mock_get_cmd_output:
result = CliRunner().invoke(show.cli.commands['runningconfiguration'].commands['all'], [])
assert result.exit_code != 0

def test_show_runningconfiguration_all_get_cmd_ouput_failure(self):
def get_cmd_output_side_effect(*args, **kwargs):
return "{}", 2
with mock.patch('show.main.get_cmd_output',
mock.MagicMock(side_effect=get_cmd_output_side_effect)) as mock_get_cmd_output:
result = CliRunner().invoke(show.cli.commands['runningconfiguration'].commands['all'], [])
assert result.exit_code != 0

def test_show_runningconfiguration_all(self):
def get_cmd_output_side_effect(*args, **kwargs):
return "{}", 0
with mock.patch('show.main.get_cmd_output',
mock.MagicMock(side_effect=get_cmd_output_side_effect)) as mock_get_cmd_output:
result = CliRunner().invoke(show.cli.commands['runningconfiguration'].commands['all'], [])
assert mock_get_cmd_output.call_count == 2
assert mock_get_cmd_output.call_args_list == [
call(['sonic-cfggen', '-d', '--print-data']),
call(['rvtysh', '-c', 'show running-config'])]

@classmethod
def teardown_class(cls):
print("TEARDOWN")
os.environ["PATH"] = os.pathsep.join(os.environ["PATH"].split(os.pathsep)[:-1])
os.environ["UTILITIES_UNIT_TESTING"] = "0"

0 comments on commit 521ecfd

Please sign in to comment.