예제 #1
0
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
예제 #2
0
    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)
예제 #3
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)
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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
    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()
예제 #8
0
    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()
예제 #9
0
 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)
예제 #10
0
    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()
예제 #11
0
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
예제 #12
0
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
예제 #13
0
    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)
예제 #14
0
    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)
예제 #16
0
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
예제 #17
0
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
예제 #18
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)
예제 #19
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)
예제 #20
0
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