diff --git a/clear/main.py b/clear/main.py index 3ba0a1d735..33bb6117fc 100755 --- a/clear/main.py +++ b/clear/main.py @@ -4,8 +4,10 @@ import sys import click import utilities_common.cli as clicommon +import utilities_common.multi_asic as multi_asic_util import json +from flow_counter_util.route import check_route_flow_counter_support from utilities_common import util_base from show.plugins.pbh import read_pbh_counters from . import plugins @@ -490,6 +492,53 @@ def flowcnt_trap(): run_command(command) +# ("sonic-clear flowcnt-route") +@cli.group(invoke_without_command=True) +@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') +@click.pass_context +def flowcnt_route(ctx, namespace): + """Clear all route flow counters""" + check_route_flow_counter_support() + if ctx.invoked_subcommand is None: + command = "flow_counters_stat -c -t route" + # None namespace means default namespace + if namespace is not None: + command += " -n {}".format(namespace) + clicommon.run_command(command) + + +# ("sonic-clear flowcnt-route pattern") +@flowcnt_route.command() +@click.option('--vrf', help='VRF/VNET name or default VRF') +@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') +@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) + if vrf: + command += ' --vrf {}'.format(vrf) + # None namespace means default namespace + if namespace is not None: + command += " -n {}".format(namespace) + clicommon.run_command(command) + + +# ("sonic-clear flowcnt-route route") +@flowcnt_route.command() +@click.option('--vrf', help='VRF/VNET name or default VRF') +@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') +@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) + if vrf: + command += ' --vrf {}'.format(vrf) + # None namespace means default namespace + if namespace is not None: + command += " -n {}".format(namespace) + clicommon.run_command(command) + + # Load plugins and register them helper = util_base.UtilHelper() helper.load_and_register_plugins(plugins, cli) diff --git a/config/flow_counters.py b/config/flow_counters.py new file mode 100644 index 0000000000..c5ed8e5465 --- /dev/null +++ b/config/flow_counters.py @@ -0,0 +1,154 @@ +import click +import ipaddress +import sys + +from flow_counter_util.route import FLOW_COUNTER_ROUTE_PATTERN_TABLE, FLOW_COUNTER_ROUTE_MAX_MATCH_FIELD, DEFAULT_VRF, PATTERN_SEPARATOR +from flow_counter_util.route import build_route_pattern, extract_route_pattern, check_route_flow_counter_support +from utilities_common.cli import AbbreviationGroup, pass_db +from utilities_common import cli # To make mock work in unit test + +# +# 'flowcnt-route' group ('config flowcnt-route ...') +# + + +@click.group(cls=AbbreviationGroup, invoke_without_command=False) +def flowcnt_route(): + """Route flow counter related configuration tasks""" + pass + + +@flowcnt_route.group() +def pattern(): + """Set pattern for route flow counter""" + pass + + +@pattern.command(name='add') +@click.option('-y', '--yes', is_flag=True) +@click.option('--vrf', help='VRF/VNET name or default VRF') +@click.option('--max', 'max_allowed_match', type=click.IntRange(1, 50), default=30, show_default=True, help='Max allowed match count') +@click.argument('prefix-pattern', required=True) +@pass_db +def pattern_add(db, yes, vrf, max_allowed_match, prefix_pattern): + """Add pattern for route flow counter""" + _update_route_flow_counter_config(db, vrf, max_allowed_match, prefix_pattern, True, yes) + + +@pattern.command(name='remove') +@click.option('--vrf', help='VRF/VNET name or default VRF') +@click.argument('prefix-pattern', required=True) +@pass_db +def pattern_remove(db, vrf, prefix_pattern): + """Remove pattern for route flow counter""" + _update_route_flow_counter_config(db, vrf, None, prefix_pattern, False) + + +def _update_route_flow_counter_config(db, vrf, max_allowed_match, prefix_pattern, add, yes=False): + """ + Update route flow counter config + :param db: db object + :param vrf: vrf string, empty vrf will be treated as default vrf + :param max_allowed_match: max allowed match count, $FLOW_COUNTER_ROUTE_MAX_MATCH_FIELD will be used if not specified + :param prefix_pattern: route prefix pattern, automatically add prefix length if not specified + :param add: True to add/set the configuration, otherwise remove + :param yes: Don't ask question if True + :return: + """ + check_route_flow_counter_support() + + if add: + try: + net = ipaddress.ip_network(prefix_pattern, strict=False) + except ValueError as e: + click.echo('Invalid prefix pattern: {}'.format(prefix_pattern)) + exit(1) + + if '/' not in prefix_pattern: + prefix_pattern += '/' + str(net.prefixlen) + + key = build_route_pattern(vrf, prefix_pattern) + for _, cfgdb in db.cfgdb_clients.items(): + if _try_find_existing_pattern(cfgdb, net, key, yes): + entry_data = cfgdb.get_entry(FLOW_COUNTER_ROUTE_PATTERN_TABLE, key) + old_max_allowed_match = entry_data.get(FLOW_COUNTER_ROUTE_MAX_MATCH_FIELD) + if old_max_allowed_match is not None and int(old_max_allowed_match) == max_allowed_match: + click.echo('The route pattern already exists, nothing to be changed') + exit(1) + cfgdb.mod_entry(FLOW_COUNTER_ROUTE_PATTERN_TABLE, + key, + {FLOW_COUNTER_ROUTE_MAX_MATCH_FIELD: str(max_allowed_match)}) + else: + found = False + key = build_route_pattern(vrf, prefix_pattern) + for _, cfgdb in db.cfgdb_clients.items(): + pattern_table = cfgdb.get_table(FLOW_COUNTER_ROUTE_PATTERN_TABLE) + + for existing_key in pattern_table: + exist_vrf, existing_prefix = extract_route_pattern(existing_key) + if (exist_vrf == vrf or (vrf is None and exist_vrf == DEFAULT_VRF)) and existing_prefix == prefix_pattern: + found = True + cfgdb.set_entry(FLOW_COUNTER_ROUTE_PATTERN_TABLE, key, None) + if not found: + click.echo("Failed to remove route pattern: {} does not exist".format(key)) + exit(1) + + +def _try_find_existing_pattern(cfgdb, input_net, input_key, yes): + """Try to find the same pattern from CONFIG DB + + Args: + cfgdb (object): CONFIG DB object + input_net (object): Input ip_network object + input_key (str): Input key + yes (bool): Whether ask user question + + Returns: + bool: True if found an existing one + """ + input_type = type(input_net) # IPv4 or IPv6 + found_invalid = [] + found = None + pattern_table = cfgdb.get_table(FLOW_COUNTER_ROUTE_PATTERN_TABLE) + for existing_key in pattern_table: + if isinstance(existing_key, tuple): + existing_prefix = existing_key[1] + existing_key = PATTERN_SEPARATOR.join(existing_key) + else: + _, existing_prefix = extract_route_pattern(existing_key) + + # In case user configures an invalid pattern via CONFIG DB. + if not existing_prefix: # Invalid pattern such as: "vrf1|" + click.echo('Detect invalid route pattern in existing configuration {}'.format(existing_key)) + found_invalid.append(existing_key) + continue + + try: + existing_net = ipaddress.ip_network(existing_prefix, strict=False) + except ValueError as e: # Invalid pattern such as: "vrf1|invalid" + click.echo('Detect invalid route pattern in existing configuration {}'.format(existing_key)) + found_invalid.append(existing_key) + continue + + if type(existing_net) == input_type: + found = existing_key + break + + if found == input_key: + return True + + if not found and found_invalid: + # If not found but there is an invalid one, ask user to replace the invalid one + found = found_invalid[0] + + if found: + if not yes: + answer = cli.query_yes_no('Only support 1 IPv4 route pattern and 1 IPv6 route pattern, remove existing pattern {}?'.format(found)) + else: + answer = True + if answer: + click.echo('Replacing existing route pattern {} with {}'.format(existing_key, input_key)) + cfgdb.set_entry(FLOW_COUNTER_ROUTE_PATTERN_TABLE, existing_key, None) + else: + exit(0) + return False diff --git a/config/main.py b/config/main.py index f5ecd70048..9e12b082ef 100644 --- a/config/main.py +++ b/config/main.py @@ -35,6 +35,7 @@ from . import chassis_modules from . import console from . import feature +from . import flow_counters from . import kdump from . import kube from . import muxcable @@ -787,7 +788,7 @@ def _per_namespace_swss_ready(service_name): return False def _swss_ready(): - list_of_swss = [] + list_of_swss = [] num_asics = multi_asic.get_num_asics() if num_asics == 1: list_of_swss.append("swss.service") @@ -800,7 +801,7 @@ def _swss_ready(): if _per_namespace_swss_ready(service_name) == False: return False - return True + return True def _is_system_starting(): out = clicommon.run_command("sudo systemctl is-system-running", return_cmd=True) @@ -1061,6 +1062,7 @@ def config(ctx): config.add_command(chassis_modules.chassis) config.add_command(console.console) config.add_command(feature.feature) +config.add_command(flow_counters.flowcnt_route) config.add_command(kdump.kdump) config.add_command(kube.kubernetes) config.add_command(muxcable.muxcable) @@ -1467,10 +1469,10 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, disable_arp_cach config_gen_opts = "" - + if os.path.isfile(INIT_CFG_FILE): config_gen_opts += " -j {} ".format(INIT_CFG_FILE) - + if file_format == 'config_db': config_gen_opts += ' -j {} '.format(file) else: @@ -6224,7 +6226,7 @@ def del_subinterface(ctx, subinterface_name): sub_intfs = [k for k,v in subintf_config_db.items() if type(k) != tuple] if subinterface_name not in sub_intfs: ctx.fail("{} does not exists".format(subinterface_name)) - + ips = {} ips = [ k[1] for k in config_db.get_table('VLAN_SUB_INTERFACE') if type(k) == tuple and k[0] == subinterface_name ] for ip in ips: diff --git a/counterpoll/main.py b/counterpoll/main.py index e5894e1676..f81fa730ef 100644 --- a/counterpoll/main.py +++ b/counterpoll/main.py @@ -1,5 +1,6 @@ import click import json +from flow_counter_util.route import check_route_flow_counter_support from swsscommon.swsscommon import ConfigDBConnector from tabulate import tabulate @@ -347,6 +348,40 @@ def disable(ctx): fc_info['FLEX_COUNTER_STATUS'] = 'disable' ctx.obj.mod_entry("FLEX_COUNTER_TABLE", "FLOW_CNT_TRAP", fc_info) +# Route flow counter commands +@cli.group() +@click.pass_context +def flowcnt_route(ctx): + """ Route flow counter commands """ + check_route_flow_counter_support() + ctx.obj = ConfigDBConnector() + ctx.obj.connect() + +@flowcnt_route.command() +@click.argument('poll_interval', type=click.IntRange(1000, 30000)) +@click.pass_context +def interval(ctx, poll_interval): + """ Set route flow counter query interval """ + fc_info = {} + fc_info['POLL_INTERVAL'] = poll_interval + ctx.obj.mod_entry("FLEX_COUNTER_TABLE", "FLOW_CNT_ROUTE", fc_info) + +@flowcnt_route.command() +@click.pass_context +def enable(ctx): + """ Enable route flow counter query """ + fc_info = {} + fc_info['FLEX_COUNTER_STATUS'] = 'enable' + ctx.obj.mod_entry("FLEX_COUNTER_TABLE", "FLOW_CNT_ROUTE", fc_info) + +@flowcnt_route.command() +@click.pass_context +def disable(ctx): + """ Disable route flow counter query """ + fc_info = {} + fc_info['FLEX_COUNTER_STATUS'] = 'disable' + ctx.obj.mod_entry("FLEX_COUNTER_TABLE", "FLOW_CNT_ROUTE", fc_info) + @cli.command() def show(): """ Show the counter configuration """ @@ -363,6 +398,7 @@ def show(): acl_info = configdb.get_entry('FLEX_COUNTER_TABLE', ACL) tunnel_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'TUNNEL') trap_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'FLOW_CNT_TRAP') + route_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'FLOW_CNT_ROUTE') header = ("Type", "Interval (in ms)", "Status") data = [] @@ -388,6 +424,9 @@ def show(): data.append(["TUNNEL_STAT", rif_info.get("POLL_INTERVAL", DEFLT_10_SEC), rif_info.get("FLEX_COUNTER_STATUS", DISABLE)]) if trap_info: data.append(["FLOW_CNT_TRAP_STAT", trap_info.get("POLL_INTERVAL", DEFLT_10_SEC), trap_info.get("FLEX_COUNTER_STATUS", DISABLE)]) + if route_info: + data.append(["FLOW_CNT_ROUTE_STAT", route_info.get("POLL_INTERVAL", DEFLT_10_SEC), + route_info.get("FLEX_COUNTER_STATUS", DISABLE)]) click.echo(tabulate(data, headers=header, tablefmt="simple", missingval="")) diff --git a/flow_counter_util/__init__.py b/flow_counter_util/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/flow_counter_util/route.py b/flow_counter_util/route.py new file mode 100644 index 0000000000..4b9aa49f97 --- /dev/null +++ b/flow_counter_util/route.py @@ -0,0 +1,80 @@ +import os +import ipaddress +import sys +from swsscommon.swsscommon import SonicV2Connector + +try: + if os.environ["UTILITIES_UNIT_TESTING"] == "1" or os.environ["UTILITIES_UNIT_TESTING"] == "2": + modules_path = os.path.join(os.path.dirname(__file__), "..") + test_path = os.path.join(modules_path, "tests") + sys.path.insert(0, modules_path) + sys.path.insert(0, test_path) + import mock_tables.dbconnector +except KeyError: + pass + + +COUNTERS_ROUTE_TO_PATTERN_MAP = 'COUNTERS_ROUTE_TO_PATTERN_MAP' +FLOW_COUNTER_CAPABILITY_TABLE = 'FLOW_COUNTER_CAPABILITY_TABLE' +FLOW_COUNTER_CAPABILITY_KEY = 'route' +FLOW_COUNTER_CAPABILITY_SUPPORT_FIELD = 'support' +FLOW_COUNTER_ROUTE_PATTERN_TABLE = 'FLOW_COUNTER_ROUTE_PATTERN_TABLE' +FLOW_COUNTER_ROUTE_MAX_MATCH_FIELD = 'max_match_count' +FLOW_COUNTER_ROUTE_CONFIG_HEADER = ['Route pattern', 'VRF', 'Max'] +DEFAULT_MAX_MATCH = 30 +DEFAULT_VRF = 'default' +PATTERN_SEPARATOR = '|' + + +def extract_route_pattern(route_pattern): + """Extract vrf and prefix from route pattern, route pattrn shall be formated like: "Vrf_1:1.1.1.1/24" + or "1.1.1.1/24" + + Args: + route_pattern (str): route pattern string + sep (str, optional): Defaults to PATTERN_SEPARATOR. + + Returns: + [tuple]: vrf and prefix + """ + if isinstance(route_pattern, tuple): + return route_pattern + items = route_pattern.split(PATTERN_SEPARATOR) + if len(items) == 1: + return DEFAULT_VRF, items[0] + elif len(items) == 2: + return items[0], items[1] + else: + return None, None + + +def build_route_pattern(vrf, prefix): + if vrf and vrf != 'default': + return '{}{}{}'.format(vrf, PATTERN_SEPARATOR, prefix) + else: + return prefix + + +def get_route_flow_counter_capability(): + state_db = SonicV2Connector(host="127.0.0.1") + state_db.connect(state_db.STATE_DB) + + return state_db.get_all(state_db.STATE_DB, '{}|{}'.format(FLOW_COUNTER_CAPABILITY_TABLE, FLOW_COUNTER_CAPABILITY_KEY)) + + +def check_route_flow_counter_support(): + capabilities = get_route_flow_counter_capability() + if not capabilities: + print('Waiting for swss to initialize route flow counter capability, please try again later') + exit(1) + + support = capabilities.get(FLOW_COUNTER_CAPABILITY_SUPPORT_FIELD) + if support is None: + print('Waiting for swss to initialize route flow counter capability, please try again later') + exit(1) + + if support != 'true': + print('Route flow counter is not supported on this platform') + exit(1) + + return diff --git a/scripts/flow_counters_stat b/scripts/flow_counters_stat index 8901d92f66..4cdeff1e87 100755 --- a/scripts/flow_counters_stat +++ b/scripts/flow_counters_stat @@ -24,13 +24,19 @@ except KeyError: pass import utilities_common.multi_asic as multi_asic_util +from flow_counter_util.route import build_route_pattern, extract_route_pattern, check_route_flow_counter_support, DEFAULT_VRF, COUNTERS_ROUTE_TO_PATTERN_MAP +from utilities_common import constants from utilities_common.netstat import format_number_with_comma, table_as_json, ns_diff, format_prate # Flow counter meta data, new type of flow counters can extend this dictinary to reuse existing logic flow_counter_meta = { 'trap': { 'headers': ['Trap Name', 'Packets', 'Bytes', 'PPS'], - 'name_map': 'COUNTERS_TRAP_NAME_MAP', + 'name_map': 'COUNTERS_TRAP_NAME_MAP' + }, + 'route': { + 'headers': ['Route pattern', 'VRF', 'Matched routes', 'Packets', 'Bytes'], + 'name_map': 'COUNTERS_ROUTE_NAME_MAP' } } flow_counters_fields = ['SAI_COUNTER_STAT_PACKETS', 'SAI_COUNTER_STAT_BYTES'] @@ -255,6 +261,295 @@ class FlowCounterStats(object): return need_update_cache +class RouteFlowCounterStats(FlowCounterStats): + SHOW_BY_PREFIX_HEADERS = ['Route', 'VRF', 'Route pattern', 'Packets', 'Bytes'] + + def __init__(self, args): + super(RouteFlowCounterStats,self).__init__(args) + + def _print_data(self, headers, table): + """Print statistic data based on output format + + Args: + headers (list): Table headers + table (list): Table data + """ + if self.args.json: + # The first column of the table might have duplicate value, have to + # add an extra index field to make table_as_json work + print(table_as_json(([i] + line for i, line in enumerate(table)), ['Index'] + headers)) + else: + print(tabulate(table, headers, tablefmt='simple', stralign='right')) + + def _prepare_show_data(self): + """Prepare table headers and table data for output. If "--prefix" is specified, fetch data that matches + the given prefix; if "--prefix_pattern" is specified, fetch data that matches the given pattern; + otherwise, fetch all data. + Returns: + headers (list): Table headers + table (list): Table data + """ + if self.args.prefix: + return self._prepare_show_data_by_prefix() + else: + return self._prepare_show_data_by_pattern() + + def _prepare_show_data_by_prefix(self): + """Prepare table header and table data by given prefix + Returns: + headers (list): Table headers + table (list): Table data + """ + table = [] + + headers = self._adjust_headers(self.SHOW_BY_PREFIX_HEADERS) + for ns, pattern_entry in self.data.items(): + if self.args.namespace is not None and self.args.namespace != ns: + continue + for route_pattern, prefix_entry in pattern_entry.items(): + if self.args.prefix in prefix_entry: + vrf, prefix_pattern = extract_route_pattern(route_pattern) + if vrf != self.args.vrf: + continue + + values = prefix_entry[self.args.prefix] + if self.multi_asic.is_multi_asic: + row = [ns] + else: + row = [] + row.extend([self.args.prefix, + self.args.vrf, + prefix_pattern, + format_number_with_comma(values[0]), + format_number_with_comma(values[1])]) + table.append(row) + + return headers, table + + def _prepare_show_data_by_pattern(self): + """Prepare table header and table data by given pattern. If pattern is not specified, show all data. + Returns: + headers (list): Table headers + table (list): Table data + """ + table = [] + + headers = self._adjust_headers(self.headers) + for ns, pattern_entries in natsorted(self.data.items()): + if self.args.namespace is not None and self.args.namespace != ns: + continue + if self.args.prefix_pattern: + route_pattern = build_route_pattern(self.args.vrf, self.args.prefix_pattern) + if route_pattern in pattern_entries: + self._fill_table_for_prefix_pattern(table, ns, pattern_entries[route_pattern], self.args.prefix_pattern, self.args.vrf) + break + else: + for route_pattern, prefix_entries in natsorted(pattern_entries.items()): + vrf, prefix_pattern = extract_route_pattern(route_pattern) + self._fill_table_for_prefix_pattern(table, ns, prefix_entries, prefix_pattern, vrf) + + return headers, table + + def _fill_table_for_prefix_pattern(self, table, ns, prefix_entries, prefix_pattern, vrf): + """Fill table data for prefix pattern + Args: + table (list): Table data to fill + ns (str): Namespace + prefix_entries (dict): Prefix to value map + prefix_pattern (str): Prefix pattern + vrf (str): VRF + """ + is_first_row = True + for prefix, values in natsorted(prefix_entries.items()): + if self.multi_asic.is_multi_asic: + row = [ns if is_first_row or self.args.json else ''] + else: + row = [] + row.extend([prefix_pattern if is_first_row or self.args.json else '', + vrf if is_first_row or self.args.json else '', + prefix, + format_number_with_comma(values[0]), + format_number_with_comma(values[1])]) + table.append(row) + if is_first_row: + is_first_row = False + + def clear(self): + """Clear statistic based on arguments. + 1. If "--prefix" is specified, clear the data matching the prefix + 2. If "--prefix_pattern" is specified, clear the data matching the pattern + 3. Otherwise, clear all data + If "--namepsace" is not specified, clear the data belongs to the default namespace. + If "--vrf" is not specified, use default VRF. + """ + if self.args.prefix: + self.clear_by_prefix() + elif self.args.prefix_pattern: + self.clear_by_pattern() + else: + super(RouteFlowCounterStats, self).clear() + + @multi_asic_util.run_on_multi_asic + def clear_by_prefix(self): + """Clear the data matching the prefix + """ + ns = constants.DEFAULT_NAMESPACE if self.args.namespace is None else self.args.namespace + if ns != self.multi_asic.current_namespace: + return + + name_map = self.db.get_all(self.db.COUNTERS_DB, self.name_map) + prefix_vrf = build_route_pattern(self.args.vrf, self.args.prefix) + if not name_map or prefix_vrf not in name_map: + print('Cannot find {} in COUNTERS_DB {} table'.format(self.args.prefix, self.name_map)) + return + + route_to_pattern_map = self.db.get_all(self.db.COUNTERS_DB, COUNTERS_ROUTE_TO_PATTERN_MAP) + if not route_to_pattern_map or prefix_vrf not in route_to_pattern_map: + print('Cannot find {} in {} table'.format(self.args.prefix, COUNTERS_ROUTE_TO_PATTERN_MAP)) + return + + self.data = self._load() + if not self.data: + self.data = {} + + if ns not in self.data: + self.data[ns] = {} + + route_pattern = route_to_pattern_map[prefix_vrf] + if route_pattern not in self.data[ns]: + self.data[ns][route_pattern] = {} + + counter_oid = name_map[prefix_vrf] + values = self._get_stats_value(counter_oid) + values.append(counter_oid) + self.data[ns][route_pattern][self.args.prefix] = values + self._save(self.data) + print('Flow Counters of the specified route were successfully cleared') + + @multi_asic_util.run_on_multi_asic + def clear_by_pattern(self): + """Clear the data matching the specified pattern + """ + ns = constants.DEFAULT_NAMESPACE if self.args.namespace is None else self.args.namespace + if ns != self.multi_asic.current_namespace: + return + + route_to_pattern_map = self.db.get_all(self.db.COUNTERS_DB, COUNTERS_ROUTE_TO_PATTERN_MAP) + expect_route_pattern = build_route_pattern(self.args.vrf, self.args.prefix_pattern) + matching_prefix_vrf_list = [prefix_vrf for prefix_vrf, route_pattern in route_to_pattern_map.items() if route_pattern == expect_route_pattern] + if not matching_prefix_vrf_list: + print('Cannot find {} in COUNTERS_DB {} table'.format(self.args.prefix_pattern, COUNTERS_ROUTE_TO_PATTERN_MAP)) + return + + data_to_update = {} + name_map = self.db.get_all(self.db.COUNTERS_DB, self.name_map) + for prefix_vrf in matching_prefix_vrf_list: + if prefix_vrf not in name_map: + print('Warning: cannot find {} in {}'.format(prefix_vrf, self.name_map)) + continue + + counter_oid = name_map[prefix_vrf] + values = self._get_stats_value(counter_oid) + values.append(counter_oid) + _, prefix = extract_route_pattern(prefix_vrf) + data_to_update[prefix] = values + + self.data = self._load() + if not self.data: + self.data = {} + + if not self.data or ns not in self.data: + self.data[ns] = {} + + if expect_route_pattern not in self.data[ns]: + self.data[ns][expect_route_pattern] = {} + + self.data[ns][expect_route_pattern].update(data_to_update) + self._save(self.data) + + def _get_stats_from_db(self): + """Get flow counter statistic from DB. + Returns: + dict: A dictionary. E.g: {: {(): {: [, , ]}}} + """ + ns = self.multi_asic.current_namespace + name_map = self.db.get_all(self.db.COUNTERS_DB, self.name_map) + data = {ns: {}} + if not name_map: + return data + + route_to_pattern_map = self.db.get_all(self.db.COUNTERS_DB, COUNTERS_ROUTE_TO_PATTERN_MAP) + if not route_to_pattern_map: + return data + + for prefix_vrf, route_pattern in route_to_pattern_map.items(): + if route_pattern not in data[ns]: + data[ns][route_pattern] = {} + + counter_oid = name_map[prefix_vrf] + values = self._get_stats_value(counter_oid) + values.append(counter_oid) + _, prefix = extract_route_pattern(prefix_vrf) + data[ns][route_pattern][prefix] = values + + return data + + def _diff(self, old_data, new_data): + """Do a diff between new data and old data. + Args: + old_data (dict): E.g: {: {(): {: [, , ]}}} + new_data (dict): E.g: {: {(): {: [, , ]}}} + """ + need_update_cache = False + if not old_data: + return need_update_cache + + for ns, stats in new_data.items(): + if ns not in old_data: + continue + + old_stats = old_data[ns] + for route_pattern, prefix_entries in stats.items(): + if route_pattern not in old_stats: + continue + + old_prefix_entries = old_stats[route_pattern] + for name, values in prefix_entries.items(): + if name not in old_prefix_entries: + continue + + old_values = old_prefix_entries[name] + if values[-1] != old_values[-1]: + # Counter OID not equal means the generic counter was removed and added again. Removing a generic counter would cause + # the stats value restart from 0. To avoid get minus value here, it should not do diff in case + # counter OID is changed. + old_values[-1] = values[-1] + for i in diff_column_positions: + old_values[i] = '0' + values[i] = ns_diff(values[i], old_values[i]) + need_update_cache = True + continue + + has_negative_diff = False + for i in diff_column_positions: + # If any diff has negative value, set all counter values to 0 and update cache + if int(values[i]) < int(old_values[i]): + has_negative_diff = True + break + + if has_negative_diff: + for i in diff_column_positions: + old_values[i] = '0' + values[i] = ns_diff(values[i], old_values[i]) + need_update_cache = True + continue + + for i in diff_column_positions: + values[i] = ns_diff(values[i], old_values[i]) + + return need_update_cache + + def main(): parser = argparse.ArgumentParser(description='Display the flow counters', formatter_class=argparse.RawTextHelpFormatter, @@ -268,11 +563,23 @@ Examples: parser.add_argument('-d', '--delete', action='store_true', help='Delete saved stats') parser.add_argument('-j', '--json', action='store_true', help='Display in JSON format') parser.add_argument('-n','--namespace', default=None, help='Display flow counters for specific namespace') - parser.add_argument('-t', '--type', required=True, choices=['trap'],help='Flow counters type') + parser.add_argument('-t', '--type', required=True, choices=['trap', 'route'],help='Flow counters type') + group = parser.add_mutually_exclusive_group() + group.add_argument('--prefix_pattern', help='Prefix pattern') # for route flow counter only, ignored by other type + group.add_argument('--prefix', help='Prefix') # for route flow counter only, ignored by other type + parser.add_argument('--vrf', help='VRF name', default=DEFAULT_VRF) # for route flow counter only, ignored by other type args = parser.parse_args() - stats = FlowCounterStats(args) + if args.type == 'trap': + stats = FlowCounterStats(args) + elif args.type == 'route': + check_route_flow_counter_support() + stats = RouteFlowCounterStats(args) + else: + print('Invalid flow counter type: {}'.format(args.type)) + exit(1) + if args.clear: stats.clear() else: diff --git a/setup.py b/setup.py index 37a4769734..d30baddbc1 100644 --- a/setup.py +++ b/setup.py @@ -40,6 +40,7 @@ 'ssdutil', 'pfc', 'psuutil', + 'flow_counter_util', 'fdbutil', 'fwutil', 'pcieutil', diff --git a/show/flow_counters.py b/show/flow_counters.py index 9870c83080..a32f328bae 100644 --- a/show/flow_counters.py +++ b/show/flow_counters.py @@ -2,6 +2,12 @@ import utilities_common.cli as clicommon import utilities_common.multi_asic as multi_asic_util +from tabulate import tabulate + +from flow_counter_util.route import FLOW_COUNTER_ROUTE_PATTERN_TABLE, FLOW_COUNTER_ROUTE_MAX_MATCH_FIELD, FLOW_COUNTER_ROUTE_CONFIG_HEADER, DEFAULT_MAX_MATCH +from flow_counter_util.route import extract_route_pattern, check_route_flow_counter_support +from utilities_common.cli import pass_db + # # 'flowcnt-trap' group ### # @@ -20,3 +26,69 @@ def stats(verbose, namespace): if namespace is not None: cmd += " -n {}".format(namespace) clicommon.run_command(cmd, display_cmd=verbose) + +# +# 'flowcnt-route' group ### +# + +@click.group(cls=clicommon.AliasedGroup) +def flowcnt_route(): + """Show route flow counter related information""" + check_route_flow_counter_support() + + +@flowcnt_route.command() +@pass_db +def config(db): + """Show route flow counter configuration""" + route_pattern_table = db.cfgdb.get_table(FLOW_COUNTER_ROUTE_PATTERN_TABLE) + data = [] + for key, entry in route_pattern_table.items(): + vrf, prefix = extract_route_pattern(key) + max = entry.get(FLOW_COUNTER_ROUTE_MAX_MATCH_FIELD, str(DEFAULT_MAX_MATCH)) + data.append([prefix, vrf, max]) + + click.echo(tabulate(data, headers=FLOW_COUNTER_ROUTE_CONFIG_HEADER, tablefmt="simple", missingval="")) + + +@flowcnt_route.group(invoke_without_command=True) +@click.option('--verbose', is_flag=True, help="Enable verbose output") +@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') +@click.pass_context +def stats(ctx, verbose, namespace): + """Show statistics of all route flow counters""" + if ctx.invoked_subcommand is None: + command = "flow_counters_stat -t route" + if namespace is not None: + command += " -n {}".format(namespace) + clicommon.run_command(command, display_cmd=verbose) + + +@stats.command() +@click.option('--verbose', is_flag=True, help="Enable verbose output") +@click.option('--vrf', help='VRF/VNET name or default VRF') +@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') +@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) + if vrf: + command += ' --vrf {}'.format(vrf) + if namespace is not None: + command += " -n {}".format(namespace) + clicommon.run_command(command, display_cmd=verbose) + + +@stats.command() +@click.option('--verbose', is_flag=True, help="Enable verbose output") +@click.option('--vrf', help='VRF/VNET name or default VRF') +@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') +@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) + if vrf: + command += ' --vrf {}'.format(vrf) + if namespace is not None: + command += " -n {}".format(namespace) + clicommon.run_command(command, display_cmd=verbose) diff --git a/show/main.py b/show/main.py index 528ad81e84..70f36d11d1 100755 --- a/show/main.py +++ b/show/main.py @@ -179,6 +179,7 @@ def cli(ctx): cli.add_command(dropcounters.dropcounters) cli.add_command(feature.feature) cli.add_command(fgnhg.fgnhg) +cli.add_command(flow_counters.flowcnt_route) cli.add_command(flow_counters.flowcnt_trap) cli.add_command(kdump.kdump) cli.add_command(interfaces.interfaces) @@ -1057,7 +1058,7 @@ def version(verbose): version_info = device_info.get_sonic_version_info() platform_info = device_info.get_platform_info() chassis_info = platform.get_chassis_info() - + sys_uptime_cmd = "uptime" sys_uptime = subprocess.Popen(sys_uptime_cmd, shell=True, text=True, stdout=subprocess.PIPE) @@ -1132,7 +1133,7 @@ def techsupport(since, global_timeout, cmd_timeout, verbose, allow_process_stop, if since: cmd += " -s '{}'".format(since) - + if debug_dump: cmd += " -d " @@ -1237,7 +1238,7 @@ def snmp(ctx, db): # ("show runningconfiguration snmp community") @snmp.command('community') -@click.option('--json', 'json_output', required=False, is_flag=True, type=click.BOOL, +@click.option('--json', 'json_output', required=False, is_flag=True, type=click.BOOL, help="Display the output in JSON format") @clicommon.pass_db def community(db, json_output): @@ -1258,7 +1259,7 @@ def community(db, json_output): # ("show runningconfiguration snmp contact") @snmp.command('contact') -@click.option('--json', 'json_output', required=False, is_flag=True, type=click.BOOL, +@click.option('--json', 'json_output', required=False, is_flag=True, type=click.BOOL, help="Display the output in JSON format") @clicommon.pass_db def contact(db, json_output): @@ -1286,7 +1287,7 @@ def contact(db, json_output): # ("show runningconfiguration snmp location") @snmp.command('location') -@click.option('--json', 'json_output', required=False, is_flag=True, type=click.BOOL, +@click.option('--json', 'json_output', required=False, is_flag=True, type=click.BOOL, help="Display the output in JSON format") @clicommon.pass_db def location(db, json_output): @@ -1313,13 +1314,13 @@ def location(db, json_output): # ("show runningconfiguration snmp user") @snmp.command('user') -@click.option('--json', 'json_output', required=False, is_flag=True, type=click.BOOL, +@click.option('--json', 'json_output', required=False, is_flag=True, type=click.BOOL, help="Display the output in JSON format") @clicommon.pass_db def users(db, json_output): """show SNMP running configuration user""" snmp_users = db.cfgdb.get_table('SNMP_USER') - snmp_user_header = ['User', "Permission Type", "Type", "Auth Type", "Auth Password", "Encryption Type", + snmp_user_header = ['User', "Permission Type", "Type", "Auth Type", "Auth Password", "Encryption Type", "Encryption Password"] snmp_user_body = [] if json_output: @@ -1332,7 +1333,7 @@ def users(db, json_output): snmp_user_encryption_type = snmp_users[snmp_user].get('SNMP_USER_ENCRYPTION_TYPE', 'Null') snmp_user_encryption_password = snmp_users[snmp_user].get('SNMP_USER_ENCRYPTION_PASSWORD', 'Null') snmp_user_type = snmp_users[snmp_user].get('SNMP_USER_TYPE', 'Null') - snmp_user_body.append([snmp_user, snmp_user_permissions_type, snmp_user_type, snmp_user_auth_type, + snmp_user_body.append([snmp_user, snmp_user_permissions_type, snmp_user_type, snmp_user_auth_type, snmp_user_auth_password, snmp_user_encryption_type, snmp_user_encryption_password]) click.echo(tabulate(natsorted(snmp_user_body), snmp_user_header)) @@ -1349,7 +1350,7 @@ def show_run_snmp(db, ctx): snmp_contact_body = [] snmp_comm_header = ["Community String", "Community Type"] snmp_comm_body = [] - snmp_user_header = ['User', "Permission Type", "Type", "Auth Type", "Auth Password", "Encryption Type", + snmp_user_header = ['User', "Permission Type", "Type", "Auth Type", "Auth Password", "Encryption Type", "Encryption Password"] snmp_user_body = [] try: @@ -1383,7 +1384,7 @@ def show_run_snmp(db, ctx): snmp_user_encryption_type = snmp_users[snmp_user].get('SNMP_USER_ENCRYPTION_TYPE', 'Null') snmp_user_encryption_password = snmp_users[snmp_user].get('SNMP_USER_ENCRYPTION_PASSWORD', 'Null') snmp_user_type = snmp_users[snmp_user].get('SNMP_USER_TYPE', 'Null') - snmp_user_body.append([snmp_user, snmp_user_permissions_type, snmp_user_type, snmp_user_auth_type, + snmp_user_body.append([snmp_user, snmp_user_permissions_type, snmp_user_type, snmp_user_auth_type, snmp_user_auth_password, snmp_user_encryption_type, snmp_user_encryption_password]) click.echo(tabulate(natsorted(snmp_user_body), snmp_user_header)) diff --git a/tests/counterpoll_input/config_db.json b/tests/counterpoll_input/config_db.json index 61ceb071c2..89c8643446 100644 --- a/tests/counterpoll_input/config_db.json +++ b/tests/counterpoll_input/config_db.json @@ -1,2668 +1,2671 @@ { "NTP_SERVER": { - "10.20.8.129": {}, + "10.20.8.129": {}, "10.20.8.130": {} - }, + }, "TACPLUS_SERVER": { "100.127.20.21": { - "priority": "1", + "priority": "1", "tcp_port": "49" } - }, + }, "DEVICE_METADATA": { "localhost": { - "hwsku": "Force10-S6000", - "default_bgp_status": "up", - "docker_routing_config_mode": "separated", - "region": "None", - "hostname": "str-s6000-acs-14", - "platform": "x86_64-dell_s6000_s1220-r0", - "mac": "f4:8e:38:16:bc:8d", - "default_pfcwd_status": "disable", - "bgp_asn": "65100", - "cloudtype": "None", - "type": "ToRRouter", + "hwsku": "Force10-S6000", + "default_bgp_status": "up", + "docker_routing_config_mode": "separated", + "region": "None", + "hostname": "str-s6000-acs-14", + "platform": "x86_64-dell_s6000_s1220-r0", + "mac": "f4:8e:38:16:bc:8d", + "default_pfcwd_status": "disable", + "bgp_asn": "65100", + "cloudtype": "None", + "type": "ToRRouter", "deployment_id": "1" } - }, + }, "BGP_PEER_RANGE": { "BGPVac": { - "src_address": "10.1.0.32", - "name": "BGPVac", + "src_address": "10.1.0.32", + "name": "BGPVac", "ip_range": [ "192.168.0.0/21" ] - }, + }, "BGPSLBPassive": { - "src_address": "10.1.0.32", - "name": "BGPSLBPassive", + "src_address": "10.1.0.32", + "name": "BGPSLBPassive", "ip_range": [ "10.255.0.0/25" ] } - }, + }, "VLAN": { "Vlan1000": { "dhcp_servers": [ - "192.0.0.1", - "192.0.0.2", - "192.0.0.3", - "192.0.0.4", - "192.0.0.5", - "192.0.0.6", - "192.0.0.7", - "192.0.0.8", - "192.0.0.9", - "192.0.0.10", - "192.0.0.11", - "192.0.0.12", - "192.0.0.13", - "192.0.0.14", - "192.0.0.15", - "192.0.0.16", - "192.0.0.17", - "192.0.0.18", - "192.0.0.19", - "192.0.0.20", - "192.0.0.21", - "192.0.0.22", - "192.0.0.23", - "192.0.0.24", - "192.0.0.25", - "192.0.0.26", - "192.0.0.27", - "192.0.0.28", - "192.0.0.29", - "192.0.0.30", - "192.0.0.31", - "192.0.0.32", - "192.0.0.33", - "192.0.0.34", - "192.0.0.35", - "192.0.0.36", - "192.0.0.37", - "192.0.0.38", - "192.0.0.39", - "192.0.0.40", - "192.0.0.41", - "192.0.0.42", - "192.0.0.43", - "192.0.0.44", - "192.0.0.45", - "192.0.0.46", - "192.0.0.47", + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4", + "192.0.0.5", + "192.0.0.6", + "192.0.0.7", + "192.0.0.8", + "192.0.0.9", + "192.0.0.10", + "192.0.0.11", + "192.0.0.12", + "192.0.0.13", + "192.0.0.14", + "192.0.0.15", + "192.0.0.16", + "192.0.0.17", + "192.0.0.18", + "192.0.0.19", + "192.0.0.20", + "192.0.0.21", + "192.0.0.22", + "192.0.0.23", + "192.0.0.24", + "192.0.0.25", + "192.0.0.26", + "192.0.0.27", + "192.0.0.28", + "192.0.0.29", + "192.0.0.30", + "192.0.0.31", + "192.0.0.32", + "192.0.0.33", + "192.0.0.34", + "192.0.0.35", + "192.0.0.36", + "192.0.0.37", + "192.0.0.38", + "192.0.0.39", + "192.0.0.40", + "192.0.0.41", + "192.0.0.42", + "192.0.0.43", + "192.0.0.44", + "192.0.0.45", + "192.0.0.46", + "192.0.0.47", "192.0.0.48" - ], + ], "vlanid": "1000" } - }, + }, "MAP_PFC_PRIORITY_TO_QUEUE": { "AZURE": { - "1": "1", - "0": "0", - "3": "3", - "2": "2", - "5": "5", - "4": "4", - "7": "7", + "1": "1", + "0": "0", + "3": "3", + "2": "2", + "5": "5", + "4": "4", + "7": "7", "6": "6" } - }, + }, "QUEUE": { "Ethernet4|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet4|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet4|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet4|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet4|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet4|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet4|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet48|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet48|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet48|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet48|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet48|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet48|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet48|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet8|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet8|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet8|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet8|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet8|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet8|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet8|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet124|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet96|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet96|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet96|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet96|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet96|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet96|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet96|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet112|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet112|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet112|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet112|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet112|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet112|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet112|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet28|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet28|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet12|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet28|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet12|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet28|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet28|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet12|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet116|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet116|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet116|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet116|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet116|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet116|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet116|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet40|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet40|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet40|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet40|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet40|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet40|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet40|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet20|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet20|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet20|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet20|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet20|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet20|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet20|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet24|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet24|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet24|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet24|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet24|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet24|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet24|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet16|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet16|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet16|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet16|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet16|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet16|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet16|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet32|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet32|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet32|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet32|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet32|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet32|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet32|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet36|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet44|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet44|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet36|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet36|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet36|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet36|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet36|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet44|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet36|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet120|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet120|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet44|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet120|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet120|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet120|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet120|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet44|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet44|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet44|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet64|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet64|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet64|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet64|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet64|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet64|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet64|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet60|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet60|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet60|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet60|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet60|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet60|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet60|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet76|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet76|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet76|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet76|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet76|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet76|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet76|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet72|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet72|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet72|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet72|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet72|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet72|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet72|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet68|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet68|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet68|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet68|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet68|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet68|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet68|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet12|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet12|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet28|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet12|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet12|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet28|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet88|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet88|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet88|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet88|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet88|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet88|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet88|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet120|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet80|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet80|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet80|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet80|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet80|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet80|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet80|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet124|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet84|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet84|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet124|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet124|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet84|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet84|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet124|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet84|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet124|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet124|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet84|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet84|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet92|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet92|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet92|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet92|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet92|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet92|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet92|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet56|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet56|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet56|6": { "scheduler": "scheduler.0" - }, + }, "Ethernet56|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet56|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet56|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet56|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet52|0": { "scheduler": "scheduler.0" - }, + }, "Ethernet52|1": { "scheduler": "scheduler.0" - }, + }, "Ethernet52|2": { "scheduler": "scheduler.0" - }, + }, "Ethernet52|3": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet52|4": { - "wred_profile": "AZURE_LOSSLESS", + "wred_profile": "AZURE_LOSSLESS", "scheduler": "scheduler.1" - }, + }, "Ethernet52|5": { "scheduler": "scheduler.0" - }, + }, "Ethernet52|6": { "scheduler": "scheduler.0" } - }, + }, "PORTCHANNEL_MEMBER": { - "PortChannel0002|Ethernet116": {}, - "PortChannel0004|Ethernet124": {}, - "PortChannel0003|Ethernet120": {}, + "PortChannel0002|Ethernet116": {}, + "PortChannel0004|Ethernet124": {}, + "PortChannel0003|Ethernet120": {}, "PortChannel0001|Ethernet112": {} - }, + }, "FLEX_COUNTER_TABLE": { "QUEUE_WATERMARK": { "FLEX_COUNTER_STATUS": "enable" - }, + }, "BUFFER_POOL_WATERMARK": { "FLEX_COUNTER_STATUS": "enable" - }, + }, "PFCWD": { "FLEX_COUNTER_STATUS": "enable" - }, + }, "QUEUE": { "FLEX_COUNTER_STATUS": "enable" - }, + }, "PG_WATERMARK": { "FLEX_COUNTER_STATUS": "enable" - }, + }, "PORT_BUFFER_DROP": { "FLEX_COUNTER_STATUS": "enable" - }, + }, "RIF": { "FLEX_COUNTER_STATUS": "enable" - }, + }, "PORT": { "FLEX_COUNTER_STATUS": "enable" }, "FLOW_CNT_TRAP": { "FLEX_COUNTER_STATUS": "enable" + }, + "FLOW_CNT_ROUTE": { + "FLEX_COUNTER_STATUS": "enable" } - }, + }, "PORT": { "Ethernet8": { - "index": "2", - "lanes": "37,38,39,40", - "description": "Servers1:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/8", - "admin_status": "up", + "index": "2", + "lanes": "37,38,39,40", + "description": "Servers1:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/8", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet0": { - "index": "0", - "lanes": "29,30,31,32", - "description": "fortyGigE0/0", - "mtu": "9100", - "alias": "fortyGigE0/0", - "pfc_asym": "off", + "index": "0", + "lanes": "29,30,31,32", + "description": "fortyGigE0/0", + "mtu": "9100", + "alias": "fortyGigE0/0", + "pfc_asym": "off", "speed": "40000" - }, + }, "Ethernet4": { - "index": "1", - "lanes": "25,26,27,28", - "description": "Servers0:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/4", - "admin_status": "up", + "index": "1", + "lanes": "25,26,27,28", + "description": "Servers0:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/4", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet108": { - "index": "27", - "lanes": "81,82,83,84", - "description": "fortyGigE0/108", - "mtu": "9100", - "alias": "fortyGigE0/108", - "pfc_asym": "off", + "index": "27", + "lanes": "81,82,83,84", + "description": "fortyGigE0/108", + "mtu": "9100", + "alias": "fortyGigE0/108", + "pfc_asym": "off", "speed": "40000" - }, + }, "Ethernet100": { - "index": "25", - "lanes": "125,126,127,128", - "description": "fortyGigE0/100", - "mtu": "9100", - "alias": "fortyGigE0/100", - "pfc_asym": "off", + "index": "25", + "lanes": "125,126,127,128", + "description": "fortyGigE0/100", + "mtu": "9100", + "alias": "fortyGigE0/100", + "pfc_asym": "off", "speed": "40000" - }, + }, "Ethernet104": { - "index": "26", - "lanes": "85,86,87,88", - "description": "fortyGigE0/104", - "mtu": "9100", - "alias": "fortyGigE0/104", - "pfc_asym": "off", + "index": "26", + "lanes": "85,86,87,88", + "description": "fortyGigE0/104", + "mtu": "9100", + "alias": "fortyGigE0/104", + "pfc_asym": "off", "speed": "40000" - }, + }, "Ethernet96": { - "index": "24", - "lanes": "121,122,123,124", - "description": "Servers23:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/96", - "admin_status": "up", + "index": "24", + "lanes": "121,122,123,124", + "description": "Servers23:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/96", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet124": { - "index": "31", - "lanes": "101,102,103,104", - "description": "ARISTA04T1:Ethernet1", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/124", - "admin_status": "up", + "index": "31", + "lanes": "101,102,103,104", + "description": "ARISTA04T1:Ethernet1", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/124", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet92": { - "index": "23", - "lanes": "113,114,115,116", - "description": "Servers22:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/92", - "admin_status": "up", + "index": "23", + "lanes": "113,114,115,116", + "description": "Servers22:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/92", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet120": { - "index": "30", - "lanes": "97,98,99,100", - "description": "ARISTA03T1:Ethernet1", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/120", - "admin_status": "up", + "index": "30", + "lanes": "97,98,99,100", + "description": "ARISTA03T1:Ethernet1", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/120", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet52": { - "index": "13", - "lanes": "53,54,55,56", - "description": "Servers12:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/52", - "admin_status": "up", + "index": "13", + "lanes": "53,54,55,56", + "description": "Servers12:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/52", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet56": { - "index": "14", - "lanes": "61,62,63,64", - "description": "Servers13:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/56", - "admin_status": "up", + "index": "14", + "lanes": "61,62,63,64", + "description": "Servers13:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/56", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet76": { - "index": "19", - "lanes": "73,74,75,76", - "description": "Servers18:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/76", - "admin_status": "up", + "index": "19", + "lanes": "73,74,75,76", + "description": "Servers18:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/76", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet72": { - "index": "18", - "lanes": "77,78,79,80", - "description": "Servers17:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/72", - "admin_status": "up", + "index": "18", + "lanes": "77,78,79,80", + "description": "Servers17:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/72", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet32": { - "index": "8", - "lanes": "9,10,11,12", - "description": "Servers7:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/32", - "admin_status": "up", + "index": "8", + "lanes": "9,10,11,12", + "description": "Servers7:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/32", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet16": { - "index": "4", - "lanes": "41,42,43,44", - "description": "Servers3:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/16", - "admin_status": "up", + "index": "4", + "lanes": "41,42,43,44", + "description": "Servers3:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/16", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet36": { - "index": "9", - "lanes": "13,14,15,16", - "description": "Servers8:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/36", - "admin_status": "up", + "index": "9", + "lanes": "13,14,15,16", + "description": "Servers8:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/36", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet12": { - "index": "3", - "lanes": "33,34,35,36", - "description": "Servers2:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/12", - "admin_status": "up", + "index": "3", + "lanes": "33,34,35,36", + "description": "Servers2:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/12", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet28": { - "index": "7", - "lanes": "1,2,3,4", - "description": "Servers6:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/28", - "admin_status": "up", + "index": "7", + "lanes": "1,2,3,4", + "description": "Servers6:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/28", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet88": { - "index": "22", - "lanes": "117,118,119,120", - "description": "Servers21:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/88", - "admin_status": "up", + "index": "22", + "lanes": "117,118,119,120", + "description": "Servers21:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/88", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet24": { - "index": "6", - "lanes": "5,6,7,8", - "description": "Servers5:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/24", - "admin_status": "up", + "index": "6", + "lanes": "5,6,7,8", + "description": "Servers5:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/24", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet116": { - "index": "29", - "lanes": "93,94,95,96", - "description": "ARISTA02T1:Ethernet1", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/116", - "admin_status": "up", + "index": "29", + "lanes": "93,94,95,96", + "description": "ARISTA02T1:Ethernet1", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/116", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet80": { - "index": "20", - "lanes": "105,106,107,108", - "description": "Servers19:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/80", - "admin_status": "up", + "index": "20", + "lanes": "105,106,107,108", + "description": "Servers19:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/80", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet112": { - "index": "28", - "lanes": "89,90,91,92", - "description": "ARISTA01T1:Ethernet1", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/112", - "admin_status": "up", + "index": "28", + "lanes": "89,90,91,92", + "description": "ARISTA01T1:Ethernet1", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/112", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet84": { - "index": "21", - "lanes": "109,110,111,112", - "description": "Servers20:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/84", - "admin_status": "up", + "index": "21", + "lanes": "109,110,111,112", + "description": "Servers20:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/84", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet48": { - "index": "12", - "lanes": "49,50,51,52", - "description": "Servers11:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/48", - "admin_status": "up", + "index": "12", + "lanes": "49,50,51,52", + "description": "Servers11:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/48", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet44": { - "index": "11", - "lanes": "17,18,19,20", - "description": "Servers10:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/44", - "admin_status": "up", + "index": "11", + "lanes": "17,18,19,20", + "description": "Servers10:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/44", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet40": { - "index": "10", - "lanes": "21,22,23,24", - "description": "Servers9:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/40", - "admin_status": "up", + "index": "10", + "lanes": "21,22,23,24", + "description": "Servers9:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/40", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet64": { - "index": "16", - "lanes": "65,66,67,68", - "description": "Servers15:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/64", - "admin_status": "up", + "index": "16", + "lanes": "65,66,67,68", + "description": "Servers15:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/64", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet60": { - "index": "15", - "lanes": "57,58,59,60", - "description": "Servers14:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/60", - "admin_status": "up", + "index": "15", + "lanes": "57,58,59,60", + "description": "Servers14:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/60", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet20": { - "index": "5", - "lanes": "45,46,47,48", - "description": "Servers4:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/20", - "admin_status": "up", + "index": "5", + "lanes": "45,46,47,48", + "description": "Servers4:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/20", + "admin_status": "up", "speed": "40000" - }, + }, "Ethernet68": { - "index": "17", - "lanes": "69,70,71,72", - "description": "Servers16:eth0", - "pfc_asym": "off", - "mtu": "9100", - "alias": "fortyGigE0/68", - "admin_status": "up", + "index": "17", + "lanes": "69,70,71,72", + "description": "Servers16:eth0", + "pfc_asym": "off", + "mtu": "9100", + "alias": "fortyGigE0/68", + "admin_status": "up", "speed": "40000" } - }, + }, "SYSLOG_SERVER": { - "100.127.20.21": {}, + "100.127.20.21": {}, "10.3.145.8": {} - }, + }, "CRM": { "Config": { - "acl_table_threshold_type": "percentage", - "nexthop_group_threshold_type": "percentage", - "fdb_entry_high_threshold": "85", - "acl_entry_threshold_type": "percentage", - "ipv6_neighbor_low_threshold": "70", - "nexthop_group_member_low_threshold": "70", - "acl_group_high_threshold": "85", - "ipv4_route_high_threshold": "85", - "acl_counter_high_threshold": "85", - "ipv4_route_low_threshold": "70", - "ipv4_route_threshold_type": "percentage", - "ipv4_neighbor_low_threshold": "70", - "acl_group_threshold_type": "percentage", - "ipv4_nexthop_high_threshold": "85", - "ipv6_route_threshold_type": "percentage", - "nexthop_group_low_threshold": "70", - "ipv4_neighbor_high_threshold": "85", - "ipv6_route_high_threshold": "85", - "ipv6_nexthop_threshold_type": "percentage", - "polling_interval": "300", - "ipv4_nexthop_threshold_type": "percentage", - "acl_group_low_threshold": "70", - "acl_entry_low_threshold": "70", - "nexthop_group_member_threshold_type": "percentage", - "ipv4_nexthop_low_threshold": "70", - "acl_counter_threshold_type": "percentage", - "ipv6_neighbor_high_threshold": "85", - "nexthop_group_member_high_threshold": "85", - "acl_table_low_threshold": "70", - "fdb_entry_threshold_type": "percentage", - "ipv6_neighbor_threshold_type": "percentage", - "acl_table_high_threshold": "85", - "ipv6_nexthop_low_threshold": "70", - "acl_counter_low_threshold": "70", - "ipv4_neighbor_threshold_type": "percentage", - "nexthop_group_high_threshold": "85", - "ipv6_route_low_threshold": "70", - "acl_entry_high_threshold": "85", - "fdb_entry_low_threshold": "70", + "acl_table_threshold_type": "percentage", + "nexthop_group_threshold_type": "percentage", + "fdb_entry_high_threshold": "85", + "acl_entry_threshold_type": "percentage", + "ipv6_neighbor_low_threshold": "70", + "nexthop_group_member_low_threshold": "70", + "acl_group_high_threshold": "85", + "ipv4_route_high_threshold": "85", + "acl_counter_high_threshold": "85", + "ipv4_route_low_threshold": "70", + "ipv4_route_threshold_type": "percentage", + "ipv4_neighbor_low_threshold": "70", + "acl_group_threshold_type": "percentage", + "ipv4_nexthop_high_threshold": "85", + "ipv6_route_threshold_type": "percentage", + "nexthop_group_low_threshold": "70", + "ipv4_neighbor_high_threshold": "85", + "ipv6_route_high_threshold": "85", + "ipv6_nexthop_threshold_type": "percentage", + "polling_interval": "300", + "ipv4_nexthop_threshold_type": "percentage", + "acl_group_low_threshold": "70", + "acl_entry_low_threshold": "70", + "nexthop_group_member_threshold_type": "percentage", + "ipv4_nexthop_low_threshold": "70", + "acl_counter_threshold_type": "percentage", + "ipv6_neighbor_high_threshold": "85", + "nexthop_group_member_high_threshold": "85", + "acl_table_low_threshold": "70", + "fdb_entry_threshold_type": "percentage", + "ipv6_neighbor_threshold_type": "percentage", + "acl_table_high_threshold": "85", + "ipv6_nexthop_low_threshold": "70", + "acl_counter_low_threshold": "70", + "ipv4_neighbor_threshold_type": "percentage", + "nexthop_group_high_threshold": "85", + "ipv6_route_low_threshold": "70", + "acl_entry_high_threshold": "85", + "fdb_entry_low_threshold": "70", "ipv6_nexthop_high_threshold": "85" } - }, + }, "VLAN_INTERFACE": { - "Vlan1000|192.168.0.1/21": {}, + "Vlan1000|192.168.0.1/21": {}, "Vlan1000": {} - }, + }, "BUFFER_PG": { "Ethernet4|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet48|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet80|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet112|3-4": { "profile": "pg_lossless_40000_40m_profile" - }, + }, "Ethernet56|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet104|3-4": { "profile": "pg_lossless_40000_300m_profile" - }, + }, "Ethernet28|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet12|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet16|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet40|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet8|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet52|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet116|3-4": { "profile": "pg_lossless_40000_40m_profile" - }, + }, "Ethernet124|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet116|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet24|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet8|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet108|3-4": { "profile": "pg_lossless_40000_300m_profile" - }, + }, "Ethernet60|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet0|3-4": { "profile": "pg_lossless_40000_300m_profile" - }, + }, "Ethernet40|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet12|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet28|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet76|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet60|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet120|3-4": { "profile": "pg_lossless_40000_40m_profile" - }, + }, "Ethernet72|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet20|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet92|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet48|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet72|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet88|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet16|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet32|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet56|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet44|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet100|3-4": { "profile": "pg_lossless_40000_300m_profile" - }, + }, "Ethernet44|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet64|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet36|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet96|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet64|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet80|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet96|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet84|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet124|3-4": { "profile": "pg_lossless_40000_40m_profile" - }, + }, "Ethernet24|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet92|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet20|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet120|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet112|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet88|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet76|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet32|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet4|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet52|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet68|0": { "profile": "ingress_lossy_profile" - }, + }, "Ethernet84|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet68|3-4": { "profile": "pg_lossless_40000_5m_profile" - }, + }, "Ethernet36|3-4": { "profile": "pg_lossless_40000_5m_profile" } - }, + }, "BGP_NEIGHBOR": { "10.0.0.59": { - "rrclient": "0", - "name": "ARISTA02T1", - "local_addr": "10.0.0.58", - "nhopself": "0", - "holdtime": "10", - "asn": "64600", + "rrclient": "0", + "name": "ARISTA02T1", + "local_addr": "10.0.0.58", + "nhopself": "0", + "holdtime": "10", + "asn": "64600", "keepalive": "3" - }, + }, "10.0.0.61": { - "rrclient": "0", - "name": "ARISTA03T1", - "local_addr": "10.0.0.60", - "nhopself": "0", - "holdtime": "10", - "asn": "64600", + "rrclient": "0", + "name": "ARISTA03T1", + "local_addr": "10.0.0.60", + "nhopself": "0", + "holdtime": "10", + "asn": "64600", "keepalive": "3" - }, + }, "10.0.0.63": { - "rrclient": "0", - "name": "ARISTA04T1", - "local_addr": "10.0.0.62", - "nhopself": "0", - "holdtime": "10", - "asn": "64600", + "rrclient": "0", + "name": "ARISTA04T1", + "local_addr": "10.0.0.62", + "nhopself": "0", + "holdtime": "10", + "asn": "64600", "keepalive": "3" - }, + }, "fc00::7e": { - "rrclient": "0", - "name": "ARISTA04T1", - "local_addr": "fc00::7d", - "nhopself": "0", - "holdtime": "10", - "asn": "64600", + "rrclient": "0", + "name": "ARISTA04T1", + "local_addr": "fc00::7d", + "nhopself": "0", + "holdtime": "10", + "asn": "64600", "keepalive": "3" - }, + }, "fc00::7a": { - "rrclient": "0", - "name": "ARISTA03T1", - "local_addr": "fc00::79", - "nhopself": "0", - "holdtime": "10", - "asn": "64600", + "rrclient": "0", + "name": "ARISTA03T1", + "local_addr": "fc00::79", + "nhopself": "0", + "holdtime": "10", + "asn": "64600", "keepalive": "3" - }, + }, "10.0.0.57": { - "rrclient": "0", - "name": "ARISTA01T1", - "local_addr": "10.0.0.56", - "nhopself": "0", - "holdtime": "10", - "asn": "64600", + "rrclient": "0", + "name": "ARISTA01T1", + "local_addr": "10.0.0.56", + "nhopself": "0", + "holdtime": "10", + "asn": "64600", "keepalive": "3" - }, + }, "fc00::76": { - "rrclient": "0", - "name": "ARISTA02T1", - "local_addr": "fc00::75", - "nhopself": "0", - "holdtime": "10", - "asn": "64600", + "rrclient": "0", + "name": "ARISTA02T1", + "local_addr": "fc00::75", + "nhopself": "0", + "holdtime": "10", + "asn": "64600", "keepalive": "3" - }, + }, "fc00::72": { - "rrclient": "0", - "name": "ARISTA01T1", - "local_addr": "fc00::71", - "nhopself": "0", - "holdtime": "10", - "asn": "64600", + "rrclient": "0", + "name": "ARISTA01T1", + "local_addr": "fc00::71", + "nhopself": "0", + "holdtime": "10", + "asn": "64600", "keepalive": "3" } - }, + }, "PORTCHANNEL_INTERFACE": { - "PortChannel0003|10.0.0.60/31": {}, - "PortChannel0001": {}, - "PortChannel0003": {}, - "PortChannel0002": {}, - "PortChannel0001|10.0.0.56/31": {}, - "PortChannel0004": {}, - "PortChannel0003|FC00::79/126": {}, - "PortChannel0002|FC00::75/126": {}, - "PortChannel0004|FC00::7D/126": {}, - "PortChannel0004|10.0.0.62/31": {}, - "PortChannel0002|10.0.0.58/31": {}, + "PortChannel0003|10.0.0.60/31": {}, + "PortChannel0001": {}, + "PortChannel0003": {}, + "PortChannel0002": {}, + "PortChannel0001|10.0.0.56/31": {}, + "PortChannel0004": {}, + "PortChannel0003|FC00::79/126": {}, + "PortChannel0002|FC00::75/126": {}, + "PortChannel0004|FC00::7D/126": {}, + "PortChannel0004|10.0.0.62/31": {}, + "PortChannel0002|10.0.0.58/31": {}, "PortChannel0001|FC00::71/126": {} - }, + }, "PORTCHANNEL": { "PortChannel0001": { - "admin_status": "up", - "min_links": "1", + "admin_status": "up", + "min_links": "1", "members": [ "Ethernet112" - ], + ], "mtu": "9100" - }, + }, "PortChannel0003": { - "admin_status": "up", - "min_links": "1", + "admin_status": "up", + "min_links": "1", "members": [ "Ethernet120" - ], + ], "mtu": "9100" - }, + }, "PortChannel0002": { - "admin_status": "up", - "min_links": "1", + "admin_status": "up", + "min_links": "1", "members": [ "Ethernet116" - ], + ], "mtu": "9100" - }, + }, "PortChannel0004": { - "admin_status": "up", - "min_links": "1", + "admin_status": "up", + "min_links": "1", "members": [ "Ethernet124" - ], + ], "mtu": "9100" } - }, + }, "LOOPBACK_INTERFACE": { - "Loopback0|FC00:1::32/128": {}, - "Loopback0": {}, + "Loopback0|FC00:1::32/128": {}, + "Loopback0": {}, "Loopback0|10.1.0.32/32": {} - }, + }, "PORT_QOS_MAP": { "Ethernet8": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet4": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet96": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet124": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet92": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet120": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet52": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet56": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet76": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet72": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet32": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet16": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet36": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet12": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet28": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet88": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet24": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet116": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet80": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet112": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet84": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet48": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet44": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet40": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet64": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet60": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet20": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" - }, + }, "Ethernet68": { - "tc_to_pg_map": "AZURE", - "tc_to_queue_map": "AZURE", - "pfc_enable": "3,4", - "pfc_to_queue_map": "AZURE", + "tc_to_pg_map": "AZURE", + "tc_to_queue_map": "AZURE", + "pfc_enable": "3,4", + "pfc_to_queue_map": "AZURE", "dscp_to_tc_map": "AZURE" } - }, + }, "DHCP_SERVER": { - "192.0.0.32": {}, - "192.0.0.7": {}, - "192.0.0.6": {}, - "192.0.0.5": {}, - "192.0.0.4": {}, - "192.0.0.3": {}, - "192.0.0.2": {}, - "192.0.0.1": {}, - "192.0.0.19": {}, - "192.0.0.9": {}, - "192.0.0.8": {}, - "192.0.0.17": {}, - "192.0.0.16": {}, - "192.0.0.15": {}, - "192.0.0.14": {}, - "192.0.0.39": {}, - "192.0.0.38": {}, - "192.0.0.11": {}, - "192.0.0.10": {}, - "192.0.0.35": {}, - "192.0.0.34": {}, - "192.0.0.37": {}, - "192.0.0.36": {}, - "192.0.0.31": {}, - "192.0.0.30": {}, - "192.0.0.33": {}, - "192.0.0.18": {}, - "192.0.0.13": {}, - "192.0.0.12": {}, - "192.0.0.28": {}, - "192.0.0.29": {}, - "192.0.0.26": {}, - "192.0.0.27": {}, - "192.0.0.24": {}, - "192.0.0.25": {}, - "192.0.0.22": {}, - "192.0.0.23": {}, - "192.0.0.20": {}, - "192.0.0.21": {}, - "192.0.0.44": {}, - "192.0.0.45": {}, - "192.0.0.46": {}, - "192.0.0.47": {}, - "192.0.0.40": {}, - "192.0.0.41": {}, - "192.0.0.42": {}, - "192.0.0.43": {}, + "192.0.0.32": {}, + "192.0.0.7": {}, + "192.0.0.6": {}, + "192.0.0.5": {}, + "192.0.0.4": {}, + "192.0.0.3": {}, + "192.0.0.2": {}, + "192.0.0.1": {}, + "192.0.0.19": {}, + "192.0.0.9": {}, + "192.0.0.8": {}, + "192.0.0.17": {}, + "192.0.0.16": {}, + "192.0.0.15": {}, + "192.0.0.14": {}, + "192.0.0.39": {}, + "192.0.0.38": {}, + "192.0.0.11": {}, + "192.0.0.10": {}, + "192.0.0.35": {}, + "192.0.0.34": {}, + "192.0.0.37": {}, + "192.0.0.36": {}, + "192.0.0.31": {}, + "192.0.0.30": {}, + "192.0.0.33": {}, + "192.0.0.18": {}, + "192.0.0.13": {}, + "192.0.0.12": {}, + "192.0.0.28": {}, + "192.0.0.29": {}, + "192.0.0.26": {}, + "192.0.0.27": {}, + "192.0.0.24": {}, + "192.0.0.25": {}, + "192.0.0.22": {}, + "192.0.0.23": {}, + "192.0.0.20": {}, + "192.0.0.21": {}, + "192.0.0.44": {}, + "192.0.0.45": {}, + "192.0.0.46": {}, + "192.0.0.47": {}, + "192.0.0.40": {}, + "192.0.0.41": {}, + "192.0.0.42": {}, + "192.0.0.43": {}, "192.0.0.48": {} - }, + }, "VLAN_MEMBER": { "Vlan1000|Ethernet64": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet4": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet68": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet8": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet32": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet16": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet36": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet12": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet76": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet72": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet44": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet40": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet48": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet80": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet84": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet88": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet20": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet24": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet28": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet60": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet52": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet56": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet96": { "tagging_mode": "untagged" - }, + }, "Vlan1000|Ethernet92": { "tagging_mode": "untagged" } - }, + }, "BUFFER_QUEUE": { "Ethernet76|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet80|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet120|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet40|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet16|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet40|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet116|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet52|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet84|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet24|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet124|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet8|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet64|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet12|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet28|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet120|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet112|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet24|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet96|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet4|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet88|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet112|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet68|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet36|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet20|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet36|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet80|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet40|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet64|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet12|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet16|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet72|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet56|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet8|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet52|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet92|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet32|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet56|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet124|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet84|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet84|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet48|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet36|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet48|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet88|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet16|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet44|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet56|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet8|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet88|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet76|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet68|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet28|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet112|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet96|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet60|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet12|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet72|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet120|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet4|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet72|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet60|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet4|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet68|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet80|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet64|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet24|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet44|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet44|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet92|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet48|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet116|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet28|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet96|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet124|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet116|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet92|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet20|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet76|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet60|5-6": { "profile": "egress_lossy_profile" - }, + }, "Ethernet32|3-4": { "profile": "egress_lossless_profile" - }, + }, "Ethernet32|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet20|0-2": { "profile": "egress_lossy_profile" - }, + }, "Ethernet52|0-2": { "profile": "egress_lossy_profile" } - }, + }, "WRED_PROFILE": { "AZURE_LOSSLESS": { - "red_max_threshold": "2097152", - "wred_green_enable": "true", - "ecn": "ecn_all", - "green_min_threshold": "1048576", - "red_min_threshold": "1048576", - "wred_yellow_enable": "true", - "yellow_min_threshold": "1048576", - "green_max_threshold": "2097152", - "green_drop_probability": "5", - "yellow_max_threshold": "2097152", - "wred_red_enable": "true", - "yellow_drop_probability": "5", + "red_max_threshold": "2097152", + "wred_green_enable": "true", + "ecn": "ecn_all", + "green_min_threshold": "1048576", + "red_min_threshold": "1048576", + "wred_yellow_enable": "true", + "yellow_min_threshold": "1048576", + "green_max_threshold": "2097152", + "green_drop_probability": "5", + "yellow_max_threshold": "2097152", + "wred_red_enable": "true", + "yellow_drop_probability": "5", "red_drop_probability": "5" } - }, + }, "TC_TO_PRIORITY_GROUP_MAP": { "AZURE": { - "1": "0", - "0": "0", - "3": "3", - "2": "0", - "5": "0", - "4": "4", - "7": "7", + "1": "0", + "0": "0", + "3": "3", + "2": "0", + "5": "0", + "4": "4", + "7": "7", "6": "0" } - }, + }, "DEVICE_NEIGHBOR_METADATA": { "ARISTA04T1": { - "lo_addr": "None", - "mgmt_addr": "172.16.131.115", - "hwsku": "Arista-VM", + "lo_addr": "None", + "mgmt_addr": "172.16.131.115", + "hwsku": "Arista-VM", "type": "LeafRouter" - }, + }, "ARISTA03T1": { - "lo_addr": "None", - "mgmt_addr": "172.16.131.114", - "hwsku": "Arista-VM", + "lo_addr": "None", + "mgmt_addr": "172.16.131.114", + "hwsku": "Arista-VM", "type": "LeafRouter" - }, + }, "ARISTA02T1": { - "lo_addr": "None", - "mgmt_addr": "172.16.131.113", - "hwsku": "Arista-VM", + "lo_addr": "None", + "mgmt_addr": "172.16.131.113", + "hwsku": "Arista-VM", "type": "LeafRouter" - }, + }, "ARISTA01T1": { - "lo_addr": "None", - "mgmt_addr": "172.16.131.112", - "hwsku": "Arista-VM", + "lo_addr": "None", + "mgmt_addr": "172.16.131.112", + "hwsku": "Arista-VM", "type": "LeafRouter" } - }, + }, "DEVICE_NEIGHBOR": { "Ethernet8": { - "name": "Servers1", + "name": "Servers1", "port": "eth0" - }, + }, "Ethernet4": { - "name": "Servers0", + "name": "Servers0", "port": "eth0" - }, + }, "Ethernet96": { - "name": "Servers23", + "name": "Servers23", "port": "eth0" - }, + }, "Ethernet124": { - "name": "ARISTA04T1", + "name": "ARISTA04T1", "port": "Ethernet1" - }, + }, "Ethernet92": { - "name": "Servers22", + "name": "Servers22", "port": "eth0" - }, + }, "Ethernet120": { - "name": "ARISTA03T1", + "name": "ARISTA03T1", "port": "Ethernet1" - }, + }, "Ethernet52": { - "name": "Servers12", + "name": "Servers12", "port": "eth0" - }, + }, "Ethernet56": { - "name": "Servers13", + "name": "Servers13", "port": "eth0" - }, + }, "Ethernet76": { - "name": "Servers18", + "name": "Servers18", "port": "eth0" - }, + }, "Ethernet72": { - "name": "Servers17", + "name": "Servers17", "port": "eth0" - }, + }, "Ethernet32": { - "name": "Servers7", + "name": "Servers7", "port": "eth0" - }, + }, "Ethernet16": { - "name": "Servers3", + "name": "Servers3", "port": "eth0" - }, + }, "Ethernet36": { - "name": "Servers8", + "name": "Servers8", "port": "eth0" - }, + }, "Ethernet12": { - "name": "Servers2", + "name": "Servers2", "port": "eth0" - }, + }, "Ethernet28": { - "name": "Servers6", + "name": "Servers6", "port": "eth0" - }, + }, "Ethernet88": { - "name": "Servers21", + "name": "Servers21", "port": "eth0" - }, + }, "Ethernet24": { - "name": "Servers5", + "name": "Servers5", "port": "eth0" - }, + }, "Ethernet116": { - "name": "ARISTA02T1", + "name": "ARISTA02T1", "port": "Ethernet1" - }, + }, "Ethernet80": { - "name": "Servers19", + "name": "Servers19", "port": "eth0" - }, + }, "Ethernet112": { - "name": "ARISTA01T1", + "name": "ARISTA01T1", "port": "Ethernet1" - }, + }, "Ethernet84": { - "name": "Servers20", + "name": "Servers20", "port": "eth0" - }, + }, "Ethernet48": { - "name": "Servers11", + "name": "Servers11", "port": "eth0" - }, + }, "Ethernet44": { - "name": "Servers10", + "name": "Servers10", "port": "eth0" - }, + }, "Ethernet40": { - "name": "Servers9", + "name": "Servers9", "port": "eth0" - }, + }, "Ethernet64": { - "name": "Servers15", + "name": "Servers15", "port": "eth0" - }, + }, "Ethernet60": { - "name": "Servers14", + "name": "Servers14", "port": "eth0" - }, + }, "Ethernet20": { - "name": "Servers4", + "name": "Servers4", "port": "eth0" - }, + }, "Ethernet68": { - "name": "Servers16", + "name": "Servers16", "port": "eth0" } - }, + }, "TELEMETRY": { "gnmi": { - "client_auth": "true", - "log_level": "2", + "client_auth": "true", + "log_level": "2", "port": "50051" - }, + }, "certs": { - "ca_crt": "/etc/sonic/telemetry/dsmsroot.cer", - "server_key": "/etc/sonic/telemetry/streamingtelemetryserver.key", + "ca_crt": "/etc/sonic/telemetry/dsmsroot.cer", + "server_key": "/etc/sonic/telemetry/streamingtelemetryserver.key", "server_crt": "/etc/sonic/telemetry/streamingtelemetryserver.cer" } - }, + }, "FEATURE": { "lldp": { - "has_per_asic_scope": "True", - "high_mem_alert": "disabled", - "auto_restart": "enabled", - "state": "enabled", - "has_global_scope": "True", + "has_per_asic_scope": "True", + "high_mem_alert": "disabled", + "auto_restart": "enabled", + "state": "enabled", + "has_global_scope": "True", "has_timer": "False" - }, + }, "pmon": { - "has_per_asic_scope": "False", - "high_mem_alert": "disabled", - "auto_restart": "enabled", - "state": "enabled", - "has_global_scope": "True", + "has_per_asic_scope": "False", + "high_mem_alert": "disabled", + "auto_restart": "enabled", + "state": "enabled", + "has_global_scope": "True", "has_timer": "False" - }, + }, "sflow": { - "has_per_asic_scope": "False", - "high_mem_alert": "disabled", - "auto_restart": "enabled", - "state": "disabled", - "has_global_scope": "True", + "has_per_asic_scope": "False", + "high_mem_alert": "disabled", + "auto_restart": "enabled", + "state": "disabled", + "has_global_scope": "True", "has_timer": "False" - }, + }, "database": { - "has_per_asic_scope": "True", - "high_mem_alert": "disabled", - "auto_restart": "disabled", - "state": "enabled", - "has_global_scope": "True", + "has_per_asic_scope": "True", + "high_mem_alert": "disabled", + "auto_restart": "disabled", + "state": "enabled", + "has_global_scope": "True", "has_timer": "False" - }, + }, "telemetry": { - "has_per_asic_scope": "False", - "status": "enabled", - "high_mem_alert": "disabled", - "auto_restart": "enabled", - "state": "enabled", - "has_global_scope": "True", + "has_per_asic_scope": "False", + "status": "enabled", + "high_mem_alert": "disabled", + "auto_restart": "enabled", + "state": "enabled", + "has_global_scope": "True", "has_timer": "True" - }, + }, "snmp": { - "has_per_asic_scope": "False", - "high_mem_alert": "disabled", - "auto_restart": "enabled", - "state": "enabled", - "has_global_scope": "True", + "has_per_asic_scope": "False", + "high_mem_alert": "disabled", + "auto_restart": "enabled", + "state": "enabled", + "has_global_scope": "True", "has_timer": "True" - }, + }, "bgp": { - "has_per_asic_scope": "True", - "high_mem_alert": "disabled", - "auto_restart": "enabled", - "state": "enabled", - "has_global_scope": "False", + "has_per_asic_scope": "True", + "high_mem_alert": "disabled", + "auto_restart": "enabled", + "state": "enabled", + "has_global_scope": "False", "has_timer": "False" - }, + }, "radv": { - "has_per_asic_scope": "False", - "high_mem_alert": "disabled", - "auto_restart": "enabled", - "state": "enabled", - "has_global_scope": "True", + "has_per_asic_scope": "False", + "high_mem_alert": "disabled", + "auto_restart": "enabled", + "state": "enabled", + "has_global_scope": "True", "has_timer": "False" - }, + }, "mgmt-framework": { - "has_per_asic_scope": "False", - "high_mem_alert": "disabled", - "auto_restart": "enabled", - "state": "enabled", - "has_global_scope": "True", + "has_per_asic_scope": "False", + "high_mem_alert": "disabled", + "auto_restart": "enabled", + "state": "enabled", + "has_global_scope": "True", "has_timer": "True" - }, + }, "nat": { - "has_per_asic_scope": "False", - "high_mem_alert": "disabled", - "auto_restart": "enabled", - "state": "disabled", - "has_global_scope": "True", + "has_per_asic_scope": "False", + "high_mem_alert": "disabled", + "auto_restart": "enabled", + "state": "disabled", + "has_global_scope": "True", "has_timer": "False" - }, + }, "teamd": { - "has_per_asic_scope": "True", - "high_mem_alert": "disabled", - "auto_restart": "enabled", - "state": "enabled", - "has_global_scope": "False", + "has_per_asic_scope": "True", + "high_mem_alert": "disabled", + "auto_restart": "enabled", + "state": "enabled", + "has_global_scope": "False", "has_timer": "False" - }, + }, "dhcp_relay": { - "has_per_asic_scope": "False", - "high_mem_alert": "disabled", - "auto_restart": "enabled", - "state": "enabled", - "has_global_scope": "True", + "has_per_asic_scope": "False", + "high_mem_alert": "disabled", + "auto_restart": "enabled", + "state": "enabled", + "has_global_scope": "True", "has_timer": "False" - }, + }, "swss": { - "has_per_asic_scope": "True", - "high_mem_alert": "disabled", - "auto_restart": "enabled", - "state": "enabled", - "has_global_scope": "False", + "has_per_asic_scope": "True", + "high_mem_alert": "disabled", + "auto_restart": "enabled", + "state": "enabled", + "has_global_scope": "False", "has_timer": "False" - }, + }, "syncd": { - "has_per_asic_scope": "True", - "high_mem_alert": "disabled", - "auto_restart": "enabled", - "state": "enabled", - "has_global_scope": "False", + "has_per_asic_scope": "True", + "high_mem_alert": "disabled", + "auto_restart": "enabled", + "state": "enabled", + "has_global_scope": "False", "has_timer": "False" } - }, + }, "DSCP_TO_TC_MAP": { "AZURE": { - "56": "1", - "54": "1", - "28": "1", - "48": "6", - "29": "1", - "60": "1", - "61": "1", - "62": "1", - "63": "1", - "49": "1", - "34": "1", - "24": "1", - "25": "1", - "26": "1", - "27": "1", - "20": "1", - "21": "1", - "22": "1", - "23": "1", - "46": "5", - "47": "1", - "44": "1", - "45": "1", - "42": "1", - "43": "1", - "40": "1", - "41": "1", - "1": "1", - "0": "1", - "3": "3", - "2": "1", - "5": "2", - "4": "4", - "7": "1", - "6": "1", - "9": "1", - "8": "0", - "35": "1", - "13": "1", - "12": "1", - "15": "1", - "58": "1", - "11": "1", - "10": "1", - "39": "1", - "38": "1", - "59": "1", - "14": "1", - "17": "1", - "16": "1", - "19": "1", - "18": "1", - "31": "1", - "30": "1", - "51": "1", - "36": "1", - "53": "1", - "52": "1", - "33": "1", - "55": "1", - "37": "1", - "32": "1", - "57": "1", + "56": "1", + "54": "1", + "28": "1", + "48": "6", + "29": "1", + "60": "1", + "61": "1", + "62": "1", + "63": "1", + "49": "1", + "34": "1", + "24": "1", + "25": "1", + "26": "1", + "27": "1", + "20": "1", + "21": "1", + "22": "1", + "23": "1", + "46": "5", + "47": "1", + "44": "1", + "45": "1", + "42": "1", + "43": "1", + "40": "1", + "41": "1", + "1": "1", + "0": "1", + "3": "3", + "2": "1", + "5": "2", + "4": "4", + "7": "1", + "6": "1", + "9": "1", + "8": "0", + "35": "1", + "13": "1", + "12": "1", + "15": "1", + "58": "1", + "11": "1", + "10": "1", + "39": "1", + "38": "1", + "59": "1", + "14": "1", + "17": "1", + "16": "1", + "19": "1", + "18": "1", + "31": "1", + "30": "1", + "51": "1", + "36": "1", + "53": "1", + "52": "1", + "33": "1", + "55": "1", + "37": "1", + "32": "1", + "57": "1", "50": "1" } - }, + }, "MGMT_INTERFACE": { "eth0|FC00:2::32/64": { "forced_mgmt_routes": [ - "10.3.145.98/31", - "10.3.145.8", - "100.127.20.16/28", - "10.3.149.170/31", - "40.122.216.24", - "13.91.48.226", - "10.3.145.14", - "10.64.246.0/24", + "10.3.145.98/31", + "10.3.145.8", + "100.127.20.16/28", + "10.3.149.170/31", + "40.122.216.24", + "13.91.48.226", + "10.3.145.14", + "10.64.246.0/24", "10.64.247.0/24" - ], + ], "gwaddr": "fc00:2::1" - }, + }, "eth0|10.3.147.17/23": { "gwaddr": "10.3.146.1" } - }, + }, "TC_TO_QUEUE_MAP": { "AZURE": { - "1": "1", - "0": "0", - "3": "3", - "2": "2", - "5": "5", - "4": "4", - "7": "7", + "1": "1", + "0": "0", + "3": "3", + "2": "2", + "5": "5", + "4": "4", + "7": "7", "6": "6" } - }, + }, "MGMT_PORT": { "eth0": { - "alias": "eth0", + "alias": "eth0", "admin_status": "up" } - }, + }, "RESTAPI": { "certs": { - "ca_crt": "/etc/sonic/credentials/restapica.crt", - "server_key": "/etc/sonic/credentials/restapiserver.key", - "client_crt_cname": "client.restapi.sonic", + "ca_crt": "/etc/sonic/credentials/restapica.crt", + "server_key": "/etc/sonic/credentials/restapiserver.key", + "client_crt_cname": "client.restapi.sonic", "server_crt": "/etc/sonic/credentials/restapiserver.crt" - }, + }, "config": { - "client_auth": "true", - "log_level": "trace", + "client_auth": "true", + "log_level": "trace", "allow_insecure": "false" } - }, + }, "VERSIONS": { "DATABASE": { "VERSION": "version_1_0_4" } - }, + }, "ACL_TABLE": { "EVERFLOW": { "ports": [ - "PortChannel0001", - "PortChannel0002", - "PortChannel0003", - "PortChannel0004", - "Ethernet24", - "Ethernet40", - "Ethernet20", - "Ethernet44", - "Ethernet48", - "Ethernet28", - "Ethernet96", - "Ethernet92", - "Ethernet76", - "Ethernet72", - "Ethernet52", - "Ethernet80", - "Ethernet56", - "Ethernet32", - "Ethernet16", - "Ethernet36", - "Ethernet12", - "Ethernet60", - "Ethernet8", - "Ethernet4", - "Ethernet64", - "Ethernet68", - "Ethernet84", + "PortChannel0001", + "PortChannel0002", + "PortChannel0003", + "PortChannel0004", + "Ethernet24", + "Ethernet40", + "Ethernet20", + "Ethernet44", + "Ethernet48", + "Ethernet28", + "Ethernet96", + "Ethernet92", + "Ethernet76", + "Ethernet72", + "Ethernet52", + "Ethernet80", + "Ethernet56", + "Ethernet32", + "Ethernet16", + "Ethernet36", + "Ethernet12", + "Ethernet60", + "Ethernet8", + "Ethernet4", + "Ethernet64", + "Ethernet68", + "Ethernet84", "Ethernet88" - ], - "type": "MIRROR", - "policy_desc": "EVERFLOW", + ], + "type": "MIRROR", + "policy_desc": "EVERFLOW", "stage": "ingress" - }, + }, "SNMP_ACL": { "services": [ "SNMP" - ], - "type": "CTRLPLANE", - "policy_desc": "SNMP_ACL", + ], + "type": "CTRLPLANE", + "policy_desc": "SNMP_ACL", "stage": "ingress" - }, + }, "SSH_ONLY": { "services": [ "SSH" - ], - "type": "CTRLPLANE", - "policy_desc": "SSH_ONLY", + ], + "type": "CTRLPLANE", + "policy_desc": "SSH_ONLY", "stage": "ingress" - }, + }, "DATAACL": { "ports": [ - "PortChannel0001", - "PortChannel0002", - "PortChannel0003", + "PortChannel0001", + "PortChannel0002", + "PortChannel0003", "PortChannel0004" - ], - "type": "L3", - "policy_desc": "DATAACL", + ], + "type": "L3", + "policy_desc": "DATAACL", "stage": "ingress" - }, + }, "EVERFLOWV6": { "ports": [ - "PortChannel0001", - "PortChannel0002", - "PortChannel0003", - "PortChannel0004", - "Ethernet24", - "Ethernet40", - "Ethernet20", - "Ethernet44", - "Ethernet48", - "Ethernet28", - "Ethernet96", - "Ethernet92", - "Ethernet76", - "Ethernet72", - "Ethernet52", - "Ethernet80", - "Ethernet56", - "Ethernet32", - "Ethernet16", - "Ethernet36", - "Ethernet12", - "Ethernet60", - "Ethernet8", - "Ethernet4", - "Ethernet64", - "Ethernet68", - "Ethernet84", + "PortChannel0001", + "PortChannel0002", + "PortChannel0003", + "PortChannel0004", + "Ethernet24", + "Ethernet40", + "Ethernet20", + "Ethernet44", + "Ethernet48", + "Ethernet28", + "Ethernet96", + "Ethernet92", + "Ethernet76", + "Ethernet72", + "Ethernet52", + "Ethernet80", + "Ethernet56", + "Ethernet32", + "Ethernet16", + "Ethernet36", + "Ethernet12", + "Ethernet60", + "Ethernet8", + "Ethernet4", + "Ethernet64", + "Ethernet68", + "Ethernet84", "Ethernet88" - ], - "type": "MIRRORV6", - "policy_desc": "EVERFLOWV6", + ], + "type": "MIRRORV6", + "policy_desc": "EVERFLOWV6", "stage": "ingress" } - }, + }, "CABLE_LENGTH": { "AZURE": { - "Ethernet8": "5m", - "Ethernet0": "300m", - "Ethernet4": "5m", - "Ethernet108": "300m", - "Ethernet100": "300m", - "Ethernet104": "300m", - "Ethernet96": "5m", - "Ethernet124": "40m", - "Ethernet92": "5m", - "Ethernet120": "40m", - "Ethernet52": "5m", - "Ethernet56": "5m", - "Ethernet76": "5m", - "Ethernet72": "5m", - "Ethernet32": "5m", - "Ethernet16": "5m", - "Ethernet36": "5m", - "Ethernet12": "5m", - "Ethernet28": "5m", - "Ethernet88": "5m", - "Ethernet24": "5m", - "Ethernet116": "40m", - "Ethernet80": "5m", - "Ethernet112": "40m", - "Ethernet84": "5m", - "Ethernet48": "5m", - "Ethernet44": "5m", - "Ethernet40": "5m", - "Ethernet64": "5m", - "Ethernet60": "5m", - "Ethernet20": "5m", + "Ethernet8": "5m", + "Ethernet0": "300m", + "Ethernet4": "5m", + "Ethernet108": "300m", + "Ethernet100": "300m", + "Ethernet104": "300m", + "Ethernet96": "5m", + "Ethernet124": "40m", + "Ethernet92": "5m", + "Ethernet120": "40m", + "Ethernet52": "5m", + "Ethernet56": "5m", + "Ethernet76": "5m", + "Ethernet72": "5m", + "Ethernet32": "5m", + "Ethernet16": "5m", + "Ethernet36": "5m", + "Ethernet12": "5m", + "Ethernet28": "5m", + "Ethernet88": "5m", + "Ethernet24": "5m", + "Ethernet116": "40m", + "Ethernet80": "5m", + "Ethernet112": "40m", + "Ethernet84": "5m", + "Ethernet48": "5m", + "Ethernet44": "5m", + "Ethernet40": "5m", + "Ethernet64": "5m", + "Ethernet60": "5m", + "Ethernet20": "5m", "Ethernet68": "5m" } - }, + }, "SCHEDULER": { "scheduler.0": { - "type": "DWRR", + "type": "DWRR", "weight": "14" - }, + }, "scheduler.1": { - "type": "DWRR", + "type": "DWRR", "weight": "15" } - }, + }, "BUFFER_POOL": { "ingress_lossless_pool": { - "type": "ingress", - "mode": "dynamic", + "type": "ingress", + "mode": "dynamic", "size": "12766208" - }, + }, "egress_lossless_pool": { - "type": "egress", - "mode": "static", + "type": "egress", + "mode": "static", "size": "12766208" - }, + }, "egress_lossy_pool": { - "type": "egress", - "mode": "dynamic", + "type": "egress", + "mode": "dynamic", "size": "7326924" } - }, + }, "BUFFER_PROFILE": { "pg_lossless_40000_300m_profile": { - "xon_offset": "2496", - "dynamic_th": "-3", - "xon": "18432", - "xoff": "55120", - "pool": "ingress_lossless_pool", + "xon_offset": "2496", + "dynamic_th": "-3", + "xon": "18432", + "xoff": "55120", + "pool": "ingress_lossless_pool", "size": "56368" - }, + }, "egress_lossy_profile": { - "dynamic_th": "3", - "pool": "egress_lossy_pool", + "dynamic_th": "3", + "pool": "egress_lossy_pool", "size": "1518" - }, + }, "egress_lossless_profile": { - "static_th": "12766208", - "pool": "egress_lossless_pool", + "static_th": "12766208", + "pool": "egress_lossless_pool", "size": "0" - }, + }, "pg_lossless_40000_5m_profile": { - "xon_offset": "2496", - "dynamic_th": "-3", - "xon": "18432", - "xoff": "55120", - "pool": "ingress_lossless_pool", + "xon_offset": "2496", + "dynamic_th": "-3", + "xon": "18432", + "xoff": "55120", + "pool": "ingress_lossless_pool", "size": "56368" - }, + }, "ingress_lossy_profile": { - "dynamic_th": "3", - "pool": "ingress_lossless_pool", + "dynamic_th": "3", + "pool": "ingress_lossless_pool", "size": "0" - }, + }, "pg_lossless_40000_40m_profile": { - "xon_offset": "2496", - "dynamic_th": "-3", - "xon": "18432", - "xoff": "55120", - "pool": "ingress_lossless_pool", + "xon_offset": "2496", + "dynamic_th": "-3", + "xon": "18432", + "xoff": "55120", + "pool": "ingress_lossless_pool", "size": "56368" } } diff --git a/tests/counterpoll_test.py b/tests/counterpoll_test.py index 71d7e914aa..b31e8ed8a7 100644 --- a/tests/counterpoll_test.py +++ b/tests/counterpoll_test.py @@ -27,6 +27,7 @@ PG_DROP_STAT 10000 enable ACL 10000 enable FLOW_CNT_TRAP_STAT 10000 enable +FLOW_CNT_ROUTE_STAT 10000 enable """ class TestCounterpoll(object): @@ -155,6 +156,18 @@ def test_update_trap_counter_status(self, status): table = db.cfgdb.get_table('FLEX_COUNTER_TABLE') assert status == table["FLOW_CNT_TRAP"]["FLEX_COUNTER_STATUS"] + @pytest.mark.parametrize("status", ["disable", "enable"]) + def test_update_route_flow_counter_status(self, status): + runner = CliRunner() + db = Db() + + result = runner.invoke(counterpoll.cli.commands["flowcnt-route"].commands[status], [], obj=db.cfgdb) + print(result.exit_code, result.output) + assert result.exit_code == 0 + + table = db.cfgdb.get_table('FLEX_COUNTER_TABLE') + assert status == table["FLOW_CNT_ROUTE"]["FLEX_COUNTER_STATUS"] + def test_update_trap_counter_interval(self): runner = CliRunner() db = Db() @@ -179,6 +192,35 @@ def test_update_trap_counter_interval(self): assert result.exit_code == 2 assert expected in result.output + def test_update_route_counter_interval(self): + runner = CliRunner() + db = Db() + test_interval = "20000" + + result = runner.invoke(counterpoll.cli.commands["flowcnt-route"].commands["interval"], [test_interval], + obj=db.cfgdb) + print(result.exit_code, result.output) + assert result.exit_code == 0 + + table = db.cfgdb.get_table('FLEX_COUNTER_TABLE') + assert test_interval == table["FLOW_CNT_ROUTE"]["POLL_INTERVAL"] + + test_interval = "500" + result = runner.invoke(counterpoll.cli.commands["flowcnt-route"].commands["interval"], [test_interval], + obj=db.cfgdb) + expected = "Invalid value for \"POLL_INTERVAL\": 500 is not in the valid range of 1000 to 30000." + assert result.exit_code == 2 + assert expected in result.output + + test_interval = "40000" + result = runner.invoke(counterpoll.cli.commands["flowcnt-route"].commands["interval"], [test_interval], + obj=db.cfgdb) + + expected = "Invalid value for \"POLL_INTERVAL\": 40000 is not in the valid range of 1000 to 30000." + assert result.exit_code == 2 + assert expected in result.output + + @classmethod def teardown_class(cls): print("TEARDOWN") diff --git a/tests/flow_counter_stats_test.py b/tests/flow_counter_stats_test.py index 807ed61223..681aa18d77 100644 --- a/tests/flow_counter_stats_test.py +++ b/tests/flow_counter_stats_test.py @@ -1,5 +1,6 @@ import importlib import os +import pytest import sys from click.testing import CliRunner @@ -7,8 +8,11 @@ import show.main as show import clear.main as clear +import config.main as config from .utils import get_result_and_return_code +from flow_counter_util.route import FLOW_COUNTER_ROUTE_PATTERN_TABLE, FLOW_COUNTER_ROUTE_MAX_MATCH_FIELD, build_route_pattern +from utilities_common.db import Db from utilities_common.general import load_module_from_source test_path = os.path.dirname(os.path.abspath(__file__)) @@ -72,9 +76,202 @@ asic1 dhcp 0 0 45.25/s """ +expect_show_route_pattern = """\ +Route pattern VRF Max +--------------- ------- ----- +1.1.0.0/24 Vrf1 30 +2000::1/64 default 30 +""" + +expect_show_all_route_stats = """\ + Route pattern VRF Matched routes Packets Bytes +--------------- ------- ---------------- --------- ------- + 1.1.1.0/24 default 1.1.1.1/24 100 2,000 + 1.1.1.2/24 1,000 2,000 + 2001::/64 default 2001::1/64 50 1,000 + 2001::/64 Vrf_1 2001::1/64 1,000 25,000 +""" + +expect_show_route_stats_by_pattern_v4 = """\ + Route pattern VRF Matched routes Packets Bytes +--------------- ------- ---------------- --------- ------- + 1.1.1.0/24 default 1.1.1.1/24 100 2,000 + 1.1.1.2/24 1,000 2,000 +""" + +expect_show_route_stats_by_pattern_v6 = """\ + Route pattern VRF Matched routes Packets Bytes +--------------- ------- ---------------- --------- ------- + 2001::/64 default 2001::1/64 50 1,000 +""" + +expect_show_route_stats_by_pattern_and_vrf_v6 = """\ + Route pattern VRF Matched routes Packets Bytes +--------------- ----- ---------------- --------- ------- + 2001::/64 Vrf_1 2001::1/64 1,000 25,000 +""" + +expect_show_route_stats_by_pattern_empty = """\ + Route pattern VRF Matched routes Packets Bytes +--------------- ----- ---------------- --------- ------- +""" + +expect_show_route_stats_by_route_v4 = """\ + Route VRF Route pattern Packets Bytes +---------- ------- --------------- --------- ------- +1.1.1.1/24 default 1.1.1.0/24 100 2,000 +""" + +expect_show_route_stats_by_route_v6 = """\ + Route VRF Route pattern Packets Bytes +---------- ------- --------------- --------- ------- +2001::1/64 default 2001::/64 50 1,000 +""" + +expect_show_route_stats_by_route_and_vrf_v6 = """\ + Route VRF Route pattern Packets Bytes +---------- ----- --------------- --------- ------- +2001::1/64 Vrf_1 2001::/64 1,000 25,000 +""" + +expect_after_clear_route_stats_all = """\ + Route pattern VRF Matched routes Packets Bytes +--------------- ------- ---------------- --------- ------- + 1.1.1.0/24 default 1.1.1.1/24 0 0 + 1.1.1.2/24 0 0 + 2001::/64 default 2001::1/64 0 0 + 2001::/64 Vrf_1 2001::1/64 0 0 +""" + +expect_after_clear_route_stats_by_pattern_v4 = """\ + Route pattern VRF Matched routes Packets Bytes +--------------- ------- ---------------- --------- ------- + 1.1.1.0/24 default 1.1.1.1/24 0 0 + 1.1.1.2/24 0 0 + 2001::/64 default 2001::1/64 50 1,000 + 2001::/64 Vrf_1 2001::1/64 1,000 25,000 +""" + +expect_after_clear_route_stats_by_pattern_v6 = """\ + Route pattern VRF Matched routes Packets Bytes +--------------- ------- ---------------- --------- ------- + 1.1.1.0/24 default 1.1.1.1/24 0 0 + 1.1.1.2/24 0 0 + 2001::/64 default 2001::1/64 0 0 + 2001::/64 Vrf_1 2001::1/64 1,000 25,000 +""" + +expect_show_route_stats_all_json = """\ +{ + "0": { + "Bytes": "2,000", + "Matched routes": "1.1.1.1/24", + "Packets": "100", + "Route pattern": "1.1.1.0/24", + "VRF": "default" + }, + "1": { + "Bytes": "2,000", + "Matched routes": "1.1.1.2/24", + "Packets": "1,000", + "Route pattern": "1.1.1.0/24", + "VRF": "default" + }, + "2": { + "Bytes": "1,000", + "Matched routes": "2001::1/64", + "Packets": "50", + "Route pattern": "2001::/64", + "VRF": "default" + }, + "3": { + "Bytes": "25,000", + "Matched routes": "2001::1/64", + "Packets": "1,000", + "Route pattern": "2001::/64", + "VRF": "Vrf_1" + } +} +""" + +expect_show_route_stats_by_pattern_v4_json = """\ +{ + "0": { + "Bytes": "2,000", + "Matched routes": "1.1.1.1/24", + "Packets": "100", + "Route pattern": "1.1.1.0/24", + "VRF": "default" + }, + "1": { + "Bytes": "2,000", + "Matched routes": "1.1.1.2/24", + "Packets": "1,000", + "Route pattern": "1.1.1.0/24", + "VRF": "default" + } +} +""" + +expect_show_route_stats_by_pattern_and_vrf_v6_json = """\ +{ + "0": { + "Bytes": "25,000", + "Packets": "1,000", + "Route": "2001::1/64", + "Route pattern": "2001::/64", + "VRF": "Vrf_1" + } +} +""" + +expect_show_route_stats_all_multi_asic = """\ + ASIC ID Route pattern VRF Matched routes Packets Bytes +--------- --------------- ------- ---------------- --------- ------- + asic0 1.1.1.0/24 default 1.1.1.1/24 100 2,000 + 1.1.1.3/24 200 4,000 + asic1 1.1.1.0/24 default 1.1.1.2/24 1,000 2,000 +""" -def delete_cache(): - cmd = 'flow_counters_stat -t trap -d' +expect_show_route_stats_all_json_multi_asic = """\ +{ + "0": { + "ASIC ID": "asic0", + "Bytes": "2,000", + "Matched routes": "1.1.1.1/24", + "Packets": "100", + "Route pattern": "1.1.1.0/24", + "VRF": "default" + }, + "1": { + "ASIC ID": "asic0", + "Bytes": "4,000", + "Matched routes": "1.1.1.3/24", + "Packets": "200", + "Route pattern": "1.1.1.0/24", + "VRF": "default" + }, + "2": { + "ASIC ID": "asic1", + "Bytes": "2,000", + "Matched routes": "1.1.1.2/24", + "Packets": "1,000", + "Route pattern": "1.1.1.0/24", + "VRF": "default" + } +} +""" + +expect_after_clear_route_stats_all_multi_asic = """\ + ASIC ID Route pattern VRF Matched routes Packets Bytes +--------- --------------- ------- ---------------- --------- ------- + asic0 1.1.1.0/24 default 1.1.1.1/24 0 0 + 1.1.1.3/24 0 0 + asic1 1.1.1.0/24 default 1.1.1.2/24 0 0 +""" + +def delete_cache(stat_type='trap'): + cmd = 'flow_counters_stat -t {} -d'.format(stat_type) get_result_and_return_code(cmd) @@ -165,12 +362,12 @@ def setup_class(cls): @classmethod def teardown_class(cls): print("TEARDOWN") + delete_cache() os.environ["PATH"] = os.pathsep.join( os.environ["PATH"].split(os.pathsep)[:-1] ) os.environ["UTILITIES_UNIT_TESTING"] = "0" os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = "" - delete_cache() from .mock_tables import mock_single_asic importlib.reload(mock_single_asic) @@ -207,3 +404,537 @@ def test_clear(self): assert result.exit_code == 0 assert result.output == expect_show_output_multi_asic_after_clear + + +class TestConfigRoutePattern: + @classmethod + def setup_class(cls): + print("SETUP") + os.environ["PATH"] += os.pathsep + scripts_path + os.environ["UTILITIES_UNIT_TESTING"] = "2" + + @classmethod + def teardown_class(cls): + print("TEARDOWN") + os.environ["PATH"] = os.pathsep.join( + os.environ["PATH"].split(os.pathsep)[:-1] + ) + os.environ["UTILITIES_UNIT_TESTING"] = "0" + os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = "" + + @mock.patch('utilities_common.cli.query_yes_no') + def test_add_remove_pattern(self, mock_input): + runner = CliRunner() + db = Db() + prefix = '1.1.1.1/24' + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + [prefix], obj=db + ) + + assert result.exit_code == 0 + table = db.cfgdb.get_table(FLOW_COUNTER_ROUTE_PATTERN_TABLE) + assert prefix in table + assert '30' == table[prefix][FLOW_COUNTER_ROUTE_MAX_MATCH_FIELD] + + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + ['--max', '50', prefix], obj=db + ) + + assert result.exit_code == 0 + table = db.cfgdb.get_table(FLOW_COUNTER_ROUTE_PATTERN_TABLE) + assert '50' == table[prefix][FLOW_COUNTER_ROUTE_MAX_MATCH_FIELD] + + mock_input.return_value = False + vrf = 'Vrf1' + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + ['--max', '50', '--vrf', vrf, prefix], obj=db + ) + + assert result.exit_code == 0 + assert prefix in table + + prefix_v6 = '2000::/64' + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + ['--max', '50', prefix_v6], obj=db + ) + + assert result.exit_code == 0 + table = db.cfgdb.get_table(FLOW_COUNTER_ROUTE_PATTERN_TABLE) + assert prefix_v6 in table + + mock_input.return_value = True + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + ['--max', '50', '--vrf', vrf, prefix], obj=db + ) + + assert result.exit_code == 0 + table = db.cfgdb.get_table(FLOW_COUNTER_ROUTE_PATTERN_TABLE) + + assert (vrf, prefix) in table + assert '50' == table[(vrf, prefix)][FLOW_COUNTER_ROUTE_MAX_MATCH_FIELD] + + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["remove"], + ['--vrf', vrf, prefix], obj=db + ) + + assert result.exit_code == 0 + table = db.cfgdb.get_table(FLOW_COUNTER_ROUTE_PATTERN_TABLE) + assert (vrf, prefix) not in table + + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["remove"], + [prefix_v6], obj=db + ) + + assert result.exit_code == 0 + table = db.cfgdb.get_table(FLOW_COUNTER_ROUTE_PATTERN_TABLE) + assert prefix_v6 not in table + + @mock.patch('utilities_common.cli.query_yes_no', mock.MagicMock(return_value=True)) + def test_replace_invalid_pattern(self): + runner = CliRunner() + db = Db() + db.cfgdb.mod_entry(FLOW_COUNTER_ROUTE_PATTERN_TABLE, + 'vrf1|', + {FLOW_COUNTER_ROUTE_MAX_MATCH_FIELD: '30'}) + prefix = '1.1.1.0/24' + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + [prefix], obj=db + ) + + assert result.exit_code == 0 + table = db.cfgdb.get_table(FLOW_COUNTER_ROUTE_PATTERN_TABLE) + assert prefix in table + + db.cfgdb.set_entry(FLOW_COUNTER_ROUTE_PATTERN_TABLE, prefix, None) + db.cfgdb.mod_entry(FLOW_COUNTER_ROUTE_PATTERN_TABLE, + 'vrf1|invalid', + {FLOW_COUNTER_ROUTE_MAX_MATCH_FIELD: '30'}) + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + [prefix], obj=db + ) + assert result.exit_code == 0 + table = db.cfgdb.get_table(FLOW_COUNTER_ROUTE_PATTERN_TABLE) + assert prefix in table + + def test_add_invalid_pattern(self): + runner = CliRunner() + prefix = 'invalid' + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + [prefix] + ) + + print(result.output) + assert result.exit_code == 1 + + def test_remove_non_exist_pattern(self): + runner = CliRunner() + prefix = '1.1.1.1/24' + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["remove"], + [prefix] + ) + + assert result.exit_code == 1 + assert 'does not exist' in result.output + + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["remove"], + ['invalid'] + ) + assert result.exit_code == 1 + assert 'does not exist' in result.output + + def test_add_pattern_repeatly(self): + runner = CliRunner() + db = Db() + prefix = '1.1.1.1/24' + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + [prefix], obj=db + ) + + assert result.exit_code == 0 + + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + [prefix], obj=db + ) + + print(result.output) + assert result.exit_code == 1 + assert 'already exists' in result.output + + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + ['--vrf', 'vnet1', '-y', prefix], obj=db + ) + + assert result.exit_code == 0 + + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + ['--vrf', 'vnet1', '-y', prefix], obj=db + ) + + assert result.exit_code == 1 + assert 'already exists' in result.output + + prefix_v6 = '2000::/64' + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + ['--max', '50', prefix_v6], obj=db + ) + + assert result.exit_code == 0 + + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + ['--max', '50', prefix_v6], obj=db + ) + + assert result.exit_code == 1 + assert 'already exists' in result.output + + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + ['--max', '50', '--vrf', 'vrf1', '-y', prefix_v6], obj=db + ) + + assert result.exit_code == 0 + + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + ['--max', '50', '--vrf', 'vrf1', '-y', prefix_v6], obj=db + ) + + assert result.exit_code == 1 + assert 'already exists' in result.output + + + def test_add_pattern_without_prefix_length(self): + runner = CliRunner() + db = Db() + prefix = '1.1.0.0' + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + [prefix], obj=db + ) + + assert result.exit_code == 0 + table = db.cfgdb.get_table(FLOW_COUNTER_ROUTE_PATTERN_TABLE) + assert (prefix + '/32') in table + + prefix_v6 = '2000::1' + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + [prefix_v6], obj=db + ) + + assert result.exit_code == 0 + table = db.cfgdb.get_table(FLOW_COUNTER_ROUTE_PATTERN_TABLE) + assert (prefix_v6 + '/128') in table + + def test_show_config(self): + runner = CliRunner() + db = Db() + prefix = '1.1.0.0/24' + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + ['--vrf', 'Vrf1', prefix], obj=db + ) + + prefix_v6 = '2000::1/64' + result = runner.invoke( + config.config.commands["flowcnt-route"].commands["pattern"].commands["add"], + [prefix_v6], obj=db + ) + + result = runner.invoke( + show.cli.commands["flowcnt-route"].commands["config"], + [], obj=db, catch_exceptions=False + ) + + assert result.exit_code == 0 + print(result.output) + assert result.output == expect_show_route_pattern + + +class TestRouteStats: + @classmethod + def setup_class(cls): + print("SETUP") + os.environ["PATH"] += os.pathsep + scripts_path + os.environ["UTILITIES_UNIT_TESTING"] = "2" + delete_cache(stat_type='route') + + @classmethod + def teardown_class(cls): + print("TEARDOWN") + os.environ["PATH"] = os.pathsep.join( + os.environ["PATH"].split(os.pathsep)[:-1] + ) + os.environ["UTILITIES_UNIT_TESTING"] = "0" + os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = "" + + def test_show_all_stats(self): + runner = CliRunner() + result = runner.invoke( + show.cli.commands["flowcnt-route"].commands["stats"], + [] + ) + + assert result.exit_code == 0 + assert expect_show_all_route_stats == result.output + + def test_show_by_pattern(self): + runner = CliRunner() + result = runner.invoke( + show.cli.commands["flowcnt-route"].commands["stats"].commands["pattern"], + ['1.1.1.0/24'] + ) + + assert result.exit_code == 0 + assert result.output == expect_show_route_stats_by_pattern_v4 + print(result.output) + + result = runner.invoke( + show.cli.commands["flowcnt-route"].commands["stats"].commands["pattern"], + ['2001::/64'] + ) + + assert result.exit_code == 0 + assert result.output == expect_show_route_stats_by_pattern_v6 + print(result.output) + + result = runner.invoke( + show.cli.commands["flowcnt-route"].commands["stats"].commands["pattern"], + ['--vrf', 'Vrf_1', '2001::/64'] + ) + + assert result.exit_code == 0 + assert result.output == expect_show_route_stats_by_pattern_and_vrf_v6 + print(result.output) + + result = runner.invoke( + show.cli.commands["flowcnt-route"].commands["stats"].commands["pattern"], + ['invalid'] + ) + + assert result.exit_code == 0 + assert result.output == expect_show_route_stats_by_pattern_empty + print(result.output) + + def test_show_by_route(self): + runner = CliRunner() + result = runner.invoke( + show.cli.commands["flowcnt-route"].commands["stats"].commands["route"], + ['1.1.1.1/24'] + ) + + assert result.exit_code == 0 + assert result.output == expect_show_route_stats_by_route_v4 + print(result.output) + + result = runner.invoke( + show.cli.commands["flowcnt-route"].commands["stats"].commands["route"], + ['2001::1/64'] + ) + + assert result.exit_code == 0 + assert result.output == expect_show_route_stats_by_route_v6 + print(result.output) + + result = runner.invoke( + show.cli.commands["flowcnt-route"].commands["stats"].commands["route"], + ['--vrf', 'Vrf_1', '2001::1/64'] + ) + + assert result.exit_code == 0 + assert result.output == expect_show_route_stats_by_route_and_vrf_v6 + print(result.output) + + def test_show_json(self): + 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' + 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' + 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 + + def test_clear_all(self): + delete_cache(stat_type='route') + runner = CliRunner() + result = runner.invoke( + clear.cli.commands["flowcnt-route"], [] + ) + + assert result.exit_code == 0 + + result = runner.invoke( + show.cli.commands["flowcnt-route"].commands["stats"], + [] + ) + + assert result.exit_code == 0 + assert expect_after_clear_route_stats_all == result.output + print(result.output) + + def test_clear_by_pattern(self): + delete_cache(stat_type='route') + runner = CliRunner() + result = runner.invoke( + clear.cli.commands["flowcnt-route"].commands['pattern'], + ['1.1.1.0/24'] + ) + + assert result.exit_code == 0 + + result = runner.invoke( + show.cli.commands["flowcnt-route"].commands["stats"], + [] + ) + + assert result.exit_code == 0 + assert expect_after_clear_route_stats_by_pattern_v4 == result.output + print(result.output) + + result = runner.invoke( + clear.cli.commands["flowcnt-route"].commands['pattern'], + ['2001::/64'] + ) + + assert result.exit_code == 0 + + result = runner.invoke( + show.cli.commands["flowcnt-route"].commands["stats"], + [] + ) + + assert result.exit_code == 0 + assert expect_after_clear_route_stats_by_pattern_v6 == result.output + print(result.output) + + result = runner.invoke( + clear.cli.commands["flowcnt-route"].commands['pattern'], + ['--vrf', 'Vrf_1', '2001::/64'] + ) + + assert result.exit_code == 0 + + result = runner.invoke( + show.cli.commands["flowcnt-route"].commands["stats"], + [] + ) + + assert result.exit_code == 0 + assert expect_after_clear_route_stats_all == result.output + print(result.output) + + def test_diff(self): + args = mock.MagicMock() + args.type = 'route' + args.delete = False + args.namespace = None + args.json = False + stats = flow_counters_stat.RouteFlowCounterStats(args) + stats._collect = mock.MagicMock() + old_data = { + '': { + '1.1.1.0/24': { + '1.1.1.1/24': ['100', '200', '1'], + '1.1.1.2/24': ['100', '100', '2'], + '1.1.1.3/24': ['100', '200', '3'] + } + } + } + stats._save(old_data) + stats.data = { + '': { + '1.1.1.0/24': { + '1.1.1.1/24': ['200', '300', '4'], + '1.1.1.2/24': ['100', '50', '2'], + '1.1.1.3/24': ['200', '300', '3'] + } + } + } + + stats._collect_and_diff() + cached_data = stats._load() + assert cached_data['']['1.1.1.0/24']['1.1.1.1/24'] == ['0', '0', '4'] + assert cached_data['']['1.1.1.0/24']['1.1.1.2/24'] == ['0', '0', '2'] + assert cached_data['']['1.1.1.0/24']['1.1.1.3/24'] == ['100', '200', '3'] + + +class TestRouteStatsMultiAsic: + @classmethod + def setup_class(cls): + print("SETUP") + os.environ["PATH"] += os.pathsep + scripts_path + os.environ["UTILITIES_UNIT_TESTING"] = "2" + os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = "multi_asic" + delete_cache(stat_type='route') + + @classmethod + def teardown_class(cls): + print("TEARDOWN") + delete_cache(stat_type='route') + os.environ["PATH"] = os.pathsep.join( + os.environ["PATH"].split(os.pathsep)[:-1] + ) + os.environ["UTILITIES_UNIT_TESTING"] = "0" + os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = "" + from .mock_tables import mock_single_asic + importlib.reload(mock_single_asic) + + def test_show_all_stats(self): + runner = CliRunner() + result = runner.invoke( + show.cli.commands["flowcnt-route"].commands["stats"], + [] + ) + + assert result.exit_code == 0 + print(result.output) + assert expect_show_route_stats_all_multi_asic == result.output + + def test_show_json(self): + 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 + + def test_clear_all(self): + delete_cache(stat_type='route') + runner = CliRunner() + result = runner.invoke( + clear.cli.commands["flowcnt-route"], [] + ) + + assert result.exit_code == 0 + + result = runner.invoke( + show.cli.commands["flowcnt-route"].commands["stats"], + [] + ) + + assert result.exit_code == 0 + assert expect_after_clear_route_stats_all_multi_asic == result.output + print(result.output) diff --git a/tests/mock_tables/asic0/counters_db.json b/tests/mock_tables/asic0/counters_db.json index 9b1688c743..fbc039e81c 100644 --- a/tests/mock_tables/asic0/counters_db.json +++ b/tests/mock_tables/asic0/counters_db.json @@ -1815,5 +1815,21 @@ }, "RATES:oid:0x1500000000034e":{ "RX_PPS": 50.25 + }, + "COUNTERS_ROUTE_NAME_MAP":{ + "1.1.1.3/24": "oid:0x1600000000034d", + "1.1.1.1/24": "oid:0x1600000000034e" + }, + "COUNTERS_ROUTE_TO_PATTERN_MAP": { + "1.1.1.1/24": "1.1.1.0/24", + "1.1.1.3/24": "1.1.1.0/24" + }, + "COUNTERS:oid:0x1600000000034e":{ + "SAI_COUNTER_STAT_PACKETS": 100, + "SAI_COUNTER_STAT_BYTES": 2000 + }, + "COUNTERS:oid:0x1600000000034d":{ + "SAI_COUNTER_STAT_PACKETS": 200, + "SAI_COUNTER_STAT_BYTES": 4000 } } diff --git a/tests/mock_tables/asic1/counters_db.json b/tests/mock_tables/asic1/counters_db.json index 720b0f099f..37ed971ee2 100644 --- a/tests/mock_tables/asic1/counters_db.json +++ b/tests/mock_tables/asic1/counters_db.json @@ -1010,5 +1010,15 @@ }, "RATES:oid:0x1500000000034e":{ "RX_PPS": 45.25 + }, + "COUNTERS_ROUTE_NAME_MAP":{ + "1.1.1.2/24": "oid:0x1600000000034f" + }, + "COUNTERS_ROUTE_TO_PATTERN_MAP": { + "1.1.1.2/24": "1.1.1.0/24" + }, + "COUNTERS:oid:0x1600000000034f":{ + "SAI_COUNTER_STAT_PACKETS": 1000, + "SAI_COUNTER_STAT_BYTES": 2000 } } diff --git a/tests/mock_tables/config_db.json b/tests/mock_tables/config_db.json index 5c26ad4f73..52e7684fc9 100644 --- a/tests/mock_tables/config_db.json +++ b/tests/mock_tables/config_db.json @@ -1585,6 +1585,10 @@ "POLL_INTERVAL": "10000", "FLEX_COUNTER_STATUS": "enable" }, + "FLEX_COUNTER_TABLE|FLOW_CNT_ROUTE": { + "POLL_INTERVAL": "10000", + "FLEX_COUNTER_STATUS": "enable" + }, "PFC_WD|Ethernet0": { "action": "drop", "detection_time": "600", diff --git a/tests/mock_tables/counters_db.json b/tests/mock_tables/counters_db.json index 35059b78a0..eba945080b 100644 --- a/tests/mock_tables/counters_db.json +++ b/tests/mock_tables/counters_db.json @@ -2040,5 +2040,33 @@ }, "RATES:oid:0x1500000000034e":{ "RX_PPS": 50.25 + }, + "COUNTERS_ROUTE_NAME_MAP":{ + "1.1.1.1/24": "oid:0x1600000000034e", + "1.1.1.2/24": "oid:0x1600000000034f", + "2001::1/64": "oid:0x1600000000035e", + "Vrf_1|2001::1/64": "oid:0x1600000000035f" + }, + "COUNTERS_ROUTE_TO_PATTERN_MAP": { + "1.1.1.1/24": "1.1.1.0/24", + "1.1.1.2/24": "1.1.1.0/24", + "2001::1/64": "2001::/64", + "Vrf_1|2001::1/64": "Vrf_1|2001::/64" + }, + "COUNTERS:oid:0x1600000000034e":{ + "SAI_COUNTER_STAT_PACKETS": 100, + "SAI_COUNTER_STAT_BYTES": 2000 + }, + "COUNTERS:oid:0x1600000000034f":{ + "SAI_COUNTER_STAT_PACKETS": 1000, + "SAI_COUNTER_STAT_BYTES": 2000 + }, + "COUNTERS:oid:0x1600000000035e":{ + "SAI_COUNTER_STAT_PACKETS": 50, + "SAI_COUNTER_STAT_BYTES": 1000 + }, + "COUNTERS:oid:0x1600000000035f":{ + "SAI_COUNTER_STAT_PACKETS": 1000, + "SAI_COUNTER_STAT_BYTES": 25000 } } diff --git a/tests/mock_tables/state_db.json b/tests/mock_tables/state_db.json index ced65dfc6d..4609df331a 100644 --- a/tests/mock_tables/state_db.json +++ b/tests/mock_tables/state_db.json @@ -748,5 +748,8 @@ "linkmgrd_switch_standby_end": "2021-May-13 10:01:15.696728", "xcvrd_switch_standby_end": "2021-May-13 10:01:15.696051", "xcvrd_switch_standby_start": "2021-May-13 10:01:15.690835" + }, + "FLOW_COUNTER_CAPABILITY_TABLE|route": { + "support": "true" } } diff --git a/utilities_common/cli.py b/utilities_common/cli.py index 4c0f2268b1..a66c0b7586 100644 --- a/utilities_common/cli.py +++ b/utilities_common/cli.py @@ -579,11 +579,11 @@ def json_dump(data): data, sort_keys=True, indent=2, ensure_ascii=False, default=json_serial ) - + def interface_is_untagged_member(db, interface_name): - """ Check if interface is already untagged member""" + """ Check if interface is already untagged member""" vlan_member_table = db.get_table('VLAN_MEMBER') - + for key,val in vlan_member_table.items(): if(key[1] == interface_name): if (val['tagging_mode'] == 'untagged'): @@ -630,3 +630,36 @@ def handle_parse_result(self, ctx, opts, args): "Illegal usage: %s is mutually exclusive with arguments %s" % (self.name, ', '.join(self.mutually_exclusive)) ) return super(MutuallyExclusiveOption, self).handle_parse_result(ctx, opts, args) + + +def query_yes_no(question, default="yes"): + """Ask a yes/no question via input() and return their answer. + + "question" is a string that is presented to the user. + "default" is the presumed answer if the user just hits . + It must be "yes" (the default), "no" or None (meaning + an answer is required of the user). + + The "answer" return value is True for "yes" or False for "no". + """ + valid = {"yes": True, "y": True, "ye": True, + "no": False, "n": False} + if default is None: + prompt = " [y/n] " + elif default == "yes": + prompt = " [Y/n] " + elif default == "no": + prompt = " [y/N] " + else: + raise ValueError("invalid default answer: '%s'" % default) + + while True: + sys.stdout.write(question + prompt) + choice = input().lower() + if default is not None and choice == '': + return valid[default] + elif choice in valid: + return valid[choice] + else: + sys.stdout.write("Please respond with 'yes' or 'no' " + "(or 'y' or 'n').\n")