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

Add show CLI for bmp related dataset. #3289

Merged
merged 26 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
58485b8
Add CLI for bmp state_db dataset show.
FengPan-Frank Apr 24, 2024
164a39a
Add CLI for bmp state_db dataset show.
FengPan-Frank Apr 24, 2024
6923770
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank Apr 24, 2024
ce89282
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank Apr 24, 2024
8efac4c
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank Apr 24, 2024
874eb8a
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank Apr 24, 2024
11da19e
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank Apr 24, 2024
9cb45fc
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank Apr 24, 2024
f686e7a
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank Apr 25, 2024
5adad73
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank Apr 25, 2024
ea68902
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank Apr 25, 2024
9cff051
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank Apr 25, 2024
2f51853
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank May 9, 2024
50e22f1
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank May 9, 2024
b5ef8fd
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank May 13, 2024
8366a68
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank May 13, 2024
fda0ac5
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank May 16, 2024
e0aaee1
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank May 16, 2024
519b3b1
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank May 29, 2024
fd27176
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank May 29, 2024
e6b6873
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank May 29, 2024
b17c89a
Merge branch 'sonic-net:master' into bmpcli_show
FengPan-Frank Aug 29, 2024
7845a02
Update db instance
FengPan-Frank Aug 29, 2024
1c9cfe7
Update db instance
FengPan-Frank Aug 29, 2024
5a81b72
Merge branch 'bmpcli_show' of https://github.com/FengPan-Frank/sonic-…
FengPan-Frank Aug 29, 2024
1a2d2c3
update test
FengPan-Frank Sep 5, 2024
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
92 changes: 92 additions & 0 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2081,6 +2081,98 @@ def ztp(status, verbose):
cmd += ["--verbose"]
run_command(cmd, display_cmd=verbose)

#
# 'bmp' group ("show bmp ...")
#
@cli.group(cls=clicommon.AliasedGroup)
def bmp():
"""Show details of the bmp dataset"""
pass

# 'bgp-neighbor-table' subcommand ("show bmp bgp-neighbor-table")
@bmp.command('bgp-neighbor-table')
@clicommon.pass_db
def bmp_neighbor_table(db):
"""Show bmp bgp-neighbor-table information"""
bmp_headers = ["Neighbor_Address", "Peer_Address", "Peer_ASN", "Peer_RD", "Peer_Port", "Local_Address", "Local_ASN", "Local_Port",
"Advertised_Capabilities", "Received_Capabilities"]

bmp_keys = db.db.keys(db.db.STATE_DB, "BGP_NEIGHBOR_TABLE|*")
FengPan-Frank marked this conversation as resolved.
Show resolved Hide resolved
FengPan-Frank marked this conversation as resolved.
Show resolved Hide resolved
FengPan-Frank marked this conversation as resolved.
Show resolved Hide resolved

click.echo("Total number of bmp neighbors: {}".format(0 if bmp_keys is None else len(bmp_keys)))

bmp_body = []
if bmp_keys is not None:
for key in bmp_keys:
key_values = key.split('|')
values = db.db.get_all(db.db.STATE_DB, key)
bmp_body.append([values["peer_addr"], values["peer_addr"], values["peer_asn"], values["peer_rd"], values["peer_port"],
FengPan-Frank marked this conversation as resolved.
Show resolved Hide resolved
values["local_addr"], values["local_asn"], values["local_port"], values["sent_cap"], values["recv_cap"]])

click.echo(tabulate(bmp_body, bmp_headers))

# 'bmp-rib-out-table' subcommand ("show bmp bgp-rib-out-table")
@bmp.command('bgp-rib-out-table')
@clicommon.pass_db
def bmp_rib_out_table(db):
"""Show bmp bgp-rib-out-table information"""
bmp_headers = ["Neighbor_Address", "NLRI", "Origin", "AS_Path", "Origin_AS", "Next_Hop", "Local_Pref",
"Originator_ID", "Community_List", "Ext_Community_List"]

bmp_keys = db.db.keys(db.db.STATE_DB, "BGP_RIB_OUT_TABLE|*")

click.echo("Total number of bmp bgp-rib-out-table: {}".format(0 if bmp_keys is None else len(bmp_keys)))

bmp_body = []
if bmp_keys is not None:
for key in bmp_keys:
key_values = key.split('|')
FengPan-Frank marked this conversation as resolved.
Show resolved Hide resolved
values = db.db.get_all(db.db.STATE_DB, key)
bmp_body.append([key_values[3], key_values[1], values["origin"], values["as_path"], values["origin_as"], values["next_hop"], values["local_pref"], values["originator_id"],
FengPan-Frank marked this conversation as resolved.
Show resolved Hide resolved
values["community_list"], values["ext_community_list"]])

click.echo(tabulate(bmp_body, bmp_headers))

# 'bgp-rib-in-table' subcommand ("show bmp bgp-rib-in-table")
@bmp.command('bgp-rib-in-table')
@clicommon.pass_db
def bmp_rib_in_table(db):
"""Show bmp bgp-rib-in-table information"""
bmp_headers = ["Neighbor_Address", "NLRI", "Origin", "AS_Path", "Origin_AS", "Next_Hop", "Local_Pref",
"Originator_ID", "Community_List", "Ext_Community_List"]

bmp_keys = db.db.keys(db.db.STATE_DB, "BGP_RIB_IN_TABLE|*")

click.echo("Total number of bmp bgp-rib-in-table: {}".format(0 if bmp_keys is None else len(bmp_keys)))

bmp_body = []
if bmp_keys is not None:
for key in bmp_keys:
key_values = key.split('|')
values = db.db.get_all(db.db.STATE_DB, key)
bmp_body.append([key_values[3], key_values[1], values["origin"], values["as_path"], values["origin_as"], values["next_hop"], values["local_pref"], values["originator_id"],
values["community_list"], values["ext_community_list"]])

click.echo(tabulate(bmp_body, bmp_headers))

# 'tables' subcommand ("show bmp tables")
@bmp.command('tables')
@clicommon.pass_db
def tables(db):
"""Show bmp table status information"""
bmp_headers = ["Table_Name", "Enabled"]
bmp_body = []
click.echo("BMP tables: ")
try:
bmp_keys = db.cfgdb.get_table('BMP')
if bmp_keys['table']:
bmp_body.append(['bgp_neighbor_table', bmp_keys['table']['bgp_neighbor_table']])
bmp_body.append(['bgp_rib_in_table', bmp_keys['table']['bgp_rib_in_table']])
bmp_body.append(['bgp_rib_out_table', bmp_keys['table']['bgp_rib_out_table']])
except KeyError:
FengPan-Frank marked this conversation as resolved.
Show resolved Hide resolved
bmp_keys['table'] = ''
click.echo(tabulate(bmp_body, bmp_headers))


#
# 'bfd' group ("show bfd ...")
Expand Down
177 changes: 177 additions & 0 deletions tests/show_bmp_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import os
import sys
from click.testing import CliRunner
import config.main as config
from swsscommon.swsscommon import SonicV2Connector
from utilities_common.db import Db

import show.main as show

test_path = os.path.dirname(os.path.abspath(__file__))
mock_db_path = os.path.join(test_path, "bmp_input")

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

def set_db_values(self, db, key, kvs):
for field, value in kvs.items():
db.set(db.STATE_DB, key, field, value)

def test_show_bmp_neighbor_table(self):
runner = CliRunner()
db = Db()
dbconnector = db.db
self.set_db_values(dbconnector, "BGP_NEIGHBOR_TABLE|10.0.1.1",
{
"peer_addr": "10.0.0.61",
"peer_asn" : "64915",
"peer_rd" : "300",
"peer_port" : "5000",
"local_addr" : "10.1.0.32",
"local_asn": "65100",
"local_port": "6000",
"sent_cap": "supports-mpbgp,supports-graceful-restart",
"recv_cap": "supports-mpbgp,supports-graceful-restart"
})
self.set_db_values(dbconnector, "BGP_NEIGHBOR_TABLE|10.0.1.2",
{
"peer_addr": "10.0.0.62",
"peer_asn" : "64915",
"peer_rd" : "300",
"peer_port" : "5000",
"local_addr" : "10.1.0.32",
"local_asn": "65100",
"local_port": "6000",
"sent_cap": "supports-mpbgp,supports-graceful-restart",
"recv_cap": "supports-mpbgp,supports-graceful-restart"
})

expected_output = """\
Total number of bmp neighbors: 2
Neighbor_Address Peer_Address Peer_ASN Peer_RD Peer_Port Local_Address Local_ASN Local_Port Advertised_Capabilities Received_Capabilities
------------------ -------------- ---------- --------- ----------- --------------- ----------- ------------ ---------------------------------------- ----------------------------------------
10.0.0.61 10.0.0.61 64915 300 5000 10.1.0.32 65100 6000 supports-mpbgp,supports-graceful-restart supports-mpbgp,supports-graceful-restart
10.0.0.62 10.0.0.62 64915 300 5000 10.1.0.32 65100 6000 supports-mpbgp,supports-graceful-restart supports-mpbgp,supports-graceful-restart
"""
result = runner.invoke(show.cli.commands['bmp'].commands['bgp-neighbor-table'], [], obj=db)
assert result.exit_code == 0
resultA = result.output.strip().replace(' ', '').replace('\n', '')
resultB = expected_output.strip().replace(' ', '').replace('\n', '')
assert resultA == resultB



def test_show_bmp_rib_out_table(self):
runner = CliRunner()
db = Db()
dbconnector = db.db
self.set_db_values(dbconnector, "BGP_RIB_OUT_TABLE|20c0:ef50::/64|BGP_NEIGHBOR|10.0.0.57",
{
"origin": "igp",
"as_path" : "65100 64600",
"origin_as" : "64915",
"next_hop" : "fc00::7e",
"local_pref" : "0",
"originator_id": "0",
"community_list": "residential",
"ext_community_list": "traffic_engineering"
})
self.set_db_values(dbconnector, "BGP_RIB_OUT_TABLE|192.181.168.0/25|BGP_NEIGHBOR|10.0.0.59",
{
"origin": "igp",
"as_path" : "65100 64600",
"origin_as" : "64915",
"next_hop" : "10.0.0.63",
"local_pref" : "0",
"originator_id": "0",
"community_list": "business",
"ext_community_list": "preferential_transit"
})

expected_output = """\
Total number of bmp bgp-rib-out-table: 2
Neighbor_Address NLRI Origin AS_Path Origin_AS Next_Hop Local_Pref Originator_ID Community_List Ext_Community_List
------------------ ---------------- -------- ----------- ----------- ---------- ------------ --------------- ---------------- --------------------
10.0.0.57 20c0:ef50::/64 igp 65100 64600 64915 fc00::7e 0 0 residential traffic_engineering
10.0.0.59 192.181.168.0/25 igp 65100 64600 64915 10.0.0.63 0 0 business preferential_transit
"""
result = runner.invoke(show.cli.commands['bmp'].commands['bgp-rib-out-table'], [], obj=db)
assert result.exit_code == 0
resultA = result.output.strip().replace(' ', '').replace('\n', '')
resultB = expected_output.strip().replace(' ', '').replace('\n', '')
assert resultA == resultB

def test_show_bmp_rib_in_table(self):
runner = CliRunner()
db = Db()
dbconnector = db.db
self.set_db_values(dbconnector, "BGP_RIB_IN_TABLE|20c0:ef50::/64|BGP_NEIGHBOR|10.0.0.57",
{
"origin": "igp",
"as_path" : "65100 64600",
"origin_as" : "64915",
"next_hop" : "fc00::7e",
"local_pref" : "0",
"originator_id": "0",
"community_list": "residential",
"ext_community_list": "traffic_engineering"
})
self.set_db_values(dbconnector, "BGP_RIB_IN_TABLE|192.181.168.0/25|BGP_NEIGHBOR|10.0.0.59",
{
"origin": "igp",
"as_path" : "65100 64600",
"origin_as" : "64915",
"next_hop" : "10.0.0.63",
"local_pref" : "0",
"originator_id": "0",
"community_list": "business",
"ext_community_list": "preferential_transit"
})

expected_output = """\
Total number of bmp bgp-rib-in-table: 2
Neighbor_Address NLRI Origin AS_Path Origin_AS Next_Hop Local_Pref Originator_ID Community_List Ext_Community_List
------------------ ---------------- -------- ----------- ----------- ---------- ------------ --------------- ---------------- --------------------
10.0.0.57 20c0:ef50::/64 igp 65100 64600 64915 fc00::7e 0 0 residential traffic_engineering
10.0.0.59 192.181.168.0/25 igp 65100 64600 64915 10.0.0.63 0 0 business preferential_transit
"""
result = runner.invoke(show.cli.commands['bmp'].commands['bgp-rib-in-table'], [], obj=db)
assert result.exit_code == 0
resultA = result.output.strip().replace(' ', '').replace('\n', '')
resultB = expected_output.strip().replace(' ', '').replace('\n', '')
assert resultA == resultB

def test_tables(self):
runner = CliRunner()
db = Db()
dbconnector = db.db
db.cfgdb.mod_entry("BMP", "table", {'bgp_neighbor_table' : 'true'})
db.cfgdb.mod_entry("BMP", "table", {'bgp_rib_in_table' : 'false'})
db.cfgdb.mod_entry("BMP", "table", {'bgp_rib_out_table' : 'true'})

assert db.cfgdb.get_entry('BMP' , 'table')['bgp_neighbor_table'] == 'true'
assert db.cfgdb.get_entry('BMP' , 'table')['bgp_rib_in_table'] == 'false'
assert db.cfgdb.get_entry('BMP' , 'table')['bgp_rib_out_table'] == 'true'

expected_output = """\
BMP tables:
Table_Name Enabled
------------------ ---------
bgp_neighbor_table true
bgp_rib_in_table false
bgp_rib_out_table true
"""
result = runner.invoke(show.cli.commands['bmp'].commands['tables'], [], obj=db)
assert result.exit_code == 0
resultA = result.output.strip().replace(' ', '').replace('\n', '')
resultB = expected_output.strip().replace(' ', '').replace('\n', '')
assert resultA == resultB

@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"
Loading