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

[Vxlan] : adding show vnet/vxlan cmds #880

Merged
merged 3 commits into from
Apr 23, 2020
Merged
Changes from 1 commit
Commits
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
283 changes: 283 additions & 0 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2916,5 +2916,288 @@ def autorestart(container_name):
body.append([name, container_feature_table[name]['auto_restart']])
click.echo(tabulate(body, header))

#
# 'vnet' command ("show vnet")
#
@cli.group(cls=AliasedGroup, default_if_no_args=False)
def vnet():
"""Show vnet related information"""
pass

@vnet.command()
@click.argument('vnet_name', required=True)
def name(vnet_name):
"""Show vnet name <vnet name> information"""
config_db = ConfigDBConnector()
config_db.connect()
header = ['vnet name', 'vxlan tunnel', 'vni', 'peer list']

# Fetching data from config_db for VNET
vnet_data = config_db.get_entry('VNET', vnet_name)

def tablelize(vnet_key, vnet_data):
table = []
if vnet_data:
r = []
r.append(vnet_key)
r.append(vnet_data.get('vxlan_tunnel'))
r.append(vnet_data.get('vni'))
r.append(vnet_data.get('peer_list'))
table.append(r)
return table

click.echo(tabulate(tablelize(vnet_name, vnet_data), header))

@vnet.command()
def brief():
"""Show vnet brief information"""
config_db = ConfigDBConnector()
config_db.connect()
header = ['vnet name', 'vxlan tunnel', 'vni', 'peer list']

# Fetching data from config_db for VNET
vnet_data = config_db.get_table('VNET')
vnet_keys = natsorted(vnet_data.keys())

def tablelize(vnet_keys, vnet_data):
table = []
for k in vnet_keys:
r = []
r.append(k)
r.append(vnet_data[k].get('vxlan_tunnel'))
r.append(vnet_data[k].get('vni'))
r.append(vnet_data[k].get('peer_list'))
table.append(r)
return table

click.echo(tabulate(tablelize(vnet_keys, vnet_data), header))

@vnet.command()
def interfaces():
"""Show vnet interfaces information"""
config_db = ConfigDBConnector()
config_db.connect()

header = ['vnet name', 'interfaces']

# Fetching data from config_db for interfaces
intfs_data = config_db.get_table("INTERFACE")
vlan_intfs_data = config_db.get_table("VLAN_INTERFACE")

vnet_intfs = {}
for k, v in intfs_data.items():
if 'vnet_name' in v:
vnet_name = v['vnet_name']
if vnet_name in vnet_intfs:
vnet_intfs[vnet_name].append(k)
else:
vnet_intfs[vnet_name] = [k]

for k, v in vlan_intfs_data.items():
if 'vnet_name' in v:
vnet_name = v['vnet_name']
if vnet_name in vnet_intfs:
vnet_intfs[vnet_name].append(k)
else:
vnet_intfs[vnet_name] = [k]

table = []
for k, v in vnet_intfs.items():
r = []
r.append(k)
r.append(",".join(natsorted(v)))
table.append(r)

click.echo(tabulate(table, header))

@vnet.command()
def neighbors():
"""Show vnet neighbors information"""
config_db = ConfigDBConnector()
config_db.connect()

header = ['<vnet_name>', 'neighbor', 'interfaces']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also provide themac addressif its available in the attribute?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added.

admin@ASW-7005:~$ show vnet neighbors 
Vnet_2000    neighbor     mac_address    interfaces
-----------  -----------  -------------  ------------
             11.11.11.11                 Ethernet1


Vnet_3000    neighbor     mac_address        interfaces
-----------  -----------  -----------------  ------------
             20.20.20.20  aa:bb:cc:dd:ee:ff  Vlan2000



# Fetching data from config_db for interfaces
intfs_data = config_db.get_table("INTERFACE")
vlan_intfs_data = config_db.get_table("VLAN_INTERFACE")

vnet_intfs = {}
for k, v in intfs_data.items():
if 'vnet_name' in v:
vnet_name = v['vnet_name']
if vnet_name in vnet_intfs:
vnet_intfs[vnet_name].append(k)
else:
vnet_intfs[vnet_name] = [k]

for k, v in vlan_intfs_data.items():
if 'vnet_name' in v:
vnet_name = v['vnet_name']
if vnet_name in vnet_intfs:
vnet_intfs[vnet_name].append(k)
else:
vnet_intfs[vnet_name] = [k]

appl_db = swsssdk.SonicV2Connector()
appl_db.connect(appl_db.APPL_DB)

# Fetching data from appl_db for neighbors
nbrs = appl_db.keys(appl_db.APPL_DB, "NEIGH_TABLE*")
nbrs_data = {}
for nbr in nbrs if nbrs else []:
tbl, intf, ip = nbr.split(":", 2)
if intf in nbrs_data:
nbrs_data[intf].append(ip)
else:
nbrs_data[intf] = [ip]

table = []
for k, v in vnet_intfs.items():
v = natsorted(v)
header[0] = k
table = []
for intf in v:
if intf in nbrs_data:
for ip in nbrs_data[intf]:
r = ["", ip, intf]
table.append(r)
click.echo(tabulate(table, header))
click.echo("\n")

@vnet.group()
def routes():
"""Show vnet routes related information"""
pass

@routes.command()
def all():
"""Show all vnet routes"""
appl_db = swsssdk.SonicV2Connector()
appl_db.connect(appl_db.APPL_DB)

header = ['vnet name', 'prefix', 'nexthop', 'interface']

# Fetching data from appl_db for VNET ROUTES
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:
r = []
r.extend(k.split(":", 2)[1:])
val = appl_db.get_all(appl_db.APPL_DB, k)
r.append(val.get('nexthop'))
r.append(val.get('ifname'))
table.append(r)

click.echo(tabulate(table, header))

click.echo("\n")

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)

click.echo(tabulate(table, header))

@routes.command()
def tunnel():
"""Show vnet tunnel routes"""
appl_db = swsssdk.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)

click.echo(tabulate(table, header))

#
# 'vxlan' command ("show vxlan")
#
@cli.group(cls=AliasedGroup, default_if_no_args=False)
def vxlan():
"""Show vxlan related information"""
pass

@vxlan.command()
@click.argument('vxlan_name', required=True)
def name(vxlan_name):
"""Show vxlan name <vxlan_name> information"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you intend to have the name in command? Its different from the description.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, the cmd is like : show vxlan name XXX, the description is not showing <>, correct it now.

config_db = ConfigDBConnector()
config_db.connect()
header = ['vxlan tunnel name', 'source ip', 'destination ip', 'tunnel map name', 'tunnel map mapping(vni -> vlan)']

# Fetching data from config_db for VXLAN TUNNEL
vxlan_data = config_db.get_entry('VXLAN_TUNNEL', vxlan_name)

table = []
if vxlan_data:
r = []
r.append(vxlan_name)
r.append(vxlan_data.get('src_ip'))
r.append(vxlan_data.get('dst_ip'))
vxlan_map_keys = config_db.keys(config_db.CONFIG_DB,
'VXLAN_TUNNEL_MAP{}{}{}*'.format(config_db.KEY_SEPARATOR, vxlan_name, config_db.KEY_SEPARATOR))
if vxlan_map_keys:
vxlan_map_mapping = config_db.get_all(config_db.CONFIG_DB, vxlan_map_keys[0])
r.append(vxlan_map_keys[0].split(config_db.KEY_SEPARATOR, 2)[2])
r.append("{} -> {}".format(vxlan_map_mapping.get('vni'), vxlan_map_mapping.get('vlan')))
table.append(r)

click.echo(tabulate(table, header))

@vxlan.command()
def tunnel():
"""Show vxlan tunnel information"""
config_db = ConfigDBConnector()
config_db.connect()
header = ['vxlan tunnel name', 'source ip', 'destination ip', 'tunnel map name', 'tunnel map mapping(vni -> vlan)']

# Fetching data from config_db for VXLAN TUNNEL
vxlan_data = config_db.get_table('VXLAN_TUNNEL')
vxlan_keys = natsorted(vxlan_data.keys())

table = []
for k in vxlan_keys:
r = []
r.append(k)
r.append(vxlan_data[k].get('src_ip'))
r.append(vxlan_data[k].get('dst_ip'))
vxlan_map_keys = config_db.keys(config_db.CONFIG_DB,
'VXLAN_TUNNEL_MAP{}{}{}*'.format(config_db.KEY_SEPARATOR,k, config_db.KEY_SEPARATOR))
if vxlan_map_keys:
vxlan_map_mapping = config_db.get_all(config_db.CONFIG_DB, vxlan_map_keys[0])
r.append(vxlan_map_keys[0].split(config_db.KEY_SEPARATOR, 2)[2])
r.append("{} -> {}".format(vxlan_map_mapping.get('vni'), vxlan_map_mapping.get('vlan')))
table.append(r)

click.echo(tabulate(table, header))

if __name__ == '__main__':
cli()