From 0626de29052caeef6ba202926845b8279411d142 Mon Sep 17 00:00:00 2001 From: Sonic Build Admin Date: Fri, 17 Apr 2026 17:52:11 +0000 Subject: [PATCH] Show vnet route cli update on 202511 #### What I did It is a manually cherry-pick from https://github.com/sonic-net/sonic-utilities/pull/4332 Updating the show vnet cli: 1. showing new filed "metric" in show vnet route all/tunnel 2. added for specific vnet name on vnet show route all/local/tunnel commands #### How I did it 1. added metric field in show vnet route 2. changed show vnet show route all/tunnel, and added vnet show route local 3. updated command reference document 4. Added mock test cases and related unit tests #### How to verify it added unit tests and passed. image #### Previous command output (if the output of a command-line utility has changed) \>show vnet routes all ``` vnet name prefix nexthop interface --------------- ---------------- ------------------------------------- ------------------------------- test_v4_in_v4-0 160.162.191.1/32 100.100.4.1 Ethernet1 test_v4_in_v4-0 160.163.191.1/32 100.101.4.1, 100.101.4.2 Ethernet1, Ethernet2 test_v4_in_v4-0 160.164.191.1/32 100.102.4.1, 100.102.4.2, 100.102.4.3 Ethernet1, Ethernet2, Ethernet3 test_v4_in_v4-1 160.165.191.1/32 100.103.4.1, 100.103.4.2, 100.103.4.3 Ethernet1, Ethernet2, Ethernet3 vnet name prefix endpoint mac address vni status --------------- ------------------------ ------------------------------------------- ------------- ----- -------- Vnet_v6_in_v6-0 fddd:a156:a251::a6:1/128 fddd:a100:a251::a10:1,fddd:a101:a251::a10:1 active fddd:a102:a251::a10:1,fddd:a103:a251::a10:1 test_v4_in_v4-0 160.162.191.1/32 100.251.7.1 active test_v4_in_v4-0 160.163.191.1/32 100.251.7.1 active test_v4_in_v4-0 160.164.191.1/32 100.251.7.1 ``` \>show vnet routes tunnel ``` vnet name prefix endpoint mac address vni --------------- ------------------------ --------------------------------------------------------------------------------------- ------------- ----- Vnet_v6_in_v6-0 fddd:a156:a251::a6:1/128 fddd:a100:a251::a10:1,fddd:a101:a251::a10:1,fddd:a102:a251::a10:1,fddd:a103:a251::a10:1 test_v4_in_v4-0 160.162.191.1/32 100.251.7.1 test_v4_in_v4-0 160.163.191.1/32 100.251.7.1 test_v4_in_v4-0 160.164.191.1/32 100.251.7.1 ``` #### New command output (if the output of a command-line utility has changed) \>show vnet routes all ``` vnet name prefix nexthop interface --------------- ---------------- ------------------------------------- ------------------------------- test_v4_in_v4-0 160.162.191.1/32 100.100.4.1 Ethernet1 test_v4_in_v4-0 160.163.191.1/32 100.101.4.1, 100.101.4.2 Ethernet1, Ethernet2 test_v4_in_v4-0 160.164.191.1/32 100.102.4.1, 100.102.4.2, 100.102.4.3 Ethernet1, Ethernet2, Ethernet3 test_v4_in_v4-1 160.165.191.1/32 100.103.4.1, 100.103.4.2, 100.103.4.3 Ethernet1, Ethernet2, Ethernet3 vnet name prefix endpoint mac address vni metric status --------------- ------------------------ ------------------------------------------- ------------- ----- -------- -------- Vnet_v6_in_v6-0 fddd:a156:a251::a6:1/128 fddd:a100:a251::a10:1,fddd:a101:a251::a10:1 active fddd:a102:a251::a10:1,fddd:a103:a251::a10:1 test_v4_in_v4-0 160.162.191.1/32 100.251.7.1 active test_v4_in_v4-0 160.163.191.1/32 100.251.7.1 0 active test_v4_in_v4-0 160.164.191.1/32 100.251.7.1 ``` \>show vnet routes all test_v4_in_v4-0 ``` vnet name prefix nexthop interface --------------- ---------------- ------------------------------------- ------------------------------- test_v4_in_v4-0 160.162.191.1/32 100.100.4.1 Ethernet1 test_v4_in_v4-0 160.163.191.1/32 100.101.4.1, 100.101.4.2 Ethernet1, Ethernet2 test_v4_in_v4-0 160.164.191.1/32 100.102.4.1, 100.102.4.2, 100.102.4.3 Ethernet1, Ethernet2, Ethernet3 vnet name prefix endpoint mac address vni metric status --------------- ---------------- ----------- ------------- ----- -------- -------- test_v4_in_v4-0 160.162.191.1/32 100.251.7.1 active test_v4_in_v4-0 160.163.191.1/32 100.251.7.1 0 active test_v4_in_v4-0 160.164.191.1/32 100.251.7.1 ``` \> show vnet routes tunnel ``` vnet name prefix endpoint mac address vni metric status --------------- ------------------------ ------------------------------------------- ------------- ----- -------- -------- Vnet_v6_in_v6-0 fddd:a156:a251::a6:1/128 fddd:a100:a251::a10:1,fddd:a101:a251::a10:1 active fddd:a102:a251::a10:1,fddd:a103:a251::a10:1 test_v4_in_v4-0 160.162.191.1/32 100.251.7.1 active test_v4_in_v4-0 160.163.191.1/32 100.251.7.1 0 active test_v4_in_v4-0 160.164.191.1/32 100.251.7.1 ``` \>show vnet routes tunnel test_v4_in_v4-0 ``` vnet name prefix endpoint mac address vni metric status --------------- ---------------- ----------- ------------- ----- -------- -------- test_v4_in_v4-0 160.162.191.1/32 100.251.7.1 active test_v4_in_v4-0 160.163.191.1/32 100.251.7.1 0 active test_v4_in_v4-0 160.164.191.1/32 100.251.7.1 ``` \>show vnet routes local ``` vnet name prefix nexthop interface --------------- ---------------- ------------------------------------- ------------------------------- test_v4_in_v4-0 160.162.191.1/32 100.100.4.1 Ethernet1 test_v4_in_v4-0 160.163.191.1/32 100.101.4.1, 100.101.4.2 Ethernet1, Ethernet2 test_v4_in_v4-0 160.164.191.1/32 100.102.4.1, 100.102.4.2, 100.102.4.3 Ethernet1, Ethernet2, Ethernet3 test_v4_in_v4-1 160.165.191.1/32 100.103.4.1, 100.103.4.2, 100.103.4.3 Ethernet1, Ethernet2, Ethernet3 ``` \>show vnet routes local test_v4_in_v4-0 ``` vnet name prefix nexthop interface --------------- ---------------- ------------------------------------- ------------------------------- test_v4_in_v4-0 160.162.191.1/32 100.100.4.1 Ethernet1 test_v4_in_v4-0 160.163.191.1/32 100.101.4.1, 100.101.4.2 Ethernet1, Ethernet2 test_v4_in_v4-0 160.164.191.1/32 100.102.4.1, 100.102.4.2, 100.102.4.3 Ethernet1, Ethernet2, Ethernet3 ``` Signed-off-by: Sonic Build Admin --- show/vnet.py | 97 +++++++++++++---------- tests/mock_tables/appl_db.json | 19 ++++- tests/show_vnet_test.py | 135 ++++++++++++++++++++++++++++----- 3 files changed, 188 insertions(+), 63 deletions(-) diff --git a/show/vnet.py b/show/vnet.py index a76845b0c..10c451b67 100644 --- a/show/vnet.py +++ b/show/vnet.py @@ -441,7 +441,8 @@ def routes(): """Show vnet routes related information""" pass -def pretty_print(table, r, epval, mac_addr, vni, state): + +def pretty_print(table, r, epval, mac_addr, vni, metric, state): endpoints = epval.split(',') row_width = 3 max_len = 0 @@ -458,28 +459,61 @@ def pretty_print(table, r, epval, mac_addr, vni, state): if iter == 0: r.append(mac_addr) r.append(vni) + r.append(metric) r.append(state) else: - r.extend(["", "", ""]) + r.extend(["", "", "", ""]) iter += row_width table.append(r) r = ["",""] @routes.command() -def all(): +@click.argument('vnet_name', required=False) +def all(vnet_name): """Show all vnet routes""" + appl_db = SonicV2Connector() - appl_db.connect(appl_db.APPL_DB) state_db = SonicV2Connector() - state_db.connect(state_db.STATE_DB) - header = ['vnet name', 'prefix', 'nexthop', 'interface'] - # Fetching data from appl_db for VNET ROUTES + _show_local_helper(vnet_name=vnet_name, appl_db=appl_db) + click.echo() + _show_tunnel_helper(vnet_name=vnet_name, appl_db=appl_db, state_db=state_db) + + +@routes.command() +@click.argument('vnet_name', required=False) +def local(vnet_name): + """Show local vnet routes""" + + appl_db = SonicV2Connector() + + _show_local_helper(vnet_name=vnet_name, appl_db=appl_db) + + +@routes.command() +@click.argument('vnet_name', required=False) +def tunnel(vnet_name): + """Show vnet tunnel routes""" + + appl_db = SonicV2Connector() + state_db = SonicV2Connector() + + _show_tunnel_helper(vnet_name=vnet_name, appl_db=appl_db, state_db=state_db) + + +def _show_local_helper(vnet_name=None, appl_db=None): + route_header = ['vnet name', 'prefix', 'nexthop', 'interface'] + + appl_db.connect(appl_db.APPL_DB) + + # VNET routes + table = [] vnet_rt_keys = appl_db.keys(appl_db.APPL_DB, "VNET_ROUTE_TABLE:*") vnet_rt_keys = natsorted(vnet_rt_keys) if vnet_rt_keys else [] - table = [] for k in vnet_rt_keys: + if vnet_name and k.split(":")[1] != vnet_name: + continue r = [] r.extend(k.split(":", 2)[1:]) val = appl_db.get_all(appl_db.APPL_DB, k) @@ -487,21 +521,26 @@ def all(): r.append(val.get('ifname')) table.append(r) - click.echo(tabulate(table, header)) + click.echo(tabulate(table, route_header)) - click.echo() - header = ['vnet name', 'prefix', 'endpoint', 'mac address', 'vni', 'status'] +def _show_tunnel_helper(vnet_name=None, appl_db=None, state_db=None): + tunnel_header = ['vnet name', 'prefix', 'endpoint', 'mac address', 'vni', 'metric', 'status'] - # Fetching data from appl_db for VNET TUNNEL ROUTES + appl_db.connect(appl_db.APPL_DB) + state_db.connect(state_db.STATE_DB) + + # VNET tunnel routes + table = [] vnet_rt_keys = appl_db.keys(appl_db.APPL_DB, "VNET_ROUTE_TUNNEL_TABLE:*") vnet_rt_keys = natsorted(vnet_rt_keys) if vnet_rt_keys else [] - table = [] for k in vnet_rt_keys: + if vnet_name and k.split(":")[1] != vnet_name: + continue r = [] r.extend(k.split(":", 2)[1:]) - state_db_key = '|'.join(k.split(":",2)) + state_db_key = '|'.join(k.split(":", 2)) val = appl_db.get_all(appl_db.APPL_DB, k) val_state = state_db.get_all(state_db.STATE_DB, state_db_key) epval = val.get('endpoint') @@ -509,36 +548,12 @@ def all(): r.append(epval) r.append(val.get('mac_address')) r.append(val.get('vni')) + r.append(val.get('metric')) if val_state: r.append(val_state.get('state')) table.append(r) continue state = val_state.get('state') if val_state else "" - pretty_print(table, r, epval, val.get('mac_address'), val.get('vni'), state ) - - click.echo(tabulate(table, header)) - - -@routes.command() -def tunnel(): - """Show vnet tunnel routes""" - appl_db = SonicV2Connector() - appl_db.connect(appl_db.APPL_DB) - - header = ['vnet name', 'prefix', 'endpoint', 'mac address', 'vni'] - - # Fetching data from appl_db for VNET TUNNEL ROUTES - vnet_rt_keys = appl_db.keys(appl_db.APPL_DB, "VNET_ROUTE_TUNNEL_TABLE:*") - vnet_rt_keys = natsorted(vnet_rt_keys) if vnet_rt_keys else [] - - table = [] - for k in vnet_rt_keys: - r = [] - r.extend(k.split(":", 2)[1:]) - val = appl_db.get_all(appl_db.APPL_DB, k) - r.append(val.get('endpoint')) - r.append(val.get('mac_address')) - r.append(val.get('vni')) - table.append(r) + pretty_print(table, r, epval, val.get('mac_address'), val.get('vni'), val.get('metric'), state) - click.echo(tabulate(table, header)) + click.echo(tabulate(table, tunnel_header)) diff --git a/tests/mock_tables/appl_db.json b/tests/mock_tables/appl_db.json index 8ea338717..06a64ff9b 100644 --- a/tests/mock_tables/appl_db.json +++ b/tests/mock_tables/appl_db.json @@ -371,9 +371,26 @@ "TUNNEL_ROUTE_TABLE:10.3.1.1": { "alias": "Vlan1000" }, + "VNET_ROUTE_TABLE:test_v4_in_v4-0:160.162.191.1/32": { + "nexthop": "100.100.4.1", + "ifname": "Ethernet1" + }, + "VNET_ROUTE_TABLE:test_v4_in_v4-0:160.163.191.1/32": { + "nexthop": "100.101.4.1, 100.101.4.2", + "ifname": "Ethernet1, Ethernet2" + }, + "VNET_ROUTE_TABLE:test_v4_in_v4-0:160.164.191.1/32": { + "nexthop": "100.102.4.1, 100.102.4.2, 100.102.4.3", + "ifname": "Ethernet1, Ethernet2, Ethernet3" + }, + "VNET_ROUTE_TABLE:test_v4_in_v4-1:160.165.191.1/32": { + "nexthop": "100.103.4.1, 100.103.4.2, 100.103.4.3", + "ifname": "Ethernet1, Ethernet2, Ethernet3" + }, "VNET_ROUTE_TUNNEL_TABLE:test_v4_in_v4-0:160.163.191.1/32": { "endpoint":"100.251.7.1", - "endpoint_monitor":"100.251.7.1" + "endpoint_monitor":"100.251.7.1", + "metric": "0" }, "VNET_ROUTE_TUNNEL_TABLE:Vnet_v6_in_v6-0:fddd:a156:a251::a6:1/128": { "endpoint": "fddd:a100:a251::a10:1,fddd:a101:a251::a10:1,fddd:a102:a251::a10:1,fddd:a103:a251::a10:1", diff --git a/tests/show_vnet_test.py b/tests/show_vnet_test.py index eff75a583..ae8e5782b 100644 --- a/tests/show_vnet_test.py +++ b/tests/show_vnet_test.py @@ -1,3 +1,4 @@ +# flake8: noqa: E501 import os from click.testing import CliRunner from utilities_common.db import Db @@ -15,42 +16,43 @@ def test_Preety_print(self): row = ["Vnet_v6_in_v6-0", "fddd:a156:a251::a6:1/128"] mac_addr = "" vni = "" + metric = "0" state = "active" epval = "fddd:a100:a251::a10:1,fddd:a101:a251::a10:1" - vnet.pretty_print(table, row, epval, mac_addr, vni, state) - expected_output = [['Vnet_v6_in_v6-0', 'fddd:a156:a251::a6:1/128', 'fddd:a100:a251::a10:1,fddd:a101:a251::a10:1', '', '', 'active']] + vnet.pretty_print(table, row, epval, mac_addr, vni, metric, state) + expected_output = [['Vnet_v6_in_v6-0', 'fddd:a156:a251::a6:1/128', 'fddd:a100:a251::a10:1,fddd:a101:a251::a10:1', '', '', '0', 'active']] assert table == expected_output table =[] row = ["Vnet_v6_in_v6-0", "fddd:a156:a251::a6:1/128"] epval = "fddd:a100:a251::a10:1,fddd:a101:a251::a10:1,fddd:a100:a251::a11:1,fddd:a100:a251::a12:1,fddd:a100:a251::a13:1" - vnet.pretty_print(table, row, epval, mac_addr, vni, state) + vnet.pretty_print(table, row, epval, mac_addr, vni, metric, state) expected_output = [ - ['Vnet_v6_in_v6-0', 'fddd:a156:a251::a6:1/128', 'fddd:a100:a251::a10:1,fddd:a101:a251::a10:1', '', '', 'active'], - ['', '', 'fddd:a100:a251::a11:1,fddd:a100:a251::a12:1', '', '', ''], - ['', '', 'fddd:a100:a251::a13:1', '', '', ''] + ['Vnet_v6_in_v6-0', 'fddd:a156:a251::a6:1/128', 'fddd:a100:a251::a10:1,fddd:a101:a251::a10:1', '', '', '0', 'active'], + ['', '', 'fddd:a100:a251::a11:1,fddd:a100:a251::a12:1', '', '', '', ''], + ['', '', 'fddd:a100:a251::a13:1', '', '', '', ''] ] assert table == expected_output table =[] row = ["Vnet_v6_in_v6-0", "fddd:a156:a251::a6:1/128"] epval = "192.168.1.1,192.168.1.2,192.168.1.3,192.168.1.4,192.168.1.5,192.168.1.6,192.168.1.7,192.168.1.8,192.168.1.9,192.168.1.10,192.168.1.11,192.168.1.12,192.168.1.13,192.168.1.14,192.168.1.15" - vnet.pretty_print(table, row, epval, mac_addr, vni, state) + vnet.pretty_print(table, row, epval, mac_addr, vni, metric, state) expected_output =[ - ['Vnet_v6_in_v6-0', 'fddd:a156:a251::a6:1/128', '192.168.1.1,192.168.1.2,192.168.1.3', '', '', 'active'], - ['', '', '192.168.1.4,192.168.1.5,192.168.1.6', '', '', ''], - ['', '', '192.168.1.7,192.168.1.8,192.168.1.9', '', '', ''], - ['', '', '192.168.1.10,192.168.1.11,192.168.1.12', '', '', ''], - ['', '', '192.168.1.13,192.168.1.14,192.168.1.15', '', '', '']] + ['Vnet_v6_in_v6-0', 'fddd:a156:a251::a6:1/128', '192.168.1.1,192.168.1.2,192.168.1.3', '', '', '0', 'active'], + ['', '', '192.168.1.4,192.168.1.5,192.168.1.6', '', '', '', ''], + ['', '', '192.168.1.7,192.168.1.8,192.168.1.9', '', '', '', ''], + ['', '', '192.168.1.10,192.168.1.11,192.168.1.12', '', '', '', ''], + ['', '', '192.168.1.13,192.168.1.14,192.168.1.15', '', '', '', '']] assert table == expected_output table =[] row = ["Vnet_v6_in_v6-0", "fddd:a156:a251::a6:1/128"] epval = "192.168.1.1" - vnet.pretty_print(table, row, epval, mac_addr, vni, state) + vnet.pretty_print(table, row, epval, mac_addr, vni, metric, state) expected_output =[ - ['Vnet_v6_in_v6-0', 'fddd:a156:a251::a6:1/128', '192.168.1.1', '', '', 'active']] + ['Vnet_v6_in_v6-0', 'fddd:a156:a251::a6:1/128', '192.168.1.1', '', '', '0', 'active']] assert table == expected_output def test_show_vnet_routes_all_basic(self): @@ -60,16 +62,107 @@ def test_show_vnet_routes_all_basic(self): result = runner.invoke(show.cli.commands['vnet'].commands['routes'].commands['all'], [], obj=db) assert result.exit_code == 0 expected_output = """\ -vnet name prefix nexthop interface ------------ -------- --------- ----------- +vnet name prefix nexthop interface +--------------- ---------------- ------------------------------------- ------------------------------- +test_v4_in_v4-0 160.162.191.1/32 100.100.4.1 Ethernet1 +test_v4_in_v4-0 160.163.191.1/32 100.101.4.1, 100.101.4.2 Ethernet1, Ethernet2 +test_v4_in_v4-0 160.164.191.1/32 100.102.4.1, 100.102.4.2, 100.102.4.3 Ethernet1, Ethernet2, Ethernet3 +test_v4_in_v4-1 160.165.191.1/32 100.103.4.1, 100.103.4.2, 100.103.4.3 Ethernet1, Ethernet2, Ethernet3 -vnet name prefix endpoint mac address vni status ---------------- ------------------------ ------------------------------------------- ------------- ----- -------- -Vnet_v6_in_v6-0 fddd:a156:a251::a6:1/128 fddd:a100:a251::a10:1,fddd:a101:a251::a10:1 active +vnet name prefix endpoint mac address vni metric status +--------------- ------------------------ ------------------------------------------- ------------- ----- -------- -------- +Vnet_v6_in_v6-0 fddd:a156:a251::a6:1/128 fddd:a100:a251::a10:1,fddd:a101:a251::a10:1 active fddd:a102:a251::a10:1,fddd:a103:a251::a10:1 -test_v4_in_v4-0 160.162.191.1/32 100.251.7.1 active -test_v4_in_v4-0 160.163.191.1/32 100.251.7.1 active +test_v4_in_v4-0 160.162.191.1/32 100.251.7.1 active +test_v4_in_v4-0 160.163.191.1/32 100.251.7.1 0 active test_v4_in_v4-0 160.164.191.1/32 100.251.7.1 +""" + assert result.output == expected_output + + def test_show_vnet_routes_all_vnetname(self): + runner = CliRunner() + db = Db() + + result = runner.invoke(show.cli.commands['vnet'].commands['routes'].commands['all'], + ['test_v4_in_v4-0'], obj=db) + assert result.exit_code == 0 + expected_output = """\ +vnet name prefix nexthop interface +--------------- ---------------- ------------------------------------- ------------------------------- +test_v4_in_v4-0 160.162.191.1/32 100.100.4.1 Ethernet1 +test_v4_in_v4-0 160.163.191.1/32 100.101.4.1, 100.101.4.2 Ethernet1, Ethernet2 +test_v4_in_v4-0 160.164.191.1/32 100.102.4.1, 100.102.4.2, 100.102.4.3 Ethernet1, Ethernet2, Ethernet3 + +vnet name prefix endpoint mac address vni metric status +--------------- ---------------- ----------- ------------- ----- -------- -------- +test_v4_in_v4-0 160.162.191.1/32 100.251.7.1 active +test_v4_in_v4-0 160.163.191.1/32 100.251.7.1 0 active +test_v4_in_v4-0 160.164.191.1/32 100.251.7.1 +""" + assert result.output == expected_output + + def test_show_vnet_routes_tunnel_basic(self): + runner = CliRunner() + db = Db() + + result = runner.invoke(show.cli.commands['vnet'].commands['routes'].commands['tunnel'], [], obj=db) + assert result.exit_code == 0 + expected_output = """\ +vnet name prefix endpoint mac address vni metric status +--------------- ------------------------ ------------------------------------------- ------------- ----- -------- -------- +Vnet_v6_in_v6-0 fddd:a156:a251::a6:1/128 fddd:a100:a251::a10:1,fddd:a101:a251::a10:1 active + fddd:a102:a251::a10:1,fddd:a103:a251::a10:1 +test_v4_in_v4-0 160.162.191.1/32 100.251.7.1 active +test_v4_in_v4-0 160.163.191.1/32 100.251.7.1 0 active +test_v4_in_v4-0 160.164.191.1/32 100.251.7.1 +""" + assert result.output == expected_output + + def test_show_vnet_routes_tunnel_vnetname(self): + runner = CliRunner() + db = Db() + + result = runner.invoke(show.cli.commands['vnet'].commands['routes'].commands['tunnel'], + ['test_v4_in_v4-0'], obj=db) + assert result.exit_code == 0 + expected_output = """\ +vnet name prefix endpoint mac address vni metric status +--------------- ---------------- ----------- ------------- ----- -------- -------- +test_v4_in_v4-0 160.162.191.1/32 100.251.7.1 active +test_v4_in_v4-0 160.163.191.1/32 100.251.7.1 0 active +test_v4_in_v4-0 160.164.191.1/32 100.251.7.1 +""" + assert result.output == expected_output + + def test_show_vnet_routes_local_basic(self): + runner = CliRunner() + db = Db() + + result = runner.invoke(show.cli.commands['vnet'].commands['routes'].commands['local'], [], obj=db) + assert result.exit_code == 0 + expected_output = """\ +vnet name prefix nexthop interface +--------------- ---------------- ------------------------------------- ------------------------------- +test_v4_in_v4-0 160.162.191.1/32 100.100.4.1 Ethernet1 +test_v4_in_v4-0 160.163.191.1/32 100.101.4.1, 100.101.4.2 Ethernet1, Ethernet2 +test_v4_in_v4-0 160.164.191.1/32 100.102.4.1, 100.102.4.2, 100.102.4.3 Ethernet1, Ethernet2, Ethernet3 +test_v4_in_v4-1 160.165.191.1/32 100.103.4.1, 100.103.4.2, 100.103.4.3 Ethernet1, Ethernet2, Ethernet3 +""" + assert result.output == expected_output + + def test_show_vnet_routes_local_vnetname(self): + runner = CliRunner() + db = Db() + + result = runner.invoke(show.cli.commands['vnet'].commands['routes'].commands['local'], + ['test_v4_in_v4-0'], obj=db) + assert result.exit_code == 0 + expected_output = """\ +vnet name prefix nexthop interface +--------------- ---------------- ------------------------------------- ------------------------------- +test_v4_in_v4-0 160.162.191.1/32 100.100.4.1 Ethernet1 +test_v4_in_v4-0 160.163.191.1/32 100.101.4.1, 100.101.4.2 Ethernet1, Ethernet2 +test_v4_in_v4-0 160.164.191.1/32 100.102.4.1, 100.102.4.2, 100.102.4.3 Ethernet1, Ethernet2, Ethernet3 """ assert result.output == expected_output