Example #1
0
def port_obj_for_chpid(obj, seq, tag):
    """Returns the port object matching the rnid/sequence-numbber and rnid/tag. Used for finding CHPIDs

    :param obj: Object with port objects, obj.r_port_objects()
    :type obj: brcddb.classes.switch.SwitchObj, brcddb.classes.fabric.FabricObj, brcddb.classes.project.ProjectObj,
                brcddb.classes.chassis.ChassisObj
    :param seq: Serial number (sequence number) for CEC
    :type seq: str
    :param tag: CHPID tag
    :type tag: str
    :rturn: Port object where this CHPID is connected. None if not found
    :rtype: brcddb.classes.port.PortObj, None
    """
    # The tag from the IOCP will never have '0x' prefix so below is just in case I ever use this for something else.
    test_tag = tag if '0x' in tag else '0x' + tag
    port_list = brcddb_search.match_test(
        obj.r_port_objects(),
        {
            'l': (
                dict(k='rnid/sequence-number', t='exact', v=seq, i=True),
                dict(k='rnid/tag', t='exact', v=test_tag, i=True),
                dict(k='rnid/flags', t='exact', v='0x10'
                     ),  # Indicates the RNID data is valid for a channel
            ),
            'logic':
            'and'  # 'and' is the default logic so this is just for clarity for the reader
        })
    return port_list[0] if len(port_list) > 0 else None
Example #2
0
def _check_remote_sfps(obj_list, t_obj):
    """Checks remote SFP levels and adds appropriate alerts to port objects

    :param obj_list: List of port object
    :type obj_list: brcddb.classes.PortObj
    :param t_obj: Individual test item from the test_list passed to best_practice(). Not used
    :type t_obj: dict
    """
    global _remote_rule_template, _alert_tbl

    for p_obj in brcddb_search.match_test(obj_list, bp_tables.is_online):
        v = p_obj.r_get('media-rdp/remote-media-voltage-alert/high-alarm')
        if v is None or v == 0:
            continue  # Sometimes threshold data is all 0 when it's not valid. Just checking the voltage makes it easy

        # Check threshold levels
        for k, rules in _remote_rule_template.items():
            try:
                v = p_obj.r_get(k)
                if v is None:
                    continue
                for k1, rules_1 in rules.items():
                    tv = p_obj.r_get(k1)
                    if rules_1.get('t') == '>=':
                        if v >= tv:
                            p_obj.s_add_alert(_alert_tbl, rules_1.get('a'), k1, v, tv)
                            break
                    else:
                        if v <= tv:
                            p_obj.s_add_alert(_alert_tbl, rules_1.get('a'), k1, v, tv)
                            break
            except:
                pass  # Remote data wasn't provided if we get here.
Example #3
0
def _fc16_48_haa_p8(obj, t_obj):
    """Check to see if there is a pre-2015 FC16-32 blade with an SFP matching S/N HAA* in port 8

    :param obj: Chassis object from the object list, obj_list, passed to best_practice()
    :type obj: brcddb.classes.switch.switch_obj
    :param t_obj: Individual test item from the test_list passed to best_practice(). Not used
    :type t_obj: dict
    :return: Alerts are applied to the ports found that meet this criteria so an empty list is always returned
    :rtype: list
    """
    global _alert_tbl

    # Get all the ports number 8 in for FC16-32 blades matching P/N 60-1001945-* (built before 2016)
    temp_l = brcddb_util.convert_to_list(obj.r_get('brocade-fru/blade'))
    fru_list = brcddb_search.match(temp_l, 'part-number', '60-1001945-*', False, 'wild')
    temp_l = [str(fru.get('slot-number')) for fru in fru_list]

    # Get a list of ports we just figured out above that have an SFP matching S/N HAA*
    if len(temp_l) > 0:
        lt = [
            {'k': 'media-rdp/serial-number', 'v': 'HAA*', 't': 'wild'},
            {'k': 'fibrechannel/name', 'v': '[' + ','.join(temp_l) + ']/(8 | 32)', 't': 'regex-m'}
        ]
        ml = brcddb_search.match_test(obj.r_port_objects(), lt, 'and')
        for port_obj in ml:
            port_obj.s_add_alert(_alert_tbl, t_obj.get('m'))

    return list()
Example #4
0
def _check_sfps(obj_list, t_obj):
    """Checks SFP levels and adds appropriate alerts to port objects

    :param obj_list: Port object
    :type obj_list: list
    :param t_obj: Individual test item from the test_list passed to best_practice(). Not used
    :type t_obj: dict
    """
    global _rule_template, sfp_rules, _alert_tbl

    if sfp_rules is None or obj_list is None:
        return

    # Perform all the checks for the SFPs on the switch.
    enabled_ports = brcddb_search.match_test(obj_list, bp_tables.is_enabled)  # SFP data is not valid for disabled ports
    for rule in sfp_rules:
        group = 'Unkonwn' if rule.get('Group') is None else rule.get('Group')
        try:
            pn_l = rule.get('Mfg. P/N')
            if pn_l is not None and pn_l != '':
                for pn in [p.strip() for p in pn_l.split(',')]:
                    plist = brcddb_search.match_test(enabled_ports,
                                                     {'k': 'media-rdp/part-number', 't': 'exact', 'v': pn})
                    if len(plist) > 0:
                        online_plist = brcddb_search.match_test(plist, bp_tables.is_online)
                        for k0, obj_0 in _rule_template.items():
                            for k1, obj_1 in obj_0.items():
                                val = float(rule.get(k1))  # The threshold to test against
                                m = obj_1.get('a')  # Alert number
                                tlist = online_plist if obj_1.get('l') else plist
                                for p_obj in brcddb_search.match_test(tlist, {'k': k0, 't': obj_1.get('t'), 'v': val}):
                                    p_obj.s_add_alert(_alert_tbl, m, k0, p_obj.r_get(k0), val)
            else:
                brcdapi_log.log('Missing P/N in ' + sfp_rules + ', Group: ' + str(group), True)

        except:
            brcdapi_log.exception('Invalid SFP rules file ' + sfp_rules + '. Group: ' + str(group), True)
            return

    return
Example #5
0
def port_obj_for_addr(obj, addr):
    """Returns the port object for a port in a given fabric matching a link address. Used for finding control units

    :param obj: Object with port objects, obj.r_port_objects()
    :type obj: brcddb.classes.switch.SwitchObj, brcddb.classes.fabric.FabricObj, brcddb.classes.project.ProjectObj,
                brcddb.classes.chassis.ChassisObj
    :param addr: Hex FC address (format is 0x123400)
    :type addr: str
    :rturn: Port object matching the link address. None if not found
    :rtype: brcddb.classes.port.PortObj, None
    """
    port_list = brcddb_search.match_test(
        obj.r_port_objects(),
        dict(k='fibrechannel/fcid-hex', t='exact', v=addr, i=True))
    return port_list[0] if len(port_list) > 0 else None
Example #6
0
def fab_obj_for_user_name(proj_obj, name):
    """Returns a list of fabric objects matching a user friendly name

    :param proj_obj: Project object
    :type proj_obj: brcddb.classes.project.ProjectObj
    :param fab_obj: List of brcddb fabric objects whose user friendly name matches name
    :type fab_obj: brcddb.classes.fabric.FabricObj
    """
    sl = brcddb_search.match_test(
        proj_obj.r_switch_objects(),
        dict(
            k=
            'brocade-fibrechannel-switch/fibrechannel-switch/fabric-user-friendly-name',
            v=name,
            t='exact',
            i=False))
    return brcddb_util.remove_duplicates(
        [switch_obj.r_fabric_obj() for switch_obj in sl])
Example #7
0
def _check_best_practice(obj_list, test_list):
    """Checks for defined conditions and adds an alert for every out of bounds condition.

    :param obj_list: A list of dictionaries or brcdapi objects to search. Must all be the same type
    :type obj_list: dict, list, tuple
    :param test_list: Pointer to table of best practice rules. See brcddb.app_data.bp_tables for details
    :type test_list: dict
    """
    global _alert_tbl

    # Validate user input
    if len(obj_list) == 0:
        return
    if not isinstance(test_list, (list, tuple)):
        brcdapi_log.exception('Invalid test_list type, ' + str(type(test_list)), True)
        return


    # Spin through each item in the test_list and perform the specified test
    for t_obj in test_list:
        if 'skip' in t_obj and t_obj.get('skip'):
            continue
        special = t_obj.get('s')
        if special is not None:
            if special in _bp_special_case_tbl:
                _bp_special(obj_list, t_obj)
            elif special in _bp_special_list_case_tbl:
                _bp_special_list(obj_list, t_obj)
            else:
                brcdapi_log.exception(
                    'Unknown special test case: ' + str(special) + ', type: ' + str(type(special)),
                    True)

        else:
            for obj in brcddb_search.match_test(obj_list, t_obj.get('l'), t_obj.get('logic')):
                # See documentation in brcddb.app_data.bp_tables for an explanation of 'm', 'p0', 'p0h', 'p1', & 'p1h'
                p0 = t_obj.get('p0h') if t_obj.get('p0h') is not None else obj.r_get(t_obj.get('p0'))
                p1 = t_obj.get('p1h') if t_obj.get('p1h') is not None else obj.r_get(t_obj.get('p1'))
                obj.s_add_alert(_alert_tbl, t_obj.get('m'), brcddb_util.convert_to_list(t_obj.get('l'))[0].get('k'),
                               p0, p1)
Example #8
0
def _fdmi_enabled(obj_list, t_obj):
    """Check to see if FDMI should be enabled on the attached device.

    :param obj_list: List of login objects, brcddb.classes.login.LoginObj, passed to best_practice()
    :type obj_list: list
    :param t_obj: Individual test item from the test_list passed to best_practice().
    :type t_obj: dict
    :return: List of port objects, brcddb.classes.port.PortObj, matching the test criteria in t_obj
    :rtype: list
    """
    ret_list = list()
    for obj in brcddb_search.match_test(obj_list, t_obj.get('l'), t_obj.get('logic')):
        port_obj = obj.r_port_obj()
        if port_obj is None:
            continue
        wwn = obj.r_obj_key()
        try:
            if port_obj.r_get('fibrechannel/neighbor/wwn')[1] == wwn:
                if obj.r_fabric_obj().r_fdmi_port_obj(wwn) is None:
                    ret_list.append(port_obj)
        except:
            if obj.r_fabric_obj().r_fdmi_port_obj(wwn) is None:
                ret_list.append(port_obj)
    return ret_list
Example #9
0
def _graphs(switch_obj, single_port_graph_in, stats_graph_in, graph_type):
    """Parses the graphing information from the command line into a list of machine readable dictionaries as follows:

    +-----------+---------------------------------------------------+
    | key       | Description                                       |
    +===========+===================================================+
    | stat      | Only present if -gs was entered on the command    |
    |           | line. This is the fibrechannel-statistics to plot |
    +-----------+---------------------------------------------------+
    | type      | Graph type. See brcddb.report.graph.chart_types.  |
    +-----------+---------------------------------------------------+
    | port      | Only present if -gp was entered on the command    |
    |           | line. This is the port number in s/p notation to  |
    |           | plot.                                             |
    +-----------+---------------------------------------------------+
    | params    | If stat is not None, this is the list of ports    |
    |           | whose statistic is to be plotted. If port is not  |
    |           | None, this is the list of statistics for the port |
    |           | to be plotted.                                    |
    +-----------+---------------------------------------------------+

    :param switch_obj: First switch object with list of ports
    :type switch_obj: brcddb.classes.switch.SwitchObj
    :param single_port_graph_in: Command line text for single port graphs
    :type single_port_graph_in: str
    :param stats_graph_in: Command line text for statistics graphs
    :type stats_graph_in: str
    :param graph_type: Type of graph
    :type graph_type: str
    :return graphs: List of dictionaries that define the graphs. See description of graph in _write_report() for details
    :rtype graphs: list
    :return messages: List of error and warning messages
    :rtype messages: list
    """
    # Figure out the graph type and set up the return list of graphs
    ml = list()
    graphs = list()
    if graph_type is None:
        graph_type = 'line'
    elif graph_type not in report_graph.chart_types.keys():
        ml.append('Invalid graph type:   ' + graph_type +
                  '. Defaulting to line')
        graph_type = 'line'

    # Single port, multiple statistics
    if isinstance(single_port_graph_in, str):
        for buf in single_port_graph_in.split(';'):
            temp_l = buf.split(',')
            if len(temp_l) > 1:
                port = temp_l.pop(0)
                if '/' not in port:
                    port = '0/' + port
                if switch_obj.r_port_obj(port) is None:
                    ml.append(port + ' not found. Skipping this port')
                else:
                    graphs.append(
                        dict(port=port, parms=temp_l, type=graph_type))

    # statistic, multiple ports
    if isinstance(stats_graph_in, str):
        for buf in stats_graph_in.split(';'):
            temp_l = buf.split(',')
            if len(temp_l) > 1:
                statistic = 'fibrechannel-statistics/' + temp_l[0]
                to_graph = dict(stat=statistic, type=graph_type)
                temp_l = temp_l[1:]

                # If top or avg was specified for the ports, figure out the top (peak) ports for this statistic and the
                # top ports for the maximum sum for this statistic
                if 'top-' in temp_l[0].lower() or 'avg-' in temp_l[0].lower():
                    n = int(temp_l[0].split('-')[1])
                    switch_obj_l = [
                        o
                        for o in switch_obj.r_project_obj().r_switch_objects()
                        if '-' in o.r_obj_key()
                    ]
                    port_total_d = dict()
                    port_peak_d = dict()
                    port_obj_l = list()
                    for port_obj in switch_obj_l.pop(0).r_port_objects():
                        port_stat = port_obj.r_get(statistic)
                        if port_stat is None:
                            ml.append(statistic + ' not found for port ' +
                                      port_obj.r_obj_key())
                        else:
                            port_total_d.update(
                                {port_obj.r_obj_key(): port_stat})
                            port_peak_d.update(
                                {port_obj.r_obj_key(): port_stat})
                            port_obj_l.append(port_obj)
                    for switch_obj in switch_obj_l:
                        for port_obj in switch_obj.r_port_objects():
                            port_stat = port_obj.r_get(statistic)
                            if port_stat is None:
                                ml.append(statistic + ' not found for port ' +
                                          port_obj.r_obj_key())
                            else:
                                port_key = port_obj.r_obj_key()
                                if port_key in port_total_d:
                                    port_total_d[port_key] += port_stat
                                    if port_stat > port_peak_d[port_key]:
                                        port_peak_d[port_key] = port_stat
                    for port_obj in port_obj_l:
                        port_obj.s_new_key('_peak',
                                           port_peak_d[port_obj.r_obj_key()],
                                           True)
                        port_obj.s_new_key('_total',
                                           port_total_d[port_obj.r_obj_key()],
                                           True)
                    peak_ports = gen_util.sort_obj_num(
                        port_obj_l, '_peak', True)[0:min(n, len(port_obj_l))]
                    max_ports = gen_util.sort_obj_num(
                        port_obj_l, '_total', True)[0:min(n, len(port_obj_l))]

                    # Above sorts by port object. All we want is the port number
                    if 'top' in temp_l[0]:
                        to_graph.update(parms=[
                            port_obj.r_obj_key() for port_obj in peak_ports
                        ])
                    else:
                        to_graph.update(parms=[
                            port_obj.r_obj_key() for port_obj in max_ports
                        ])

                elif 'eport' in temp_l[0].lower().replace('-', ''):
                    port_list = brcddb_search.match_test(
                        switch_obj.r_port_objects, bp_tables.is_e_port)
                    if len(port_list) == 0:
                        ml.append('No E-Ports found')
                    to_graph.update(
                        parms=[port_obj.r_obj_key() for port_obj in port_list])

                else:  # It's a list of ports. Make sure they are valid and prepend '0/' if necessary
                    port_list = list()
                    for port in temp_l:
                        mod_port = port if '/' in port else '0/' + port
                        if switch_obj.r_port_obj(mod_port) is None:
                            ml.append(
                                'Invalid port number or port not found in switch: '
                                + mod_port)
                        else:
                            port_list.append(mod_port)
                    to_graph.update(parms=port_list)

                if len(to_graph['parms']) > 0:
                    graphs.append(to_graph)

            else:
                ml.append('Missing parameter in ' + buf)

    return graphs, ml
Example #10
0
def _f_ports(switch_obj):
    return [
        p.r_obj_key() for p in brcddb_search.match_test(
            switch_obj.r_port_objects(), bp_tables.is_f_port)
    ]
def _test_act(obj):
    global _working_obj_l

    _working_obj_l = brcddb_search.match_test(_working_obj_l, obj)