def show_acl_resources(self): """ CRM Handler to display ACL recources information. """ if multi_asic.is_multi_asic(): header = (self.multi_asic.current_namespace.upper() + "\n\nStage", "\n\nBind Point", "\n\nResource Name", "\n\nUsed Count", "\n\nAvailable Count") else: header = ("Stage", "Bind Point", "Resource Name", "Used Count", "Available Count") data = [] data = self.get_acl_resources() click.echo() click.echo( tabulate(data, headers=header, tablefmt="simple", missingval="")) click.echo()
def show_resources(self, resource): """ CRM Handler to display resources information. """ if multi_asic.is_multi_asic(): header = (self.multi_asic.current_namespace.upper() + "\n\nResource Name", "\n\nUsed Count", "\n\nAvailable Count") err_msg = '\nCRM counters are not ready for '+ self.multi_asic.current_namespace.upper() + '. They would be populated after the polling interval.' else: header = ("Resource Name", "Used Count", "Available Count") err_msg = '\nCRM counters are not ready. They would be populated after the polling interval.' data = [] data = self.get_resources(resource) if data: click.echo() click.echo(tabulate(data, headers=header, tablefmt="simple", missingval="")) click.echo() else: click.echo(err_msg)
def platform_sfputil_read_porttab_mappings(): try: if multi_asic.is_multi_asic(): # For multi ASIC platforms we pass DIR of port_config_file_path and the number of asics (platform_path, hwsku_path) = device_info.get_paths_to_platform_and_hwsku_dirs() # Load platform module from source platform_sfputil.read_all_porttab_mappings( hwsku_path, multi_asic.get_num_asics()) else: # For single ASIC platforms we pass port_config_file_path and the asic_inst as 0 port_config_file_path = device_info.get_path_to_port_config_file() platform_sfputil.read_porttab_mappings(port_config_file_path, 0) except Exception as e: click.echo("Error reading port info (%s)" % str(e)) sys.exit(1) return 0
def load_db_config(): ''' Load the correct database config file: - database_global.json for multi asic - database_config.json for single asic Loading database config file is not required for 201911 images so ignore import error or function name error. ''' try: from sonic_py_common import multi_asic from swsscommon import swsscommon if multi_asic.is_multi_asic(): if not swsscommon.SonicDBConfig.isGlobalInit(): swsscommon.SonicDBConfig.load_sonic_global_db_config() else: if not swsscommon.SonicDBConfig.isInit(): swsscommon.SonicDBConfig.load_sonic_db_config() except ImportError: pass except NameError: pass except AttributeError: pass
def init(self): global platform_sfputil global platform_chassis self.log_info("Start daemon init...") config_db, metadata_tbl, metadata_dict = {}, {}, {} is_vs = False namespaces = multi_asic.get_front_end_namespaces() for namespace in namespaces: asic_id = multi_asic.get_asic_index_from_namespace(namespace) config_db[asic_id] = daemon_base.db_connect("CONFIG_DB", namespace) metadata_tbl[asic_id] = swsscommon.Table(config_db[asic_id], "DEVICE_METADATA") (status, fvs) = metadata_tbl[0].get("localhost") if status is False: helper_logger.log_debug( "Could not retreive fieldvalue pairs for {}, inside config_db table {}" .format('localhost', metadata_tbl[0].getTableName())) return else: # Convert list of tuples to a dictionary metadata_dict = dict(fvs) if "platform" in metadata_dict: val = metadata_dict.get("platform", None) if val == "x86_64-kvm_x86_64-r0": is_vs = True # Load new platform api class try: if is_vs is False: import sonic_platform.platform platform_chassis = sonic_platform.platform.Platform( ).get_chassis() self.log_info("chassis loaded {}".format(platform_chassis)) # we have to make use of sfputil for some features # even though when new platform api is used for all vendors. # in this sense, we treat it as a part of new platform api. # we have already moved sfputil to sonic_platform_base # which is the root of new platform api. import sonic_platform_base.sonic_sfp.sfputilhelper platform_sfputil = sonic_platform_base.sonic_sfp.sfputilhelper.SfpUtilHelper( ) except Exception as e: self.log_warning("Failed to load chassis due to {}".format( repr(e))) # Load platform specific sfputil class if platform_chassis is None or platform_sfputil is None: if is_vs is False: try: platform_sfputil = self.load_platform_util( PLATFORM_SPECIFIC_MODULE_NAME, PLATFORM_SPECIFIC_CLASS_NAME) except Exception as e: self.log_error("Failed to load sfputil: {}".format(str(e)), True) sys.exit(SFPUTIL_LOAD_ERROR) if multi_asic.is_multi_asic(): # Load the namespace details first from the database_global.json file. swsscommon.SonicDBConfig.initializeGlobalConfig() # Load port info try: if multi_asic.is_multi_asic(): # For multi ASIC platforms we pass DIR of port_config_file_path and the number of asics (platform_path, hwsku_path ) = device_info.get_paths_to_platform_and_hwsku_dirs() platform_sfputil.read_all_porttab_mappings( hwsku_path, self.num_asics) else: # For single ASIC platforms we pass port_config_file_path and the asic_inst as 0 port_config_file_path = device_info.get_path_to_port_config_file( ) platform_sfputil.read_porttab_mappings(port_config_file_path, 0) except Exception as e: self.log_error("Failed to read port info: {}".format(str(e)), True) sys.exit(PORT_CONFIG_LOAD_ERROR) # Connect to STATE_DB and create ycable tables state_db = {} # Get the namespaces in the platform namespaces = multi_asic.get_front_end_namespaces() for namespace in namespaces: asic_id = multi_asic.get_asic_index_from_namespace(namespace) state_db[asic_id] = daemon_base.db_connect("STATE_DB", namespace) """ # TODO need to decide if we need warm start capability in this ycabled daemon warmstart = swsscommon.WarmStart() warmstart.initialize("ycabled", "pmon") warmstart.checkWarmStart("ycabled", "pmon", False) is_warm_start = warmstart.isWarmStart() """ # Make sure this daemon started after all port configured self.log_info("Wait for port config is done") # Init port y_cable status table y_cable_helper.init_ports_status_for_y_cable(platform_sfputil, platform_chassis, self.y_cable_presence, self.stop_event, is_vs)
def multi_asic_display_default_option(): if not multi_asic.is_multi_asic(): return constants.DISPLAY_ALL else: return constants.DISPLAY_EXTERNAL
def multi_asic_display_choices(): if not multi_asic.is_multi_asic(): return [constants.DISPLAY_ALL] else: return [constants.DISPLAY_ALL, constants.DISPLAY_EXTERNAL]
def multi_asic_ns_choices(): if not multi_asic.is_multi_asic(): return [constants.DEFAULT_NAMESPACE] choices = multi_asic.get_namespace_list() return choices
def mpls(ctx, interfacename, namespace, display): """Show Interface MPLS status""" #Edge case: Force show frontend interfaces on single asic if not (multi_asic.is_multi_asic()): if (display == 'frontend' or display == 'all' or display is None): display = None else: print("Error: Invalid display option command for single asic") return display = "all" if interfacename else display masic = multi_asic_util.MultiAsic(display_option=display, namespace_option=namespace) ns_list = masic.get_ns_list_based_on_options() intfs_data = {} intf_found = False for ns in ns_list: appl_db = multi_asic.connect_to_all_dbs_for_ns(namespace=ns) if interfacename is not None: interfacename = try_convert_interfacename_from_alias( ctx, interfacename) # Fetching data from appl_db for intfs keys = appl_db.keys(appl_db.APPL_DB, "INTF_TABLE:*") for key in keys if keys else []: tokens = key.split(":") ifname = tokens[1] # Skip INTF_TABLE entries with address information if len(tokens) != 2: continue if (interfacename is not None): if (interfacename != ifname): continue intf_found = True if (display != "all"): if ("Loopback" in ifname): continue if ifname.startswith( "Ethernet") and multi_asic.is_port_internal( ifname, ns): continue if ifname.startswith( "PortChannel") and multi_asic.is_port_channel_internal( ifname, ns): continue mpls_intf = appl_db.get_all(appl_db.APPL_DB, key) if 'mpls' not in mpls_intf or mpls_intf['mpls'] == 'disable': intfs_data.update({ifname: 'disable'}) else: intfs_data.update({ifname: mpls_intf['mpls']}) # Check if interface is valid if (interfacename is not None and not intf_found): ctx.fail('interface {} doesn`t exist'.format(interfacename)) header = ['Interface', 'MPLS State'] body = [] # Output name and alias for all interfaces for intf_name in natsorted(list(intfs_data.keys())): if clicommon.get_interface_naming_mode() == "alias": alias = clicommon.InterfaceAliasConverter().name_to_alias( intf_name) body.append([alias, intfs_data[intf_name]]) else: body.append([intf_name, intfs_data[intf_name]]) click.echo(tabulate(body, header))
def show_routes(args, namespace, display, verbose, ipver): import utilities_common.bgp_util as bgp_util """Show IPv4/IPV6 routing table""" filter_back_end = False if display is None: if multi_asic.is_multi_asic(): display = constants.DISPLAY_EXTERNAL filter_back_end = True else: if multi_asic.is_multi_asic(): if display not in multi_asic_util.multi_asic_display_choices(): print("dislay option '{}' is not a valid option.".format( display)) return else: if display == constants.DISPLAY_EXTERNAL: filter_back_end = True else: if display not in ['frontend', 'all']: print("dislay option '{}' is not a valid option.".format( display)) return device = multi_asic_util.MultiAsic(display, namespace) arg_strg = "" found_json = 0 found_other_parms = 0 ns_l = [] print_ns_str = False filter_by_ip = False asic_cnt = 0 try: ns_l = device.get_ns_list_based_on_options() except ValueError: print("namespace '{}' is not valid. valid name spaces are:\n{}".format( namespace, multi_asic_util.multi_asic_ns_choices())) return asic_cnt = len(ns_l) if asic_cnt > 1 and display == constants.DISPLAY_ALL: print_ns_str = True if namespace is not None: if not multi_asic.is_multi_asic(): print( "namespace option is not applicable for non-multi-asic platform" ) return # build the filter set only if necessary if filter_back_end: back_end_intf_set = multi_asic.get_back_end_interface_set() else: back_end_intf_set = None # get all the other arguments except json that needs to be the last argument of the cmd if present # For Multi-ASIC platform the support for combining routes will be supported for "show ip/v6 route" # and optionally with specific IP address as parameter and the json option. If any other option is # specified, the handling will always be handled by the specific namespace FRR. for arg in args: arg_strg += str(arg) + " " if str(arg) == "json": found_json = 1 else: try: filter_by_ip = ipaddress.ip_network(arg) except ValueError: # Not ip address just ignore it found_other_parms = 1 if multi_asic.is_multi_asic(): if not found_json and not found_other_parms: arg_strg += "json" combined_route = {} for ns in ns_l: # Need to add "ns" to form bgpX so it is sent to the correct bgpX docker to handle the request # If not MultiASIC, skip namespace argument cmd = "show {} route {}".format(ipver, arg_strg) if multi_asic.is_multi_asic(): output = bgp_util.run_bgp_show_command(cmd, ns) else: output = bgp_util.run_bgp_show_command(cmd) print("{}".format(output)) return # in case no output or something went wrong with user specified cmd argument(s) error it out # error from FRR always start with character "%" if output == "": return if output[0] == "%": # remove the "json" keyword that was added by this handler to show original cmd user specified json_str = output[-5:-1] if json_str == "json": error_msg = output[:-5] else: error_msg = output print(error_msg) return # Multi-asic show ip route with additional parms are handled by going to FRR directly and get those outputs from each namespace if found_other_parms: print("{}:".format(ns)) print(output) continue route_info = json.loads(output) if filter_back_end or print_ns_str: # clean up the dictionary to remove all the nexthops that are back-end interface process_route_info(route_info, device, filter_back_end, print_ns_str, asic_cnt, ns, combined_route, back_end_intf_set) else: combined_route = route_info if not combined_route: return if not found_json: #print out the header if this is not a json request if not filter_by_ip: print_show_ip_route_hdr() if print_ns_str: for name_space, ns_route in sorted(combined_route.items()): print("{}:".format(name_space)) print_ip_routes(ns_route, filter_by_ip) else: print_ip_routes(combined_route, filter_by_ip) else: new_string = json.dumps(combined_route, sort_keys=True, indent=4) print(new_string)
continue data_dict = state_db.get_all(state_db.STATE_DB, key) ip = data_dict[CHASSIS_MIDPLANE_INFO_IP_FIELD] access = data_dict[CHASSIS_MIDPLANE_INFO_ACCESS_FIELD] table.append((key_list[1], ip, access)) if table: click.echo(tabulate(table, header, tablefmt='simple', stralign='right')) else: click.echo('No data available in CHASSIS_MIDPLANE_TABLE\n') @chassis.command() @click.argument('systemportname', required=False) @click.option('--namespace', '-n', 'namespace', required=True if multi_asic.is_multi_asic() else False, default=None, type=str, show_default=False, help='Namespace name or all') @click.option('--verbose', is_flag=True, help="Enable verbose output") def system_ports(systemportname, namespace, verbose): """Show VOQ system ports information""" cmd = "voqutil -c system_ports" if systemportname is not None: cmd += " -i \"{}\"".format(systemportname) if namespace is not None: cmd += " -n {}".format(namespace) clicommon.run_command(cmd, display_cmd=verbose)
parser = argparse.ArgumentParser( description='Get the interface list for an asic', formatter_class=argparse.RawTextHelpFormatter) parser.add_argument('-asicid', '--asic_index', type=str, help='the asic instance', default=None) args = parser.parse_args() if args.asic_index: asic_id = args.asic_index platform_sfputil = sonic_platform_base.sonic_sfp.sfputilhelper.SfpUtilHelper() if multi_asic.is_multi_asic(): # load and parse the port configuration file on DUT (platform_path, hwsku_path) = device_info.get_paths_to_platform_and_hwsku_dirs() # handle case where asic_id input is "all" or a valid asic index. if asic_id == "all": platform_sfputil.read_all_porttab_mappings(hwsku_path, multi_asic.get_num_asics()) else: port_config_path = os.path.join(hwsku_path, asic_id, PORT_CONFIG_FILE) platform_sfputil.read_porttab_mappings(port_config_path) else: port_config_path = device_info.get_path_to_port_config_file() platform_sfputil.read_porttab_mappings(port_config_path)
def __init__(self): self.task_thread = None if multi_asic.is_multi_asic(): # Load the namespace details first from the database_global.json file. swsscommon.SonicDBConfig.initializeGlobalConfig()
def multi_asic_display_default_option(): if not multi_asic.is_multi_asic() and not device_info.is_chassis(): return constants.DISPLAY_ALL else: return constants.DISPLAY_EXTERNAL
def multi_asic_display_choices(): if not multi_asic.is_multi_asic() and not device_info.is_chassis(): return [constants.DISPLAY_ALL] else: return [constants.DISPLAY_ALL, constants.DISPLAY_EXTERNAL]