Skip to content

Commit 9700e45

Browse files
authored
[show/config]: combine feature and container feature cli (sonic-net#1015)
merge container feature cli into feature cli config command: ``` admin@vlab-01:~$ sudo config feature Usage: config feature [OPTIONS] COMMAND [ARGS]... Modify configuration of features Options: -?, -h, --help Show this message and exit. Commands: autorestart Configure autorestart status for a feature state Configure status of feature ``` show command: ``` admin@vlab-01:~$ show feature Usage: show feature [OPTIONS] COMMAND [ARGS]... Show feature status Options: -?, -h, --help Show this message and exit. Commands: autorestart Show auto-restart status for a feature status Show feature status ``` output: ``` admin@vlab-01:~$ show feature status Feature Status AutoRestart ---------- -------- ------------- lldp enabled enabled pmon enabled enabled sflow disabled enabled database enabled disabled restapi disabled enabled telemetry enabled enabled snmp enabled enabled bgp enabled enabled radv enabled enabled dhcp_relay enabled enabled nat enabled enabled teamd enabled enabled syncd enabled enabled swss enabled enabled admin@vlab-01:~$ show feature autorestart Feature AutoRestart ---------- ------------- lldp enabled pmon enabled sflow enabled database disabled restapi enabled telemetry enabled snmp enabled bgp enabled radv enabled dhcp_relay enabled nat enabled teamd enabled syncd enabled swss enabled ``` Signed-off-by: Guohan Lu <[email protected]>
1 parent c9d3550 commit 9700e45

File tree

4 files changed

+356
-120
lines changed

4 files changed

+356
-120
lines changed

config/main.py

+70-74
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@
4848
CFG_LOOPBACK_NAME_TOTAL_LEN_MAX = 11
4949
CFG_LOOPBACK_ID_MAX_VAL = 999
5050
CFG_LOOPBACK_NO="<0-999>"
51+
52+
asic_type = None
53+
config_db = None
54+
5155
# ========================== Syslog wrappers ==========================
5256

5357
def log_debug(msg):
@@ -112,17 +116,6 @@ def get_command(self, ctx, cmd_name):
112116

113117
ctx.fail('Too many matches: %s' % ', '.join(sorted(matches)))
114118

115-
116-
#
117-
# Load asic_type for further use
118-
#
119-
120-
try:
121-
version_info = sonic_device_util.get_sonic_version_info()
122-
asic_type = version_info['asic_type']
123-
except (KeyError, TypeError):
124-
raise click.Abort()
125-
126119
#
127120
# Load breakout config file for Dynamic Port Breakout
128121
#
@@ -552,7 +545,7 @@ def _is_neighbor_ipaddress(config_db, ipaddress):
552545

553546
def _get_all_neighbor_ipaddresses(config_db, ignore_local_hosts=False):
554547
"""Returns list of strings containing IP addresses of all BGP neighbors
555-
if the flag ignore_local_hosts is set to True, additional check to see if
548+
if the flag ignore_local_hosts is set to True, additional check to see if
556549
if the BGP neighbor AS number is same as local BGP AS number, if so ignore that neigbor.
557550
"""
558551
addrs = []
@@ -692,12 +685,12 @@ def _get_disabled_services_list():
692685
log_warning("Feature is None")
693686
continue
694687

695-
status = feature_table[feature_name]['status']
696-
if not status:
697-
log_warning("Status of feature '{}' is None".format(feature_name))
688+
state = feature_table[feature_name]['state']
689+
if not state:
690+
log_warning("Enable state of feature '{}' is None".format(feature_name))
698691
continue
699692

700-
if status == "disabled":
693+
if state == "disabled":
701694
disabled_services_list.append(feature_name)
702695
else:
703696
log_warning("Unable to retreive FEATURE table")
@@ -890,6 +883,19 @@ def validate_mirror_session_config(config_db, session_name, dst_port, src_port,
890883
@click.group(cls=AbbreviationGroup, context_settings=CONTEXT_SETTINGS)
891884
def config():
892885
"""SONiC command line - 'config' command"""
886+
#
887+
# Load asic_type for further use
888+
#
889+
global asic_type
890+
891+
try:
892+
version_info = sonic_device_util.get_sonic_version_info()
893+
asic_type = version_info['asic_type']
894+
except KeyError, TypeError:
895+
raise click.Abort()
896+
897+
if asic_type == 'mellanox':
898+
platform.add_command(mlnx.mlnx)
893899

894900
# Load the global config file database_global.json once.
895901
SonicDBConfig.load_sonic_global_db_config()
@@ -899,6 +905,10 @@ def config():
899905

900906
SonicDBConfig.load_sonic_global_db_config()
901907

908+
global config_db
909+
910+
config_db = ConfigDBConnector()
911+
config_db.connect()
902912

903913
config.add_command(aaa.aaa)
904914
config.add_command(aaa.tacacs)
@@ -1007,7 +1017,7 @@ def load(filename, yes):
10071017
# if any of the config files in linux host OR namespace is not present, return
10081018
if not os.path.isfile(file):
10091019
click.echo("The config_db file {} doesn't exist".format(file))
1010-
return
1020+
return
10111021

10121022
if namespace is None:
10131023
command = "{} -j {} --write-to-db".format(SONIC_CFGGEN_PATH, file)
@@ -1225,7 +1235,7 @@ def load_minigraph(no_service_restart):
12251235

12261236
if os.path.isfile('/etc/sonic/acl.json'):
12271237
run_command("acl-loader update full /etc/sonic/acl.json", display_cmd=True)
1228-
1238+
12291239
# Write latest db version string into db
12301240
db_migrator='/usr/bin/db_migrator.py'
12311241
if os.path.isfile(db_migrator) and os.access(db_migrator, os.X_OK):
@@ -1235,7 +1245,7 @@ def load_minigraph(no_service_restart):
12351245
else:
12361246
cfggen_namespace_option = " -n {}".format(namespace)
12371247
run_command(db_migrator + ' -o set_version' + cfggen_namespace_option)
1238-
1248+
12391249
# We first run "systemctl reset-failed" to remove the "failed"
12401250
# status from all services before we attempt to restart them
12411251
if not no_service_restart:
@@ -1891,7 +1901,7 @@ def add_snmp_agent_address(ctx, agentip, port, vrf):
18911901
#Construct SNMP_AGENT_ADDRESS_CONFIG table key in the format ip|<port>|<vrf>
18921902
key = agentip+'|'
18931903
if port:
1894-
key = key+port
1904+
key = key+port
18951905
key = key+'|'
18961906
if vrf:
18971907
key = key+vrf
@@ -1912,7 +1922,7 @@ def del_snmp_agent_address(ctx, agentip, port, vrf):
19121922

19131923
key = agentip+'|'
19141924
if port:
1915-
key = key+port
1925+
key = key+port
19161926
key = key+'|'
19171927
if vrf:
19181928
key = key+vrf
@@ -2174,7 +2184,7 @@ def all(verbose):
21742184
config_db = ConfigDBConnector(use_unix_socket_path=True, namespace=namespace)
21752185
config_db.connect()
21762186
bgp_neighbor_ip_list = _get_all_neighbor_ipaddresses(config_db, ignore_local_hosts)
2177-
for ipaddress in bgp_neighbor_ip_list:
2187+
for ipaddress in bgp_neighbor_ip_list:
21782188
_change_bgp_session_status_by_addr(config_db, ipaddress, 'up', verbose)
21792189

21802190
# 'neighbor' subcommand
@@ -2463,7 +2473,7 @@ def breakout(ctx, interface_name, mode, verbose, force_remove_dependencies, load
24632473
sys.exit(0)
24642474

24652475
def _get_all_mgmtinterface_keys():
2466-
"""Returns list of strings containing mgmt interface keys
2476+
"""Returns list of strings containing mgmt interface keys
24672477
"""
24682478
config_db = ConfigDBConnector()
24692479
config_db.connect()
@@ -3191,9 +3201,9 @@ def priority(ctx, interface_name, priority, status):
31913201
interface_name = interface_alias_to_name(interface_name)
31923202
if interface_name is None:
31933203
ctx.fail("'interface_name' is None!")
3194-
3204+
31953205
run_command("pfc config priority {0} {1} {2}".format(status, interface_name, priority))
3196-
3206+
31973207
#
31983208
# 'platform' group ('config platform ...')
31993209
#
@@ -3202,9 +3212,6 @@ def priority(ctx, interface_name, priority, status):
32023212
def platform():
32033213
"""Platform-related configuration tasks"""
32043214

3205-
if asic_type == 'mellanox':
3206-
platform.add_command(mlnx.mlnx)
3207-
32083215
# 'firmware' subgroup ("config platform firmware ...")
32093216
@platform.group(cls=AbbreviationGroup)
32103217
def firmware():
@@ -3292,10 +3299,10 @@ def naming_mode_alias():
32923299
def is_loopback_name_valid(loopback_name):
32933300
"""Loopback name validation
32943301
"""
3295-
3302+
32963303
if loopback_name[:CFG_LOOPBACK_PREFIX_LEN] != CFG_LOOPBACK_PREFIX :
32973304
return False
3298-
if (loopback_name[CFG_LOOPBACK_PREFIX_LEN:].isdigit() is False or
3305+
if (loopback_name[CFG_LOOPBACK_PREFIX_LEN:].isdigit() is False or
32993306
int(loopback_name[CFG_LOOPBACK_PREFIX_LEN:]) > CFG_LOOPBACK_ID_MAX_VAL) :
33003307
return False
33013308
if len(loopback_name) > CFG_LOOPBACK_NAME_TOTAL_LEN_MAX:
@@ -3462,7 +3469,7 @@ def add_ntp_server(ctx, ntp_ip_address):
34623469
if ntp_ip_address in ntp_servers:
34633470
click.echo("NTP server {} is already configured".format(ntp_ip_address))
34643471
return
3465-
else:
3472+
else:
34663473
db.set_entry('NTP_SERVER', ntp_ip_address, {'NULL': 'NULL'})
34673474
click.echo("NTP server {} added to configuration".format(ntp_ip_address))
34683475
try:
@@ -3483,7 +3490,7 @@ def del_ntp_server(ctx, ntp_ip_address):
34833490
if ntp_ip_address in ntp_servers:
34843491
db.set_entry('NTP_SERVER', '{}'.format(ntp_ip_address), None)
34853492
click.echo("NTP server {} removed from configuration".format(ntp_ip_address))
3486-
else:
3493+
else:
34873494
ctx.fail("NTP server {} is not configured.".format(ntp_ip_address))
34883495
try:
34893496
click.echo("Restarting ntp-config service...")
@@ -3770,58 +3777,47 @@ def delete(ctx):
37703777
config_db.set_entry('SFLOW', 'global', sflow_tbl['global'])
37713778

37723779
#
3773-
# 'feature' command ('config feature name state')
3774-
#
3775-
@config.command('feature')
3776-
@click.argument('name', metavar='<feature-name>', required=True)
3777-
@click.argument('state', metavar='<feature-state>', required=True, type=click.Choice(["enabled", "disabled"]))
3778-
def feature_status(name, state):
3779-
""" Configure status of feature"""
3780-
config_db = ConfigDBConnector()
3781-
config_db.connect()
3782-
status_data = config_db.get_entry('FEATURE', name)
3783-
3784-
if not status_data:
3785-
click.echo(" Feature '{}' doesn't exist".format(name))
3786-
return
3787-
3788-
config_db.mod_entry('FEATURE', name, {'status': state})
3789-
3790-
#
3791-
# 'container' group ('config container ...')
3780+
# 'feature' group ('config feature ...')
37923781
#
3793-
@config.group(cls=AbbreviationGroup, name='container', invoke_without_command=False)
3794-
def container():
3795-
"""Modify configuration of containers"""
3782+
@config.group(cls=AbbreviationGroup, name='feature', invoke_without_command=False)
3783+
def feature():
3784+
"""Modify configuration of features"""
37963785
pass
37973786

37983787
#
3799-
# 'feature' group ('config container feature ...')
3788+
# 'state' command ('config feature state ...')
38003789
#
3801-
@container.group(cls=AbbreviationGroup, name='feature', invoke_without_command=False)
3802-
def feature():
3803-
"""Modify configuration of container features"""
3804-
pass
3790+
@feature.command('state', short_help="Enable/disable a feature")
3791+
@click.argument('name', metavar='<feature-name>', required=True)
3792+
@click.argument('state', metavar='<state>', required=True, type=click.Choice(["enabled", "disabled"]))
3793+
def feature_state(name, state):
3794+
"""Enable/disable a feature"""
3795+
state_data = config_db.get_entry('FEATURE', name)
3796+
3797+
if not state_data:
3798+
click.echo("Feature '{}' doesn't exist".format(name))
3799+
sys.exit(1)
3800+
3801+
config_db.mod_entry('FEATURE', name, {'state': state})
38053802

38063803
#
3807-
# 'autorestart' subcommand ('config container feature autorestart ...')
3804+
# 'autorestart' command ('config feature autorestart ...')
38083805
#
3809-
@feature.command(name='autorestart', short_help="Configure the status of autorestart feature for specific container")
3810-
@click.argument('container_name', metavar='<container_name>', required=True)
3811-
@click.argument('autorestart_status', metavar='<autorestart_status>', required=True, type=click.Choice(["enabled", "disabled"]))
3812-
def autorestart(container_name, autorestart_status):
3813-
config_db = ConfigDBConnector()
3814-
config_db.connect()
3815-
container_feature_table = config_db.get_table('CONTAINER_FEATURE')
3816-
if not container_feature_table:
3817-
click.echo("Unable to retrieve container feature table from Config DB.")
3818-
return
3806+
@feature.command(name='autorestart', short_help="Enable/disable autosrestart of a feature")
3807+
@click.argument('name', metavar='<feature-name>', required=True)
3808+
@click.argument('autorestart', metavar='<autorestart>', required=True, type=click.Choice(["enabled", "disabled"]))
3809+
def feature_autorestart(name, autorestart):
3810+
"""Enable/disable autorestart of a feature"""
3811+
feature_table = config_db.get_table('FEATURE')
3812+
if not feature_table:
3813+
click.echo("Unable to retrieve feature table from Config DB.")
3814+
sys.exit(1)
38193815

3820-
if not container_feature_table.has_key(container_name):
3821-
click.echo("Unable to retrieve features for container '{}'".format(container_name))
3822-
return
3816+
if not feature_table.has_key(name):
3817+
click.echo("Unable to retrieve feature '{}'".format(name))
3818+
sys.exit(1)
38233819

3824-
config_db.mod_entry('CONTAINER_FEATURE', container_name, {'auto_restart': autorestart_status})
3820+
config_db.mod_entry('FEATURE', name, {'auto_restart': autorestart})
38253821

38263822
if __name__ == '__main__':
38273823
config()

0 commit comments

Comments
 (0)