def _get_psu_status(self, psu_index): """ Get PSU status :return: the status of particular PSU """ psu_name = PSU_INFO_KEY_TEMPLATE.format(psu_index) psu_info = self.statedb.get_all(self.statedb.STATE_DB, mibs.psu_info_table(psu_name)) presence, status = get_psu_data(psu_info) return status == PSU_STATUS_OK
def _get_psu_presence(self, psu_index): """ Get PSU presence :return: the presence of particular PSU """ psu_name = PSU_INFO_KEY_TEMPLATE.format(psu_index) psu_info = self.statedb.get_all(self.statedb.STATE_DB, mibs.psu_info_table(psu_name)) presence, status = get_psu_data(psu_info) return presence == PSU_PRESENCE_OK
def _update_entity_cache(self, psu_name): psu_info = Namespace.dbs_get_all(self.mib_updater.statedb, mibs.STATE_DB, mibs.psu_info_table(psu_name)) if not psu_info: return model, serial, current, power, presence, voltage, temperature, replaceable = get_db_data( psu_info, PsuInfoDB) if presence.lower() != 'true': self._remove_entity_cache(psu_name) return psu_relation_info = self.get_physical_relation_info(psu_name) psu_position, psu_parent_name = get_db_data(psu_relation_info, PhysicalRelationInfoDB) psu_position = int(psu_position) psu_sub_id = get_psu_sub_id(psu_position) self._add_entity_related_oid(psu_name, psu_sub_id) self.mib_updater.update_name_to_oid_map(psu_name, psu_sub_id) # add PSU to available OID list self.mib_updater.add_sub_id(psu_sub_id) self.mib_updater.set_phy_class(psu_sub_id, PhysicalClass.POWERSUPPLY) self.mib_updater.set_phy_descr(psu_sub_id, psu_name) self.mib_updater.set_phy_name(psu_sub_id, psu_name) if not is_null_str(model): self.mib_updater.set_phy_model_name(psu_sub_id, model) if not is_null_str(serial): self.mib_updater.set_phy_serial_num(psu_sub_id, serial) self.mib_updater.set_phy_parent_relative_pos(psu_sub_id, psu_position) self.mib_updater.set_phy_contained_in(psu_sub_id, psu_parent_name) self.mib_updater.set_phy_fru(psu_sub_id, replaceable) # add psu current sensor as a physical entity if current and not is_null_str(current): self._update_psu_sensor_cache(psu_name, psu_sub_id, 'current') if power and not is_null_str(power): self._update_psu_sensor_cache(psu_name, psu_sub_id, 'power') if temperature and not is_null_str(temperature): self._update_psu_sensor_cache(psu_name, psu_sub_id, 'temperature') if voltage and not is_null_str(voltage): self._update_psu_sensor_cache(psu_name, psu_sub_id, 'voltage')
class PsuCacheUpdater(PhysicalEntityCacheUpdater): KEY_PATTERN = mibs.psu_info_table("*") def __init__(self, mib_updater): super(PsuCacheUpdater, self).__init__(mib_updater) def get_key_pattern(self): return PsuCacheUpdater.KEY_PATTERN def _update_entity_cache(self, psu_name): psu_info = Namespace.dbs_get_all(self.mib_updater.statedb, mibs.STATE_DB, mibs.psu_info_table(psu_name)) if not psu_info: return model, serial, current, power, presence, voltage, temperature, replaceable = get_db_data( psu_info, PsuInfoDB) if presence.lower() != 'true': self._remove_entity_cache(psu_name) return psu_relation_info = self.get_physical_relation_info(psu_name) psu_position, psu_parent_name = get_db_data(psu_relation_info, PhysicalRelationInfoDB) psu_position = int(psu_position) psu_sub_id = get_psu_sub_id(psu_position) self._add_entity_related_oid(psu_name, psu_sub_id) self.mib_updater.update_name_to_oid_map(psu_name, psu_sub_id) # add PSU to available OID list self.mib_updater.add_sub_id(psu_sub_id) self.mib_updater.set_phy_class(psu_sub_id, PhysicalClass.POWERSUPPLY) self.mib_updater.set_phy_descr(psu_sub_id, psu_name) self.mib_updater.set_phy_name(psu_sub_id, psu_name) if not is_null_str(model): self.mib_updater.set_phy_model_name(psu_sub_id, model) if not is_null_str(serial): self.mib_updater.set_phy_serial_num(psu_sub_id, serial) self.mib_updater.set_phy_parent_relative_pos(psu_sub_id, psu_position) self.mib_updater.set_phy_contained_in(psu_sub_id, psu_parent_name) self.mib_updater.set_phy_fru(psu_sub_id, replaceable) # add psu current sensor as a physical entity if current and not is_null_str(current): self._update_psu_sensor_cache(psu_name, psu_sub_id, 'current') if power and not is_null_str(power): self._update_psu_sensor_cache(psu_name, psu_sub_id, 'power') if temperature and not is_null_str(temperature): self._update_psu_sensor_cache(psu_name, psu_sub_id, 'temperature') if voltage and not is_null_str(voltage): self._update_psu_sensor_cache(psu_name, psu_sub_id, 'voltage') def _update_psu_sensor_cache(self, psu_name, psu_sub_id, sensor_name): psu_current_sub_id = get_psu_sensor_sub_id(psu_sub_id, sensor_name) self._add_entity_related_oid(psu_name, psu_current_sub_id) self.mib_updater.add_sub_id(psu_current_sub_id) self.mib_updater.set_phy_class(psu_current_sub_id, PhysicalClass.SENSOR) desc = '{} for {}'.format(PSU_SENSOR_NAME_MAP[sensor_name], psu_name) self.mib_updater.set_phy_descr(psu_current_sub_id, desc) self.mib_updater.set_phy_name(psu_current_sub_id, desc) self.mib_updater.set_phy_parent_relative_pos( psu_current_sub_id, PSU_SENSOR_POSITION_MAP[sensor_name]) self.mib_updater.set_phy_contained_in(psu_current_sub_id, psu_sub_id) self.mib_updater.set_phy_fru(psu_current_sub_id, False)
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