def init_sync_d_vlan_tables(db_conn): """ Initializes vlan interface maps for SyncD-connected MIB(s). :return: tuple(vlan_name_map, oid_sai_map, oid_name_map) """ vlan_name_map = port_util.get_vlan_interface_oid_map(db_conn) logger.debug("Vlan oid map:\n" + pprint.pformat(vlan_name_map, indent=2)) # { OID -> sai_id } oid_sai_map = { get_index_from_str(if_name): sai_id for sai_id, if_name in vlan_name_map.items() # only map the interface if it's a style understood to be a SONiC interface. if get_index_from_str(if_name) is not None } logger.debug("OID sai map:\n" + pprint.pformat(oid_sai_map, indent=2)) # { OID -> if_name (SONiC) } oid_name_map = { get_index_from_str(if_name): if_name for sai_id, if_name in vlan_name_map.items() # only map the interface if it's a style understood to be a SONiC interface. if get_index_from_str(if_name) is not None } logger.debug("OID name map:\n" + pprint.pformat(oid_name_map, indent=2)) return vlan_name_map, oid_sai_map, oid_name_map
def _update_entity_cache(self, interface): """ Update data for single transceiver :param: interface: Interface name associated with transceiver """ # get interface from interface name ifindex = port_util.get_index_from_str(interface) if ifindex is None: # interface name invalid, skip this entry mibs.logger.warning("Invalid interface name in {} \ in STATE_DB, skipping".format(interface)) return # get transceiver information from transceiver info entry in STATE DB transceiver_info = Namespace.dbs_get_all( self.mib_updater.statedb, mibs.STATE_DB, mibs.transceiver_info_table(interface)) if not transceiver_info: return # update xcvr info from DB # use port's name as key for transceiver info entries sub_id = get_transceiver_sub_id(ifindex) # add interface to available OID list self.mib_updater.add_sub_id(sub_id) self._add_entity_related_oid(interface, sub_id) # physical class - network port self.mib_updater.set_phy_class(sub_id, PhysicalClass.PORT) # save values into cache sfp_type, hw_version, serial_number, mfg_name, model_name, replaceable = get_db_data( transceiver_info, XcvrInfoDB) self.mib_updater.set_phy_hw_ver(sub_id, hw_version) self.mib_updater.set_phy_serial_num(sub_id, serial_number) self.mib_updater.set_phy_mfg_name(sub_id, mfg_name) self.mib_updater.set_phy_model_name(sub_id, model_name) self.mib_updater.set_phy_contained_in(sub_id, CHASSIS_SUB_ID) self.mib_updater.set_phy_fru(sub_id, replaceable) # Relative position of SFP can be changed at run time. For example, plug out a normal cable SFP3 and plug in # a 1 split 4 SFP, the relative position of SFPs after SPF3 will change. In this case, it is hard to determine # the relative position for other SFP. According to RFC 2737, 'If the agent cannot determine the parent-relative position # for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned'. # See https://tools.ietf.org/html/rfc2737. self.mib_updater.set_phy_parent_relative_pos(sub_id, -1) ifalias = self.if_alias_map.get(interface, "") # generate a description for this transceiver self.mib_updater.set_phy_descr( sub_id, get_transceiver_description(sfp_type, ifalias)) self.mib_updater.set_phy_name(sub_id, interface) # update transceiver sensor cache self._update_transceiver_sensor_cache(interface, sub_id)
def _update_transceiver_sensor_cache(self, interface): """ Update sensor data for single transceiver :param: interface: Interface name associated with transceiver """ ifalias = self.if_alias_map.get(interface.encode(), b"").decode() ifindex = port_util.get_index_from_str(interface) # get transceiver sensors from transceiver dom entry in STATE DB transceiver_dom_entry = Namespace.dbs_get_all(self.statedb, mibs.STATE_DB, mibs.transceiver_dom_table(interface)) if not transceiver_dom_entry: return # go over transceiver sensors for sensor in map(bytes.decode, transceiver_dom_entry): if sensor not in SENSOR_NAME_MAP: continue sensor_sub_id = mibs.get_transceiver_sensor_sub_id(ifindex, sensor) sensor_description = get_transceiver_sensor_description(sensor, ifalias) self.physical_classes_map[sensor_sub_id] = PhysicalClass.SENSOR self.physical_description_map[sensor_sub_id] = sensor_description # add to available OIDs list insort_right(self.physical_entities, sensor_sub_id)
def poll_lldp_entry_updates(pubsub): ret = None, None, None msg = pubsub.get_message() if not msg: return ret try: interface = msg["channel"].split(b":")[-1].decode() data = msg['data'] except (KeyError, AttributeError) as e: logger.error("Invalid msg when polling for lldp updates: {}\n" "The error seems to be: {}".format(msg, e)) return ret if interface == 'eth0': return ret # get interface from interface name if_index = port_util.get_index_from_str(interface) if if_index is None: # interface name invalid, skip this entry logger.warning( "Invalid interface name in {} in APP_DB, skipping".format( interface)) return ret return data, interface, if_index
def init_sync_d_vlan_tables(db_conn): """ Initializes vlan interface maps for SyncD-connected MIB(s). :return: tuple(vlan_name_map, oid_sai_map, oid_name_map) """ vlan_name_map = port_util.get_vlan_interface_oid_map(db_conn) logger.debug("Vlan oid map:\n" + pprint.pformat(vlan_name_map, indent=2)) oid_sai_map = {} oid_name_map = {} for sai_id, if_name in vlan_name_map.items(): port_index = get_index_from_str(if_name) if not port_index: continue # { OID -> sai_id } oid_sai_map[port_index] = sai_id # { OID -> if_name (SONiC) } oid_name_map[port_index] = if_name logger.debug("OID sai map:\n" + pprint.pformat(oid_sai_map, indent=2)) logger.debug("OID name map:\n" + pprint.pformat(oid_name_map, indent=2)) return vlan_name_map, oid_sai_map, oid_name_map
def init_sync_d_queue_tables(db_conn): """ Initializes queue maps for SyncD-connected MIB(s). :return: tuple(port_queues_map, queue_stat_map) """ # { Port name : Queue index (SONiC) -> sai_id } # ex: { "Ethernet0:2" : "1000000000023" } queue_name_map = db_conn.get_all(COUNTERS_DB, COUNTERS_QUEUE_NAME_MAP, blocking=True) logger.debug("Queue name map:\n" + pprint.pformat(queue_name_map, indent=2)) # Parse the queue_name_map and create the following maps: # port_queues_map -> {"port_index : queue_index" : sai_oid} # queue_stat_map -> {"port_index : queue stat table name" : {counter name : value}} # port_queue_list_map -> {port_index: [sorted queue list]} port_queues_map = {} queue_stat_map = {} port_queue_list_map = {} for queue_name, sai_id in queue_name_map.items(): port_name, queue_index = queue_name.split(':') queue_index = ''.join(i for i in queue_index if i.isdigit()) port_index = get_index_from_str(port_name) key = queue_key(port_index, queue_index) port_queues_map[key] = sai_id queue_stat_name = queue_table(sai_id) queue_stat = db_conn.get_all(COUNTERS_DB, queue_stat_name, blocking=False) if queue_stat is not None: queue_stat_key = queue_key(port_index, queue_stat_name) queue_stat_map[queue_stat_key] = queue_stat if not port_queue_list_map.get(int(port_index)): port_queue_list_map[int(port_index)] = [int(queue_index)] else: port_queue_list_map[int(port_index)].append(int(queue_index)) # SyncD consistency checks. if not port_queues_map: # In the event no queue exists that follows the SONiC pattern, no OIDs are able to be registered. # A RuntimeError here will prevent the 'main' module from loading. (This is desirable.) logger.error( "No queues found in the Counter DB. SyncD database is incoherent.") raise RuntimeError('The port_queues_map is not defined') elif not queue_stat_map: logger.error( "No queue stat counters found in the Counter DB. SyncD database is incoherent." ) raise RuntimeError('The queue_stat_map is not defined') for queues in port_queue_list_map.values(): queues.sort() return port_queues_map, queue_stat_map, port_queue_list_map
def update_data(self): """ Update sensors cache. """ self.sub_ids = [] if not self.transceiver_dom: return # update transceiver sensors cache for transceiver_dom_entry in self.transceiver_dom: # extract interface name interface = transceiver_dom_entry.split( mibs.TABLE_NAME_SEPARATOR_VBAR)[-1] ifindex = port_util.get_index_from_str(interface) if ifindex is None: mibs.logger.warning("Invalid interface name in {} \ in STATE_DB, skipping".format(transceiver_dom_entry)) continue # get transceiver sensors from transceiver dom entry in STATE DB transceiver_dom_entry_data = self.statedb.get_all( self.statedb.STATE_DB, transceiver_dom_entry) if not transceiver_dom_entry_data: continue for sensor_key in map(bytes.decode, transceiver_dom_entry_data): if sensor_key not in TRANSCEIVER_SENSOR_MAP: continue raw_sensor_value = transceiver_dom_entry_data.get( sensor_key.encode()).decode() sensor = get_transceiver_sensor(sensor_key) sub_id = mibs.get_transceiver_sensor_sub_id( ifindex, sensor_key) try: mib_values = sensor.mib_values(raw_sensor_value) except (ValueError, ArithmeticError): mibs.logger.error( "Exception occured when converting" "value for sensor {} interface {}".format( sensor, interface)) # skip continue else: self.ent_phy_sensor_type_map[sub_id], \ self.ent_phy_sensor_scale_map[sub_id], \ self.ent_phy_sensor_precision_map[sub_id], \ self.ent_phy_sensor_value_map[sub_id], \ self.ent_phy_sensor_oper_state_map[sub_id] = mib_values self.sub_ids.append(sub_id) self.sub_ids.sort()
def update_data(self): """ Update sensors cache. """ self.sub_ids = [] if not self.transceiver_dom: return # update transceiver sensors cache for transceiver_dom_entry in self.transceiver_dom: # extract interface name interface = transceiver_dom_entry.split( mibs.TABLE_NAME_SEPARATOR_VBAR)[-1] ifindex = port_util.get_index_from_str(interface) if ifindex is None: mibs.logger.warning("Invalid interface name in {} \ in STATE_DB, skipping".format(transceiver_dom_entry)) continue # get transceiver sensors from transceiver dom entry in STATE DB transceiver_dom_entry_data = Namespace.dbs_get_all( self.statedb, mibs.STATE_DB, transceiver_dom_entry) if not transceiver_dom_entry_data: continue sensor_data_list = TransceiverSensorData.create_sensor_data( transceiver_dom_entry_data) for sensor_data in sensor_data_list: raw_sensor_value = sensor_data.get_raw_value() sensor = sensor_data.get_sensor_interface() sub_id = get_transceiver_sensor_sub_id( ifindex, sensor_data.get_oid_offset()) try: mib_values = sensor.mib_values(raw_sensor_value) except (ValueError, ArithmeticError): mibs.logger.error( "Exception occured when converting" "value for sensor {} interface {}".format( sensor, interface)) # skip continue else: self.ent_phy_sensor_type_map[sub_id], \ self.ent_phy_sensor_scale_map[sub_id], \ self.ent_phy_sensor_precision_map[sub_id], \ self.ent_phy_sensor_value_map[sub_id], \ self.ent_phy_sensor_oper_state_map[sub_id] = mib_values self.sub_ids.append(sub_id) self.sub_ids.sort()
def update_data(self): """ Update redis (caches config) Pulls the table references for each interface. """ for sai_id_key in self.if_id_map: namespace, sai_id = mibs.split_sai_id_key(sai_id_key) if_idx = get_index_from_str(self.if_id_map[sai_id_key].decode()) self.if_counters[if_idx] = self.namespace_db_map[namespace].get_all(mibs.COUNTERS_DB, \ mibs.counter_table(sai_id), blocking=True)
def update_data(self): """ Update sensors cache. """ self.sub_ids = [] if not self.transceiver_dom: return # update transceiver sensors cache for transceiver_dom_entry in self.transceiver_dom: # extract interface name interface = transceiver_dom_entry.split(mibs.TABLE_NAME_SEPARATOR_VBAR)[-1] ifindex = port_util.get_index_from_str(interface) if ifindex is None: mibs.logger.warning( "Invalid interface name in {} \ in STATE_DB, skipping".format(transceiver_dom_entry)) continue # get transceiver sensors from transceiver dom entry in STATE DB transceiver_dom_entry_data = self.statedb.get_all(self.statedb.STATE_DB, transceiver_dom_entry) if not transceiver_dom_entry_data: continue for sensor_key in map(bytes.decode, transceiver_dom_entry_data): if sensor_key not in TRANSCEIVER_SENSOR_MAP: continue raw_sensor_value = transceiver_dom_entry_data.get(sensor_key.encode()).decode() sensor = get_transceiver_sensor(sensor_key) sub_id = mibs.get_transceiver_sensor_sub_id(ifindex, sensor_key) try: mib_values = sensor.mib_values(raw_sensor_value) except (ValueError, ArithmeticError): mibs.logger.error("Exception occured when converting" "value for sensor {} interface {}".format(sensor, interface)) # skip continue else: self.ent_phy_sensor_type_map[sub_id], \ self.ent_phy_sensor_scale_map[sub_id], \ self.ent_phy_sensor_precision_map[sub_id], \ self.ent_phy_sensor_value_map[sub_id], \ self.ent_phy_sensor_oper_state_map[sub_id] = mib_values self.sub_ids.append(sub_id) self.sub_ids.sort()
def init_sync_d_lag_tables(db_conn): """ Helper method. Connects to and initializes LAG interface maps for SyncD-connected MIB(s). :param db_conn: database connector :return: tuple(lag_name_if_name_map, if_name_lag_name_map, oid_lag_name_map) """ # { lag_name (SONiC) -> [ lag_members (if_name) ] } # ex: { "PortChannel0" : [ "Ethernet0", "Ethernet4" ] } lag_name_if_name_map = {} # { if_name (SONiC) -> lag_name } # ex: { "Ethernet0" : "PortChannel0" } if_name_lag_name_map = {} # { OID -> lag_name (SONiC) } oid_lag_name_map = {} # { lag_name (SONiC) -> lag_oid (SAI) } lag_sai_map = {} # { lag_oid (SAI) -> lag_name (SONiC) } sai_lag_map = {} db_conn.connect(APPL_DB) lag_entries = db_conn.keys(APPL_DB, "LAG_TABLE:*") if not lag_entries: return lag_name_if_name_map, if_name_lag_name_map, oid_lag_name_map, lag_sai_map db_conn.connect(COUNTERS_DB) lag_sai_map = db_conn.get_all(COUNTERS_DB, "COUNTERS_LAG_NAME_MAP") for name, sai_id in lag_sai_map.items(): sai_id_key = get_sai_id_key(db_conn.namespace, sai_id.lstrip("oid:0x")) lag_sai_map[name] = sai_id_key sai_lag_map[sai_id_key] = name for lag_entry in lag_entries: lag_name = lag_entry[len("LAG_TABLE:"):] lag_members = db_conn.keys(APPL_DB, "LAG_MEMBER_TABLE:%s:*" % lag_name) # TODO: db_conn.keys() should really return [] instead of None if lag_members is None: lag_members = [] def member_name_str(val, lag_name): return val[len("LAG_MEMBER_TABLE:%s:" % lag_name):] lag_member_names = [member_name_str(m, lag_name) for m in lag_members] lag_name_if_name_map[lag_name] = lag_member_names for lag_member_name in lag_member_names: if_name_lag_name_map[lag_member_name] = lag_name for if_name in lag_name_if_name_map.keys(): idx = get_index_from_str(if_name) if idx: oid_lag_name_map[idx] = if_name return lag_name_if_name_map, if_name_lag_name_map, oid_lag_name_map, sai_lag_map
def init_sync_d_queue_tables(db_conn): """ Initializes queue maps for SyncD-connected MIB(s). :return: tuple(port_queues_map, queue_stat_map) """ # Make sure we're connected to COUNTERS_DB db_conn.connect(COUNTERS_DB) # { Port index : Queue index (SONiC) -> sai_id } # ex: { "1:2" : "1000000000023" } queue_name_map = db_conn.get_all(COUNTERS_DB, COUNTERS_QUEUE_NAME_MAP, blocking=True) logger.debug("Queue name map:\n" + pprint.pformat(queue_name_map, indent=2)) # Parse the queue_name_map and create the following maps: # port_queues_map -> {"if_index : queue_index" : sai_oid} # queue_stat_map -> {queue stat table name : {counter name : value}} # port_queue_list_map -> {if_index: [sorted queue list]} port_queues_map = {} queue_stat_map = {} port_queue_list_map = {} for queue_name, sai_id in queue_name_map.items(): port_name, queue_index = queue_name.decode().split(':') queue_index = ''.join(i for i in queue_index if i.isdigit()) port_index = get_index_from_str(port_name) key = queue_key(port_index, queue_index) port_queues_map[key] = sai_id queue_stat_name = queue_table(sai_id) queue_stat = db_conn.get_all(COUNTERS_DB, queue_stat_name, blocking=False) if queue_stat is not None: queue_stat_map[queue_stat_name] = queue_stat if not port_queue_list_map.get(int(port_index)): port_queue_list_map[int(port_index)] = [int(queue_index)] else: port_queue_list_map[int(port_index)].append(int(queue_index)) # SyncD consistency checks. if not port_queues_map: # In the event no queue exists that follows the SONiC pattern, no OIDs are able to be registered. # A RuntimeError here will prevent the 'main' module from loading. (This is desirable.) logger.error("No queues found in the Counter DB. SyncD database is incoherent.") raise RuntimeError('The port_queues_map is not defined') elif not queue_stat_map: logger.error("No queue stat counters found in the Counter DB. SyncD database is incoherent.") raise RuntimeError('The queue_stat_map is not defined') for queues in port_queue_list_map.values(): queues.sort() return port_queues_map, queue_stat_map, port_queue_list_map
def update_data(self): """ Update cache. Here we listen to changes in STATE_DB TRANSCEIVER_INFO table and update data only when there is a change (SET, DELETE) """ # This code is not executed in unit test, since mockredis # does not support pubsub if not self.pubsub: redis_client = self.statedb.get_redis_client(self.statedb.STATE_DB) db = self.statedb.get_dbid(self.statedb.STATE_DB) self.pubsub = redis_client.pubsub() self.pubsub.psubscribe("__keyspace@{}__:{}".format( db, self.TRANSCEIVER_KEY_PATTERN)) while True: msg = self.pubsub.get_message() if not msg: break transceiver_entry = msg["channel"].split(b":")[-1].decode() data = msg['data'] # event data # extract interface name interface = transceiver_entry.split( mibs.TABLE_NAME_SEPARATOR_VBAR)[-1] # get interface from interface name ifindex = port_util.get_index_from_str(interface) if ifindex is None: # interface name invalid, skip this entry mibs.logger.warning("Invalid interface name in {} \ in STATE_DB, skipping".format(transceiver_entry)) continue if b"set" in data: self._update_transceiver_cache(interface) elif b"del" in data: # remove deleted transceiver remove_sub_ids = [mibs.get_transceiver_sub_id(ifindex)] # remove all sensor OIDs associated with removed transceiver for sensor in SENSOR_NAME_MAP: remove_sub_ids.append( mibs.get_transceiver_sensor_sub_id(ifindex, sensor)) for sub_id in remove_sub_ids: if sub_id and sub_id in self.physical_entities: self.physical_entities.remove(sub_id)
def _update_transceiver_cache(self, interface): """ Update data for single transceiver :param: interface: Interface name associated with transceiver """ # get interface from interface name ifindex = port_util.get_index_from_str(interface) # update xcvr info from DB # use port's name as key for transceiver info entries sub_id = mibs.get_transceiver_sub_id(ifindex) # add interface to available OID list insort_right(self.physical_entities, sub_id) # get transceiver information from transceiver info entry in STATE DB transceiver_info = Namespace.dbs_get_all( self.statedb, mibs.STATE_DB, mibs.transceiver_info_table(interface)) if not transceiver_info: return # physical class - network port self.physical_classes_map[sub_id] = PhysicalClass.PORT # save values into cache sfp_type, \ self.physical_hw_version_map[sub_id],\ self.physical_serial_number_map[sub_id], \ self.physical_mfg_name_map[sub_id], \ self.physical_model_name_map[sub_id] = get_transceiver_data(transceiver_info) ifalias = self.if_alias_map.get(interface.encode(), b"").decode() # generate a description for this transceiver self.physical_description_map[sub_id] = get_transceiver_description( sfp_type, ifalias) # update transceiver sensor cache self._update_transceiver_sensor_cache(interface)
def update_db(self, ifname, op): index = port_util.get_index_from_str(ifname) if op == 'SET' and index is None: return ifindex = if_nametoindex(ifname) if op == 'SET' and ifindex is None: return # Check if ifname already exist or if index/ifindex changed due to # syncd restart if (ifname in self.cur_interfaces and self.cur_interfaces[ifname] == (index, ifindex)): return _hash = '{}|{}'.format('PORT_INDEX_TABLE', ifname) if op == 'SET': self.cur_interfaces[ifname] = (index, ifindex) self.set_port_index_table_entry(_hash, str(index), str(ifindex)) elif op == 'DEL': del self.cur_interfaces[ifname] self.state_db.delete(self.state_db.STATE_DB, _hash)
def init_mgmt_interface_tables(db_conn): """ Initializes interface maps for mgmt ports :param db_conn: db connector :return: tuple of mgmt name to oid map and mgmt name to alias map """ db_conn.connect(CONFIG_DB) db_conn.connect(STATE_DB) mgmt_ports_keys = db_conn.keys(CONFIG_DB, mgmt_if_entry_table('*')) if not mgmt_ports_keys: logger.debug('No managment ports found in {}'.format( mgmt_if_entry_table(''))) return {}, {} mgmt_ports = [ key.split(mgmt_if_entry_table(''))[-1] for key in mgmt_ports_keys ] oid_name_map = { get_index_from_str(mgmt_name): mgmt_name for mgmt_name in mgmt_ports } logger.debug('Managment port map:\n' + pprint.pformat(oid_name_map, indent=2)) if_alias_map = dict() for if_name in oid_name_map.values(): if_entry = db_conn.get_all(CONFIG_DB, mgmt_if_entry_table(if_name), blocking=True) if_alias_map[if_name] = if_entry.get('alias', if_name) logger.debug("Management alias map:\n" + pprint.pformat(if_alias_map, indent=2)) return oid_name_map, if_alias_map
def poll_lldp_entry_updates(pubsub): ret = None, None, None msg = pubsub.get_message() if not msg: return ret try: interface = msg["channel"].split(b":")[-1].decode() data = msg['data'] except (KeyError, AttributeError) as e: logger.error("Invalid msg when polling for lldp updates: {}\n" "The error seems to be: {}".format(msg, e)) return ret # get interface from interface name if_index = port_util.get_index_from_str(interface) if if_index is None: # interface name invalid, skip this entry logger.warning("Invalid interface name in {} in APP_DB, skipping" .format(interface)) return ret return data, interface, if_index
def _update_transceiver_sensor_cache(self, interface, sub_id): """ Update sensor data for single transceiver :param: interface: Interface name associated with transceiver :param: sub_id: OID of transceiver """ ifalias = self.if_alias_map.get(interface, "") ifindex = port_util.get_index_from_str(interface) # get transceiver sensors from transceiver dom entry in STATE DB transceiver_dom_entry = Namespace.dbs_get_all( self.mib_updater.statedb, mibs.STATE_DB, mibs.transceiver_dom_table(interface)) if not transceiver_dom_entry: return sensor_data_list = TransceiverSensorData.create_sensor_data( transceiver_dom_entry) sensor_data_list = TransceiverSensorData.sort_sensor_data( sensor_data_list) for index, sensor_data in enumerate(sensor_data_list): sensor_sub_id = get_transceiver_sensor_sub_id( ifindex, sensor_data.get_oid_offset()) self._add_entity_related_oid(interface, sensor_sub_id) self.mib_updater.set_phy_class(sensor_sub_id, PhysicalClass.SENSOR) sensor_description = get_transceiver_sensor_description( sensor_data.get_name(), sensor_data.get_lane_number(), ifalias) self.mib_updater.set_phy_descr(sensor_sub_id, sensor_description) self.mib_updater.set_phy_name(sensor_sub_id, sensor_description) self.mib_updater.set_phy_contained_in(sensor_sub_id, sub_id) self.mib_updater.set_phy_parent_relative_pos( sensor_sub_id, index + 1) self.mib_updater.set_phy_fru(sensor_sub_id, False) # add to available OIDs list self.mib_updater.add_sub_id(sensor_sub_id)
def _update_transceiver_sensor_cache(self, interface, sub_id): """ Update sensor data for single transceiver :param: interface: Interface name associated with transceiver :param: sub_id: OID of transceiver """ ifalias = self.if_alias_map.get(interface, "") ifindex = port_util.get_index_from_str(interface) # get transceiver sensors from transceiver dom entry in STATE DB transceiver_dom_entry = Namespace.dbs_get_all( self.mib_updater.statedb, mibs.STATE_DB, mibs.transceiver_dom_table(interface)) if not transceiver_dom_entry: return # go over transceiver sensors for sensor in transceiver_dom_entry: if sensor not in XCVR_SENSOR_NAME_MAP: continue sensor_sub_id = get_transceiver_sensor_sub_id(ifindex, sensor) self._add_entity_related_oid(interface, sensor_sub_id) sensor_description = get_transceiver_sensor_description( sensor, ifalias) self.mib_updater.set_phy_class(sensor_sub_id, PhysicalClass.SENSOR) self.mib_updater.set_phy_descr(sensor_sub_id, sensor_description) self.mib_updater.set_phy_name(sensor_sub_id, sensor_description) self.mib_updater.set_phy_contained_in(sensor_sub_id, sub_id) self.mib_updater.set_phy_parent_relative_pos( sensor_sub_id, XCVR_SENSOR_INDEX_MAP[sensor]) self.mib_updater.set_phy_fru(sensor_sub_id, False) # add to available OIDs list self.mib_updater.add_sub_id(sensor_sub_id)
def init_sync_d_interface_tables(db_conn): """ Initializes interface maps for SyncD-connected MIB(s). :return: tuple(if_name_map, if_id_map, oid_map, if_alias_map) """ if_id_map = {} if_name_map = {} # { if_name (SONiC) -> sai_id } # ex: { "Ethernet76" : "1000000000023" } if_name_map_util, if_id_map_util = port_util.get_interface_oid_map(db_conn) for if_name, sai_id in if_name_map_util.items(): if_name_str = if_name if (re.match(port_util.SONIC_ETHERNET_RE_PATTERN, if_name_str) or \ re.match(port_util.SONIC_ETHERNET_BP_RE_PATTERN, if_name_str)): if_name_map[if_name] = sai_id # As sai_id is not unique in multi-asic platform, concatenate it with # namespace to get a unique key. Assuming that ':' is not present in namespace # string or in sai id. # sai_id_key = namespace : sai_id for sai_id, if_name in if_id_map_util.items(): if (re.match(port_util.SONIC_ETHERNET_RE_PATTERN, if_name) or \ re.match(port_util.SONIC_ETHERNET_BP_RE_PATTERN, if_name)): if_id_map[get_sai_id_key(db_conn.namespace, sai_id)] = if_name logger.debug("Port name map:\n" + pprint.pformat(if_name_map, indent=2)) logger.debug("Interface name map:\n" + pprint.pformat(if_id_map, indent=2)) # { OID -> if_name (SONiC) } oid_name_map = { get_index_from_str(if_name): if_name for if_name in if_name_map # only map the interface if it's a style understood to be a SONiC interface. if get_index_from_str(if_name) is not None } logger.debug("OID name map:\n" + pprint.pformat(oid_name_map, indent=2)) # SyncD consistency checks. if not oid_name_map: # In the event no interface exists that follows the SONiC pattern, no OIDs are able to be registered. # A RuntimeError here will prevent the 'main' module from loading. (This is desirable.) message = "No interfaces found matching pattern '{}'. SyncD database is incoherent." \ .format(port_util.SONIC_ETHERNET_RE_PATTERN) logger.error(message) raise RuntimeError(message) elif len(if_id_map) < len(if_name_map) or len(oid_name_map) < len( if_name_map): # a length mismatch indicates a bad interface name logger.warning( "SyncD database contains incoherent interface names. Interfaces must match pattern '{}'" .format(port_util.SONIC_ETHERNET_RE_PATTERN)) logger.warning("Port name map:\n" + pprint.pformat(if_name_map, indent=2)) if_alias_map = dict() for if_name in if_name_map: if_entry = db_conn.get_all(APPL_DB, if_entry_table(if_name), blocking=True) if_alias_map[if_name] = if_entry.get('alias', if_name) logger.debug("Chassis name map:\n" + pprint.pformat(if_alias_map, indent=2)) return if_name_map, if_alias_map, if_id_map, oid_name_map