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 _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)
class PhysicalSensorTableMIBUpdater(MIBUpdater): """ Updater for sensors. """ TRANSCEIVER_DOM_KEY_PATTERN = mibs.transceiver_dom_table("*") PSU_SENSOR_KEY_PATTERN = mibs.psu_info_table("*") FAN_SENSOR_KEY_PATTERN = mibs.fan_info_table("*") THERMAL_SENSOR_KEY_PATTERN = mibs.thermal_info_table("*") def __init__(self): """ ctor """ super().__init__() self.statedb = Namespace.init_namespace_dbs() Namespace.connect_all_dbs(self.statedb, mibs.STATE_DB) # list of available sub OIDs self.sub_ids = [] # sensor MIB required values self.ent_phy_sensor_type_map = {} self.ent_phy_sensor_scale_map = {} self.ent_phy_sensor_precision_map = {} self.ent_phy_sensor_value_map = {} self.ent_phy_sensor_oper_state_map = {} self.transceiver_dom = [] self.fan_sensor = [] self.psu_sensor = [] self.thermal_sensor = [] def reinit_data(self): """ Reinit data, clear cache """ # clear cache self.ent_phy_sensor_type_map = {} self.ent_phy_sensor_scale_map = {} self.ent_phy_sensor_precision_map = {} self.ent_phy_sensor_value_map = {} self.ent_phy_sensor_oper_state_map = {} transceiver_dom_encoded = Namespace.dbs_keys( self.statedb, mibs.STATE_DB, self.TRANSCEIVER_DOM_KEY_PATTERN) if transceiver_dom_encoded: self.transceiver_dom = [entry for entry in transceiver_dom_encoded] # for FAN, PSU and thermal sensors, they are in host namespace DB, to avoid iterating all namespace DBs, # just get data from host namespace DB, which is self.statedb[0]. fan_sensor_encoded = self.statedb[HOST_NAMESPACE_DB_IDX].keys( self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB, self.FAN_SENSOR_KEY_PATTERN) if fan_sensor_encoded: self.fan_sensor = [entry for entry in fan_sensor_encoded] psu_sensor_encoded = self.statedb[HOST_NAMESPACE_DB_IDX].keys( self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB, self.PSU_SENSOR_KEY_PATTERN) if psu_sensor_encoded: self.psu_sensor = [entry for entry in psu_sensor_encoded] thermal_sensor_encoded = self.statedb[HOST_NAMESPACE_DB_IDX].keys( self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB, self.THERMAL_SENSOR_KEY_PATTERN) if thermal_sensor_encoded: self.thermal_sensor = [entry for entry in thermal_sensor_encoded] def update_xcvr_dom_data(self): 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 occurred when converting" "value for sensor {} interface {}".format( sensor, interface)) 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) def update_psu_sensor_data(self): if not self.psu_sensor: return for psu_sensor_entry in self.psu_sensor: psu_name = psu_sensor_entry.split( mibs.TABLE_NAME_SEPARATOR_VBAR)[-1] psu_relation_info = self.statedb[HOST_NAMESPACE_DB_IDX].get_all( self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB, mibs.physical_entity_info_table(psu_name)) psu_position, psu_parent_name = get_db_data( psu_relation_info, PhysicalRelationInfoDB) if is_null_empty_str(psu_position): continue psu_position = int(psu_position) psu_sub_id = get_psu_sub_id(psu_position) psu_sensor_entry_data = self.statedb[ HOST_NAMESPACE_DB_IDX].get_all( self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB, psu_sensor_entry) if not psu_sensor_entry_data: continue sensor_data_list = PSUSensorData.create_sensor_data( psu_sensor_entry_data) for sensor_data in sensor_data_list: raw_sensor_value = sensor_data.get_raw_value() if is_null_empty_str(raw_sensor_value): continue sensor = sensor_data.get_sensor_interface() sub_id = get_psu_sensor_sub_id(psu_sub_id, sensor_data.get_name().lower()) try: mib_values = sensor.mib_values(raw_sensor_value) except (ValueError, ArithmeticError): mibs.logger.error("Exception occurred when converting" "value for sensor {} PSU {}".format( sensor, psu_name)) 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) def update_fan_sensor_data(self): if not self.fan_sensor: return fan_parent_sub_id = 0 for fan_sensor_entry in self.fan_sensor: fan_name = fan_sensor_entry.split( mibs.TABLE_NAME_SEPARATOR_VBAR)[-1] fan_relation_info = self.statedb[HOST_NAMESPACE_DB_IDX].get_all( self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB, mibs.physical_entity_info_table(fan_name)) fan_position, fan_parent_name = get_db_data( fan_relation_info, PhysicalRelationInfoDB) if is_null_empty_str(fan_position): continue fan_position = int(fan_position) if CHASSIS_NAME_SUB_STRING in fan_parent_name: fan_parent_sub_id = (CHASSIS_SUB_ID, ) else: fan_parent_relation_info = self.statedb[ HOST_NAMESPACE_DB_IDX].get_all( self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB, mibs.physical_entity_info_table(fan_parent_name)) if fan_parent_relation_info: fan_parent_position, fan_grad_parent_name = get_db_data( fan_parent_relation_info, PhysicalRelationInfoDB) fan_parent_position = int(fan_parent_position) if PSU_NAME_SUB_STRING in fan_parent_name: fan_parent_sub_id = get_psu_sub_id(fan_parent_position) else: fan_parent_sub_id = get_fan_drawer_sub_id( fan_parent_position) else: mibs.logger.error( "fan_name = {} get fan parent failed".format(fan_name)) continue fan_sub_id = get_fan_sub_id(fan_parent_sub_id, fan_position) fan_sensor_entry_data = self.statedb[ HOST_NAMESPACE_DB_IDX].get_all( self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB, fan_sensor_entry) if not fan_sensor_entry_data: mibs.logger.error( "fan_name = {} get fan_sensor_entry_data failed".format( fan_name)) continue sensor_data_list = FANSensorData.create_sensor_data( fan_sensor_entry_data) for sensor_data in sensor_data_list: raw_sensor_value = sensor_data.get_raw_value() if is_null_empty_str(raw_sensor_value): continue sensor = sensor_data.get_sensor_interface() sub_id = get_fan_tachometers_sub_id(fan_sub_id) try: mib_values = sensor.mib_values(raw_sensor_value) except (ValueError, ArithmeticError): mibs.logger.error("Exception occurred when converting" "value for sensor {} PSU {}".format( sensor, fan_name)) 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) def update_thermal_sensor_data(self): if not self.thermal_sensor: return for thermal_sensor_entry in self.thermal_sensor: thermal_name = thermal_sensor_entry.split( mibs.TABLE_NAME_SEPARATOR_VBAR)[-1] thermal_relation_info = self.statedb[ HOST_NAMESPACE_DB_IDX].get_all( self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB, mibs.physical_entity_info_table(thermal_name)) thermal_position, thermal_parent_name = get_db_data( thermal_relation_info, PhysicalRelationInfoDB) if is_null_empty_str(thermal_parent_name) or is_null_empty_str(thermal_parent_name) or \ CHASSIS_NAME_SUB_STRING not in thermal_parent_name.lower(): continue thermal_position = int(thermal_position) thermal_sensor_entry_data = self.statedb[ HOST_NAMESPACE_DB_IDX].get_all( self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB, thermal_sensor_entry) if not thermal_sensor_entry_data: continue sensor_data_list = ThermalSensorData.create_sensor_data( thermal_sensor_entry_data) for sensor_data in sensor_data_list: raw_sensor_value = sensor_data.get_raw_value() if is_null_empty_str(raw_sensor_value): continue sensor = sensor_data.get_sensor_interface() sub_id = get_chassis_thermal_sub_id(thermal_position) try: mib_values = sensor.mib_values(raw_sensor_value) except (ValueError, ArithmeticError): mibs.logger.error("Exception occurred when converting" "value for sensor {} PSU {}".format( sensor, thermal_name)) 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) def update_data(self): """ Update sensors cache. """ self.sub_ids = [] self.update_xcvr_dom_data() self.update_psu_sensor_data() self.update_fan_sensor_data() self.update_thermal_sensor_data() self.sub_ids.sort() def get_next(self, sub_id): """ :param sub_id: Input sub_id. :return: The next sub id. """ right = bisect_right(self.sub_ids, sub_id) if right == len(self.sub_ids): return None return self.sub_ids[right] def get_ent_physical_sensor_type(self, sub_id): """ Get sensor type based on sub OID :param sub_id: sub ID of the sensor :return: sensor type from EntitySensorDataType enum or None if sub_id not in the cache. """ if sub_id in self.sub_ids: return self.ent_phy_sensor_type_map.get( sub_id, EntitySensorDataType.UNKNOWN) return None def get_ent_physical_sensor_scale(self, sub_id): """ Get sensor scale value based on sub OID :param sub_id: sub ID of the sensor :return: sensor scale from EntitySensorDataScale enum or None if sub_id not in the cache. """ if sub_id in self.sub_ids: return self.ent_phy_sensor_scale_map.get(sub_id, 0) return None def get_ent_physical_sensor_precision(self, sub_id): """ Get sensor precision value based on sub OID :param sub_id: sub ID of the sensor :return: sensor precision in range (-8, 9) or None if sub_id not in the cache. """ if sub_id in self.sub_ids: return self.ent_phy_sensor_precision_map.get(sub_id, 0) return None def get_ent_physical_sensor_value(self, sub_id): """ Get sensor value based on sub OID :param sub_id: sub ID of the sensor :return: sensor value converted according to tuple (type, scale, precision) """ if sub_id in self.sub_ids: return self.ent_phy_sensor_value_map.get(sub_id, 0) return None def get_ent_physical_sensor_oper_status(self, sub_id): """ Get sensor operational state based on sub OID :param sub_id: sub ID of the sensor :return: sensor's operational state """ if sub_id in self.sub_ids: return self.ent_phy_sensor_oper_state_map.get( sub_id, EntitySensorStatus.UNAVAILABLE) return None
class PhysicalSensorTableMIBUpdater(MIBUpdater): """ Updater for sensors. """ TRANSCEIVER_DOM_KEY_PATTERN = mibs.transceiver_dom_table("*") def __init__(self): """ ctor """ super().__init__() self.statedb = Namespace.init_namespace_dbs() Namespace.connect_all_dbs(self.statedb, mibs.STATE_DB) # list of available sub OIDs self.sub_ids = [] # sensor MIB requiered values self.ent_phy_sensor_type_map = {} self.ent_phy_sensor_scale_map = {} self.ent_phy_sensor_precision_map = {} self.ent_phy_sensor_value_map = {} self.ent_phy_sensor_oper_state_map = {} self.transceiver_dom = [] def reinit_data(self): """ Reinit data, clear cache """ # clear cache self.ent_phy_sensor_type_map = {} self.ent_phy_sensor_scale_map = {} self.ent_phy_sensor_precision_map = {} self.ent_phy_sensor_value_map = {} self.ent_phy_sensor_oper_state_map = {} transceiver_dom_encoded = Namespace.dbs_keys( self.statedb, mibs.STATE_DB, self.TRANSCEIVER_DOM_KEY_PATTERN) if transceiver_dom_encoded: self.transceiver_dom = [entry for entry in transceiver_dom_encoded] 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 get_next(self, sub_id): """ :param sub_id: Input sub_id. :return: The next sub id. """ right = bisect_right(self.sub_ids, sub_id) if right == len(self.sub_ids): return None return self.sub_ids[right] def get_ent_physical_sensor_type(self, sub_id): """ Get sensor type based on sub OID :param sub_id: sub ID of the sensor :return: sensor type from EntitySensorDataType enum or None if sub_id not in the cache. """ if sub_id in self.sub_ids: return self.ent_phy_sensor_type_map.get( sub_id, EntitySensorDataType.UNKNOWN) return None def get_ent_physical_sensor_scale(self, sub_id): """ Get sensor scale value based on sub OID :param sub_id: sub ID of the sensor :return: sensor scale from EntitySensorDataScale enum or None if sub_id not in the cache. """ if sub_id in self.sub_ids: return self.ent_phy_sensor_scale_map.get(sub_id, 0) return None def get_ent_physical_sensor_precision(self, sub_id): """ Get sensor precision value based on sub OID :param sub_id: sub ID of the sensor :return: sensor precision in range (-8, 9) or None if sub_id not in the cache. """ if sub_id in self.sub_ids: return self.ent_phy_sensor_precision_map.get(sub_id, 0) return None def get_ent_physical_sensor_value(self, sub_id): """ Get sensor value based on sub OID :param sub_id: sub ID of the sensor :return: sensor value converted according to tuple (type, scale, precision) """ if sub_id in self.sub_ids: return self.ent_phy_sensor_value_map.get(sub_id, 0) return None def get_ent_physical_sensor_oper_status(self, sub_id): """ Get sensor operational state based on sub OID :param sub_id: sub ID of the sensor :return: sensor's operational state """ if sub_id in self.sub_ids: return self.ent_phy_sensor_oper_state_map.get( sub_id, EntitySensorStatus.UNAVAILABLE) return None