Repository: sonic-net/sonic-utilities

Issue:
The output of "show ipv6 bgp summary" is unexpected if there is no IPv6 BGP session configured
<!--
    If you are reporting a new issue, make sure that we do not have any duplicates
    already open. You can ensure this by searching the issue list for this
    repository. If there is a duplicate, please close your issue and add a comment
    to the existing issue instead.

    If you suspect your issue is a bug, please edit your issue description to
    include the BUG REPORT INFORMATION shown below. If you fail to provide this
    information within 7 days, we cannot debug your issue and will close it. We
    will, however, reopen it if you later provide the information.

    For more information about reporting issues, see
    https://github.com/Azure/SONiC/wiki#report-issues

    ---------------------------------------------------
    GENERAL SUPPORT INFORMATION
    ---------------------------------------------------

    The GitHub issue tracker is for bug reports and feature requests.
    General support can be found at the following locations:

    - SONiC Support Forums - https://groups.google.com/forum/#!forum/sonicproject

    ---------------------------------------------------
    BUG REPORT INFORMATION
    ---------------------------------------------------
    Use the commands below to provide key information from your environment:
    You do NOT have to include this information if this is a FEATURE REQUEST
-->

#### Description

<!--
     Briefly describe the problem you are having in a few paragraphs.
-->
We saw some errors using CLI "show ipv6 bgp summary" as below:
  _$show ipv6 bgp sum
  Usage: show ipv6 bgp sum [OPTIONS]
  Try "show ipv6 bgp sum -h" for help.
  
  Error: bgp summary from bgp container in invalid format_

It will only happen on the devices which don't configure the IPv6 BGP session. 
IPv4 should be the same thing. 
 
## Steps to reproduce the issue
1. Make sure there isn't IPv6 BGP session configured in config_db 
2. Run CLI "config reload" 
3. Run CLI "show ipv6 bgp summary"
Then you should see above errors. Tried on branch 202205 and 202012.

#### Describe the results you received


#### Describe the results you expected


#### Additional information you deem important (e.g. issue happens only occasionally)


#### Output of `show version`

```
(paste your output here)
```

<!--
     Also attach debug file produced by `sudo generate_dump`
-->




Discussion:
Expected behavior:
The command to succeed with 0 neighbors reported.

A sample o/p from EOS/Arista:
EOS: (No v6 peers)
```
DB5-0101-0410-07BT0#show ipv6 bgp summ
BGP summary information for VRF default
Router identifier 172.16.97.146, local AS number 64607
Neighbor Status Codes: m - Under maintenance
  Neighbor         V  AS           MsgRcvd   MsgSent  InQ OutQ  Up/Down State  PfxRcd PfxAcc
DB5-0101-0410-07BT0#
```

 

For the MultiASIC support there is some preprocessing going on and it is treating this case as an error case.
Ideally it should behave the same as if this was executed directly from inside the bgp docker and when there is no no IPV6 or IPV4 configured, it should have the following output:
```
admin@SONIC:/etc/sonic$ docker exec -it bgp bash
root@SONIC:/# vtysh -c "show bgp ipv6 sum"
% No BGP neighbors found in VRF default
root@SONIC:/#
```

@arlakshm will help fix this to make it behave the same way instead of printing the error message thinking that it is a malformed json having invalid format.

Resolving patch:
diff --git a/utilities_common/bgp_util.py b/utilities_common/bgp_util.py
--- a/utilities_common/bgp_util.py
+++ b/utilities_common/bgp_util.py
@@ -186,8 +186,10 @@ def get_bgp_summary_from_all_bgp_instances(af, namespace, display):
         except ValueError:
             ctx.fail("bgp summary from bgp container not in json format")
 
+        # exit cli command without printing the error message
         if key not in cmd_output_json:
-            ctx.fail("bgp summary from bgp container in invalid format")
+            click.echo("No IP{} neighbor is configured".format(af))
+            exit()
 
         device.current_namespace = ns
 


Test patch:
diff --git a/tests/bgp_commands_test.py b/tests/bgp_commands_test.py
--- a/tests/bgp_commands_test.py
+++ b/tests/bgp_commands_test.py
@@ -91,6 +91,13 @@
 Error: bgp summary from bgp container not in json format
 """
 
+show_error_no_v6_neighbor = """\
+No IPv6 neighbor is configured
+"""
+
+show_error_no_v4_neighbor = """\
+No IPv4 neighbor is configured
+"""
 
 class TestBgpCommands(object):
     @classmethod
@@ -139,3 +146,31 @@ def test_bgp_summary_error(
         print("{}".format(result.output))
         assert result.exit_code == 2
         assert result.output == show_error_invalid_json
+
+    @pytest.mark.parametrize('setup_single_bgp_instance',
+                             ['show_bgp_summary_no_neigh'], indirect=['setup_single_bgp_instance'])
+    def test_bgp_summary_no_v4_neigh(
+            self,
+            setup_bgp_commands,
+            setup_single_bgp_instance):
+        show = setup_bgp_commands
+        runner = CliRunner()
+        result = runner.invoke(
+            show.cli.commands["ipv6"].commands["bgp"].commands["summary"], [])
+        print("{}".format(result.output))
+        assert result.exit_code == 0
+        assert result.output == show_error_no_v6_neighbor
+
+    @pytest.mark.parametrize('setup_single_bgp_instance',
+                             ['show_bgp_summary_no_neigh'], indirect=['setup_single_bgp_instance'])
+    def test_bgp_summary_no_v6_neigh(
+            self,
+            setup_bgp_commands,
+            setup_single_bgp_instance):
+        show = setup_bgp_commands
+        runner = CliRunner()
+        result = runner.invoke(
+            show.cli.commands["ip"].commands["bgp"].commands["summary"], [])
+        print("{}".format(result.output))
+        assert result.exit_code == 0
+        assert result.output == show_error_no_v4_neighbor
diff --git a/tests/conftest.py b/tests/conftest.py
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -119,6 +119,9 @@ def setup_single_bgp_instance(request):
         bgp_mocked_json = os.path.join(
             test_path, 'mock_tables', 'dummy.json')
 
+    def mock_show_bgp_summary_no_neigh(vtysh_cmd, bgp_namespace, vtysh_shell_cmd=constants.RVTYSH_COMMAND):
+        return "{}"
+    
     def mock_run_bgp_command(vtysh_cmd, bgp_namespace, vtysh_shell_cmd=constants.RVTYSH_COMMAND):
         if os.path.isfile(bgp_mocked_json):
             with open(bgp_mocked_json) as json_data:
@@ -148,6 +151,9 @@ def mock_run_show_ip_route_commands(request):
              request.param == 'ipv6_route', request.param == 'ipv6_specific_route']):
         bgp_util.run_bgp_command = mock.MagicMock(
             return_value=mock_run_show_ip_route_commands(request))
+    elif request.param == "show_bgp_summary_no_neigh":
+        bgp_util.run_bgp_command = mock.MagicMock(
+            return_value=mock_show_bgp_summary_no_neigh("", ""))
     else:
         bgp_util.run_bgp_command = mock.MagicMock(
             return_value=mock_run_bgp_command("", ""))