Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
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
Пример #5
0
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