diff --git a/clear/main.py b/clear/main.py index 19c1b6073a..21c87d555b 100755 --- a/clear/main.py +++ b/clear/main.py @@ -492,10 +492,10 @@ def flowcnt_route(ctx, namespace): """Clear all route flow counters""" exit_if_route_flow_counter_not_support() if ctx.invoked_subcommand is None: - command = "flow_counters_stat -c -t route" + command = ['flow_counters_stat', '-c', '-t', 'route'] # None namespace means default namespace if namespace is not None: - command += " -n {}".format(namespace) + command += ['-n', str(namespace)] clicommon.run_command(command) @@ -506,12 +506,12 @@ def flowcnt_route(ctx, namespace): @click.argument('prefix-pattern', required=True) def pattern(prefix_pattern, vrf, namespace): """Clear route flow counters by pattern""" - command = "flow_counters_stat -c -t route --prefix_pattern {}".format(prefix_pattern) + command = ['flow_counters_stat', '-c', '-t', 'route', '--prefix_pattern', str(prefix_pattern)] if vrf: - command += ' --vrf {}'.format(vrf) + command += ['--vrf', str(vrf)] # None namespace means default namespace if namespace is not None: - command += " -n {}".format(namespace) + command += ['-n', str(namespace)] clicommon.run_command(command) @@ -522,12 +522,12 @@ def pattern(prefix_pattern, vrf, namespace): @click.argument('prefix', required=True) def route(prefix, vrf, namespace): """Clear route flow counters by prefix""" - command = "flow_counters_stat -c -t route --prefix {}".format(prefix) + command = ['flow_counters_stat', '-c', '-t', 'route', '--prefix', str(prefix)] if vrf: - command += ' --vrf {}'.format(vrf) + command += ['--vrf', str(vrf)] # None namespace means default namespace if namespace is not None: - command += " -n {}".format(namespace) + command += ['-n', str(namespace)] clicommon.run_command(command) diff --git a/config/main.py b/config/main.py index abef5397af..ecdd3ae986 100644 --- a/config/main.py +++ b/config/main.py @@ -23,6 +23,7 @@ from portconfig import get_child_ports from socket import AF_INET, AF_INET6 from sonic_py_common import device_info, multi_asic +from sonic_py_common.general import getstatusoutput_noshell from sonic_py_common.interface import get_interface_table_name, get_port_table_name, get_intf_longname from utilities_common import util_base from swsscommon import swsscommon @@ -635,10 +636,12 @@ def _remove_bgp_neighbor_config(config_db, neighbor_ip_or_hostname): def _change_hostname(hostname): current_hostname = os.uname()[1] if current_hostname != hostname: - clicommon.run_command('echo {} > /etc/hostname'.format(hostname), display_cmd=True) - clicommon.run_command('hostname -F /etc/hostname', display_cmd=True) - clicommon.run_command(r'sed -i "/\s{}$/d" /etc/hosts'.format(current_hostname), display_cmd=True) - clicommon.run_command('echo "127.0.0.1 {}" >> /etc/hosts'.format(hostname), display_cmd=True) + with open('/etc/hostname', 'w') as f: + f.write(str(hostname) + '\n') + clicommon.run_command(['hostname', '-F', '/etc/hostname'], display_cmd=True) + clicommon.run_command(['sed', '-i', r"/\s{}$/d".format(current_hostname), '/etc/hosts'], display_cmd=True) + with open('/etc/hosts', 'a') as f: + f.write("127.0.0.1 " + str(hostname) + '\n') def _clear_cbf(): CBF_TABLE_NAMES = [ @@ -858,45 +861,44 @@ def _stop_services(): try: subprocess.check_call(['sudo', 'monit', 'status'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) click.echo("Disabling container monitoring ...") - clicommon.run_command("sudo monit unmonitor container_checker") + clicommon.run_command(['sudo', 'monit', 'unmonitor', 'container_checker']) except subprocess.CalledProcessError as err: pass click.echo("Stopping SONiC target ...") - clicommon.run_command("sudo systemctl stop sonic.target --job-mode replace-irreversibly") + clicommon.run_command(['sudo', 'systemctl', 'stop', 'sonic.target', '--job-mode', 'replace-irreversibly']) def _get_sonic_services(): - out, _ = clicommon.run_command("systemctl list-dependencies --plain sonic.target | sed '1d'", return_cmd=True) - return (unit.strip() for unit in out.splitlines()) - + cmd = ['systemctl', 'list-dependencies', '--plain', 'sonic.target'] + out, _ = clicommon.run_command(cmd, return_cmd=True) + out = out.strip().split('\n')[1:] + return (unit.strip() for unit in out) def _reset_failed_services(): for service in _get_sonic_services(): - clicommon.run_command("systemctl reset-failed {}".format(service)) - + clicommon.run_command(['systemctl', 'reset-failed', str(service)]) def _restart_services(): click.echo("Restarting SONiC target ...") - clicommon.run_command("sudo systemctl restart sonic.target") + clicommon.run_command(['sudo', 'systemctl', 'restart', 'sonic.target']) try: subprocess.check_call(['sudo', 'monit', 'status'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) click.echo("Enabling container monitoring ...") - clicommon.run_command("sudo monit monitor container_checker") + clicommon.run_command(['sudo', 'monit', 'monitor', 'container_checker']) except subprocess.CalledProcessError as err: pass # Reload Monit configuration to pick up new hostname in case it changed click.echo("Reloading Monit configuration ...") - clicommon.run_command("sudo monit reload") - + clicommon.run_command(['sudo', 'monit', 'reload']) def _per_namespace_swss_ready(service_name): - out, _ = clicommon.run_command("systemctl show {} --property ActiveState --value".format(service_name), return_cmd=True) + out, _ = clicommon.run_command(['systemctl', 'show', str(service_name), '--property', 'ActiveState', '--value'], return_cmd=True) if out.strip() != "active": return False - out, _ = clicommon.run_command("systemctl show {} --property ActiveEnterTimestampMonotonic --value".format(service_name), return_cmd=True) + out, _ = clicommon.run_command(['systemctl', 'show', str(service_name), '--property', 'ActiveEnterTimestampMonotonic', '--value'], return_cmd=True) swss_up_time = float(out.strip())/1000000 now = time.monotonic() if (now - swss_up_time > 120): @@ -921,7 +923,7 @@ def _swss_ready(): return True def _is_system_starting(): - out, _ = clicommon.run_command("sudo systemctl is-system-running", return_cmd=True) + out, _ = clicommon.run_command(['sudo', 'systemctl', 'is-system-running'], return_cmd=True) return out.strip() == "starting" def interface_is_in_vlan(vlan_member_table, interface_name): @@ -1092,13 +1094,8 @@ def update_sonic_environment(): if os.path.isfile(SONIC_ENV_TEMPLATE_FILE) and os.path.isfile(SONIC_VERSION_YML_FILE): clicommon.run_command( - "{} -d -y {} -t {},{}".format( - SONIC_CFGGEN_PATH, - SONIC_VERSION_YML_FILE, - SONIC_ENV_TEMPLATE_FILE, - SONIC_ENV_FILE - ), - display_cmd=True + [SONIC_CFGGEN_PATH, '-d', '-y', SONIC_VERSION_YML_FILE, '-t', '{},{}'.format(SONIC_ENV_TEMPLATE_FILE, SONIC_ENV_FILE)], + display_cmd=True ) def remove_router_interface_ip_address(config_db, interface_name, ipaddress_to_remove): @@ -1247,7 +1244,7 @@ def save(filename): command = "{} -n {} -d --print-data > {}".format(SONIC_CFGGEN_PATH, namespace, file) log.log_info("'save' executing...") - clicommon.run_command(command, display_cmd=True) + clicommon.run_command(command, display_cmd=True, shell=True) config_db = sort_dict(read_json_file(file)) with open(file, 'w') as config_db_file: @@ -1307,9 +1304,9 @@ def load(filename, yes): return if namespace is None: - command = "{} -j {} --write-to-db".format(SONIC_CFGGEN_PATH, file) + command = [str(SONIC_CFGGEN_PATH), '-j', file, '--write-to-db'] else: - command = "{} -n {} -j {} --write-to-db".format(SONIC_CFGGEN_PATH, namespace, file) + command = [str(SONIC_CFGGEN_PATH), '-n', str(namespace), '-j', file, '--write-to-db'] log.log_info("'load' executing...") clicommon.run_command(command, display_cmd=True) @@ -1581,9 +1578,9 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, force, file_form if load_sysinfo: if namespace is None: - command = "{} -H -k {} --write-to-db".format(SONIC_CFGGEN_PATH, cfg_hwsku) + command = [str(SONIC_CFGGEN_PATH), '-H', '-k', str(cfg_hwsku), '--write-to-db'] else: - command = "{} -H -k {} -n {} --write-to-db".format(SONIC_CFGGEN_PATH, cfg_hwsku, namespace) + command = [str(SONIC_CFGGEN_PATH), '-H', '-k', str(cfg_hwsku), '-n', str(namespace), '--write-to-db'] clicommon.run_command(command, display_cmd=True) # For the database service running in linux host we use the file user gives as input @@ -1591,23 +1588,20 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, force, file_form # the default config_db.json format is used. - config_gen_opts = "" + config_gen_opts = [] if os.path.isfile(INIT_CFG_FILE): - config_gen_opts += " -j {} ".format(INIT_CFG_FILE) + config_gen_opts += ['-j', str(INIT_CFG_FILE)] if file_format == 'config_db': - config_gen_opts += ' -j {} '.format(file) + config_gen_opts += ['-j', str(file)] else: - config_gen_opts += ' -Y {} '.format(file) + config_gen_opts += ['-Y', str(file)] if namespace is not None: - config_gen_opts += " -n {} ".format(namespace) - + config_gen_opts += ['-n', str(namespace)] - command = "{sonic_cfggen} {options} --write-to-db".format( - sonic_cfggen=SONIC_CFGGEN_PATH, - options=config_gen_opts) + command = [SONIC_CFGGEN_PATH] + config_gen_opts + ['--write-to-db'] clicommon.run_command(command, display_cmd=True) client.set(config_db.INIT_INDICATOR, 1) @@ -1616,9 +1610,9 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, force, file_form db_migrator='/usr/local/bin/db_migrator.py' if os.path.isfile(db_migrator) and os.access(db_migrator, os.X_OK): if namespace is None: - command = "{} -o migrate".format(db_migrator) + command = [db_migrator, '-o', 'migrate'] else: - command = "{} -o migrate -n {}".format(db_migrator, namespace) + command = [db_migrator, '-o', 'migrate', '-n', str(namespace)] clicommon.run_command(command, display_cmd=True) # Re-generate the environment variable in case config_db.json was edited @@ -1638,7 +1632,7 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, force, file_form def load_mgmt_config(filename): """Reconfigure hostname and mgmt interface based on device description file.""" log.log_info("'load_mgmt_config' executing...") - command = "{} -M {} --write-to-db".format(SONIC_CFGGEN_PATH, filename) + command = [SONIC_CFGGEN_PATH, '-M', str(filename), '--write-to-db'] clicommon.run_command(command, display_cmd=True) #FIXME: After config DB daemon for hostname and mgmt interface is implemented, we'll no longer need to do manual configuration here config_data = parse_device_desc_xml(filename) @@ -1650,19 +1644,29 @@ def load_mgmt_config(filename): mgmt_conf = netaddr.IPNetwork(key[1]) gw_addr = config_data['MGMT_INTERFACE'][key]['gwaddr'] if mgmt_conf.version == 4: - command = "ifconfig eth0 {} netmask {}".format(str(mgmt_conf.ip), str(mgmt_conf.netmask)) + command = ['ifconfig', 'eth0', str(mgmt_conf.ip), 'netmask', str(mgmt_conf.netmask)] clicommon.run_command(command, display_cmd=True) else: - command = "ifconfig eth0 add {}".format(str(mgmt_conf)) + command = ['ifconfig', 'eth0', 'add', str(mgmt_conf)] # Ignore error for IPv6 configuration command due to it not allows config the same IP twice clicommon.run_command(command, display_cmd=True, ignore_error=True) - command = "ip{} route add default via {} dev eth0 table default".format(" -6" if mgmt_conf.version == 6 else "", gw_addr) + command = ['ip'] + (["-6"] if mgmt_conf.version == 6 else []) + ['route', 'add', 'default', 'via', str(gw_addr), 'dev', 'eth0', 'table', 'default'] clicommon.run_command(command, display_cmd=True, ignore_error=True) - command = "ip{} rule add from {} table default".format(" -6" if mgmt_conf.version == 6 else "", str(mgmt_conf.ip)) + command = ['ip'] + (["-6"] if mgmt_conf.version == 6 else []) + ['rule', 'add', 'from', str(mgmt_conf.ip), 'table', 'default'] clicommon.run_command(command, display_cmd=True, ignore_error=True) if len(config_data['MGMT_INTERFACE'].keys()) > 0: - command = "[ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid" - clicommon.run_command(command, display_cmd=True, ignore_error=True) + filepath = '/var/run/dhclient.eth0.pid' + if not os.path.isfile(filepath): + sys.exit('File {} does not exist'.format(filepath)) + + out0, rc0 = clicommon.run_command(['cat', filepath], display_cmd=True, return_cmd=True) + if rc0 != 0: + sys.exit('Exit: {}. Command: cat {} failed.'.format(rc0, filepath)) + + out1, rc1 = clicommon.run_command(['kill', str(out0).strip('\n')], return_cmd=True) + if rc1 != 0: + sys.exit('Exit: {}. Command: kill {} failed.'.format(rc1, out0)) + clicommon.run_command(['rm', '-f', filepath], display_cmd=True, return_cmd=True) click.echo("Please note loaded setting will be lost after system reboot. To preserve setting, run `config save`.") @config.command("load_minigraph") @@ -1694,19 +1698,19 @@ def load_minigraph(db, no_service_restart, traffic_shift_away, override_config, for namespace in namespace_list: if namespace is DEFAULT_NAMESPACE: config_db = ConfigDBConnector() - cfggen_namespace_option = " " + cfggen_namespace_option = [] ns_cmd_prefix = "" else: config_db = ConfigDBConnector(use_unix_socket_path=True, namespace=namespace) - cfggen_namespace_option = " -n {}".format(namespace) + cfggen_namespace_option = ['-n', str(namespace)] ns_cmd_prefix = "sudo ip netns exec {} ".format(namespace) config_db.connect() client = config_db.get_redis_client(config_db.CONFIG_DB) client.flushdb() if os.path.isfile('/etc/sonic/init_cfg.json'): - command = "{} -H -m -j /etc/sonic/init_cfg.json {} --write-to-db".format(SONIC_CFGGEN_PATH, cfggen_namespace_option) + command = [SONIC_CFGGEN_PATH, '-H', '-m', '-j', '/etc/sonic/init_cfg.json'] + cfggen_namespace_option + ['--write-to-db'] else: - command = "{} -H -m --write-to-db {}".format(SONIC_CFGGEN_PATH, cfggen_namespace_option) + command = [SONIC_CFGGEN_PATH, '-H', '-m', '--write-to-db'] + cfggen_namespace_option clicommon.run_command(command, display_cmd=True) client.set(config_db.INIT_INDICATOR, 1) @@ -1714,7 +1718,7 @@ def load_minigraph(db, no_service_restart, traffic_shift_away, override_config, update_sonic_environment() if os.path.isfile('/etc/sonic/acl.json'): - clicommon.run_command("acl-loader update full /etc/sonic/acl.json", display_cmd=True) + clicommon.run_command(['acl-loader', 'update', 'full', '/etc/sonic/acl.json'], display_cmd=True) # Load port_config.json try: @@ -1723,26 +1727,26 @@ def load_minigraph(db, no_service_restart, traffic_shift_away, override_config, click.secho("Failed to load port_config.json, Error: {}".format(str(e)), fg='magenta') # generate QoS and Buffer configs - clicommon.run_command("config qos reload --no-dynamic-buffer --no-delay", display_cmd=True) + clicommon.run_command(['config', 'qos', 'reload', '--no-dynamic-buffer', '--no-delay'], display_cmd=True) # get the device type device_type = _get_device_type() if device_type != 'MgmtToRRouter' and device_type != 'MgmtTsToR' and device_type != 'BmcMgmtToRRouter' and device_type != 'EPMS': - clicommon.run_command("pfcwd start_default", display_cmd=True) + clicommon.run_command(['pfcwd', 'start_default'], display_cmd=True) # Write latest db version string into db - db_migrator='/usr/local/bin/db_migrator.py' + db_migrator = '/usr/local/bin/db_migrator.py' if os.path.isfile(db_migrator) and os.access(db_migrator, os.X_OK): for namespace in namespace_list: if namespace is DEFAULT_NAMESPACE: - cfggen_namespace_option = " " + cfggen_namespace_option = [] else: - cfggen_namespace_option = " -n {}".format(namespace) - clicommon.run_command(db_migrator + ' -o set_version' + cfggen_namespace_option) + cfggen_namespace_option = ['-n', str(namespace)] + clicommon.run_command([db_migrator, '-o', 'set_version'] + cfggen_namespace_option) # Keep device isolated with TSA if traffic_shift_away: - clicommon.run_command("TSA", display_cmd=True) + clicommon.run_command(["TSA"], display_cmd=True) if override_config: log.log_warning("Golden configuration may override System Maintenance state. Please execute TSC to check the current System mode") click.secho("[WARNING] Golden configuration may override Traffic-shift-away state. Please execute TSC to check the current System mode") @@ -1811,16 +1815,15 @@ def load_port_config(config_db, port_config_path): if 'admin_status' in port_table[port_name]: if port_table[port_name]['admin_status'] == port_config[port_name]['admin_status']: continue - clicommon.run_command('config interface {} {}'.format( + clicommon.run_command(['config', 'interface', 'startup' if port_config[port_name]['admin_status'] == 'up' else 'shutdown', - port_name), display_cmd=True) + port_name], display_cmd=True) return def override_config_by(golden_config_path): # Override configDB with golden config - clicommon.run_command('config override-config-table {}'.format( - golden_config_path), display_cmd=True) + clicommon.run_command(['config', 'override-config-table', str(golden_config_path)], display_cmd=True) return @@ -2457,20 +2460,20 @@ def start(action, restoration_time, ports, detection_time, verbose): Example: config pfcwd start --action drop all 400 --restoration-time 400 """ - cmd = "pfcwd start" + cmd = ['pfcwd', 'start'] if action: - cmd += " --action {}".format(action) + cmd += ['--action', str(action)] if ports: ports = set(ports) - set(['ports', 'detection-time']) - cmd += " {}".format(' '.join(ports)) + cmd += list(ports) if detection_time: - cmd += " {}".format(detection_time) + cmd += [str(detection_time)] if restoration_time: - cmd += " --restoration-time {}".format(restoration_time) + cmd += ['--restoration-time', str(restoration_time)] clicommon.run_command(cmd, display_cmd=verbose) @@ -2479,7 +2482,7 @@ def start(action, restoration_time, ports, detection_time, verbose): def stop(verbose): """ Stop PFC watchdog """ - cmd = "pfcwd stop" + cmd = ['pfcwd', 'stop'] clicommon.run_command(cmd, display_cmd=verbose) @@ -2489,7 +2492,7 @@ def stop(verbose): def interval(poll_interval, verbose): """ Set PFC watchdog counter polling interval (ms) """ - cmd = "pfcwd interval {}".format(poll_interval) + cmd = ['pfcwd', 'interval', str(poll_interval)] clicommon.run_command(cmd, display_cmd=verbose) @@ -2499,7 +2502,7 @@ def interval(poll_interval, verbose): def counter_poll(counter_poll, verbose): """ Enable/disable counter polling """ - cmd = "pfcwd counter_poll {}".format(counter_poll) + cmd = ['pfcwd', 'counter_poll', str(counter_poll)] clicommon.run_command(cmd, display_cmd=verbose) @@ -2509,7 +2512,7 @@ def counter_poll(counter_poll, verbose): def big_red_switch(big_red_switch, verbose): """ Enable/disable BIG_RED_SWITCH mode """ - cmd = "pfcwd big_red_switch {}".format(big_red_switch) + cmd = ['pfcwd', 'big_red_switch', str(big_red_switch)] clicommon.run_command(cmd, display_cmd=verbose) @@ -2518,7 +2521,7 @@ def big_red_switch(big_red_switch, verbose): def start_default(verbose): """ Start PFC WD by default configurations """ - cmd = "pfcwd start_default" + cmd = ['pfcwd', 'start_default'] clicommon.run_command(cmd, display_cmd=verbose) @@ -2554,9 +2557,9 @@ def reload(ctx, dry_run, json_data): _, hwsku_path = device_info.get_paths_to_platform_and_hwsku_dirs() sonic_version_file = device_info.get_sonic_version_file() - from_db = "-d --write-to-db" + from_db = ['-d', '--write-to-db'] if dry_run: - from_db = "--additional-data \'{}\'".format(json_data) if json_data else "" + from_db = ['--additional-data'] + [str(json_data)] if json_data else [] namespace_list = [DEFAULT_NAMESPACE] if multi_asic.get_num_asics() > 1: @@ -2585,12 +2588,9 @@ def reload(ctx, dry_run, json_data): cbf_template_file = os.path.join(hwsku_path, asic_id_suffix, "cbf.json.j2") if os.path.isfile(cbf_template_file): - cmd_ns = "" if ns is DEFAULT_NAMESPACE else "-n {}".format(ns) + cmd_ns = [] if ns is DEFAULT_NAMESPACE else ['-n', str(ns)] fname = "{}{}".format(dry_run, asic_id_suffix) if dry_run else "config-db" - command = "{} {} {} -t {},{} -y {}".format( - SONIC_CFGGEN_PATH, cmd_ns, from_db, - cbf_template_file, fname, sonic_version_file - ) + command = [SONIC_CFGGEN_PATH] + cmd_ns + from_db + ['-t', '{},{}'.format(cbf_template_file, fname), '-y', str(sonic_version_file)] # Apply the configuration clicommon.run_command(command, display_cmd=True) @@ -2652,9 +2652,9 @@ def reload(ctx, no_dynamic_buffer, no_delay, dry_run, json_data, ports, verbose) _, hwsku_path = device_info.get_paths_to_platform_and_hwsku_dirs() sonic_version_file = device_info.get_sonic_version_file() - from_db = "-d --write-to-db" + from_db = ['-d', '--write-to-db'] if dry_run: - from_db = "--additional-data \'{}\'".format(json_data) if json_data else "" + from_db = ['--additional-data'] + [str(json_data)] if json_data else [] namespace_list = [DEFAULT_NAMESPACE] if multi_asic.get_num_asics() > 1: @@ -2697,12 +2697,9 @@ def reload(ctx, no_dynamic_buffer, no_delay, dry_run, json_data, ports, verbose) hwsku_path, asic_id_suffix, "qos.json.j2" ) if os.path.isfile(qos_template_file): - cmd_ns = "" if ns is DEFAULT_NAMESPACE else "-n {}".format(ns) + cmd_ns = [] if ns is DEFAULT_NAMESPACE else ['-n', str(ns)] fname = "{}{}".format(dry_run, asic_id_suffix) if dry_run else "config-db" - command = "{} {} {} -t {},{} -t {},{} -y {}".format( - SONIC_CFGGEN_PATH, cmd_ns, from_db, buffer_template_file, - fname, qos_template_file, fname, sonic_version_file - ) + command = [SONIC_CFGGEN_PATH] + cmd_ns + from_db + ['-t', '{},{}'.format(buffer_template_file, fname), '-t', '{},{}'.format(qos_template_file, fname), '-y', sonic_version_file] # Apply the configurations only when both buffer and qos # configuration files are present clicommon.run_command(command, display_cmd=True) @@ -2743,9 +2740,9 @@ def _qos_update_ports(ctx, ports, dry_run, json_data): 'BUFFER_QUEUE'] if json_data: - from_db = "--additional-data \'{}\'".format(json_data) if json_data else "" + from_db = ['--additional-data'] + [json_data] if json_data else [] else: - from_db = "-d" + from_db = ["-d"] items_to_update = {} config_dbs = {} @@ -2789,10 +2786,8 @@ def _qos_update_ports(ctx, ports, dry_run, json_data): continue config_db.set_entry(table_name, '|'.join(key), None) - cmd_ns = "" if ns is DEFAULT_NAMESPACE else "-n {}".format(ns) - command = "{} {} {} -t {},config-db -t {},config-db -y {} --print-data".format( - SONIC_CFGGEN_PATH, cmd_ns, from_db, buffer_template_file, qos_template_file, sonic_version_file - ) + cmd_ns = [] if ns is DEFAULT_NAMESPACE else ['-n', str(ns)] + command = [SONIC_CFGGEN_PATH] + cmd_ns + from_db + ['-t', '{},config-db'.format(buffer_template_file), '-t', '{},config-db'.format(qos_template_file), '-y', sonic_version_file, '--print-data'] jsonstr, _ = clicommon.run_command(command, display_cmd=False, return_cmd=True) jsondict = json.loads(jsonstr) @@ -2870,8 +2865,8 @@ def _qos_update_ports(ctx, ports, dry_run, json_data): json.dump(items_to_apply, f, sort_keys=True, indent=4) else: jsonstr = json.dumps(items_to_apply) - cmd_ns = "" if ns is DEFAULT_NAMESPACE else "-n {}".format(ns) - command = "{} {} --additional-data '{}' --write-to-db".format(SONIC_CFGGEN_PATH, cmd_ns, jsonstr) + cmd_ns = [] if ns is DEFAULT_NAMESPACE else ['-n', str(ns)] + command = [SONIC_CFGGEN_PATH] + cmd_ns + ['--additional-data', jsonstr, '--write-to-db'] clicommon.run_command(command, display_cmd=False) if portset_to_handle != portset_handled: @@ -3277,8 +3272,8 @@ def add_community(db, community, string_type): try: click.echo("Restarting SNMP service...") - clicommon.run_command("systemctl reset-failed snmp.service", display_cmd=False) - clicommon.run_command("systemctl restart snmp.service", display_cmd=False) + clicommon.run_command(['systemctl', 'reset-failed', 'snmp.service'], display_cmd=False) + clicommon.run_command(['systemctl', 'restart', 'snmp.service'], display_cmd=False) except SystemExit as e: click.echo("Restart service snmp failed with error {}".format(e)) raise click.Abort() @@ -3305,8 +3300,8 @@ def del_community(db, community): try: click.echo("Restarting SNMP service...") - clicommon.run_command("systemctl reset-failed snmp.service", display_cmd=False) - clicommon.run_command("systemctl restart snmp.service", display_cmd=False) + clicommon.run_command(['systemctl', 'reset-failed', 'snmp.service'], display_cmd=False) + clicommon.run_command(['systemctl', 'restart', 'snmp.service'], display_cmd=False) except SystemExit as e: click.echo("Restart service snmp failed with error {}".format(e)) raise click.Abort() @@ -3336,8 +3331,8 @@ def replace_community(db, current_community, new_community): click.echo('SNMP community {} replace community {}'.format(new_community, current_community)) try: click.echo("Restarting SNMP service...") - clicommon.run_command("systemctl reset-failed snmp.service", display_cmd=False) - clicommon.run_command("systemctl restart snmp.service", display_cmd=False) + clicommon.run_command(['systemctl', 'reset-failed', 'snmp.service'], display_cmd=False) + clicommon.run_command(['systemctl', 'restart', 'snmp.service'], display_cmd=False) except SystemExit as e: click.echo("Restart service snmp failed with error {}".format(e)) raise click.Abort() @@ -3370,8 +3365,8 @@ def add_contact(db, contact, contact_email): "configuration".format(contact, contact_email)) try: click.echo("Restarting SNMP service...") - clicommon.run_command("systemctl reset-failed snmp.service", display_cmd=False) - clicommon.run_command("systemctl restart snmp.service", display_cmd=False) + clicommon.run_command(['systemctl', 'reset-failed', 'snmp.service'], display_cmd=False) + clicommon.run_command(['systemctl', 'restart', 'snmp.service'], display_cmd=False) except SystemExit as e: click.echo("Restart service snmp failed with error {}".format(e)) raise click.Abort() @@ -3385,8 +3380,8 @@ def add_contact(db, contact, contact_email): "configuration".format(contact, contact_email)) try: click.echo("Restarting SNMP service...") - clicommon.run_command("systemctl reset-failed snmp.service", display_cmd=False) - clicommon.run_command("systemctl restart snmp.service", display_cmd=False) + clicommon.run_command(['systemctl', 'reset-failed', 'snmp.service'], display_cmd=False) + clicommon.run_command(['systemctl', 'restart', 'snmp.service'], display_cmd=False) except SystemExit as e: click.echo("Restart service snmp failed with error {}".format(e)) raise click.Abort() @@ -3407,8 +3402,8 @@ def del_contact(db, contact): click.echo("SNMP contact {} removed from configuration".format(contact)) try: click.echo("Restarting SNMP service...") - clicommon.run_command("systemctl reset-failed snmp.service", display_cmd=False) - clicommon.run_command("systemctl restart snmp.service", display_cmd=False) + clicommon.run_command(['systemctl', 'reset-failed', 'snmp.service'], display_cmd=False) + clicommon.run_command(['systemctl', 'restart', 'snmp.service'], display_cmd=False) except SystemExit as e: click.echo("Restart service snmp failed with error {}".format(e)) raise click.Abort() @@ -3442,8 +3437,8 @@ def modify_contact(db, contact, contact_email): click.echo("SNMP contact {} email updated to {}".format(contact, contact_email)) try: click.echo("Restarting SNMP service...") - clicommon.run_command("systemctl reset-failed snmp.service", display_cmd=False) - clicommon.run_command("systemctl restart snmp.service", display_cmd=False) + clicommon.run_command(['systemctl', 'reset-failed', 'snmp.service'], display_cmd=False) + clicommon.run_command(['systemctl', 'restart', 'snmp.service'], display_cmd=False) except SystemExit as e: click.echo("Restart service snmp failed with error {}".format(e)) raise click.Abort() @@ -3456,8 +3451,8 @@ def modify_contact(db, contact, contact_email): click.echo("SNMP contact {} and contact email {} updated".format(contact, contact_email)) try: click.echo("Restarting SNMP service...") - clicommon.run_command("systemctl reset-failed snmp.service", display_cmd=False) - clicommon.run_command("systemctl restart snmp.service", display_cmd=False) + clicommon.run_command(['systemctl', 'reset-failed', 'snmp.service'], display_cmd=False) + clicommon.run_command(['systemctl', 'restart', 'snmp.service'], display_cmd=False) except SystemExit as e: click.echo("Restart service snmp failed with error {}".format(e)) raise click.Abort() @@ -3498,8 +3493,8 @@ def add_location(db, location): ctx.fail("Failed to set SNMP location. Error: {}".format(e)) try: click.echo("Restarting SNMP service...") - clicommon.run_command("systemctl reset-failed snmp.service", display_cmd=False) - clicommon.run_command("systemctl restart snmp.service", display_cmd=False) + clicommon.run_command(['systemctl', 'reset-failed', 'snmp.service'], display_cmd=False) + clicommon.run_command(['systemctl', 'restart', 'snmp.service'], display_cmd=False) except SystemExit as e: click.echo("Restart service snmp failed with error {}".format(e)) raise click.Abort() @@ -3526,8 +3521,8 @@ def delete_location(db, location): ctx.fail("Failed to remove SNMP location from configuration. Error: {}".format(e)) try: click.echo("Restarting SNMP service...") - clicommon.run_command("systemctl reset-failed snmp.service", display_cmd=False) - clicommon.run_command("systemctl restart snmp.service", display_cmd=False) + clicommon.run_command(['systemctl', 'reset-failed', 'snmp.service'], display_cmd=False) + clicommon.run_command(['systemctl', 'restart', 'snmp.service'], display_cmd=False) except SystemExit as e: click.echo("Restart service snmp failed with error {}".format(e)) raise click.Abort() @@ -3565,8 +3560,8 @@ def modify_location(db, location): ctx.fail("Failed to modify SNMP location. Error: {}".format(e)) try: click.echo("Restarting SNMP service...") - clicommon.run_command("systemctl reset-failed snmp.service", display_cmd=False) - clicommon.run_command("systemctl restart snmp.service", display_cmd=False) + clicommon.run_command(['systemctl', 'reset-failed', 'snmp.service'], display_cmd=False) + clicommon.run_command(['systemctl', 'restart', 'snmp.service'], display_cmd=False) except SystemExit as e: click.echo("Restart service snmp failed with error {}".format(e)) raise click.Abort() @@ -3679,8 +3674,8 @@ def add_user(db, user, user_type, user_permission_type, user_auth_type, user_aut click.echo("SNMP user {} added to configuration".format(user)) try: click.echo("Restarting SNMP service...") - clicommon.run_command("systemctl reset-failed snmp.service", display_cmd=False) - clicommon.run_command("systemctl restart snmp.service", display_cmd=False) + clicommon.run_command(['systemctl', 'reset-failed', 'snmp.service'], display_cmd=False) + clicommon.run_command(['systemctl', 'restart', 'snmp.service'], display_cmd=False) except SystemExit as e: click.echo("Restart service snmp failed with error {}".format(e)) raise click.Abort() @@ -3700,8 +3695,8 @@ def del_user(db, user): click.echo("SNMP user {} removed from configuration".format(user)) try: click.echo("Restarting SNMP service...") - clicommon.run_command("systemctl reset-failed snmp.service", display_cmd=False) - clicommon.run_command("systemctl restart snmp.service", display_cmd=False) + clicommon.run_command(['systemctl', 'reset-failed', 'snmp.service'], display_cmd=False) + clicommon.run_command(['systemctl', 'restart', 'snmp.service'], display_cmd=False) except SystemExit as e: click.echo("Restart service snmp failed with error {}".format(e)) raise click.Abort() @@ -3981,12 +3976,12 @@ def speed(ctx, interface_name, interface_speed, verbose): log.log_info("'interface speed {} {}' executing...".format(interface_name, interface_speed)) if ctx.obj['namespace'] is DEFAULT_NAMESPACE: - command = "portconfig -p {} -s {}".format(interface_name, interface_speed) + command = ['portconfig', '-p', str(interface_name), '-s', str(interface_speed)] else: - command = "portconfig -p {} -s {} -n {}".format(interface_name, interface_speed, ctx.obj['namespace']) + command = ['portconfig', '-p', str(interface_name), '-s', str(interface_speed), '-n', str(ctx.obj['namespace'])] if verbose: - command += " -vv" + command += ["-vv"] clicommon.run_command(command, display_cmd=verbose) # @@ -4011,12 +4006,12 @@ def link_training(ctx, interface_name, mode, verbose): log.log_info("'interface link-training {} {}' executing...".format(interface_name, mode)) if ctx.obj['namespace'] is DEFAULT_NAMESPACE: - command = "portconfig -p {} -lt {}".format(interface_name, mode) + command = ['portconfig', '-p', str(interface_name), '-lt', str(mode)] else: - command = "portconfig -p {} -lt {} -n {}".format(interface_name, mode, ctx.obj['namespace']) + command = ['portconfig', '-p', str(interface_name), '-lt', str(mode), '-n', str(ctx.obj['namespace'])] if verbose: - command += " -vv" + command += ["-vv"] clicommon.run_command(command, display_cmd=verbose) # @@ -4041,12 +4036,12 @@ def autoneg(ctx, interface_name, mode, verbose): log.log_info("'interface autoneg {} {}' executing...".format(interface_name, mode)) if ctx.obj['namespace'] is DEFAULT_NAMESPACE: - command = "portconfig -p {} -an {}".format(interface_name, mode) + command = ['portconfig', '-p', str(interface_name), '-an', str(mode)] else: - command = "portconfig -p {} -an {} -n {}".format(interface_name, mode, ctx.obj['namespace']) + command = ['portconfig', '-p', str(interface_name), '-an', str(mode), '-n', str(ctx.obj['namespace'])] if verbose: - command += " -vv" + command += ["-vv"] clicommon.run_command(command, display_cmd=verbose) # @@ -4071,12 +4066,12 @@ def advertised_speeds(ctx, interface_name, speed_list, verbose): log.log_info("'interface advertised_speeds {} {}' executing...".format(interface_name, speed_list)) if ctx.obj['namespace'] is DEFAULT_NAMESPACE: - command = "portconfig -p {} -S {}".format(interface_name, speed_list) + command = ['portconfig', '-p', str(interface_name), '-S', str(speed_list)] else: - command = "portconfig -p {} -S {} -n {}".format(interface_name, speed_list, ctx.obj['namespace']) + command = ['portconfig', '-p', str(interface_name), '-S', str(speed_list), '-n', ctx.obj['namespace']] if verbose: - command += " -vv" + command += ["-vv"] clicommon.run_command(command, display_cmd=verbose) # @@ -4101,12 +4096,12 @@ def interface_type(ctx, interface_name, interface_type_value, verbose): log.log_info("'interface interface_type {} {}' executing...".format(interface_name, interface_type_value)) if ctx.obj['namespace'] is DEFAULT_NAMESPACE: - command = "portconfig -p {} -t {}".format(interface_name, interface_type_value) + command = ['portconfig', '-p', str(interface_name), '-t', str(interface_type_value)] else: - command = "portconfig -p {} -t {} -n {}".format(interface_name, interface_type_value, ctx.obj['namespace']) + command = ['portconfig', '-p', str(interface_name), '-t', str(interface_type_value), '-n', str(ctx.obj['namespace'])] if verbose: - command += " -vv" + command += ["-vv"] clicommon.run_command(command, display_cmd=verbose) # @@ -4131,12 +4126,12 @@ def advertised_types(ctx, interface_name, interface_type_list, verbose): log.log_info("'interface advertised_interface_types {} {}' executing...".format(interface_name, interface_type_list)) if ctx.obj['namespace'] is DEFAULT_NAMESPACE: - command = "portconfig -p {} -T {}".format(interface_name, interface_type_list) + command = ['portconfig', '-p', str(interface_name), '-T', str(interface_type_list)] else: - command = "portconfig -p {} -T {} -n {}".format(interface_name, interface_type_list, ctx.obj['namespace']) + command = ['portconfig', '-p', str(interface_name), '-T', str(interface_type_list), '-n', str(ctx.obj['namespace'])] if verbose: - command += " -vv" + command += ["-vv"] clicommon.run_command(command, display_cmd=verbose) # @@ -4283,12 +4278,12 @@ def mtu(ctx, interface_name, interface_mtu, verbose): ctx.fail("'interface_name' is in portchannel!") if ctx.obj['namespace'] is DEFAULT_NAMESPACE: - command = "portconfig -p {} -m {}".format(interface_name, interface_mtu) + command = ['portconfig', '-p', str(interface_name), '-m', str(interface_mtu)] else: - command = "portconfig -p {} -m {} -n {}".format(interface_name, interface_mtu, ctx.obj['namespace']) + command = ['portconfig', '-p', str(interface_name), '-m', str(interface_mtu), '-n', str(ctx.obj['namespace'])] if verbose: - command += " -vv" + command += ["-vv"] clicommon.run_command(command, display_cmd=verbose) # @@ -4310,12 +4305,12 @@ def tpid(ctx, interface_name, interface_tpid, verbose): ctx.fail("'interface_name' is None!") if ctx.obj['namespace'] is DEFAULT_NAMESPACE: - command = "portconfig -p {} -tp {}".format(interface_name, interface_tpid) + command = ['portconfig', '-p', str(interface_name), '-tp', str(interface_tpid)] else: - command = "portconfig -p {} -tp {} -n {}".format(interface_name, interface_tpid, ctx.obj['namespace']) + command = ['portconfig', '-p', str(interface_name), '-tp', str(interface_tpid), '-n', str(ctx.obj['namespace'])] if verbose: - command += " -vv" + command += ["-vv"] clicommon.run_command(command, display_cmd=verbose) @@ -4335,12 +4330,12 @@ def fec(ctx, interface_name, interface_fec, verbose): ctx.fail("'interface_name' is None!") if ctx.obj['namespace'] is DEFAULT_NAMESPACE: - command = "portconfig -p {} -f {}".format(interface_name, interface_fec) + command = ['portconfig', '-p', str(interface_name), '-f', str(interface_fec)] else: - command = "portconfig -p {} -f {} -n {}".format(interface_name, interface_fec, ctx.obj['namespace']) + command = ['portconfig', '-p', str(interface_name), '-f', str(interface_fec), '-n', str(ctx.obj['namespace'])] if verbose: - command += " -vv" + command += ["-vv"] clicommon.run_command(command, display_cmd=verbose) # @@ -4436,7 +4431,6 @@ def remove(ctx, interface_name, ip_addr): """Remove an IP address from the interface""" # Get the config_db connector config_db = ValidatedConfigDBConnector(ctx.obj['config_db']) - if clicommon.get_interface_naming_mode() == "alias": interface_name = interface_alias_to_name(config_db, interface_name) if interface_name is None: @@ -4480,9 +4474,9 @@ def remove(ctx, interface_name, ip_addr): config_db.set_entry(table_name, interface_name, None) if multi_asic.is_multi_asic(): - command = "sudo ip netns exec {} ip neigh flush dev {} {}".format(ctx.obj['namespace'], interface_name, str(ip_address)) + command = ['sudo', 'ip', 'netns', 'exec', str(ctx.obj['namespace']), 'ip', 'neigh', 'flush', 'dev', str(interface_name), str(ip_address)] else: - command = "ip neigh flush dev {} {}".format(interface_name, str(ip_address)) + command = ['ip', 'neigh', 'flush', 'dev', str(interface_name), str(ip_address)] clicommon.run_command(command) # @@ -4892,9 +4886,9 @@ def frequency(ctx, interface_name, frequency): log.log_info("{} Setting transceiver frequency {} GHz".format(interface_name, frequency)) if ctx.obj['namespace'] is DEFAULT_NAMESPACE: - command = "portconfig -p {} -F {}".format(interface_name, frequency) + command = ['portconfig', '-p', str(interface_name), '-F', str(frequency)] else: - command = "portconfig -p {} -F {} -n {}".format(interface_name, frequency, ctx.obj['namespace']) + command = ['portconfig', '-p', str(interface_name), '-F', str(frequency), '-n', str(ctx.obj['namespace'])] clicommon.run_command(command) @@ -4924,9 +4918,9 @@ def tx_power(ctx, interface_name, tx_power): log.log_info("{} Setting transceiver power {} dBm".format(interface_name, tx_power)) if ctx.obj['namespace'] is DEFAULT_NAMESPACE: - command = "portconfig -p {} -P {}".format(interface_name, tx_power) + command = ['portconfig', '-p', str(interface_name), '-P', str(tx_power)] else: - command = "portconfig -p {} -P {} -n {}".format(interface_name, tx_power, ctx.obj['namespace']) + command = ['portconfig', '-p', str(interface_name), '-P', str(tx_power), '-n', str(ctx.obj['namespace'])] clicommon.run_command(command) @@ -4951,7 +4945,7 @@ def lpmode(ctx, interface_name, state): if interface_name_is_valid(config_db, interface_name) is False: ctx.fail("Interface name is invalid. Please enter a valid interface name!!") - cmd = "sudo sfputil lpmode {} {}".format("on" if state == "enable" else "off", interface_name) + cmd = ['sudo', 'sfputil', 'lpmode', "{}".format("on" if state == "enable" else "off"), str(interface_name)] clicommon.run_command(cmd) # @@ -4974,7 +4968,7 @@ def reset(ctx, interface_name): if interface_name_is_valid(config_db, interface_name) is False: ctx.fail("Interface name is invalid. Please enter a valid interface name!!") - cmd = "sudo sfputil reset {}".format(interface_name) + cmd = ['sudo', 'sfputil', 'reset', str(interface_name)] clicommon.run_command(cmd) # @@ -5713,7 +5707,7 @@ def update(): def full(file_name): """Full update of ACL rules configuration.""" log.log_info("'acl update full {}' executing...".format(file_name)) - command = "acl-loader update full {}".format(file_name) + command = ['acl-loader', 'update', 'full', str(file_name)] clicommon.run_command(command) @@ -5726,7 +5720,7 @@ def full(file_name): def incremental(file_name): """Incremental update of ACL rule configuration.""" log.log_info("'acl update incremental {}' executing...".format(file_name)) - command = "acl-loader update incremental {}".format(file_name) + command = ['acl-loader', 'update', 'incremental', str(file_name)] clicommon.run_command(command) @@ -5753,13 +5747,13 @@ def dropcounters(): @click.option('-v', '--verbose', is_flag=True, help="Enable verbose output") def install(counter_name, alias, group, counter_type, desc, reasons, verbose): """Install a new drop counter""" - command = "dropconfig -c install -n '{}' -t '{}' -r '{}'".format(counter_name, counter_type, reasons) + command = ['dropconfig', '-c', 'install', '-n', str(counter_name), '-t', str(counter_type), '-r', str(reasons)] if alias: - command += " -a '{}'".format(alias) + command += ['-a', str(alias)] if group: - command += " -g '{}'".format(group) + command += ['-g', str(group)] if desc: - command += " -d '{}'".format(desc) + command += ['-d', str(desc)] clicommon.run_command(command, display_cmd=verbose) @@ -5772,7 +5766,7 @@ def install(counter_name, alias, group, counter_type, desc, reasons, verbose): @click.option('-v', '--verbose', is_flag=True, help="Enable verbose output") def delete(counter_name, verbose): """Delete an existing drop counter""" - command = "dropconfig -c uninstall -n {}".format(counter_name) + command = ['dropconfig', '-c', 'uninstall', '-n', str(counter_name)] clicommon.run_command(command, display_cmd=verbose) @@ -5785,7 +5779,7 @@ def delete(counter_name, verbose): @click.option('-v', '--verbose', is_flag=True, help="Enable verbose output") def add_reasons(counter_name, reasons, verbose): """Add reasons to an existing drop counter""" - command = "dropconfig -c add -n {} -r {}".format(counter_name, reasons) + command = ['dropconfig', '-c', 'add', '-n', str(counter_name), '-r', str(reasons)] clicommon.run_command(command, display_cmd=verbose) @@ -5798,7 +5792,7 @@ def add_reasons(counter_name, reasons, verbose): @click.option('-v', '--verbose', is_flag=True, help="Enable verbose output") def remove_reasons(counter_name, reasons, verbose): """Remove reasons from an existing drop counter""" - command = "dropconfig -c remove -n {} -r {}".format(counter_name, reasons) + command = ['dropconfig', '-c', 'remove', '-n', str(counter_name), '-r', str(reasons)] clicommon.run_command(command, display_cmd=verbose) @@ -5820,17 +5814,17 @@ def remove_reasons(counter_name, reasons, verbose): def ecn(profile, rmax, rmin, ymax, ymin, gmax, gmin, rdrop, ydrop, gdrop, verbose): """ECN-related configuration tasks""" log.log_info("'ecn -profile {}' executing...".format(profile)) - command = "ecnconfig -p %s" % profile - if rmax is not None: command += " -rmax %d" % rmax - if rmin is not None: command += " -rmin %d" % rmin - if ymax is not None: command += " -ymax %d" % ymax - if ymin is not None: command += " -ymin %d" % ymin - if gmax is not None: command += " -gmax %d" % gmax - if gmin is not None: command += " -gmin %d" % gmin - if rdrop is not None: command += " -rdrop %d" % rdrop - if ydrop is not None: command += " -ydrop %d" % ydrop - if gdrop is not None: command += " -gdrop %d" % gdrop - if verbose: command += " -vv" + command = ['ecnconfig', '-p', str(profile)] + if rmax is not None: command += ['-rmax', str(rmax)] + if rmin is not None: command += ['-rmin', str(rmin)] + if ymax is not None: command += ['-ymax', str(ymax)] + if ymin is not None: command += ['-ymin', str(ymin)] + if gmax is not None: command += ['-gmax', str(gmax)] + if gmin is not None: command += ['-gmin', str(gmin)] + if rdrop is not None: command += ['-rdrop', str(rdrop)] + if ydrop is not None: command += ['-ydrop', str(ydrop)] + if gdrop is not None: command += ['-gdrop', str(gdrop)] + if verbose: command += ["-vv"] clicommon.run_command(command, display_cmd=verbose) @@ -5863,7 +5857,7 @@ def asymmetric(ctx, interface_name, status): if interface_name is None: ctx.fail("'interface_name' is None!") - clicommon.run_command("pfc config asymmetric {0} {1}".format(status, interface_name)) + clicommon.run_command(['pfc', 'config', 'asymmetric', str(status), str(interface_name)]) # # 'pfc priority' command ('config interface pfc priority ...') @@ -5884,7 +5878,7 @@ def priority(ctx, interface_name, priority, status): if interface_name is None: ctx.fail("'interface_name' is None!") - clicommon.run_command("pfc config priority {0} {1} {2}".format(status, interface_name, priority)) + clicommon.run_command(['pfc', 'config', 'priority', str(status), str(interface_name), str(priority)]) # # 'buffer' group ('config buffer ...') @@ -6205,7 +6199,7 @@ def telemetry(): @click.argument('interval', required=True) def interval(interval): """Configure watermark telemetry interval""" - command = 'watermarkcfg --config-interval ' + interval + command = ['watermarkcfg', '--config-interval', str(interval)] clicommon.run_command(command) @@ -6354,7 +6348,7 @@ def ztp(): @click.argument('run', required=False, type=click.Choice(["run"])) def run(run): """Restart ZTP of the device.""" - command = "ztp run -y" + command = ['ztp', 'run', '-y'] clicommon.run_command(command, display_cmd=True) @ztp.command() @@ -6363,14 +6357,14 @@ def run(run): @click.argument('disable', required=False, type=click.Choice(["disable"])) def disable(disable): """Administratively Disable ZTP.""" - command = "ztp disable -y" + command = ['ztp', 'disable', '-y'] clicommon.run_command(command, display_cmd=True) @ztp.command() @click.argument('enable', required=False, type=click.Choice(["enable"])) def enable(enable): """Administratively Enable ZTP.""" - command = "ztp enable" + command = ['ztp', 'enable'] clicommon.run_command(command, display_cmd=True) # @@ -6405,7 +6399,7 @@ def add_ntp_server(ctx, ntp_ip_address): click.echo("NTP server {} added to configuration".format(ntp_ip_address)) try: click.echo("Restarting ntp-config service...") - clicommon.run_command("systemctl restart ntp-config", display_cmd=False) + clicommon.run_command(['systemctl', 'restart', 'ntp-config'], display_cmd=False) except SystemExit as e: ctx.fail("Restart service ntp-config failed with error {}".format(e)) @@ -6429,7 +6423,7 @@ def del_ntp_server(ctx, ntp_ip_address): ctx.fail("NTP server {} is not configured.".format(ntp_ip_address)) try: click.echo("Restarting ntp-config service...") - clicommon.run_command("systemctl restart ntp-config", display_cmd=False) + clicommon.run_command(['systemctl', 'restart', 'ntp-config'], display_cmd=False) except SystemExit as e: ctx.fail("Restart service ntp-config failed with error {}".format(e)) @@ -6472,8 +6466,8 @@ def enable(ctx): if out != "active": log.log_info("sflow service is not enabled. Starting sflow docker...") - clicommon.run_command("sudo systemctl enable sflow") - clicommon.run_command("sudo systemctl start sflow") + clicommon.run_command(['sudo', 'systemctl', 'enable', 'sflow']) + clicommon.run_command(['sudo', 'systemctl', 'start', 'sflow']) # # 'sflow' command ('config sflow disable') diff --git a/config/plugins/mlnx.py b/config/plugins/mlnx.py index f088926b3f..75846d54e3 100644 --- a/config/plugins/mlnx.py +++ b/config/plugins/mlnx.py @@ -52,7 +52,7 @@ SNIFFER_CONF_FILE = '/etc/supervisor/conf.d/mlnx_sniffer.conf' SNIFFER_CONF_FILE_IN_CONTAINER = CONTAINER_NAME + ':' + SNIFFER_CONF_FILE # Command to restart swss service -COMMAND_RESTART_SWSS = 'systemctl restart swss.service' +COMMAND_RESTART_SWSS = ['systemctl', 'restart', 'swss.service'] # Global logger instance @@ -99,12 +99,12 @@ def env_variable_delete(delete_line): def conf_file_copy(src, dest): - command = 'docker cp ' + src + ' ' + dest + command = ['docker', 'cp', str(src), str(dest)] clicommon.run_command(command) def conf_file_receive(): - command = "docker exec {} bash -c 'touch {}'".format(CONTAINER_NAME, SNIFFER_CONF_FILE) + command = ['docker', 'exec', str(CONTAINER_NAME), 'bash', '-c', 'touch ' + str(SNIFFER_CONF_FILE)] clicommon.run_command(command) conf_file_copy(SNIFFER_CONF_FILE_IN_CONTAINER, TMP_SNIFFER_CONF_FILE) @@ -134,7 +134,7 @@ def sniffer_env_variable_set(enable, env_variable_name, env_variable_string=""): if not ignore: config_file_send() - command = 'rm -rf {}'.format(TMP_SNIFFER_CONF_FILE) + command = ['rm', '-rf', str(TMP_SNIFFER_CONF_FILE)] clicommon.run_command(command) return ignore diff --git a/config/syslog.py b/config/syslog.py index 0df6fffd35..90fc52ec9d 100644 --- a/config/syslog.py +++ b/config/syslog.py @@ -410,8 +410,8 @@ def add(db, server_ip_address, source, port, vrf): try: add_entry(db.cfgdb, table, key, data) - clicommon.run_command("systemctl reset-failed rsyslog-config rsyslog", display_cmd=True) - clicommon.run_command("systemctl restart rsyslog-config", display_cmd=True) + clicommon.run_command(['systemctl', 'reset-failed', 'rsyslog-config', 'rsyslog'], display_cmd=True) + clicommon.run_command(['systemctl', 'restart', 'rsyslog-config'], display_cmd=True) log.log_notice("Added remote syslog logging: server={},source={},port={},vrf={}".format( server_ip_address, data.get(SYSLOG_SOURCE, "N/A"), @@ -442,8 +442,8 @@ def delete(db, server_ip_address): try: del_entry(db.cfgdb, table, key) - clicommon.run_command("systemctl reset-failed rsyslog-config rsyslog", display_cmd=True) - clicommon.run_command("systemctl restart rsyslog-config", display_cmd=True) + clicommon.run_command(['systemctl', 'reset-failed', 'rsyslog-config', 'rsyslog'], display_cmd=True) + clicommon.run_command(['systemctl', 'restart', 'rsyslog-config'], display_cmd=True) log.log_notice("Removed remote syslog logging: server={}".format(server_ip_address)) except Exception as e: log.log_error("Failed to remove remote syslog logging: {}".format(str(e))) diff --git a/config/vlan.py b/config/vlan.py index 0540739208..41c9f3551a 100644 --- a/config/vlan.py +++ b/config/vlan.py @@ -128,13 +128,13 @@ def del_vlan(db, vid, no_restart_dhcp_relay): def restart_ndppd(): - verify_swss_running_cmd = "docker container inspect -f '{{.State.Status}}' swss" - docker_exec_cmd = "docker exec -i swss {}" - ndppd_status_cmd= "supervisorctl status ndppd" - ndppd_conf_copy_cmd = "cp /usr/share/sonic/templates/ndppd.conf /etc/supervisor/conf.d/" - supervisor_update_cmd = "supervisorctl update" - ndppd_config_gen_cmd = "sonic-cfggen -d -t /usr/share/sonic/templates/ndppd.conf.j2,/etc/ndppd.conf" - ndppd_restart_cmd = "supervisorctl restart ndppd" + verify_swss_running_cmd = ['docker', 'container', 'inspect', '-f', '{{.State.Status}}', 'swss'] + docker_exec_cmd = ['docker', 'exec', '-i', 'swss'] + ndppd_config_gen_cmd = ['sonic-cfggen', '-d', '-t', '/usr/share/sonic/templates/ndppd.conf.j2,/etc/ndppd.conf'] + ndppd_restart_cmd =['supervisorctl', 'restart', 'ndppd'] + ndppd_status_cmd= ["supervisorctl", "status", "ndppd"] + ndppd_conf_copy_cmd = ['cp', '/usr/share/sonic/templates/ndppd.conf', '/etc/supervisor/conf.d/'] + supervisor_update_cmd = ['supervisorctl', 'update'] output, _ = clicommon.run_command(verify_swss_running_cmd, return_cmd=True) @@ -142,17 +142,16 @@ def restart_ndppd(): click.echo(click.style('SWSS container is not running, changes will take effect the next time the SWSS container starts', fg='red'),) return - _, rc = clicommon.run_command(docker_exec_cmd.format(ndppd_status_cmd), ignore_error=True, return_cmd=True) + _, rc = clicommon.run_command(docker_exec_cmd + ndppd_status_cmd, ignore_error=True, return_cmd=True) if rc != 0: - clicommon.run_command(docker_exec_cmd.format(ndppd_conf_copy_cmd)) - clicommon.run_command(docker_exec_cmd.format(supervisor_update_cmd), return_cmd=True) + clicommon.run_command(docker_exec_cmd + ndppd_conf_copy_cmd) + clicommon.run_command(docker_exec_cmd + supervisor_update_cmd, return_cmd=True) click.echo("Starting ndppd service") - clicommon.run_command(docker_exec_cmd.format(ndppd_config_gen_cmd)) + clicommon.run_command(docker_exec_cmd + ndppd_config_gen_cmd) sleep(3) - clicommon.run_command(docker_exec_cmd.format(ndppd_restart_cmd), return_cmd=True) - + clicommon.run_command(docker_exec_cmd + ndppd_restart_cmd, return_cmd=True) @vlan.command('proxy_arp') @click.argument('vid', metavar='', required=True, type=int) diff --git a/scripts/sonic-bootchart b/scripts/sonic-bootchart index 0b7646c74c..31f54ba0d8 100755 --- a/scripts/sonic-bootchart +++ b/scripts/sonic-bootchart @@ -50,12 +50,12 @@ def check_bootchart_installed(): def get_enabled_status(): """ Get systemd-bootchart status """ - output, _ = clicommon.run_command("systemctl is-enabled systemd-bootchart", return_cmd=True) + output, _ = clicommon.run_command(['systemctl', 'is-enabled', 'systemd-bootchart'], return_cmd=True) return output def get_active_status(): """ Get systemd-bootchart status """ - output, _ = clicommon.run_command("systemctl is-active systemd-bootchart", return_cmd=True) + output, _ = clicommon.run_command(['systemctl', 'is-active', 'systemd-bootchart'], return_cmd=True) return output def get_output_files(): @@ -75,14 +75,14 @@ def cli(): @root_privileges_required def enable(): """ Enable bootchart """ - clicommon.run_command("systemctl enable systemd-bootchart", display_cmd=True) + clicommon.run_command(['systemctl', 'enable', 'systemd-bootchart'], display_cmd=True) @cli.command() @root_privileges_required def disable(): """ Disable bootchart """ - clicommon.run_command("systemctl disable systemd-bootchart", display_cmd=True) + clicommon.run_command(['systemctl', 'disable', 'systemd-bootchart'], display_cmd=True) @cli.command() diff --git a/show/acl.py b/show/acl.py index a2c8ab496f..de3d2d0693 100644 --- a/show/acl.py +++ b/show/acl.py @@ -19,13 +19,13 @@ def acl(): @click.option('--verbose', is_flag=True, help="Enable verbose output") def rule(table_name, rule_id, verbose): """Show existing ACL rules""" - cmd = "acl-loader show rule" + cmd = ['acl-loader', 'show', 'rule'] if table_name is not None: - cmd += " {}".format(table_name) + cmd += [str(table_name)] if rule_id is not None: - cmd += " {}".format(rule_id) + cmd += [str(rule_id)] clicommon.run_command(cmd, display_cmd=verbose) @@ -36,9 +36,9 @@ def rule(table_name, rule_id, verbose): @click.option('--verbose', is_flag=True, help="Enable verbose output") def table(table_name, verbose): """Show existing ACL tables""" - cmd = "acl-loader show table" + cmd = ['acl-loader', 'show', 'table'] if table_name is not None: - cmd += " {}".format(table_name) + cmd += [str(table_name)] clicommon.run_command(cmd, display_cmd=verbose) diff --git a/show/chassis_modules.py b/show/chassis_modules.py index acc0263b6f..73ea92d1ed 100644 --- a/show/chassis_modules.py +++ b/show/chassis_modules.py @@ -117,13 +117,13 @@ def midplane_status(chassis_module_name): def system_ports(systemportname, namespace, verbose): """Show VOQ system ports information""" - cmd = "voqutil -c system_ports" + cmd = ['voqutil', '-c', 'system_ports'] if systemportname is not None: - cmd += " -i \"{}\"".format(systemportname) + cmd += ['-i', str(systemportname)] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) @@ -134,13 +134,13 @@ def system_ports(systemportname, namespace, verbose): def system_neighbors(asicname, ipaddress, verbose): """Show VOQ system neighbors information""" - cmd = "voqutil -c system_neighbors" + cmd = ['voqutil', '-c', 'system_neighbors'] if ipaddress is not None: - cmd += " -a {}".format(ipaddress) + cmd += ['-a', str(ipaddress)] if asicname is not None: - cmd += " -n {}".format(asicname) + cmd += ['-n', str(asicname)] clicommon.run_command(cmd, display_cmd=verbose) @@ -152,15 +152,15 @@ def system_neighbors(asicname, ipaddress, verbose): def system_lags(systemlagname, asicname, linecardname, verbose): """Show VOQ system lags information""" - cmd = "voqutil -c system_lags" + cmd = ['voqutil', '-c', 'system_lags'] if systemlagname is not None: - cmd += " -s \"{}\"".format(systemlagname) + cmd += ['-s', str(systemlagname)] if asicname is not None: - cmd += " -n {}".format(asicname) + cmd += ['-n', str(asicname)] if linecardname is not None: - cmd += " -l \"{}\"".format(linecardname) + cmd += ['-l', str(linecardname)] clicommon.run_command(cmd, display_cmd=verbose) diff --git a/show/dropcounters.py b/show/dropcounters.py index 63ae138f45..30779b9364 100644 --- a/show/dropcounters.py +++ b/show/dropcounters.py @@ -18,10 +18,10 @@ def dropcounters(): @click.option('--verbose', is_flag=True, help="Enable verbose output") def configuration(group, verbose): """Show current drop counter configuration""" - cmd = "dropconfig -c show_config" + cmd = ['dropconfig', '-c', 'show_config'] if group: - cmd += " -g '{}'".format(group) + cmd += ['-g', str(group)] clicommon.run_command(cmd, display_cmd=verbose) @@ -31,7 +31,7 @@ def configuration(group, verbose): @click.option('--verbose', is_flag=True, help="Enable verbose output") def capabilities(verbose): """Show device drop counter capabilities""" - cmd = "dropconfig -c show_capabilities" + cmd = ['dropconfig', '-c', 'show_capabilities'] clicommon.run_command(cmd, display_cmd=verbose) @@ -43,12 +43,12 @@ def capabilities(verbose): @click.option('--verbose', is_flag=True, help="Enable verbose output") def counts(group, counter_type, verbose): """Show drop counts""" - cmd = "dropstat -c show" + cmd = ['dropstat', '-c', 'show'] if group: - cmd += " -g '{}'".format(group) + cmd += ['-g', str(group)] if counter_type: - cmd += " -t '{}'".format(counter_type) + cmd += ['-t', str(counter_type)] clicommon.run_command(cmd, display_cmd=verbose) diff --git a/show/fabric.py b/show/fabric.py index 2e55887a0f..c8dc956e44 100644 --- a/show/fabric.py +++ b/show/fabric.py @@ -18,11 +18,11 @@ def counters(): @click.option('-e', '--errors', is_flag=True) def reachability(namespace, errors): """Show fabric reachability""" - cmd = "fabricstat -r" + cmd = ['fabricstat', '-r'] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] if errors: - cmd += " -e" + cmd += ["-e"] clicommon.run_command(cmd) @counters.command() @@ -30,18 +30,18 @@ def reachability(namespace, errors): @click.option('-e', '--errors', is_flag=True) def port(namespace, errors): """Show fabric port stat""" - cmd = "fabricstat" + cmd = ["fabricstat"] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] if errors: - cmd += " -e" + cmd += ["-e"] clicommon.run_command(cmd) @counters.command() @multi_asic_util.multi_asic_click_option_namespace def queue(namespace): """Show fabric queue stat""" - cmd = "fabricstat -q" + cmd = ['fabricstat', '-q'] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd) diff --git a/show/flow_counters.py b/show/flow_counters.py index 0767a2a9a5..4c7764c9da 100644 --- a/show/flow_counters.py +++ b/show/flow_counters.py @@ -21,9 +21,9 @@ def flowcnt_trap(): @click.option('--namespace', '-n', 'namespace', default=None, type=click.Choice(multi_asic_util.multi_asic_ns_choices()), show_default=True, help='Namespace name or all') def stats(verbose, namespace): """Show trap flow counter statistic""" - cmd = "flow_counters_stat -t trap" + cmd = ['flow_counters_stat', '-t', 'trap'] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) # @@ -57,9 +57,9 @@ def config(db): def stats(ctx, verbose, namespace): """Show statistics of all route flow counters""" if ctx.invoked_subcommand is None: - command = "flow_counters_stat -t route" + command = ['flow_counters_stat', '-t', 'route'] if namespace is not None: - command += " -n {}".format(namespace) + command += ['-n', str(namespace)] clicommon.run_command(command, display_cmd=verbose) @@ -70,11 +70,11 @@ def stats(ctx, verbose, namespace): @click.argument('prefix-pattern', required=True) def pattern(prefix_pattern, vrf, verbose, namespace): """Show statistics of route flow counters by pattern""" - command = "flow_counters_stat -t route --prefix_pattern \"{}\"".format(prefix_pattern) + command = ['flow_counters_stat', '-t', 'route', '--prefix_pattern', str(prefix_pattern)] if vrf: - command += ' --vrf {}'.format(vrf) + command += ['--vrf', str(vrf)] if namespace is not None: - command += " -n {}".format(namespace) + command += ['-n', str(namespace)] clicommon.run_command(command, display_cmd=verbose) @@ -85,9 +85,9 @@ def pattern(prefix_pattern, vrf, verbose, namespace): @click.argument('prefix', required=True) def route(prefix, vrf, verbose, namespace): """Show statistics of route flow counters by prefix""" - command = "flow_counters_stat -t route --prefix {}".format(prefix) + command = ['flow_counters_stat', '-t', 'route', '--prefix', str(prefix)] if vrf: - command += ' --vrf {}'.format(vrf) + command += ['--vrf', str(vrf)] if namespace is not None: - command += " -n {}".format(namespace) + command += ['-n', str(namespace)] clicommon.run_command(command, display_cmd=verbose) diff --git a/show/gearbox.py b/show/gearbox.py index 1c46c78150..cbb16302b1 100644 --- a/show/gearbox.py +++ b/show/gearbox.py @@ -18,7 +18,7 @@ def phys(): @click.pass_context def status(ctx): """Show gearbox phys status""" - clicommon.run_command("gearboxutil phys status") + clicommon.run_command(['gearboxutil', 'phys', 'status']) # 'interfaces' subcommand ("show gearbox interfaces") @gearbox.group(cls=clicommon.AliasedGroup) @@ -31,4 +31,4 @@ def interfaces(): @click.pass_context def status(ctx): """Show gearbox interfaces status""" - clicommon.run_command("gearboxutil interfaces status") + clicommon.run_command(['gearboxutil', 'interfaces', 'status']) diff --git a/show/interfaces/__init__.py b/show/interfaces/__init__.py index 3b876cdad9..c376afe71e 100644 --- a/show/interfaces/__init__.py +++ b/show/interfaces/__init__.py @@ -103,18 +103,18 @@ def description(interfacename, namespace, display, verbose): ctx = click.get_current_context() - cmd = "intfutil -c description" + cmd = ['intfutil', '-c', 'description'] #ignore the display option when interface name is passed if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) - cmd += " -i {}".format(interfacename) + cmd += ['-i', str(interfacename)] else: - cmd += " -d {}".format(display) + cmd += ['-d', str(display)] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) @@ -135,17 +135,17 @@ def status(interfacename, namespace, display, verbose): ctx = click.get_current_context() - cmd = "intfutil -c status" + cmd = ['intfutil', '-c', 'status'] if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) - cmd += " -i {}".format(interfacename) + cmd += ['-i', str(interfacename)] else: - cmd += " -d {}".format(display) + cmd += ['-d', str(display)] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) @@ -158,17 +158,17 @@ def tpid(interfacename, namespace, display, verbose): ctx = click.get_current_context() - cmd = "intfutil -c tpid" + cmd = ['intfutil', '-c', 'tpid'] if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) - cmd += " -i {}".format(interfacename) + cmd += ['-i', str(interfacename)] else: - cmd += " -d {}".format(display) + cmd += ['-d', str(display)] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) @@ -431,18 +431,18 @@ def eeprom(interfacename, dump_dom, namespace, verbose): ctx = click.get_current_context() - cmd = "sfpshow eeprom" + cmd = ['sfpshow', 'eeprom'] if dump_dom: - cmd += " --dom" + cmd += ["--dom"] if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) - cmd += " -p {}".format(interfacename) + cmd += ['-p', str(interfacename)] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) @@ -456,16 +456,16 @@ def pm(interfacename, namespace, verbose): ctx = click.get_current_context() - cmd = "sfpshow pm" + cmd = ['sfpshow', 'pm'] if interfacename is not None: interfacename = try_convert_interfacename_from_alias( ctx, interfacename) - cmd += " -p {}".format(interfacename) + cmd += ['-p', str(interfacename)] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) @@ -479,15 +479,15 @@ def info(interfacename, namespace, verbose): ctx = click.get_current_context() - cmd = "sfpshow info" + cmd = ['sfpshow', 'info'] if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) - cmd += " -p {}".format(interfacename) + cmd += ['-p', str(interfacename)] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) @@ -499,12 +499,12 @@ def lpmode(interfacename, verbose): ctx = click.get_current_context() - cmd = "sudo sfputil show lpmode" + cmd = ['sudo', 'sfputil', 'show', 'lpmode'] if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) - cmd += " -p {}".format(interfacename) + cmd += ['-p', str(interfacename)] clicommon.run_command(cmd, display_cmd=verbose) @@ -519,15 +519,15 @@ def presence(db, interfacename, namespace, verbose): ctx = click.get_current_context() - cmd = "sfpshow presence" + cmd = ['sfpshow', 'presence'] if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) - cmd += " -p {}".format(interfacename) + cmd += ['-p', str(interfacename)] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) @@ -544,15 +544,17 @@ def error_status(db, interfacename, fetch_from_hardware, namespace, verbose): ctx = click.get_current_context() - cmd = "sudo sfputil show error-status" + cmd = ['sudo', 'sfputil', 'show', 'error-status'] if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) - cmd += " -p {}".format(interfacename) + cmd += ['-p', str(interfacename)] if fetch_from_hardware: - cmd += " -hw" + cmd += ["-hw"] + if namespace is not None: + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) @@ -571,19 +573,19 @@ def counters(ctx, verbose, period, interface, printall, namespace, display): """Show interface counters""" if ctx.invoked_subcommand is None: - cmd = "portstat" + cmd = ["portstat"] if printall: - cmd += " -a" + cmd += ["-a"] if period is not None: - cmd += " -p {}".format(period) + cmd += ['-p', str(period)] if interface is not None: interface = try_convert_interfacename_from_alias(ctx, interface) - cmd += " -i {}".format(interface) + cmd += ['-i', str(interface)] else: - cmd += " -s {}".format(display) + cmd += ['-s', str(display)] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) @@ -594,13 +596,13 @@ def counters(ctx, verbose, period, interface, printall, namespace, display): @click.option('--verbose', is_flag=True, help="Enable verbose output") def errors(verbose, period, namespace, display): """Show interface counters errors""" - cmd = "portstat -e" + cmd = ['portstat', '-e'] if period is not None: - cmd += " -p {}".format(period) + cmd += ['-p', str(period)] - cmd += " -s {}".format(display) + cmd += ['-s', str(display)] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) @@ -611,13 +613,13 @@ def errors(verbose, period, namespace, display): @click.option('--verbose', is_flag=True, help="Enable verbose output") def fec_stats(verbose, period, namespace, display): """Show interface counters fec-stats""" - cmd = "portstat -f" + cmd = ['portstat', '-f'] if period is not None: - cmd += " -p {}".format(period) + cmd += ['-p', str(period)] - cmd += " -s {}".format(display) + cmd += ['-s', str(display)] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) @@ -628,12 +630,12 @@ def fec_stats(verbose, period, namespace, display): @click.option('--verbose', is_flag=True, help="Enable verbose output") def rates(verbose, period, namespace, display): """Show interface counters rates""" - cmd = "portstat -R" + cmd = ['portstat', '-R'] if period is not None: - cmd += " -p {}".format(period) - cmd += " -s {}".format(display) + cmd += ['-p', str(period)] + cmd += ['-s', str(display)] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) # 'counters' subcommand ("show interfaces counters rif") @@ -645,13 +647,12 @@ def rif(interface, period, verbose): """Show interface counters""" ctx = click.get_current_context() - - cmd = "intfstat" + cmd = ["intfstat"] if period is not None: - cmd += " -p {}".format(period) + cmd += ['-p', str(period)] if interface is not None: interface = try_convert_interfacename_from_alias(ctx, interface) - cmd += " -i {}".format(interface) + cmd += ['-i', str(interface)] clicommon.run_command(cmd, display_cmd=verbose) @@ -664,13 +665,12 @@ def detailed(interface, period, verbose): """Show interface counters detailed""" ctx = click.get_current_context() - - cmd = "portstat -l" + cmd = ['portstat', '-l'] if period is not None: - cmd += " -p {}".format(period) + cmd += ['-p', str(period)] if interface is not None: interface = try_convert_interfacename_from_alias(ctx, interface) - cmd += " -i {}".format(interface) + cmd += ['-i', str(interface)] clicommon.run_command(cmd, display_cmd=verbose) @@ -694,18 +694,18 @@ def autoneg_status(interfacename, namespace, display, verbose): ctx = click.get_current_context() - cmd = "intfutil -c autoneg" + cmd = ['intfutil', '-c', 'autoneg'] #ignore the display option when interface name is passed if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) - cmd += " -i {}".format(interfacename) + cmd += ['-i', str(interfacename)] else: - cmd += " -d {}".format(display) + cmd += ['-d', str(display)] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) @@ -727,17 +727,17 @@ def link_training_status(interfacename, namespace, display, verbose): ctx = click.get_current_context() - cmd = "intfutil -c link_training" + cmd = ['intfutil', '-c', 'link_training'] #ignore the display option when interface name is passed if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) - cmd += " -i {}".format(interfacename) + cmd += ['-i', str(interfacename)] else: - cmd += " -d {}".format(display) + cmd += ['-d', str(display)] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) diff --git a/show/kdump.py b/show/kdump.py index e5ce7cde74..6eba55082e 100644 --- a/show/kdump.py +++ b/show/kdump.py @@ -49,7 +49,7 @@ def get_kdump_oper_mode(): returns "Not Ready"; """ oper_mode = "Not Ready" - command_stdout, _ = clicommon.run_command("/usr/sbin/kdump-config status", return_cmd=True) + command_stdout, _ = clicommon.run_command(['/usr/sbin/kdump-config', 'status'], return_cmd=True) for line in command_stdout.splitlines(): if ": ready to kdump" in line: @@ -95,7 +95,7 @@ def get_kdump_core_files(): of 'find' command. dump_file_list: A list contains kernel core dump files. """ - find_core_dump_files = "find /var/crash -name 'kdump.*'" + find_core_dump_files = ['find', '/var/crash', '-name', 'kdump.*'] dump_file_list = [] cmd_message = None @@ -119,7 +119,7 @@ def get_kdump_dmesg_files(): of 'find' command. dmesg_file_list: A list contains kernel dmesg files. """ - find_dmesg_files = "find /var/crash -name 'dmesg.*'" + find_dmesg_files = ['find', '/var/crash', '-name', 'dmesg.*'] dmesg_file_list = [] cmd_message = None @@ -167,13 +167,13 @@ def files(): @click.argument('filename', required=False) @click.option('-l', '--lines', default=10, show_default=True) def logging(filename, lines): - cmd = "sudo tail -{}".format(lines) + cmd = ['sudo', 'tail', '-'+str(lines)] if filename: timestamp = filename.strip().split(".")[-1] file_path = "/var/crash/{}/{}".format(timestamp, filename) if os.path.isfile(file_path): - cmd += " {}".format(file_path) + cmd += [str(file_path)] else: click.echo("Invalid filename: '{}'!".format(filename)) sys.exit(1) @@ -184,6 +184,6 @@ def logging(filename, lines): sys.exit(2) dmesg_file_result.sort(reverse=True) - cmd += " {}".format(dmesg_file_result[0]) + cmd += [str(dmesg_file_result[0])] clicommon.run_command(cmd) diff --git a/show/main.py b/show/main.py index 7f79cd4779..2d21e1b3aa 100755 --- a/show/main.py +++ b/show/main.py @@ -981,11 +981,11 @@ def ip(): @click.pass_context def interfaces(ctx, namespace, display): if ctx.invoked_subcommand is None: - cmd = "sudo ipintutil -a ipv4" + cmd = ['sudo', 'ipintutil', '-a', 'ipv4'] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] - cmd += " -d {}".format(display) + cmd += ['-d', str(display)] clicommon.run_command(cmd) # @@ -1108,12 +1108,12 @@ def prefix_list(prefix_list_name, verbose): @ipv6.command() @multi_asic_util.multi_asic_click_options def interfaces(namespace, display): - cmd = "sudo ipintutil -a ipv6" + cmd = ['sudo', 'ipintutil', '-a', 'ipv6'] if namespace is not None: - cmd += " -n {}".format(namespace) + cmd += ['-n', str(namespace)] - cmd += " -d {}".format(display) + cmd += ['-d', str(display)] clicommon.run_command(cmd) diff --git a/show/nat.py b/show/nat.py index 72b81dc61d..9e3c868ed7 100644 --- a/show/nat.py +++ b/show/nat.py @@ -18,7 +18,7 @@ def nat(): def statistics(verbose): """ Show NAT statistics """ - cmd = "sudo natshow -s" + cmd = ['sudo', 'natshow', '-s'] clicommon.run_command(cmd, display_cmd=verbose) @@ -30,16 +30,17 @@ def translations(ctx, verbose): """ Show NAT translations """ if ctx.invoked_subcommand is None: - cmd = "sudo natshow -t" + cmd = ['sudo', 'natshow', '-t'] clicommon.run_command(cmd, display_cmd=verbose) # 'count' subcommand ("show nat translations count") @translations.command() -def count(): +@click.option('--verbose', is_flag=True, help="Enable verbose output") +def count(verbose): """ Show NAT translations count """ - cmd = "sudo natshow -c" + cmd = ['sudo', 'natshow', '-c'] clicommon.run_command(cmd, display_cmd=verbose) @@ -51,23 +52,23 @@ def config(ctx, verbose): """Show NAT config related information""" if ctx.invoked_subcommand is None: click.echo("\nGlobal Values") - cmd = "sudo natconfig -g" + cmd = ['sudo', 'natconfig', '-g'] clicommon.run_command(cmd, display_cmd=verbose) click.echo("Static Entries") - cmd = "sudo natconfig -s" + cmd = ['sudo', 'natconfig', '-s'] clicommon.run_command(cmd, display_cmd=verbose) click.echo("Pool Entries") - cmd = "sudo natconfig -p" + cmd = ['sudo', 'natconfig', '-p'] clicommon.run_command(cmd, display_cmd=verbose) click.echo("NAT Bindings") - cmd = "sudo natconfig -b" + cmd = ['sudo', 'natconfig', '-b'] clicommon.run_command(cmd, display_cmd=verbose) click.echo("NAT Zones") - cmd = "sudo natconfig -z" + cmd = ['sudo', 'natconfig', '-z'] clicommon.run_command(cmd, display_cmd=verbose) @@ -77,7 +78,7 @@ def config(ctx, verbose): def static(verbose): """Show static NAT configuration""" - cmd = "sudo natconfig -s" + cmd = ['sudo', 'natconfig', '-s'] clicommon.run_command(cmd, display_cmd=verbose) @@ -87,7 +88,7 @@ def static(verbose): def pool(verbose): """Show NAT Pool configuration""" - cmd = "sudo natconfig -p" + cmd = ['sudo', 'natconfig', '-p'] clicommon.run_command(cmd, display_cmd=verbose) @@ -97,7 +98,7 @@ def pool(verbose): def bindings(verbose): """Show NAT binding configuration""" - cmd = "sudo natconfig -b" + cmd = ['sudo', 'natconfig', '-b'] clicommon.run_command(cmd, display_cmd=verbose) @@ -107,7 +108,7 @@ def bindings(verbose): def globalvalues(verbose): """Show NAT Global configuration""" - cmd = "sudo natconfig -g" + cmd = ['sudo', 'natconfig', '-g'] clicommon.run_command(cmd, display_cmd=verbose) @@ -117,5 +118,5 @@ def globalvalues(verbose): def zones(verbose): """Show NAT Zone configuration""" - cmd = "sudo natconfig -z" + cmd = ['sudo', 'natconfig', '-z'] clicommon.run_command(cmd, display_cmd=verbose) diff --git a/show/platform.py b/show/platform.py index 1916e10d84..85d729df84 100644 --- a/show/platform.py +++ b/show/platform.py @@ -74,7 +74,7 @@ def summary(json): @click.option('--verbose', is_flag=True, help="Enable verbose output") def syseeprom(verbose): """Show system EEPROM information""" - cmd = "sudo decode-syseeprom -d" + cmd = ['sudo', 'decode-syseeprom', '-d'] clicommon.run_command(cmd, display_cmd=verbose) @@ -85,13 +85,13 @@ def syseeprom(verbose): @click.option('--verbose', is_flag=True, help="Enable verbose output") def psustatus(index, json, verbose): """Show PSU status information""" - cmd = "psushow -s" + cmd = ['psushow', '-s'] if index >= 0: - cmd += " -i {}".format(index) + cmd += ['-i', str(index)] if json: - cmd += " -j" + cmd += ["-j"] clicommon.run_command(cmd, display_cmd=verbose) @@ -105,9 +105,9 @@ def ssdhealth(device, verbose, vendor): """Show SSD Health information""" if not device: device = os.popen("lsblk -o NAME,TYPE -p | grep disk").readline().strip().split()[0] - cmd = "sudo ssdutil -d " + device - options = " -v" if verbose else "" - options += " -e" if vendor else "" + cmd = ['sudo', 'ssdutil', '-d', str(device)] + options = ["-v"] if verbose else [] + options += ["-e"] if vendor else [] clicommon.run_command(cmd + options, display_cmd=verbose) @@ -116,9 +116,9 @@ def ssdhealth(device, verbose, vendor): @click.option('-c', '--check', is_flag=True, help="Check the platfome pcie device") def pcieinfo(check, verbose): """Show Device PCIe Info""" - cmd = "sudo pcieutil show" + cmd = ['sudo', 'pcieutil', 'show'] if check: - cmd = "sudo pcieutil check" + cmd = ['sudo', 'pcieutil', 'check'] clicommon.run_command(cmd, display_cmd=verbose) @@ -126,7 +126,7 @@ def pcieinfo(check, verbose): @platform.command() def fan(): """Show fan status information""" - cmd = 'fanshow' + cmd = ['fanshow'] clicommon.run_command(cmd) @@ -134,7 +134,7 @@ def fan(): @platform.command() def temperature(): """Show device temperature information""" - cmd = 'tempershow' + cmd = ['tempershow'] clicommon.run_command(cmd) # 'firmware' subcommand ("show platform firmware") diff --git a/show/processes.py b/show/processes.py index c603826c09..69a5a2fcc0 100644 --- a/show/processes.py +++ b/show/processes.py @@ -17,7 +17,7 @@ def processes(): def summary(verbose): """Show processes info""" # Run top batch mode to prevent unexpected newline after each newline - cmd = "ps -eo pid,ppid,cmd,%mem,%cpu " + cmd = ['ps', '-eo', 'pid,ppid,cmd,%mem,%cpu'] clicommon.run_command(cmd, display_cmd=verbose) @@ -27,7 +27,7 @@ def summary(verbose): def cpu(verbose): """Show processes CPU info""" # Run top in batch mode to prevent unexpected newline after each newline - cmd = "top -bn 1 -o %CPU" + cmd = ['top', '-bn', '1', '-o', '%CPU'] clicommon.run_command(cmd, display_cmd=verbose) @@ -37,5 +37,5 @@ def cpu(verbose): def memory(verbose): """Show processes memory info""" # Run top batch mode to prevent unexpected newline after each newline - cmd = "top -bn 1 -o %MEM" + cmd = ['top', '-bn', '1', '-o', '%MEM'] clicommon.run_command(cmd, display_cmd=verbose) diff --git a/show/system_health.py b/show/system_health.py index 08e9e70594..1fa92f6592 100644 --- a/show/system_health.py +++ b/show/system_health.py @@ -137,7 +137,7 @@ def sysready_status(ctx): if ctx.invoked_subcommand is None: try: - cmd = "sysreadyshow" + cmd = ["sysreadyshow"] clicommon.run_command(cmd, display_cmd=False) except Exception as e: click.echo("Exception: {}".format(str(e))) @@ -146,7 +146,7 @@ def sysready_status(ctx): @sysready_status.command('brief') def sysready_status_brief(): try: - cmd = "sysreadyshow --brief" + cmd = ["sysreadyshow", "--brief"] clicommon.run_command(cmd, display_cmd=False) except Exception as e: click.echo("Exception: {}".format(str(e))) @@ -155,7 +155,7 @@ def sysready_status_brief(): @sysready_status.command('detail') def sysready_status_detail(): try: - cmd = "sysreadyshow --detail" + cmd = ["sysreadyshow", "--detail"] clicommon.run_command(cmd, display_cmd=False) except Exception as e: click.echo("Exception: {}".format(str(e))) diff --git a/show/vxlan.py b/show/vxlan.py index 3d04552904..16743fc07a 100644 --- a/show/vxlan.py +++ b/show/vxlan.py @@ -326,11 +326,11 @@ def remotemac(remote_vtep_ip, count): def counters(tunnel, period, verbose): """Show VxLAN counters""" - cmd = "tunnelstat -T vxlan" + cmd = ['tunnelstat', '-T', 'vxlan'] if period is not None: - cmd += " -p {}".format(period) + cmd += ['-p', str(period)] if tunnel is not None: - cmd += " -i {}".format(tunnel) + cmd += ['-i', str(tunnel)] clicommon.run_command(cmd, display_cmd=verbose) diff --git a/tests/chassis_modules_test.py b/tests/chassis_modules_test.py index e6dbe569d2..6b9e0f3e6e 100644 --- a/tests/chassis_modules_test.py +++ b/tests/chassis_modules_test.py @@ -259,14 +259,14 @@ def test_midplane_show_incorrect_module(self): def test_show_and_verify_system_ports_output_asic0(self): os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = "multi_asic" - return_code, result = get_result_and_return_code('voqutil -c system_ports -n asic0') + return_code, result = get_result_and_return_code(['voqutil', '-c', 'system_ports', '-n', 'asic0']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == show_chassis_system_ports_output_asic0 def test_show_and_verify_system_ports_output_1_asic0(self): - return_code, result = get_result_and_return_code('voqutil -c system_ports -i "Linecard1|Asic0|Ethernet0" -n asic0') + return_code, result = get_result_and_return_code(['voqutil', '-c', 'system_ports', '-i', "Linecard1|Asic0|Ethernet0", '-n', 'asic0']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -280,21 +280,21 @@ def test_show_and_verify_system_neighbors_output_all(self): assert(result.output == show_chassis_system_neighbors_output_all) def test_show_and_verify_system_neighbors_output_ipv4(self): - return_code, result = get_result_and_return_code('voqutil -c system_neighbors -a 10.0.0.5') + return_code, result = get_result_and_return_code(['voqutil', '-c', 'system_neighbors', '-a', '10.0.0.5']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == show_chassis_system_neighbors_output_ipv4 def test_show_and_verify_system_neighbors_output_ipv6(self): - return_code, result = get_result_and_return_code('voqutil -c system_neighbors -a fc00::16') + return_code, result = get_result_and_return_code(['voqutil', '-c', 'system_neighbors', '-a', 'fc00::16']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == show_chassis_system_neighbors_output_ipv6 def test_show_and_verify_system_neighbors_output_asic0(self): - return_code, result = get_result_and_return_code('voqutil -c system_neighbors -n Asic0') + return_code, result = get_result_and_return_code(['voqutil', '-c', 'system_neighbors', '-n', 'Asic0']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -313,14 +313,14 @@ def test_show_and_verify_system_lags_output_1(self): assert(result.output == show_chassis_system_lags_output_1) def test_show_and_verify_system_lags_output_asic1(self): - return_code, result = get_result_and_return_code('voqutil -c system_lags -n Asic1') + return_code, result = get_result_and_return_code(['voqutil', '-c', 'system_lags', '-n', 'Asic1']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == show_chassis_system_lags_output_asic1 def test_show_and_verify_system_lags_output_lc4(self): - return_code, result = get_result_and_return_code('voqutil -c system_lags -l Linecard4') + return_code, result = get_result_and_return_code(['voqutil', '-c', 'system_lags', '-l', 'Linecard4']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 diff --git a/tests/clear_test.py b/tests/clear_test.py index a9c2a367f2..97f0f55643 100644 --- a/tests/clear_test.py +++ b/tests/clear_test.py @@ -1,3 +1,4 @@ +import click import pytest import clear.main as clear from click.testing import CliRunner @@ -286,3 +287,35 @@ def test_clear_ipv6_frr(self, run_command): def teardown(self): print('TEAR DOWN') + +class TestClearFlowcnt(object): + def setup(self): + print('SETUP') + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_flowcnt_route(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(clear.cli.commands['flowcnt-route'], ['-n', 'asic0']) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['flow_counters_stat', '-c', '-t', 'route', '-n', 'asic0']) + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_flowcnt_route_pattern(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(clear.cli.commands['flowcnt-route'].commands['pattern'], ['--vrf', 'Vrf_1', '-n', 'asic0', '3.3.0.0/16']) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['flow_counters_stat', '-c', '-t', 'route', '--prefix_pattern', '3.3.0.0/16', '--vrf', str('Vrf_1'), '-n', 'asic0']) + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_flowcnt_route_route(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(clear.cli.commands['flowcnt-route'].commands['route'], ['--vrf', 'Vrf_1', '-n', 'asic0', '3.3.0.0/16']) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['flow_counters_stat', '-c', '-t', 'route', '--prefix', '3.3.0.0/16', '--vrf', str('Vrf_1'), '-n', 'asic0']) + + def teardown(self): + print('TEAR DOWN') + diff --git a/tests/config_int_ip_test.py b/tests/config_int_ip_test.py index d1addd0f6d..170ea4ddf5 100644 --- a/tests/config_int_ip_test.py +++ b/tests/config_int_ip_test.py @@ -185,4 +185,4 @@ def test_config_int_ip_rem_static_multiasic( print(result.exit_code, result.output) assert result.exit_code != 0 assert "Error: Cannot remove the last IP entry of interface Ethernet8. A static ipv6 route is still bound to the RIF." in result.output - assert mock_run_command.call_count == 0 \ No newline at end of file + assert mock_run_command.call_count == 0 diff --git a/tests/config_test.py b/tests/config_test.py index 8d5e6c820b..b5be1717cb 100644 --- a/tests/config_test.py +++ b/tests/config_test.py @@ -17,7 +17,7 @@ from sonic_py_common import device_info from utilities_common.db import Db from utilities_common.general import load_module_from_source -from mock import patch, MagicMock +from mock import call, patch, mock_open, MagicMock from generic_config_updater.generic_updater import ConfigFormat @@ -69,7 +69,8 @@ Running command: ifconfig eth0 10.0.0.100 netmask 255.255.255.0 Running command: ip route add default via 10.0.0.1 dev eth0 table default Running command: ip rule add from 10.0.0.100 table default -Running command: [ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid +Running command: kill `cat /var/run/dhclient.eth0.pid` +Running command: rm -f /var/run/dhclient.eth0.pid Please note loaded setting will be lost after system reboot. To preserve setting, run `config save`. """ @@ -80,7 +81,8 @@ Running command: ifconfig eth0 add fc00:1::32/64 Running command: ip -6 route add default via fc00:1::1 dev eth0 table default Running command: ip -6 rule add from fc00:1::32 table default -Running command: [ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid +Running command: kill `cat /var/run/dhclient.eth0.pid` +Running command: rm -f /var/run/dhclient.eth0.pid Please note loaded setting will be lost after system reboot. To preserve setting, run `config save`. """ @@ -94,29 +96,30 @@ Running command: ifconfig eth0 add fc00:1::32/64 Running command: ip -6 route add default via fc00:1::1 dev eth0 table default Running command: ip -6 rule add from fc00:1::32 table default -Running command: [ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid +Running command: kill `cat /var/run/dhclient.eth0.pid` +Running command: rm -f /var/run/dhclient.eth0.pid Please note loaded setting will be lost after system reboot. To preserve setting, run `config save`. """ RELOAD_CONFIG_DB_OUTPUT = """\ Stopping SONiC target ... -Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json --write-to-db +Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json --write-to-db Restarting SONiC target ... Reloading Monit configuration ... """ RELOAD_YANG_CFG_OUTPUT = """\ Stopping SONiC target ... -Running command: /usr/local/bin/sonic-cfggen -Y /tmp/config.json --write-to-db +Running command: /usr/local/bin/sonic-cfggen -Y /tmp/config.json --write-to-db Restarting SONiC target ... Reloading Monit configuration ... """ RELOAD_MASIC_CONFIG_DB_OUTPUT = """\ Stopping SONiC target ... -Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json --write-to-db -Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json -n asic0 --write-to-db -Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json -n asic1 --write-to-db +Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json --write-to-db +Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json -n asic0 --write-to-db +Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json -n asic1 --write-to-db Restarting SONiC target ... Reloading Monit configuration ... """ @@ -126,22 +129,28 @@ reload_config_with_disabled_service_output="""\ Stopping SONiC target ... -Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json --write-to-db +Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json --write-to-db Restarting SONiC target ... Reloading Monit configuration ... """ def mock_run_command_side_effect(*args, **kwargs): command = args[0] + if isinstance(command, str): + command = command + elif isinstance(command, list): + command = ' '.join(command) if kwargs.get('display_cmd'): + if 'cat /var/run/dhclient.eth0.pid' in command: + command = 'kill `cat /var/run/dhclient.eth0.pid`' click.echo(click.style("Running command: ", fg='cyan') + click.style(command, fg='green')) if kwargs.get('return_cmd'): if command == "systemctl list-dependencies --plain sonic-delayed.target | sed '1d'": - return 'snmp.timer' , 0 - elif command == "systemctl list-dependencies --plain sonic.target | sed '1d'": - return 'swss', 0 + return 'snmp.timer', 0 + elif command == "systemctl list-dependencies --plain sonic.target": + return 'sonic.target\nswss', 0 elif command == "systemctl is-enabled snmp.timer": return 'enabled', 0 else: @@ -149,6 +158,10 @@ def mock_run_command_side_effect(*args, **kwargs): def mock_run_command_side_effect_disabled_timer(*args, **kwargs): command = args[0] + if isinstance(command, str): + command = command + elif isinstance(command, list): + command = ' '.join(command) if kwargs.get('display_cmd'): click.echo(click.style("Running command: ", fg='cyan') + click.style(command, fg='green')) @@ -156,8 +169,8 @@ def mock_run_command_side_effect_disabled_timer(*args, **kwargs): if kwargs.get('return_cmd'): if command == "systemctl list-dependencies --plain sonic-delayed.target | sed '1d'": return 'snmp.timer', 0 - elif command == "systemctl list-dependencies --plain sonic.target | sed '1d'": - return 'swss', 0 + elif command == "systemctl list-dependencies --plain sonic.target": + return 'sonic.target\nswss', 0 elif command == "systemctl is-enabled snmp.timer": return 'masked', 0 elif command == "systemctl show swss.service --property ActiveState --value": @@ -280,7 +293,7 @@ def test_load_minigraph(self, get_cmd_module, setup_single_broadcom_asic): assert result.exit_code == 0 assert "\n".join([l.rstrip() for l in result.output.split('\n')]) == load_minigraph_command_output # Verify "systemctl reset-failed" is called for services under sonic.target - mock_run_command.assert_any_call('systemctl reset-failed swss') + mock_run_command.assert_any_call(['systemctl', 'reset-failed', 'swss']) assert mock_run_command.call_count == 8 @mock.patch('sonic_py_common.device_info.get_paths_to_platform_and_hwsku_dirs', mock.MagicMock(return_value=(load_minigraph_platform_path, None))) @@ -295,7 +308,7 @@ def test_load_minigraph_platform_plugin(self, get_cmd_module, setup_single_broad assert result.exit_code == 0 assert "\n".join([l.rstrip() for l in result.output.split('\n')]) == load_minigraph_platform_plugin_command_output # Verify "systemctl reset-failed" is called for services under sonic.target - mock_run_command.assert_any_call('systemctl reset-failed swss') + mock_run_command.assert_any_call(['systemctl', 'reset-failed', 'swss']) assert mock_run_command.call_count == 8 @mock.patch('sonic_py_common.device_info.get_paths_to_platform_and_hwsku_dirs', mock.MagicMock(return_value=(load_minigraph_platform_false_path, None))) @@ -1551,7 +1564,7 @@ def test_config_load_mgmt_config_ipv4_only(self, get_cmd_module, setup_single_br } } } - self.check_output(get_cmd_module, device_desc_result, load_mgmt_config_command_ipv4_only_output, 5) + self.check_output(get_cmd_module, device_desc_result, load_mgmt_config_command_ipv4_only_output, 7) def test_config_load_mgmt_config_ipv6_only(self, get_cmd_module, setup_single_broadcom_asic): device_desc_result = { @@ -1566,7 +1579,7 @@ def test_config_load_mgmt_config_ipv6_only(self, get_cmd_module, setup_single_br } } } - self.check_output(get_cmd_module, device_desc_result, load_mgmt_config_command_ipv6_only_output, 5) + self.check_output(get_cmd_module, device_desc_result, load_mgmt_config_command_ipv6_only_output, 7) def test_config_load_mgmt_config_ipv4_ipv6(self, get_cmd_module, setup_single_broadcom_asic): device_desc_result = { @@ -1584,7 +1597,7 @@ def test_config_load_mgmt_config_ipv4_ipv6(self, get_cmd_module, setup_single_br } } } - self.check_output(get_cmd_module, device_desc_result, load_mgmt_config_command_ipv4_ipv6_output, 8) + self.check_output(get_cmd_module, device_desc_result, load_mgmt_config_command_ipv4_ipv6_output, 10) def check_output(self, get_cmd_module, parse_device_desc_xml_result, expected_output, expected_command_call_count): def parse_device_desc_xml_side_effect(filename): @@ -1593,20 +1606,21 @@ def parse_device_desc_xml_side_effect(filename): def change_hostname_side_effect(hostname): print("change hostname to {}".format(hostname)) with mock.patch("utilities_common.cli.run_command", mock.MagicMock(side_effect=mock_run_command_side_effect)) as mock_run_command: - with mock.patch('config.main.parse_device_desc_xml', mock.MagicMock(side_effect=parse_device_desc_xml_side_effect)): - with mock.patch('config.main._change_hostname', mock.MagicMock(side_effect=change_hostname_side_effect)): - (config, show) = get_cmd_module - runner = CliRunner() - with runner.isolated_filesystem(): - with open('device_desc.xml', 'w') as f: - f.write('dummy') - result = runner.invoke(config.config.commands["load_mgmt_config"], ["-y", "device_desc.xml"]) - print(result.exit_code) - print(result.output) - traceback.print_tb(result.exc_info[2]) - assert result.exit_code == 0 - assert "\n".join([l.rstrip() for l in result.output.split('\n')]) == expected_output - assert mock_run_command.call_count == expected_command_call_count + with mock.patch('os.path.isfile', mock.MagicMock(return_value=True)): + with mock.patch('config.main.parse_device_desc_xml', mock.MagicMock(side_effect=parse_device_desc_xml_side_effect)): + with mock.patch('config.main._change_hostname', mock.MagicMock(side_effect=change_hostname_side_effect)): + (config, show) = get_cmd_module + runner = CliRunner() + with runner.isolated_filesystem(): + with open('device_desc.xml', 'w') as f: + f.write('dummy') + result = runner.invoke(config.config.commands["load_mgmt_config"], ["-y", "device_desc.xml"]) + print(result.exit_code) + print(result.output) + traceback.print_tb(result.exc_info[2]) + assert result.exit_code == 0 + assert "\n".join([l.rstrip() for l in result.output.split('\n')]) == expected_output + assert mock_run_command.call_count == expected_command_call_count @classmethod def teardown_class(cls): @@ -2001,3 +2015,351 @@ def test_del_ntp_server_invalid_ip_yang_validation(self): @classmethod def teardown_class(cls): print("TEARDOWN") + + +class TestConfigPfcwd(object): + def setup(self): + print("SETUP") + + @patch('utilities_common.cli.run_command') + def test_start(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(config.config.commands['pfcwd'].commands['start'], ['-a', 'forward', '-r', 150, 'Ethernet0', '200', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['pfcwd', 'start', '--action', 'forward', 'Ethernet0', '200', '--restoration-time', '150'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_stop(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(config.config.commands['pfcwd'].commands['stop'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['pfcwd', 'stop'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_interval(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(config.config.commands['pfcwd'].commands['interval'], ['300', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['pfcwd', 'interval', '300'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_counter_poll(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(config.config.commands['pfcwd'].commands['counter_poll'], ['enable', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['pfcwd', 'counter_poll', 'enable'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_big_red_switch(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(config.config.commands['pfcwd'].commands['big_red_switch'], ['enable', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['pfcwd', 'big_red_switch', 'enable'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_start_default(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(config.config.commands['pfcwd'].commands['start_default'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['pfcwd', 'start_default'], display_cmd=True) + + def teardown(self): + print("TEARDOWN") + + +class TestConfigAclUpdate(object): + def setup(self): + print("SETUP") + + @patch('utilities_common.cli.run_command') + def test_full(self, mock_run_command): + file_name = '/etc/sonic/full_snmp.json' + runner = CliRunner() + result = runner.invoke(config.config.commands['acl'].commands['update'].commands['full'], [file_name]) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['acl-loader', 'update', 'full', file_name]) + + @patch('utilities_common.cli.run_command') + def test_incremental(self, mock_run_command): + file_name = '/etc/sonic/full_snmp.json' + runner = CliRunner() + result = runner.invoke(config.config.commands['acl'].commands['update'].commands['incremental'], [file_name]) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['acl-loader', 'update', 'incremental', file_name]) + + def teardown(self): + print("TEARDOWN") + + +class TestConfigDropcounters(object): + def setup(self): + print("SETUP") + + @patch('utilities_common.cli.run_command') + def test_install(self, mock_run_command): + counter_name = 'DEBUG_2' + counter_type = 'PORT_INGRESS_DROPS' + reasons = '[EXCEEDS_L2_MTU,DECAP_ERROR]' + alias = 'BAD_DROPS' + group = 'BAD' + desc = 'more port ingress drops' + + runner = CliRunner() + result = runner.invoke(config.config.commands['dropcounters'].commands['install'], [counter_name, counter_type, reasons, '-d', desc, '-g', group, '-a', alias]) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['dropconfig', '-c', 'install', '-n', str(counter_name), '-t', str(counter_type), '-r', str(reasons), '-a', str(alias), '-g', str(group), '-d', str(desc)], display_cmd=False) + + @patch('utilities_common.cli.run_command') + def test_delete(self, mock_run_command): + counter_name = 'DEBUG_2' + runner = CliRunner() + result = runner.invoke(config.config.commands['dropcounters'].commands['delete'], [counter_name, '-v']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['dropconfig', '-c', 'uninstall', '-n', str(counter_name)], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_add_reasons(self, mock_run_command): + counter_name = 'DEBUG_2' + reasons = '[EXCEEDS_L2_MTU,DECAP_ERROR]' + runner = CliRunner() + result = runner.invoke(config.config.commands['dropcounters'].commands['add-reasons'], [counter_name, reasons, '-v']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['dropconfig', '-c', 'add', '-n', str(counter_name), '-r', str(reasons)], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_remove_reasons(self, mock_run_command): + counter_name = 'DEBUG_2' + reasons = '[EXCEEDS_L2_MTU,DECAP_ERROR]' + runner = CliRunner() + result = runner.invoke(config.config.commands['dropcounters'].commands['remove-reasons'], [counter_name, reasons, '-v']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['dropconfig', '-c', 'remove', '-n', str(counter_name), '-r', str(reasons)], display_cmd=True) + + def teardown(self): + print("TEARDOWN") + + +class TestConfigWatermarkTelemetry(object): + def setup(self): + print("SETUP") + + @patch('utilities_common.cli.run_command') + def test_interval(self, mock_run_command): + interval = '18' + runner = CliRunner() + result = runner.invoke(config.config.commands['watermark'].commands['telemetry'].commands['interval'], [interval]) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['watermarkcfg', '--config-interval', str(interval)]) + + def teardown(self): + print("TEARDOWN") + + +class TestConfigZtp(object): + def setup(self): + print("SETUP") + + @patch('utilities_common.cli.run_command') + def test_run(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(config.config.commands['ztp'].commands['run'], ['-y']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['ztp', 'run', '-y'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_disable(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(config.config.commands['ztp'].commands['disable'], ['-y']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['ztp', 'disable', '-y'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_enable(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(config.config.commands['ztp'].commands['enable']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['ztp', 'enable'], display_cmd=True) + + def teardown(self): + print("TEARDOWN") + + +@patch('utilities_common.cli.run_command') +@patch('os.uname', MagicMock(return_value=['Linux', 'current-hostname', '5.11.0-34-generic', '#36~20.04.1-Ubuntu SMP Thu Aug 5 14:22:16 UTC 2021', 'x86_64'])) +def test_change_hostname(mock_run_command): + new_hostname = 'new_hostname' + with patch('builtins.open', mock_open()) as mock_file: + config._change_hostname(new_hostname) + + assert mock_file.call_args_list == [ + call('/etc/hostname', 'w'), + call('/etc/hosts', 'a') + ] + assert mock_file().write.call_args_list == [ + call('new_hostname\n'), + call('127.0.0.1 new_hostname\n') + ] + assert mock_run_command.call_args_list == [ + call(['hostname', '-F', '/etc/hostname'], display_cmd=True), + call(['sed', '-i', r"/\scurrent-hostname$/d", '/etc/hosts'], display_cmd=True) + ] + + +class TestConfigInterface(object): + def setup(self): + print("SETUP") + + @patch('utilities_common.cli.run_command') + def test_speed(self, mock_run_command): + interface_name = 'Ethernet0' + interface_speed = '100' + db = Db() + runner = CliRunner() + + obj = {'config_db': db.cfgdb, 'namespace': ''} + result = runner.invoke(config.config.commands['interface'].commands['speed'], [interface_name, interface_speed, '--verbose'], obj=obj) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['portconfig', '-p', str(interface_name), '-s', str(interface_speed), '-vv'], display_cmd=True) + + obj = {'config_db': db.cfgdb, 'namespace': 'ns'} + result = runner.invoke(config.config.commands['interface'].commands['speed'], [interface_name, interface_speed, '--verbose'], obj=obj) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['portconfig', '-p', str(interface_name), '-s', str(interface_speed), '-n', 'ns', '-vv'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_link_training(self, mock_run_command): + interface_name = 'Ethernet0' + mode = 'on' + db = Db() + runner = CliRunner() + + obj = {'config_db': db.cfgdb, 'namespace': ''} + result = runner.invoke(config.config.commands['interface'].commands['link-training'], [interface_name, mode, '--verbose'], obj=obj) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['portconfig', '-p', str(interface_name), '-lt', str(mode), '-vv'], display_cmd=True) + + obj = {'config_db': db.cfgdb, 'namespace': 'ns'} + result = runner.invoke(config.config.commands['interface'].commands['link-training'], [interface_name, mode, '--verbose'], obj=obj) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['portconfig', '-p', str(interface_name), '-lt', str(mode), '-n', 'ns', '-vv'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_advertised_speeds(self, mock_run_command): + interface_name = 'Ethernet0' + speed_list = '50,100' + db = Db() + runner = CliRunner() + + obj = {'config_db': db.cfgdb, 'namespace': ''} + result = runner.invoke(config.config.commands['interface'].commands['advertised-speeds'], [interface_name, speed_list, '--verbose'], obj=obj) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['portconfig', '-p', str(interface_name), '-S', str(speed_list), '-vv'], display_cmd=True) + + obj = {'config_db': db.cfgdb, 'namespace': 'ns'} + result = runner.invoke(config.config.commands['interface'].commands['advertised-speeds'], [interface_name, speed_list, '--verbose'], obj=obj) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['portconfig', '-p', str(interface_name), '-S', str(speed_list), '-n', 'ns', '-vv'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_advertised_types(self, mock_run_command): + interface_name = 'Ethernet0' + interface_type = 'CR,CR4' + db = Db() + runner = CliRunner() + + obj = {'config_db': db.cfgdb, 'namespace': ''} + result = runner.invoke(config.config.commands['interface'].commands['advertised-types'], [interface_name, interface_type, '--verbose'], obj=obj) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['portconfig', '-p', str(interface_name), '-T', str(interface_type), '-vv'], display_cmd=True) + + obj = {'config_db': db.cfgdb, 'namespace': 'ns'} + result = runner.invoke(config.config.commands['interface'].commands['advertised-types'], [interface_name, interface_type, '--verbose'], obj=obj) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['portconfig', '-p', str(interface_name), '-T', str(interface_type), '-n', 'ns', '-vv'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_mtu(self, mock_run_command): + interface_name = 'Ethernet0' + interface_mtu = '1000' + db = Db() + runner = CliRunner() + + obj = {'config_db': db.cfgdb, 'namespace': ''} + result = runner.invoke(config.config.commands['interface'].commands['mtu'], [interface_name, interface_mtu, '--verbose'], obj=obj) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['portconfig', '-p', str(interface_name), '-m', str(interface_mtu), '-vv'], display_cmd=True) + + obj = {'config_db': db.cfgdb, 'namespace': 'ns'} + result = runner.invoke(config.config.commands['interface'].commands['mtu'], [interface_name, interface_mtu, '--verbose'], obj=obj) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['portconfig', '-p', str(interface_name), '-m', str(interface_mtu), '-n', 'ns', '-vv'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_tpid(self, mock_run_command): + interface_name = 'Ethernet0' + interface_tpid = '0x9200' + db = Db() + runner = CliRunner() + + obj = {'config_db': db.cfgdb, 'namespace': ''} + result = runner.invoke(config.config.commands['interface'].commands['tpid'], [interface_name, interface_tpid, '--verbose'], obj=obj) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['portconfig', '-p', str(interface_name), '-tp', str(interface_tpid), '-vv'], display_cmd=True) + + obj = {'config_db': db.cfgdb, 'namespace': 'ns'} + result = runner.invoke(config.config.commands['interface'].commands['tpid'], [interface_name, interface_tpid, '--verbose'], obj=obj) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['portconfig', '-p', str(interface_name), '-tp', str(interface_tpid), '-n', 'ns', '-vv'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_fec(self, mock_run_command): + interface_name = 'Ethernet0' + interface_fec = 'rs' + db = Db() + runner = CliRunner() + + obj = {'config_db': db.cfgdb, 'namespace': ''} + result = runner.invoke(config.config.commands['interface'].commands['fec'], [interface_name, interface_fec, '--verbose'], obj=obj) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['portconfig', '-p', str(interface_name), '-f', str(interface_fec), '-vv'], display_cmd=True) + + obj = {'config_db': db.cfgdb, 'namespace': 'ns'} + result = runner.invoke(config.config.commands['interface'].commands['fec'], [interface_name, interface_fec, '--verbose'], obj=obj) + assert result.exit_code == 0 + mock_run_command.assert_called_with(['portconfig', '-p', str(interface_name), '-f', str(interface_fec), '-n', 'ns', '-vv'], display_cmd=True) + + def teardown(self): + print("TEARDOWN") + diff --git a/tests/conftest.py b/tests/conftest.py index 6e70f8c9aa..fe99ef47bd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -204,7 +204,7 @@ def mock_show_run_bgp(request): return mock_frr_data return "" - def mock_run_bgp_command_for_static(vtysh_cmd, bgp_namespace="", vtysh_shell_cmd=constants.RVTYSH_COMMAND): + def mock_run_bgp_command_for_static(vtysh_cmd, bgp_namespace=[], vtysh_shell_cmd=constants.RVTYSH_COMMAND): if vtysh_cmd == "show ip route vrf all static": return config_int_ip_common.show_ip_route_with_static_expected_output elif vtysh_cmd == "show ipv6 route vrf all static": diff --git a/tests/ecn_test.py b/tests/ecn_test.py index ef1539af17..0eac54ddbb 100644 --- a/tests/ecn_test.py +++ b/tests/ecn_test.py @@ -132,7 +132,7 @@ def executor(self, input): exit_code = result.exit_code output = result.output elif 'q_cmd' in input['cmd'] : - exit_code, output = get_result_and_return_code("ecnconfig {}".format(" ".join(input['args']))) + exit_code, output = get_result_and_return_code(["ecnconfig"] + input['args']) else: exec_cmd = config.config.commands["ecn"] result = runner.invoke(exec_cmd, input['args']) diff --git a/tests/fabricstat_test.py b/tests/fabricstat_test.py index 7c2174b761..7e37e993fe 100644 --- a/tests/fabricstat_test.py +++ b/tests/fabricstat_test.py @@ -135,7 +135,7 @@ def test_single_show_fabric_counters(self): dbconnector.load_database_config dbconnector.load_namespace_config() - return_code, result = get_result_and_return_code('fabricstat') + return_code, result = get_result_and_return_code(['fabricstat']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -159,49 +159,49 @@ def setup_class(cls): os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = "multi_asic" def test_multi_show_fabric_counters(self): - return_code, result = get_result_and_return_code('fabricstat') + return_code, result = get_result_and_return_code(['fabricstat']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == multi_asic_fabric_counters def test_multi_show_fabric_counters_asic(self): - return_code, result = get_result_and_return_code('fabricstat -n asic0') + return_code, result = get_result_and_return_code(['fabricstat', '-n', 'asic0']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == multi_asic_fabric_counters_asic0 def test_multi_asic_invalid_asic(self): - return_code, result = get_result_and_return_code('fabricstat -n asic99') + return_code, result = get_result_and_return_code(['fabricstat', '-n', 'asic99']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 1 assert result == fabric_invalid_asic_error def test_multi_show_fabric_counters_queue(self): - return_code, result = get_result_and_return_code('fabricstat -q') + return_code, result = get_result_and_return_code(['fabricstat', '-q']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == multi_asic_fabric_counters_queue def test_multi_show_fabric_counters_queue_asic(self): - return_code, result = get_result_and_return_code('fabricstat -q -n asic0') + return_code, result = get_result_and_return_code(['fabricstat', '-q', '-n', 'asic0']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == multi_asic_fabric_counters_queue_asic0 def test_multi_show_fabric_reachability(self): - return_code, result = get_result_and_return_code('fabricstat -r') + return_code, result = get_result_and_return_code(['fabricstat', '-r']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == multi_asic_fabric_reachability def test_multi_show_fabric_reachability_asic(self): - return_code, result = get_result_and_return_code('fabricstat -r -n asic0') + return_code, result = get_result_and_return_code(['fabricstat', '-r', '-n', 'asic0']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 diff --git a/tests/fdbshow_test.py b/tests/fdbshow_test.py index 8814a6b323..578b278a95 100755 --- a/tests/fdbshow_test.py +++ b/tests/fdbshow_test.py @@ -171,7 +171,7 @@ def test_show_mac_def_vlan(self): assert result.exit_code == 0 assert result.output == show_mac_output_with_def_vlan - return_code, result = get_result_and_return_code('fdbshow') + return_code, result = get_result_and_return_code(['fdbshow']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -216,7 +216,7 @@ def test_show_mac(self): assert result.exit_code == 0 assert result.output == show_mac_output - return_code, result = get_result_and_return_code('fdbshow') + return_code, result = get_result_and_return_code(['fdbshow']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -231,7 +231,7 @@ def test_show_mac_count(self): assert result.exit_code == 0 assert result.output == show_mac_count_output - return_code, result = get_result_and_return_code('fdbshow -c') + return_code, result = get_result_and_return_code(['fdbshow', '-c']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -246,7 +246,7 @@ def test_show_mac_port_vlan(self): assert result.exit_code == 0 assert result.output == show_mac__port_vlan_output - return_code, result = get_result_and_return_code('fdbshow -p Ethernet0 -v 2') + return_code, result = get_result_and_return_code(['fdbshow', '-p', 'Ethernet0', '-v', '2']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -261,7 +261,7 @@ def test_show_mac_address(self): assert result.exit_code == 0 assert result.output == show_mac__address_output - return_code, result = get_result_and_return_code('fdbshow -a 11:22:33:66:55:44') + return_code, result = get_result_and_return_code(['fdbshow', '-a', '11:22:33:66:55:44']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -276,7 +276,7 @@ def test_show_mac_address_case(self): assert result.exit_code == 0 assert result.output == show_mac__address_case_output - return_code, result = get_result_and_return_code('fdbshow -a 34:5f:78:9a:bc:de') + return_code, result = get_result_and_return_code(['fdbshow', '-a', '34:5f:78:9a:bc:de']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -291,7 +291,7 @@ def test_show_mac_type(self): assert result.exit_code == 0 assert result.output == show_mac__type_output - return_code, result = get_result_and_return_code('fdbshow -t Static') + return_code, result = get_result_and_return_code(['fdbshow', '-t', 'Static']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -306,7 +306,7 @@ def test_show_mac_type_case(self): assert result.exit_code == 0 assert result.output == show_mac__type_case_output - return_code, result = get_result_and_return_code('fdbshow -t DYNAMIC') + return_code, result = get_result_and_return_code(['fdbshow', '-t', 'DYNAMIC']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -321,7 +321,7 @@ def test_show_mac_port_address(self): assert result.exit_code == 0 assert result.output == show_mac__port_address_output - return_code, result = get_result_and_return_code('fdbshow -a 66:55:44:33:22:11 -p Ethernet0') + return_code, result = get_result_and_return_code(['fdbshow', '-a', '66:55:44:33:22:11', '-p', 'Ethernet0']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -336,7 +336,7 @@ def test_show_mac_vlan_address(self): assert result.exit_code == 0 assert result.output == show_mac__vlan_address_output - return_code, result = get_result_and_return_code('fdbshow -a 66:55:44:33:22:11 -v 4') + return_code, result = get_result_and_return_code(['fdbshow', '-a', '66:55:44:33:22:11', '-v', '4']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -351,7 +351,7 @@ def test_show_mac_port_type(self): assert result.exit_code == 0 assert result.output == show_mac__port_type_output - return_code, result = get_result_and_return_code('fdbshow -p Ethernet4 -t Static') + return_code, result = get_result_and_return_code(['fdbshow', '-p', 'Ethernet4', '-t', 'Static']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -366,7 +366,7 @@ def test_show_mac_vlan_type(self): assert result.exit_code == 0 assert result.output == show_mac__vlan_type_output - return_code, result = get_result_and_return_code('fdbshow -v 3 -t Static') + return_code, result = get_result_and_return_code(['fdbshow', '-v', '3', '-t', 'Static']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -381,7 +381,7 @@ def test_show_mac_address_type(self): assert result.exit_code == 0 assert result.output == show_mac__address_type_output - return_code, result = get_result_and_return_code('fdbshow -a 11:22:33:66:55:44 -t Static') + return_code, result = get_result_and_return_code(['fdbshow', '-a', '11:22:33:66:55:44', '-t', 'Static']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -396,7 +396,7 @@ def test_show_mac_port_vlan_address_type(self): assert result.exit_code == 0 assert result.output == show_mac__port_vlan_address_type_output - return_code, result = get_result_and_return_code('fdbshow -v 3 -p Ethernet4 -a 11:22:33:66:55:44 -t Static') + return_code, result = get_result_and_return_code(['fdbshow', '-v', '3', '-p', 'Ethernet4', '-a', '11:22:33:66:55:44', '-t', 'Static']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -411,7 +411,7 @@ def test_show_mac_no_port(self): assert result.exit_code == 0 assert result.output == show_mac_no_results_output - return_code, result = get_result_and_return_code('fdbshow -p Ethernet8') + return_code, result = get_result_and_return_code(['fdbshow', '-p', 'Ethernet8']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -426,7 +426,7 @@ def test_show_mac_no_vlan(self): assert result.exit_code == 0 assert result.output == show_mac_no_results_output - return_code, result = get_result_and_return_code('fdbshow -v 123') + return_code, result = get_result_and_return_code(['fdbshow', '-v', '123']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -441,7 +441,7 @@ def test_show_mac_no_address(self): assert result.exit_code == 0 assert result.output == show_mac_no_results_output - return_code, result = get_result_and_return_code('fdbshow -a 12:34:56:78:9A:BC') + return_code, result = get_result_and_return_code(['fdbshow', '-a', '12:34:56:78:9A:BC']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -456,7 +456,7 @@ def test_show_mac_no_type(self): assert result.exit_code == 0 assert result.output == show_mac_no_results_output - return_code, result = get_result_and_return_code('fdbshow -t Static') + return_code, result = get_result_and_return_code(['fdbshow', '-t', 'Static']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -471,7 +471,7 @@ def test_show_mac_no_fdb(self): assert result.exit_code == 0 assert result.output == show_mac_no_results_output - return_code, result = get_result_and_return_code('fdbshow') + return_code, result = get_result_and_return_code(['fdbshow']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -486,7 +486,7 @@ def test_show_mac_no_bridge(self): assert result.exit_code == 0 assert result.output == show_mac_no_results_output - return_code, result = get_result_and_return_code('fdbshow') + return_code, result = get_result_and_return_code(['fdbshow']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -522,7 +522,7 @@ def test_show_mac_invalid_port(self): assert result.exit_code == 1 assert result.output == show_mac_invalid_port_output - return_code, result = get_result_and_return_code('fdbshow -p eth123') + return_code, result = get_result_and_return_code(['fdbshow', '-p', 'eth123']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 1 @@ -537,7 +537,7 @@ def test_show_mac_invalid_vlan(self): assert result.exit_code == 1 assert result.output == show_mac_invalid_vlan_output - return_code, result = get_result_and_return_code('fdbshow -v 10000') + return_code, result = get_result_and_return_code(['fdbshow', '-v', '10000']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 1 @@ -552,7 +552,7 @@ def test_show_mac_invalid_type(self): assert result.exit_code == 1 assert result.output == show_mac_invalid_type_output - return_code, result = get_result_and_return_code('fdbshow -t both') + return_code, result = get_result_and_return_code(['fdbshow', '-t', 'both']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 1 @@ -567,7 +567,7 @@ def test_show_mac_invalid_address(self): assert result.exit_code == 1 assert result.output == show_mac_invalid_address_output - return_code, result = get_result_and_return_code('fdbshow -a 12:345:67:a9:bc:d') + return_code, result = get_result_and_return_code(['fdbshow', '-a', '12:345:67:a9:bc:d']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 1 diff --git a/tests/flow_counter_stats_test.py b/tests/flow_counter_stats_test.py index dc5bb22dee..1ddd5031bc 100644 --- a/tests/flow_counter_stats_test.py +++ b/tests/flow_counter_stats_test.py @@ -270,7 +270,7 @@ """ def delete_cache(stat_type='trap'): - cmd = 'flow_counters_stat -t {} -d'.format(stat_type) + cmd = ['flow_counters_stat', '-t', stat_type, '-d'] get_result_and_return_code(cmd) @@ -294,7 +294,7 @@ def test_show(self): assert result.output == expect_show_output def test_show_json(self): - cmd = 'flow_counters_stat -t trap -j' + cmd = ['flow_counters_stat', '-t', 'trap', '-j'] return_code, result = get_result_and_return_code(cmd) assert return_code == 0 assert result == expect_show_output_json @@ -382,7 +382,7 @@ def test_show(self): assert result.output == expect_show_output_multi_asic def test_show_json(self): - cmd = 'flow_counters_stat -t trap -j' + cmd = ['flow_counters_stat', '-t', 'trap', '-j'] return_code, result = get_result_and_return_code(cmd) assert return_code == 0 assert result == expect_show_output_json_multi_asic @@ -764,17 +764,17 @@ def test_show_by_route(self): print(result.output) def test_show_json(self): - cmd = 'flow_counters_stat -t route -j' + cmd = ['flow_counters_stat', '-t', 'route', '-j'] return_code, result = get_result_and_return_code(cmd) assert return_code == 0 assert result == expect_show_route_stats_all_json - cmd = 'flow_counters_stat -t route -j --prefix_pattern 1.1.1.0/24' + cmd = ['flow_counters_stat', '-t', 'route', '-j', '--prefix_pattern', '1.1.1.0/24'] return_code, result = get_result_and_return_code(cmd) assert return_code == 0 assert result == expect_show_route_stats_by_pattern_v4_json - cmd = 'flow_counters_stat -t route -j --prefix 2001::1/64 --vrf Vrf_1' + cmd = ['flow_counters_stat', '-t', 'route', '-j', '--prefix', '2001::1/64', '--vrf', 'Vrf_1'] return_code, result = get_result_and_return_code(cmd) assert return_code == 0 assert result == expect_show_route_stats_by_pattern_and_vrf_v6_json @@ -916,7 +916,7 @@ def test_show_all_stats(self): assert expect_show_route_stats_all_multi_asic == result.output def test_show_json(self): - cmd = 'flow_counters_stat -t route -j' + cmd = ['flow_counters_stat', '-t', 'route', '-j'] return_code, result = get_result_and_return_code(cmd) assert return_code == 0 assert result == expect_show_route_stats_all_json_multi_asic diff --git a/tests/multi_asic_intfutil_test.py b/tests/multi_asic_intfutil_test.py index 37e5b5b0f0..1b3655e44e 100644 --- a/tests/multi_asic_intfutil_test.py +++ b/tests/multi_asic_intfutil_test.py @@ -98,70 +98,70 @@ def setUp(self): self.runner = CliRunner() def test_multi_asic_interface_status_all(self): - return_code, result = get_result_and_return_code( 'intfutil -c status -d all') + return_code, result = get_result_and_return_code(['intfutil', '-c', 'status', '-d', 'all']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == intf_status_all def test_multi_asic_interface_status(self): - return_code, result = get_result_and_return_code('intfutil -c status') + return_code, result = get_result_and_return_code(['intfutil', '-c', 'status']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == intf_status def test_multi_asic_interface_status_asic0_all(self): - return_code, result = get_result_and_return_code('intfutil -c status -n asic0 -d all') + return_code, result = get_result_and_return_code(['intfutil', '-c', 'status', '-n', 'asic0', '-d', 'all']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == intf_status_asic0_all def test_multi_asic_interface_status_asic0(self): - return_code, result = get_result_and_return_code('intfutil -c status -n asic0') + return_code, result = get_result_and_return_code(['intfutil', '-c', 'status', '-n', 'asic0']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == intf_status_asic0 def test_multi_asic_interface_desc(self): - return_code, result = get_result_and_return_code('intfutil -c description') + return_code, result = get_result_and_return_code(['intfutil', '-c', 'description']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == intf_description def test_multi_asic_interface_desc_all(self): - return_code, result = get_result_and_return_code( 'intfutil -c description -d all') + return_code, result = get_result_and_return_code(['intfutil', '-c', 'description', '-d', 'all']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == intf_description_all def test_multi_asic_interface_asic0(self): - return_code, result = get_result_and_return_code( 'intfutil -c description -n asic0') + return_code, result = get_result_and_return_code(['intfutil', '-c', 'description', '-n', 'asic0']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == intf_description_asic0 def test_multi_asic_interface_desc_asic0_all(self): - return_code, result = get_result_and_return_code('intfutil -c description -n asic0 -d all') + return_code, result = get_result_and_return_code(['intfutil', '-c', 'description', '-n', 'asic0', '-d', 'all']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == intf_description_asic0_all def test_invalid_asic_name(self): - return_code, result = get_result_and_return_code('intfutil -c description -n asic99 -d all') + return_code, result = get_result_and_return_code(['intfutil', '-c', 'description', '-n', 'asic99', '-d', 'all']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 1 assert result == intf_invalid_asic_error def test_invalid_asic_name(self): - return_code, result = get_result_and_return_code('intfutil -c status -n asic99') + return_code, result = get_result_and_return_code(['intfutil', '-c', 'status', '-n', 'asic99']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 1 diff --git a/tests/multi_asic_queue_counter_test.py b/tests/multi_asic_queue_counter_test.py index c501c68609..fe8b057b5d 100644 --- a/tests/multi_asic_queue_counter_test.py +++ b/tests/multi_asic_queue_counter_test.py @@ -132,13 +132,13 @@ def setup_class(cls): print("SETUP") def test_queue_counters(self): - return_code, result = get_result_and_return_code('queuestat -n asic0') + return_code, result = get_result_and_return_code(['queuestat', '-n', 'asic0']) assert return_code == 0 print(result) assert result == show_queue_counters def test_queue_counters_port(self): - return_code, result = get_result_and_return_code('queuestat -p Ethernet-BP4 -n asic0') + return_code, result = get_result_and_return_code(['queuestat', '-p', 'Ethernet-BP4', '-n', 'asic0']) assert return_code == 0 print(result) assert result == show_queue_counters_port diff --git a/tests/pfcstat_test.py b/tests/pfcstat_test.py index fc24dd090d..6ac0401b24 100644 --- a/tests/pfcstat_test.py +++ b/tests/pfcstat_test.py @@ -174,11 +174,11 @@ def pfc_clear(expected_output): del_cached_stats() return_code, result = get_result_and_return_code( - 'pfcstat -c' + ['pfcstat', '-c'] ) return_code, result = get_result_and_return_code( - 'pfcstat -s all' + ['pfcstat', '-s', 'all'] ) result_stat = [s for s in result.split("\n") if "Last cached" not in s] expected = expected_output.split("\n") @@ -270,21 +270,21 @@ def test_pfc_counters_all_with_clear(self): def test_pfc_counters_frontend(self): return_code, result = get_result_and_return_code( - 'pfcstat -s frontend' + ['pfcstat', '-s', 'frontend'] ) assert return_code == 0 assert result == show_pfc_counters_asic0_frontend def test_pfc_counters_asic(self): return_code, result = get_result_and_return_code( - 'pfcstat -n asic0' + ['pfcstat', '-n', 'asic0'] ) assert return_code == 0 assert result == show_pfc_counters_asic0_frontend def test_pfc_counters_asic_all(self): return_code, result = get_result_and_return_code( - 'pfcstat -n asic0 -s all' + ['pfcstat', '-n', 'asic0', '-s', 'all'] ) assert return_code == 0 assert result == show_pfc_counters_all_asic diff --git a/tests/portstat_test.py b/tests/portstat_test.py index d418a16feb..bf7a2db190 100644 --- a/tests/portstat_test.py +++ b/tests/portstat_test.py @@ -269,7 +269,7 @@ def test_show_intf_counters(self): assert result.exit_code == 0 assert result.output == intf_counters_before_clear - return_code, result = get_result_and_return_code('portstat') + return_code, result = get_result_and_return_code(['portstat']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -278,14 +278,14 @@ def test_show_intf_counters(self): def test_show_intf_counters_ethernet4(self): runner = CliRunner() result = runner.invoke( - show.cli.commands["interfaces"].commands["counters"], ["-i Ethernet4"]) + show.cli.commands["interfaces"].commands["counters"], ["-i", "Ethernet4"]) print(result.exit_code) print(result.output) assert result.exit_code == 0 assert result.output == intf_counters_ethernet4 return_code, result = get_result_and_return_code( - 'portstat -i Ethernet4') + ['portstat', '-i', 'Ethernet4']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -300,7 +300,7 @@ def test_show_intf_counters_all(self): assert result.exit_code == 0 assert result.output == intf_counters_all - return_code, result = get_result_and_return_code('portstat -a') + return_code, result = get_result_and_return_code(['portstat', '-a']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -315,7 +315,7 @@ def test_show_intf_fec_counters(self): assert result.exit_code == 0 assert result.output == intf_fec_counters - return_code, result = get_result_and_return_code('portstat -f') + return_code, result = get_result_and_return_code(['portstat', '-f']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -331,7 +331,7 @@ def test_show_intf_fec_counters_period(self): assert result.output == intf_fec_counters_period return_code, result = get_result_and_return_code( - 'portstat -f -p {}'.format(TEST_PERIOD)) + ['portstat', '-f', '-p', str(TEST_PERIOD)]) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -349,7 +349,7 @@ def test_show_intf_counters_period(self): assert result.output == intf_counters_period return_code, result = get_result_and_return_code( - 'portstat -p {}'.format(TEST_PERIOD)) + ['portstat', '-p', str(TEST_PERIOD)]) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -364,7 +364,7 @@ def test_show_intf_counters_detailed(self): assert result.exit_code == 0 assert result.output == intf_counters_detailed - return_code, result = get_result_and_return_code('portstat -l -i Ethernet4') + return_code, result = get_result_and_return_code(['portstat', '-l', '-i', 'Ethernet4']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -378,7 +378,7 @@ def test_clear_intf_counters(self): assert result.exit_code == 0 assert result.output.rstrip() == clear_counter - return_code, result = get_result_and_return_code('portstat -c') + return_code, result = get_result_and_return_code(['portstat', '-c']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -392,7 +392,7 @@ def test_clear_intf_counters(self): assert result.exit_code == 0 verify_after_clear(result.output, intf_counter_after_clear) - return_code, result = get_result_and_return_code('portstat') + return_code, result = get_result_and_return_code(['portstat']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -417,21 +417,21 @@ def setup_class(cls): remove_tmp_cnstat_file() def test_multi_show_intf_counters(self): - return_code, result = get_result_and_return_code('portstat') + return_code, result = get_result_and_return_code(['portstat']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == multi_asic_external_intf_counters def test_multi_show_intf_counters_all(self): - return_code, result = get_result_and_return_code('portstat -s all') + return_code, result = get_result_and_return_code(['portstat', '-s', 'all']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == multi_asic_all_intf_counters def test_multi_show_intf_counters_asic(self): - return_code, result = get_result_and_return_code('portstat -n asic0') + return_code, result = get_result_and_return_code(['portstat', '-n', 'asic0']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -439,21 +439,21 @@ def test_multi_show_intf_counters_asic(self): def test_multi_show_intf_counters_asic_all(self): return_code, result = get_result_and_return_code( - 'portstat -n asic0 -s all') + ['portstat', '-n', 'asic0', '-s', 'all']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == multi_asic_intf_counters_asic0 def test_multi_show_external_intf_counters_printall(self): - return_code, result = get_result_and_return_code('portstat -a') + return_code, result = get_result_and_return_code(['portstat', '-a']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == multi_asic_external_intf_counters_printall def test_multi_show_intf_counters_printall(self): - return_code, result = get_result_and_return_code('portstat -a -s all') + return_code, result = get_result_and_return_code(['portstat', '-a', '-s', 'all']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -461,7 +461,7 @@ def test_multi_show_intf_counters_printall(self): def test_multi_show_intf_counters_printall_asic(self): return_code, result = get_result_and_return_code( - 'portstat --a -n asic0') + ['portstat', '--a', '-n', 'asic0']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -469,7 +469,7 @@ def test_multi_show_intf_counters_printall_asic(self): def test_multi_show_intf_counters_printall_asic_all(self): return_code, result = get_result_and_return_code( - 'portstat -a -n asic0 -s all') + ['portstat', '-a', '-n', 'asic0', '-s', 'all']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -477,7 +477,7 @@ def test_multi_show_intf_counters_printall_asic_all(self): def test_multi_show_intf_counters_period(self): return_code, result = get_result_and_return_code( - 'portstat -p {}'.format(TEST_PERIOD)) + ['portstat', '-p', str(TEST_PERIOD)]) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -485,7 +485,7 @@ def test_multi_show_intf_counters_period(self): def test_multi_show_intf_counters_period_all(self): return_code, result = get_result_and_return_code( - 'portstat -p {} -s all'.format(TEST_PERIOD)) + ['portstat', '-p', str(TEST_PERIOD), '-s', 'all']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -493,7 +493,7 @@ def test_multi_show_intf_counters_period_all(self): def test_multi_show_intf_counters_period_asic(self): return_code, result = get_result_and_return_code( - 'portstat -p {} -n asic0'.format(TEST_PERIOD)) + ['portstat', '-p', str(TEST_PERIOD), '-n', 'asic0']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 @@ -501,28 +501,28 @@ def test_multi_show_intf_counters_period_asic(self): def test_multi_show_intf_counters_period_asic_all(self): return_code, result = get_result_and_return_code( - 'portstat -p {} -n asic0 -s all'.format(TEST_PERIOD)) + ['portstat', '-p', str(TEST_PERIOD), '-n', 'asic0', '-s', 'all']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result == multi_asic_intf_counter_period_asic_all def test_multi_asic_clear_intf_counters(self): - return_code, result = get_result_and_return_code('portstat -c') + return_code, result = get_result_and_return_code(['portstat', '-c']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 assert result.rstrip() == clear_counter # check stats for all the interfaces are cleared - return_code, result = get_result_and_return_code('portstat -s all') + return_code, result = get_result_and_return_code(['portstat', '-s', 'all']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 0 verify_after_clear(result, mutli_asic_intf_counters_after_clear) def test_multi_asic_invalid_asic(self): - return_code, result = get_result_and_return_code('portstat -n asic99') + return_code, result = get_result_and_return_code(['portstat', '-n', 'asic99']) print("return_code: {}".format(return_code)) print("result = {}".format(result)) assert return_code == 1 diff --git a/tests/sfp_test.py b/tests/sfp_test.py index b6b94ebff6..4900071898 100644 --- a/tests/sfp_test.py +++ b/tests/sfp_test.py @@ -1,8 +1,8 @@ import sys import os from click.testing import CliRunner - from .mock_tables import dbconnector +from unittest.mock import patch, MagicMock test_path = os.path.dirname(os.path.abspath(__file__)) modules_path = os.path.dirname(test_path) @@ -10,6 +10,7 @@ sys.path.insert(0, modules_path) import show.main as show +import show as show_module test_sfp_eeprom_with_dom_output = """\ Ethernet0: SFP EEPROM detected @@ -510,13 +511,13 @@ def test_sfp_presence(self): def test_sfp_eeprom_with_dom(self): runner = CliRunner() - result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["eeprom"], ["Ethernet0 -d"]) + result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["eeprom"], ["Ethernet0", "-d"]) assert result.exit_code == 0 assert "\n".join([ l.rstrip() for l in result.output.split('\n')]) == test_sfp_eeprom_with_dom_output def test_qsfp_dd_eeprom_with_dom(self): runner = CliRunner() - result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["eeprom"], ["Ethernet8 -d"]) + result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["eeprom"], ["Ethernet8", "-d"]) assert result.exit_code == 0 assert result.output == test_qsfp_dd_eeprom_with_dom_output @@ -583,9 +584,10 @@ def setup_class(cls): os.environ["UTILITIES_UNIT_TESTING"] = "2" os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = "multi_asic" + @patch.object(show_module.interfaces.click.Choice, 'convert', MagicMock(return_value='asic0')) def test_sfp_presence_with_ns(self): runner = CliRunner() - result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["presence"], ["Ethernet0 -n asic0"]) + result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["presence"], ['Ethernet0', '-n', 'asic0']) expected = """Port Presence --------- ---------- Ethernet0 Present @@ -593,7 +595,7 @@ def test_sfp_presence_with_ns(self): assert result.exit_code == 0 assert result.output == expected - result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["presence"], ["Ethernet200 -n asic0"]) + result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["presence"], ['Ethernet200', '-n', 'asic0']) expected = """Port Presence ----------- ----------- Ethernet200 Not present @@ -607,33 +609,37 @@ def test_sfp_presence_all(self): assert result.exit_code == 0 assert "\n".join([ l.rstrip() for l in result.output.split('\n')]) == test_sfp_presence_all_output + @patch.object(show_module.interfaces.click.Choice, 'convert', MagicMock(return_value='asic0')) def test_sfp_eeprom_with_dom_with_ns(self): runner = CliRunner() - result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["eeprom"], ["Ethernet0 -d -n asic0"]) + result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["eeprom"], ['Ethernet0', '-d', '-n', 'asic0']) assert result.exit_code == 0 assert "\n".join([ l.rstrip() for l in result.output.split('\n')]) == test_sfp_eeprom_with_dom_output + @patch.object(show_module.interfaces.click.Choice, 'convert', MagicMock(return_value='asic0')) def test_sfp_eeprom_with_ns(self): runner = CliRunner() - result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["eeprom"], ["Ethernet0 -n asic0"]) + result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["eeprom"], ['Ethernet0', '-n', 'asic0']) assert result.exit_code == 0 assert "\n".join([ l.rstrip() for l in result.output.split('\n')]) == test_sfp_eeprom_output - result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["eeprom"], ["Ethernet200 -n asic0"]) + result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["eeprom"], ['Ethernet200', '-n', 'asic0']) result_lines = result.output.strip('\n') expected = "Ethernet200: SFP EEPROM Not detected" assert result_lines == expected + @patch.object(show_module.interfaces.click.Choice, 'convert', MagicMock(return_value='asic0')) def test_qsfp_dd_pm_with_ns(self): runner = CliRunner() - result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["pm"], ["Ethernet0 -n asic0"]) + result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["pm"], ['Ethernet0', '-n', 'asic0']) result_lines = result.output.strip('\n') expected = "Ethernet0: Transceiver performance monitoring not applicable" assert result_lines == expected + @patch.object(show_module.interfaces.click.Choice, 'convert', MagicMock(return_value='asic1')) def test_cmis_sfp_info_with_ns(self): runner = CliRunner() - result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["info"], ["Ethernet64 -n asic1"]) + result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["info"], ['Ethernet64', '-n', 'asic1']) assert result.exit_code == 0 assert "\n".join([ l.rstrip() for l in result.output.split('\n')]) == test_cmis_eeprom_output diff --git a/tests/show_ip_int_test.py b/tests/show_ip_int_test.py index d2abdbbf5d..16160df75d 100644 --- a/tests/show_ip_int_test.py +++ b/tests/show_ip_int_test.py @@ -101,18 +101,18 @@ def verify_output(output, expected_output): class TestShowIpInt(object): def test_show_ip_intf_v4(self): - return_code, result = get_result_and_return_code(" ipintutil") + return_code, result = get_result_and_return_code(["ipintutil"]) assert return_code == 0 verify_output(result, show_ipv4_intf_with_multple_ips) def test_show_ip_intf_v6(self): - return_code, result = get_result_and_return_code(" ipintutil -a ipv6") + return_code, result = get_result_and_return_code(['ipintutil', '-a', 'ipv6']) assert return_code == 0 verify_output(result, show_ipv6_intf_with_multiple_ips) def test_show_intf_invalid_af_option(self): - return_code, result = get_result_and_return_code(" ipintutil -a ipv5") + return_code, result = get_result_and_return_code(['ipintutil', '-a', 'ipv5']) assert return_code == 1 assert result == show_error_invalid_af @@ -121,36 +121,36 @@ def test_show_intf_invalid_af_option(self): class TestMultiAsicShowIpInt(object): def test_show_ip_intf_v4(self): - return_code, result = get_result_and_return_code("ipintutil") + return_code, result = get_result_and_return_code(["ipintutil"]) assert return_code == 0 verify_output(result, show_multi_asic_ip_intf) def test_show_ip_intf_v4_asic0(self): - return_code, result = get_result_and_return_code("ipintutil -n asic0") + return_code, result = get_result_and_return_code(['ipintutil', '-n', 'asic0']) assert return_code == 0 verify_output(result, show_multi_asic_ip_intf) def test_show_ip_intf_v4_all(self): - return_code, result = get_result_and_return_code("ipintutil -d all") + return_code, result = get_result_and_return_code(['ipintutil', '-d', 'all']) assert return_code == 0 verify_output(result, show_multi_asic_ip_intf_all) def test_show_ip_intf_v6(self): - return_code, result = get_result_and_return_code("ipintutil -a ipv6") + return_code, result = get_result_and_return_code(['ipintutil', '-a', 'ipv6']) assert return_code == 0 verify_output(result, show_multi_asic_ipv6_intf) def test_show_ip_intf_v6_asic0(self): - return_code, result = get_result_and_return_code("ipintutil -a ipv6 -n asic0") + return_code, result = get_result_and_return_code(['ipintutil', '-a', 'ipv6', '-n', 'asic0']) assert return_code == 0 verify_output(result, show_multi_asic_ipv6_intf) def test_show_ip_intf_v6_all(self): - return_code, result = get_result_and_return_code("ipintutil -a ipv6 -d all") + return_code, result = get_result_and_return_code(['ipintutil', '-a', 'ipv6', '-d', 'all']) assert return_code == 0 verify_output(result, show_multi_asic_ipv6_intf_all) def test_show_intf_invalid_af_option(self): - return_code, result = get_result_and_return_code(" ipintutil -a ipv5") + return_code, result = get_result_and_return_code(['ipintutil', '-a', 'ipv5']) assert return_code == 1 assert result == show_error_invalid_af diff --git a/tests/show_platform_test.py b/tests/show_platform_test.py index 4dcf73a978..a867f067ee 100644 --- a/tests/show_platform_test.py +++ b/tests/show_platform_test.py @@ -62,28 +62,28 @@ def test_all_psus(self): with mock.patch('utilities_common.cli.run_command') as mock_run_command: CliRunner().invoke(show.cli.commands['platform'].commands['psustatus'], []) assert mock_run_command.call_count == 1 - mock_run_command.assert_called_with('psushow -s', display_cmd=False) + mock_run_command.assert_called_with(['psushow', '-s'], display_cmd=False) def test_all_psus_json(self): with mock.patch('utilities_common.cli.run_command') as mock_run_command: CliRunner().invoke(show.cli.commands['platform'].commands['psustatus'], ['--json']) assert mock_run_command.call_count == 1 - mock_run_command.assert_called_with('psushow -s -j', display_cmd=False) + mock_run_command.assert_called_with(['psushow', '-s', '-j'], display_cmd=False) def test_single_psu(self): with mock.patch('utilities_common.cli.run_command') as mock_run_command: CliRunner().invoke(show.cli.commands['platform'].commands['psustatus'], ['--index=1']) assert mock_run_command.call_count == 1 - mock_run_command.assert_called_with('psushow -s -i 1', display_cmd=False) + mock_run_command.assert_called_with(['psushow', '-s', '-i', '1'], display_cmd=False) def test_single_psu_json(self): with mock.patch('utilities_common.cli.run_command') as mock_run_command: CliRunner().invoke(show.cli.commands['platform'].commands['psustatus'], ['--index=1', '--json']) assert mock_run_command.call_count == 1 - mock_run_command.assert_called_with('psushow -s -i 1 -j', display_cmd=False) + mock_run_command.assert_called_with(['psushow', '-s', '-i', '1', '-j'], display_cmd=False) def test_verbose(self): with mock.patch('utilities_common.cli.run_command') as mock_run_command: CliRunner().invoke(show.cli.commands['platform'].commands['psustatus'], ['--verbose']) assert mock_run_command.call_count == 1 - mock_run_command.assert_called_with('psushow -s', display_cmd=True) + mock_run_command.assert_called_with(['psushow', '-s'], display_cmd=True) diff --git a/tests/show_test.py b/tests/show_test.py index ddb59078b2..7b3e492fc9 100644 --- a/tests/show_test.py +++ b/tests/show_test.py @@ -1,9 +1,10 @@ import os import sys +import click import pytest import show.main as show -from click.testing import CliRunner from unittest import mock +from click.testing import CliRunner from unittest.mock import call, MagicMock, patch EXPECTED_BASE_COMMAND = 'sudo ' @@ -13,6 +14,15 @@ sys.path.insert(0, test_path) sys.path.insert(0, modules_path) +expected_nat_config_output = \ +""" +Global Values +Static Entries +Pool Entries +NAT Bindings +NAT Zones +""" + class TestShowRunAllCommands(object): @classmethod @@ -147,3 +157,487 @@ def test_show_version(): runner = CliRunner() result = runner.invoke(show.cli.commands["version"]) assert "SONiC OS Version: 11" in result.output + + +class TestShowAcl(object): + def setup(self): + print('SETUP') + + @patch('utilities_common.cli.run_command') + def test_rule(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['acl'].commands['rule'], ['SNMP_ACL', 'RULE_1', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['acl-loader', 'show', 'rule', 'SNMP_ACL', 'RULE_1'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_table(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['acl'].commands['table'], ['EVERFLOW', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['acl-loader', 'show', 'table', 'EVERFLOW'], display_cmd=True) + + def teardown(self): + print('TEAR DOWN') + + +class TestShowChassis(object): + def setup(self): + print('SETUP') + + @patch('utilities_common.cli.run_command') + def test_system_ports(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['chassis'].commands['system-ports'], ['Linecard1|asic0|Ethernet0', '-n', 'asic0', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['voqutil', '-c', 'system_ports', '-i', 'Linecard1|asic0|Ethernet0', '-n', 'asic0'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_system_neighbors(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['chassis'].commands['system-neighbors'], ['10.0.0.0', '-n', 'asic0', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['voqutil', '-c', 'system_neighbors', '-a', '10.0.0.0', '-n', 'asic0'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_system_lags(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['chassis'].commands['system-lags'], ['-l', 'Linecard6' , '-n', 'asic0', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['voqutil', '-c', 'system_lags', '-n', 'asic0', '-l', 'Linecard6'], display_cmd=True) + + def teardown(self): + print('TEAR DOWN') + + +class TestShowFabric(object): + def setup(self): + print('SETUP') + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_port(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['fabric'].commands['counters'].commands['port'], ['-n', 'asic0', '-e']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(["fabricstat", '-n', 'asic0', '-e']) + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_queue(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['fabric'].commands['counters'].commands['queue'], ['-n', 'asic0']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(["fabricstat", '-q', '-n', 'asic0']) + + def teardown(self): + print('TEAR DOWN') + + +class TestShowFlowCounters(object): + def setup(self): + print('SETUP') + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_flowcnt_trap_stats(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['flowcnt-trap'].commands['stats'], ['-n', 'asic0', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['flow_counters_stat', '-t', 'trap', '-n', 'asic0'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_flowcnt_route_stats(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['flowcnt-route'].commands['stats'], ['-n', 'asic0', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['flow_counters_stat', '-t', 'route', '-n', 'asic0'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_flowcnt_route_stats_pattern(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['flowcnt-route'].commands['stats'].commands['pattern'], ['2001::/64', '--vrf', 'Vrf_1', '-n', 'asic0', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['flow_counters_stat', '-t', 'route', '--prefix_pattern', '2001::/64', '--vrf', 'Vrf_1', '-n', 'asic0'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_flowcnt_route_stats_route(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['flowcnt-route'].commands['stats'].commands['route'], ['2001::/64', '--vrf', 'Vrf_1', '-n', 'asic0', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['flow_counters_stat', '-t', 'route', '--prefix', '2001::/64', '--vrf', 'Vrf_1', '-n', 'asic0'], display_cmd=True) + + def teardown(self): + print('TEAR DOWN') + + +class TestShowInterfaces(object): + def setup(self): + print('SETUP') + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_description(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['interfaces'].commands['description'], ['Ethernet0', '-n', 'asic0', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['intfutil', '-c', 'description', '-i', 'Ethernet0', '-n', 'asic0'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_status(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['interfaces'].commands['status'], ['Ethernet0', '-n', 'asic0', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['intfutil', '-c', 'status', '-i', 'Ethernet0', '-n', 'asic0'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_tpid(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['interfaces'].commands['tpid'], ['Ethernet0', '-n', 'asic0', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['intfutil', '-c', 'tpid', '-i', 'Ethernet0', '-n', 'asic0'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_transceiver_lpmode(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['interfaces'].commands['transceiver'].commands['lpmode'], ['Ethernet0', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['sudo', 'sfputil', 'show', 'lpmode', '-p', 'Ethernet0'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_transceiver_error_status(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['interfaces'].commands['transceiver'].commands['error-status'], ['Ethernet0', '-hw', '-n', 'asic0', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['sudo', 'sfputil', 'show', 'error-status', '-p', 'Ethernet0', '-hw', '-n', 'asic0'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_counters(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['interfaces'].commands['counters'], ['-i', 'Ethernet0', '-p', '3', '-a', '-n', 'asic0', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['portstat', '-a', '-p', '3', '-i', 'Ethernet0', '-n', 'asic0'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_counters_error(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['interfaces'].commands['counters'].commands['errors'], ['-p', '3', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['portstat', '-e', '-p', '3', '-s', 'all'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_counters_rates(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['interfaces'].commands['counters'].commands['rates'], ['-p', '3', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['portstat', '-R', '-p', '3', '-s', 'all'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_counters_detailed(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['interfaces'].commands['counters'].commands['detailed'], ['Ethernet0', '-p', '3', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['portstat', '-l', '-p', '3', '-i', 'Ethernet0'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_autoneg_status(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['interfaces'].commands['autoneg'].commands['status'], ['Ethernet0', '-n', 'asic0', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['intfutil', '-c', 'autoneg', '-i', 'Ethernet0', '-n', 'asic0'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + @patch.object(click.Choice, 'convert', MagicMock(return_value='asic0')) + def test_link_training_status(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['interfaces'].commands['link-training'].commands['status'], ['Ethernet0', '-n', 'asic0', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['intfutil', '-c', 'link_training', '-i', 'Ethernet0', '-n', 'asic0'], display_cmd=True) + + def teardown(self): + print('TEAR DOWN') + + +class TestShowIp(object): + def setup(self): + print('SETUP') + + @patch('utilities_common.cli.run_command') + def test_ip_interfaces(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['ip'].commands['interfaces']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['sudo', 'ipintutil', '-a', 'ipv4', '-d', 'all']) + + @patch('utilities_common.cli.run_command') + def test_ipv6_interfaces(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['ipv6'].commands['interfaces']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['sudo', 'ipintutil', '-a', 'ipv6', '-d', 'all']) + + def teardown(self): + print('TEAR DOWN') + + +class TestShowVxlan(object): + def setup(self): + print('SETUP') + + @patch('utilities_common.cli.run_command') + def test_counters(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['vxlan'].commands['counters'], ['-p', '3', 'tunnel1', '--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['tunnelstat', '-T', 'vxlan', '-p', '3', '-i', 'tunnel1'], display_cmd=True) + + def teardown(self): + print('TEAR DOWN') + + +class TestShowNat(object): + def setup(self): + print('SETUP') + + @patch('utilities_common.cli.run_command') + def test_statistics(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['nat'].commands['statistics'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['sudo', 'natshow', '-s'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_translations(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['nat'].commands['translations'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['sudo', 'natshow', '-t'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_translations_count(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['nat'].commands['translations'].commands['count'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['sudo', 'natshow', '-c'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_config(self, mock_run_command): + expected_calls = [ + call(['sudo', 'natconfig', '-g'], display_cmd=True), + call(['sudo', 'natconfig', '-s'], display_cmd=True), + call(['sudo', 'natconfig', '-p'], display_cmd=True), + call(['sudo', 'natconfig', '-b'], display_cmd=True), + call(['sudo', 'natconfig', '-z'], display_cmd=True), + ] + + runner = CliRunner() + result = runner.invoke(show.cli.commands['nat'].commands['config'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == expected_nat_config_output + assert mock_run_command.call_args_list == expected_calls + + @patch('utilities_common.cli.run_command') + def test_config_static(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['nat'].commands['config'].commands['static'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['sudo', 'natconfig', '-s'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_config_pool(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['nat'].commands['config'].commands['pool'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['sudo', 'natconfig', '-p'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_config_bindings(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['nat'].commands['config'].commands['bindings'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['sudo', 'natconfig', '-b'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_config_globalvalues(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['nat'].commands['config'].commands['globalvalues'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['sudo', 'natconfig', '-g'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_config_zones(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['nat'].commands['config'].commands['zones'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['sudo', 'natconfig', '-z'], display_cmd=True) + + def teardown(self): + print('TEAR DOWN') + + +class TestShowProcesses(object): + def setup(self): + print('SETUP') + + @patch('utilities_common.cli.run_command') + def test_summary(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['processes'].commands['summary'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['ps', '-eo', 'pid,ppid,cmd,%mem,%cpu'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_cpu(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['processes'].commands['cpu'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['top', '-bn', '1', '-o', '%CPU'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_memory(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['processes'].commands['memory'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['top', '-bn', '1', '-o', '%MEM'], display_cmd=True) + + def teardown(self): + print('TEAR DOWN') + + +class TestShowPlatform(object): + def setup(self): + print('SETUP') + + @patch('utilities_common.cli.run_command') + def test_syseeprom(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['platform'].commands['syseeprom'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['sudo', 'decode-syseeprom', '-d'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + @patch('os.popen') + def test_ssdhealth(self, mock_popen, mock_run_command): + mock_popen.return_value.readline.return_value = '/dev/sda\n' + runner = CliRunner() + result = runner.invoke(show.cli.commands['platform'].commands['ssdhealth'], ['--verbose', '--vendor']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_popen.assert_called_once_with('lsblk -o NAME,TYPE -p | grep disk') + mock_run_command.assert_called_once_with(['sudo', 'ssdutil', '-d', '/dev/sda', '-v', '-e'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_pcieinfo(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['platform'].commands['pcieinfo'], ['--verbose']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['sudo', 'pcieutil', 'show'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_pcieinfo_check(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['platform'].commands['pcieinfo'], ['--verbose', '-c']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['sudo', 'pcieutil', 'check'], display_cmd=True) + + @patch('utilities_common.cli.run_command') + def test_temporature(self, mock_run_command): + runner = CliRunner() + result = runner.invoke(show.cli.commands['platform'].commands['temperature']) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + mock_run_command.assert_called_once_with(['tempershow']) + + def teardown(self): + print('TEAR DOWN') + diff --git a/tests/sonic_bootchart_test.py b/tests/sonic_bootchart_test.py index c9d796a5d6..9a9d3dd929 100755 --- a/tests/sonic_bootchart_test.py +++ b/tests/sonic_bootchart_test.py @@ -40,13 +40,13 @@ def test_enable(self, mock_run_command): runner = CliRunner() result = runner.invoke(sonic_bootchart.cli.commands['enable'], []) assert not result.exit_code - mock_run_command.assert_called_with("systemctl enable systemd-bootchart", display_cmd=True) + mock_run_command.assert_called_with(['systemctl', 'enable', 'systemd-bootchart'], display_cmd=True) def test_disable(self, mock_run_command): runner = CliRunner() result = runner.invoke(sonic_bootchart.cli.commands['disable'], []) assert not result.exit_code - mock_run_command.assert_called_with("systemctl disable systemd-bootchart", display_cmd=True) + mock_run_command.assert_called_with(['systemctl', 'disable', 'systemd-bootchart'], display_cmd=True) def test_config_show(self, mock_run_command): def run_command_side_effect(command, **kwargs): diff --git a/tests/utils.py b/tests/utils.py index ff40865f06..f24210e36f 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -8,7 +8,7 @@ def get_result_and_return_code(cmd): return_code = 0 try: output = subprocess.check_output( - cmd, stderr=subprocess.STDOUT, shell=True, text=True) + cmd, stderr=subprocess.STDOUT, text=True) except subprocess.CalledProcessError as e: return_code = e.returncode # store only the error, no need for the traceback diff --git a/tests/vlan_test.py b/tests/vlan_test.py index ce1271024b..bd0ca7ad59 100644 --- a/tests/vlan_test.py +++ b/tests/vlan_test.py @@ -565,12 +565,12 @@ def test_config_vlan_proxy_arp_enable(self): print(result.exit_code) print(result.output) - expected_calls = [mock.call("docker container inspect -f '{{.State.Status}}' swss", return_cmd=True), - mock.call('docker exec -i swss supervisorctl status ndppd', ignore_error=True, return_cmd=True), - mock.call('docker exec -i swss cp /usr/share/sonic/templates/ndppd.conf /etc/supervisor/conf.d/'), - mock.call('docker exec -i swss supervisorctl update', return_cmd=True), - mock.call('docker exec -i swss sonic-cfggen -d -t /usr/share/sonic/templates/ndppd.conf.j2,/etc/ndppd.conf'), - mock.call('docker exec -i swss supervisorctl restart ndppd', return_cmd=True)] + expected_calls = [mock.call(['docker', 'container', 'inspect', '-f', '{{.State.Status}}', 'swss'], return_cmd=True), + mock.call(['docker', 'exec', '-i', 'swss', 'supervisorctl', 'status', 'ndppd'], ignore_error=True, return_cmd=True), + mock.call(['docker', 'exec', '-i', 'swss', 'cp', '/usr/share/sonic/templates/ndppd.conf', '/etc/supervisor/conf.d/']), + mock.call(['docker', 'exec', '-i', 'swss', 'supervisorctl', 'update'], return_cmd=True), + mock.call(['docker', 'exec', '-i', 'swss', 'sonic-cfggen', '-d', '-t', '/usr/share/sonic/templates/ndppd.conf.j2,/etc/ndppd.conf']), + mock.call(['docker', 'exec', '-i', 'swss', 'supervisorctl', 'restart', 'ndppd'], return_cmd=True)] mock_run_command.assert_has_calls(expected_calls) assert result.exit_code == 0 diff --git a/utilities_common/bgp_util.py b/utilities_common/bgp_util.py index 3897d4a103..fd306fdcd0 100644 --- a/utilities_common/bgp_util.py +++ b/utilities_common/bgp_util.py @@ -177,14 +177,12 @@ def get_neighbor_dict_from_table(db, table_name): def run_bgp_command(vtysh_cmd, bgp_namespace=multi_asic.DEFAULT_NAMESPACE, vtysh_shell_cmd=constants.VTYSH_COMMAND): - bgp_instance_id = ' ' + bgp_instance_id = [] output = None if bgp_namespace is not multi_asic.DEFAULT_NAMESPACE: - bgp_instance_id = " -n {} ".format( - multi_asic.get_asic_id_from_name(bgp_namespace)) + bgp_instance_id = ['-n', str(multi_asic.get_asic_id_from_name(bgp_namespace))] - cmd = 'sudo {} {} -c "{}"'.format( - vtysh_shell_cmd, bgp_instance_id, vtysh_cmd) + cmd = ['sudo', vtysh_shell_cmd] + bgp_instance_id + ['-c', vtysh_cmd] try: output, ret = clicommon.run_command(cmd, return_cmd=True) if ret != 0: diff --git a/utilities_common/cli.py b/utilities_common/cli.py index 45b2cc5f3f..9d3cdae710 100644 --- a/utilities_common/cli.py +++ b/utilities_common/cli.py @@ -15,7 +15,7 @@ from sonic_py_common import multi_asic from utilities_common.db import Db from utilities_common.general import load_db_config - +from sonic_py_common.general import getstatusoutput_noshell_pipe VLAN_SUB_INTERFACE_SEPARATOR = '.' pass_db = click.make_pass_decorator(Db, ensure=True) @@ -391,12 +391,15 @@ def print_output_in_alias_mode(output, index): click.echo(output.rstrip('\n')) -def run_command_in_alias_mode(command): +def run_command_in_alias_mode(command, shell=False): """Run command and replace all instances of SONiC interface names in output with vendor-sepecific interface aliases. """ - - process = subprocess.Popen(command, shell=True, text=True, stdout=subprocess.PIPE) + if not shell: + command_str = ' '.join(command) + else: + command_str = command + process = subprocess.Popen(command, text=True, shell=shell, stdout=subprocess.PIPE) while True: output = process.stdout.readline() @@ -408,7 +411,7 @@ def run_command_in_alias_mode(command): raw_output = output output = output.lstrip() - if command.startswith("portstat"): + if command_str.startswith("portstat"): """Show interface counters""" index = 0 if output.startswith("IFACE"): @@ -416,7 +419,7 @@ def run_command_in_alias_mode(command): iface_alias_converter.alias_max_length)) print_output_in_alias_mode(output, index) - elif command.startswith("intfstat"): + elif command_str.startswith("intfstat"): """Show RIF counters""" index = 0 if output.startswith("IFACE"): @@ -424,7 +427,7 @@ def run_command_in_alias_mode(command): iface_alias_converter.alias_max_length)) print_output_in_alias_mode(output, index) - elif command == "pfcstat": + elif command_str == "pfcstat": """Show pfc counters""" index = 0 if output.startswith("Port Tx"): @@ -436,12 +439,12 @@ def run_command_in_alias_mode(command): iface_alias_converter.alias_max_length)) print_output_in_alias_mode(output, index) - elif (command.startswith("sudo sfputil show eeprom")): + elif (command_str.startswith("sudo sfputil show eeprom")): """Show interface transceiver eeprom""" index = 0 print_output_in_alias_mode(raw_output, index) - elif (command.startswith("sudo sfputil show")): + elif (command_str.startswith("sudo sfputil show")): """Show interface transceiver lpmode, presence """ @@ -451,7 +454,7 @@ def run_command_in_alias_mode(command): iface_alias_converter.alias_max_length)) print_output_in_alias_mode(output, index) - elif command == "sudo lldpshow": + elif command_str == "sudo lldpshow": """Show lldp table""" index = 0 if output.startswith("LocalPort"): @@ -459,7 +462,7 @@ def run_command_in_alias_mode(command): iface_alias_converter.alias_max_length)) print_output_in_alias_mode(output, index) - elif command.startswith("queuestat"): + elif command_str.startswith("queuestat"): """Show queue counters""" index = 0 if output.startswith("Port"): @@ -467,7 +470,7 @@ def run_command_in_alias_mode(command): iface_alias_converter.alias_max_length)) print_output_in_alias_mode(output, index) - elif command == "fdbshow": + elif command_str == "fdbshow": """Show mac""" index = 3 if output.startswith("No."): @@ -478,13 +481,13 @@ def run_command_in_alias_mode(command): output = " " + output print_output_in_alias_mode(output, index) - elif command.startswith("nbrshow"): + elif command_str.startswith("nbrshow"): """Show arp""" index = 2 if "Vlan" in output: output = output.replace('Vlan', ' Vlan') print_output_in_alias_mode(output, index) - elif command.startswith("sudo ipintutil"): + elif command_str.startswith("sudo ipintutil"): """Show ip(v6) int""" index = 0 if output.startswith("Interface"): @@ -511,7 +514,7 @@ def run_command_in_alias_mode(command): sys.exit(rc) -def run_command(command, display_cmd=False, ignore_error=False, return_cmd=False, interactive_mode=False): +def run_command(command, display_cmd=False, ignore_error=False, return_cmd=False, interactive_mode=False, shell=False): """ Run bash command. Default behavior is to print output to stdout. If the command returns a non-zero return code, the function will exit with that return code. @@ -522,20 +525,24 @@ def run_command(command, display_cmd=False, ignore_error=False, return_cmd=False return_cmd: Boolean; If true, the function will return the output, ignoring any non-zero return code interactive_mode: Boolean; If true, it will treat the process as a long-running process which may generate multiple lines of output over time + shell: Boolean; If true, the command will be run in a shell """ - + if not shell: + command_str = ' '.join(command) + else: + command_str = command if display_cmd == True: - click.echo(click.style("Running command: ", fg='cyan') + click.style(command, fg='green')) + click.echo(click.style("Running command: ", fg='cyan') + click.style(command_str, fg='green')) # No conversion needed for intfutil commands as it already displays # both SONiC interface name and alias name for all interfaces. # IP route table cannot be handled in function run_command_in_alias_mode since it is in JSON format # with a list for next hops - if get_interface_naming_mode() == "alias" and not command.startswith("intfutil") and not re.search("show ip|ipv6 route", command): - run_command_in_alias_mode(command) + if get_interface_naming_mode() == "alias" and not command_str.startswith("intfutil") and not re.search("show ip|ipv6 route", command_str): + run_command_in_alias_mode(command, shell=shell) sys.exit(0) - proc = subprocess.Popen(command, shell=True, text=True, stdout=subprocess.PIPE) + proc = subprocess.Popen(command, shell=shell, text=True, stdout=subprocess.PIPE) if return_cmd: output = proc.communicate()[0]