Skip to content

Commit 9d74aa0

Browse files
paavaananjleveque
paavaanan
authored andcommitted
[config] Add support for accepting port alias in lieu of port name (sonic-net#260)
1 parent c217fe5 commit 9d74aa0

File tree

1 file changed

+149
-6
lines changed

1 file changed

+149
-6
lines changed

config/main.py

+149-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
import json
77
import subprocess
88
import netaddr
9+
import re
910
from swsssdk import ConfigDBConnector
11+
from natsort import natsorted
1012
from minigraph import parse_device_desc_xml
1113

1214
import aaa
@@ -18,6 +20,7 @@
1820
# Helper functions
1921
#
2022

23+
2124
def run_command(command, display_cmd=False, ignore_error=False):
2225
"""Run bash command and print output to stdout
2326
"""
@@ -33,6 +36,79 @@ def run_command(command, display_cmd=False, ignore_error=False):
3336
if proc.returncode != 0 and not ignore_error:
3437
sys.exit(proc.returncode)
3538

39+
40+
def interface_alias_to_name(interface_alias):
41+
"""Return default interface name if alias name is given as argument
42+
"""
43+
44+
cmd = 'sonic-cfggen -d --var-json "PORT"'
45+
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
46+
47+
port_dict = json.loads(p.stdout.read())
48+
49+
if interface_alias is not None:
50+
for port_name in natsorted(port_dict.keys()):
51+
if interface_alias == port_dict[port_name]['alias']:
52+
return port_name
53+
print "Invalid interface {}".format(interface_alias)
54+
55+
return None
56+
57+
58+
def interface_name_to_alias(interface_name):
59+
"""Return alias interface name if default name is given as argument
60+
"""
61+
62+
cmd = 'sonic-cfggen -d --var-json "PORT"'
63+
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
64+
65+
port_dict = json.loads(p.stdout.read())
66+
67+
if interface_name is not None:
68+
for port_name in natsorted(port_dict.keys()):
69+
if interface_name == port_name:
70+
return port_dict[port_name]['alias']
71+
print "Invalid interface {}".format(interface_alias)
72+
73+
return None
74+
75+
76+
def set_interface_mode(mode):
77+
"""Modify SONIC_CLI_IFACE_MODE env variable in user .bashrc
78+
"""
79+
user = os.getenv('SUDO_USER')
80+
bashrc_ifacemode_line = "SONIC_CLI_IFACE_MODE={}".format(mode)
81+
82+
if not user:
83+
user = os.getenv('USER')
84+
85+
if user != "root":
86+
bashrc = "/home/{}/.bashrc".format(user)
87+
else:
88+
raise click.Abort()
89+
90+
f = open(bashrc, 'r')
91+
filedata = f.read()
92+
f.close()
93+
94+
if "SONIC_CLI_IFACE_MODE" not in filedata:
95+
newdata = filedata + bashrc_ifacemode_line
96+
newdata += "\n"
97+
else:
98+
newdata = re.sub(r"SONIC_CLI_IFACE_MODE=\w+",
99+
bashrc_ifacemode_line, filedata)
100+
f = open(bashrc, 'w')
101+
f.write(newdata)
102+
f.close()
103+
print "Please logout and log back in for changes take effect."
104+
105+
106+
def get_interface_mode():
107+
mode = os.getenv('SONIC_CLI_IFACE_MODE')
108+
if mode is None:
109+
mode = "default"
110+
return mode
111+
36112
def _is_neighbor_ipaddress(ipaddress):
37113
"""Returns True if a neighbor has the IP address <ipaddress>, False if not
38114
"""
@@ -340,11 +416,13 @@ def del_vlan(ctx, vid):
340416
db.set_entry('VLAN_MEMBER', k, None)
341417
db.set_entry('VLAN', 'Vlan{}'.format(vid), None)
342418

419+
343420
@vlan.group('member')
344421
@click.pass_context
345422
def vlan_member(ctx):
346423
pass
347424

425+
348426
@vlan_member.command('add')
349427
@click.argument('vid', metavar='<vid>', required=True, type=int)
350428
@click.argument('interface_name', metavar='<interface_name>', required=True)
@@ -354,13 +432,27 @@ def add_vlan_member(ctx, vid, interface_name, untagged):
354432
db = ctx.obj['db']
355433
vlan_name = 'Vlan{}'.format(vid)
356434
vlan = db.get_entry('VLAN', vlan_name)
435+
436+
if get_interface_mode() == "alias":
437+
interface_name = interface_alias_to_name(interface_name)
438+
if interface_name is None:
439+
raise click.Abort()
440+
357441
if len(vlan) == 0:
358442
print "{} doesn't exist".format(vlan_name)
359-
raise click.Abort
443+
raise click.Abort()
360444
members = vlan.get('members', [])
361445
if interface_name in members:
362-
print "{} is already a member of {}".format(interface_name, vlan_name)
363-
raise click.Abort
446+
if get_interface_mode() == "alias":
447+
interface_name = interface_name_to_alias(interface_name)
448+
if interface_name is None:
449+
raise click.Abort()
450+
print "{} is already a member of {}".format(interface_name,
451+
vlan_name)
452+
else:
453+
print "{} is already a member of {}".format(interface_name,
454+
vlan_name)
455+
raise click.Abort()
364456
members.append(interface_name)
365457
vlan['members'] = members
366458
db.set_entry('VLAN', vlan_name, vlan)
@@ -375,13 +467,25 @@ def del_vlan_member(ctx, vid, interface_name):
375467
db = ctx.obj['db']
376468
vlan_name = 'Vlan{}'.format(vid)
377469
vlan = db.get_entry('VLAN', vlan_name)
470+
471+
if get_interface_mode() == "alias":
472+
interface_name = interface_alias_to_name(interface_name)
473+
if interface_name is None:
474+
raise click.Abort()
475+
378476
if len(vlan) == 0:
379477
print "{} doesn't exist".format(vlan_name)
380-
raise click.Abort
478+
raise click.Abort()
381479
members = vlan.get('members', [])
382480
if interface_name not in members:
383-
print "{} is not a member of {}".format(interface_name, vlan_name)
384-
raise click.Abort
481+
if get_interface_mode() == "alias":
482+
interface_name = interface_name_to_alias(interface_name)
483+
if interface_name is None:
484+
raise click.Abort()
485+
print "{} is not a member of {}".format(interface_name, vlan_name)
486+
else:
487+
print "{} is not a member of {}".format(interface_name, vlan_name)
488+
raise click.Abort()
385489
members.remove(interface_name)
386490
if len(members) == 0:
387491
del vlan['members']
@@ -466,6 +570,11 @@ def interface():
466570
@click.option('-v', '--verbose', is_flag=True, help="Enable verbose output")
467571
def shutdown(interface_name, verbose):
468572
"""Shut down interface"""
573+
if get_interface_mode() == "alias":
574+
interface_name = interface_alias_to_name(interface_name)
575+
if interface_name is None:
576+
raise click.Abort()
577+
469578
command = "ip link set {} down".format(interface_name)
470579
run_command(command, display_cmd=verbose)
471580

@@ -478,6 +587,12 @@ def shutdown(interface_name, verbose):
478587
@click.option('-v', '--verbose', is_flag=True, help="Enable verbose output")
479588
def startup(interface_name, verbose):
480589
"""Start up interface"""
590+
if get_interface_mode() == "alias":
591+
interface_name = interface_alias_to_name(interface_name)
592+
if interface_name is None:
593+
raise click.Abort()
594+
595+
481596
command = "ip link set {} up".format(interface_name)
482597
run_command(command, display_cmd=verbose)
483598

@@ -491,6 +606,11 @@ def startup(interface_name, verbose):
491606
@click.option('-v', '--verbose', is_flag=True, help="Enable verbose output")
492607
def speed(interface_name, interface_speed, verbose):
493608
"""Set interface speed"""
609+
if get_interface_mode() == "alias":
610+
interface_name = interface_alias_to_name(interface_name)
611+
if interface_name is None:
612+
raise click.Abort()
613+
494614
command = "portconfig -p {} -s {}".format(interface_name, interface_speed)
495615
if verbose: command += " -vv"
496616
run_command(command, display_cmd=verbose)
@@ -572,5 +692,28 @@ def platform():
572692
platform.add_command(mlnx.mlnx)
573693

574694

695+
#
696+
# 'interface_mode' group
697+
#
698+
699+
@cli.group()
700+
def interface_naming_mode():
701+
"""Modify interface naming mode for interacting with SONiC CLI"""
702+
pass
703+
704+
705+
@interface_naming_mode.command('default')
706+
def interface_mode_default():
707+
"""Set CLI interface naming mode to DEFAULT (SONiC port name)"""
708+
alias_mode = "default"
709+
set_interface_mode(alias_mode)
710+
711+
712+
@interface_naming_mode.command('alias')
713+
def interface_mode_alias():
714+
"""Set CLI interface naming mode to ALIAS (Vendor port alias)"""
715+
alias_mode = "alias"
716+
set_interface_mode(alias_mode)
717+
575718
if __name__ == '__main__':
576719
cli()

0 commit comments

Comments
 (0)