Ejemplo n.º 1
0
def _switch_from_list_match_case(switch_obj, obj, uri):
    switch_wwn = switch_obj.r_obj_key()
    element = uri.split('/').pop()
    i = 0
    for s_obj in brcddb_util.convert_to_list(obj.get(element)):
        fos_switch_wwn = s_obj.get('switch-wwn')
        if fos_switch_wwn is not None and fos_switch_wwn == switch_wwn:
            _update_brcddb_obj_from_list(switch_obj, brcddb_util.convert_to_list(obj.get(element))[i], uri)
            return
        i += 1
Ejemplo n.º 2
0
def _chassis_fru_check(obj, t_obj):
    """Check temperature sensors and H/W faults.

    :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().
    :type t_obj: dict
    :return: List of alert dictionaries {'a': alert number, 'p0': p0, 'p1': p1, 'k': '_isl_map'}
    :rtype: list
    """
    global _alert_tbl

    r_list = list()
    # Blades
    for d in brcddb_util.convert_to_list(obj.r_get('brocade-fru/blade')):
        v = str(d.get('blade-state'))
        if 'ault' in v:  # Sometimes it's 'fault' and sometimes it's 'Fault'.
            r_list.append({'a': t_obj.get('m'), 'p0': 'blade: ' + str(d.get('slot-number')), 'p1': v, 'k': None})

    # Fans
    for d in brcddb_util.convert_to_list(obj.r_get('brocade-fru/fan')):
        v = str(d.get('operational-state'))
        if v.upper() != 'OK':
            r_list.append({'a': t_obj.get('m'), 'p0': 'Fan: ' + str(d.get('unit-number')), 'p1': v, 'k': None})

    # Power Supply
    for d in brcddb_util.convert_to_list(obj.r_get('brocade-fru/power-supply')):
        v = str(d.get('operational-state'))
        if v.upper() != 'OK':
            r_list.append({'a': t_obj.get('m'), 'p0': 'Power Supply: ' + str(d.get('unit-number')), 'p1': v, 'k': None})

    # Temp Sensor
    for d in brcddb_util.convert_to_list(obj.r_get('brocade-fru/sensor')):
        v = str(d.get('state'))
        if v.upper() != 'ABSENT':
            if v.upper() != 'OK':
                p0 = 'Temp Sensor ID: ' + str(d.get('id')) + \
                     str(d.get('slot-number')) if d.get('slot-number') is not None else ''
                r_list.append({'a': t_obj.get('m'), 'p0': p0, 'p1': v, 'k': None})
            v1 = d.get('temperature')
            if isinstance(v1, (int, float)):
                if v1 >= HIGH_TEMP_WARN:
                    a = al.ALERT_NUM.CHASSIS_TEMP_ERROR if v1 >= HIGH_TEMP_ERROR else al.ALERT_NUM.CHASSIS_TEMP_WARN
                    p0 = '' if d.get('slot-number') is None else 'Slot: ' + str(d.get('slot-number')) + ' '
                    p0 += '' if d.get('id') is None else 'ID: ' + str(d.get('id'))
                    r_list.append({'a': a , 'p0': p0, 'p1': v1, 'k': None})

    return r_list
Ejemplo n.º 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()
Ejemplo n.º 4
0
def _switch_from_list_case(switch_obj, obj, uri):
    try:
        _update_brcddb_obj_from_list(switch_obj, brcddb_util.convert_to_list(obj.get(uri.split('/').pop()))[0], uri)
        if switch_obj.r_is_principal():
            switch_obj.r_project_obj().s_add_fabric(switch_obj.r_obj_key())
    except:
        pass
Ejemplo n.º 5
0
def add_rest_port_data(switch_obj, pobj, flag_obj=None, skip_list=list()):
    """Adds port statistics from rest request 'brocade-interface/fibrechannel-statistics' to each port object

    :param switch_obj: Switch object
    :type switch_obj: SwitchObj
    :param pobj: Object returned from the FOS Rest API
    :type pobj: dict
    :param flag_obj: Not used. Must be here for methods that call rest add methods from a table.
    :type flag_obj: None
    :param skip_list: Keys to skip
    :type skip_list: (list, tuple)
    :return: None
    :rtype: None
    """
    sl = ['name', 'enabled-state']
    sl.extend(skip_list)
    for k in pobj.keys():
        for pdict in brcddb_util.convert_to_list(pobj.get(k)):
            if k == 'media-rdp':
                # The media name is in the format type/s/p, but for everything else, it's just s/p, which is how the key
                # is created for the port object in the switch object. By splitting on '/', removing the first list
                # element, and joining the rest with '/', I end up with just s/p.
                port_obj = switch_obj.s_add_port('/'.join(pdict.get('name').split('/')[1:]))
            else:
                port_obj = switch_obj.s_add_port(pdict.get('name'))
            v = dict()
            port_obj.s_new_key(k, v)
            brcddb_copy.object_copy(pdict, v, port_obj, sl)
            # Make sure there is a login object for every login found
            fab_obj = switch_obj.r_fabric_obj()
            if fab_obj is not None:
                for wwn in port_obj.r_login_keys():
                    fab_obj.s_add_login(wwn)
Ejemplo n.º 6
0
def _add_switch_to_chassis_int(chassis_obj, switch, uri, switch_wwn):
    switch_obj = chassis_obj.s_add_switch(switch_wwn)
    _update_brcddb_obj_from_list(switch_obj, switch, uri)

    # Add the ports
    try:
        for port in brcddb_util.convert_to_list(switch.get('port-member-list').get('port-member')):
            switch_obj.s_add_port(port)
    except:
        pass

    # Add the GE ports
    try:
        for port in brcddb_util.convert_to_list(switch.get('ge-port-member-list').get('port-member')):
            switch_obj.s_add_ge_port(port)
    except:
        pass
Ejemplo n.º 7
0
def get_batch(session, proj_obj, kpi_list, fid=None):
    """Processes a batch API requests. All chassis request are performed first, followed by processing of fid_rest_data

    If any warnings or errors are encountered, the log is updated and the appropriate flag bits for the proj_obj are
    set. Search for _project_warn in brcddb_common.py for additional information. Again, search for _project_warn in
    brcddb.classes for object methods to set and check these bits.
    :param session: Session object, or list of session objects, returned from brcdapi.pyfos_auth.login()
    :type session: dict
    :param proj_obj: Project object
    :type proj_obj: brcddb.classes.ProjectObj
    :param kpi_list: List of KPIs to request from the switches and chassis
    :type kpi_list: list
    :param fid: FID, or list of FIDs for logical switch level requests. If None, execute requests for all FIDs.
    :type fid: int, list, tuple, None
    :rtype: None
    """
    # Get the chassis object
    chassis_obj = get_chassis(session, proj_obj)
    if chassis_obj is None:
        brcdapi_log.log(brcdapi_util.mask_ip_addr(session.get('ip_addr')) + 'Chassis not found.', True)
        return

    kl = brcddb_util.convert_to_list(kpi_list)

    # Get all the chassis data
    for kpi in [kpi for kpi in kl if not brcdapi_util.uri_map[kpi]['fid']]:
        results_action(chassis_obj, get_rest(session, kpi, chassis_obj), kpi)

    # Figure out which logical switches to poll switch level data from.
    if chassis_obj.r_is_vf_enabled() and fid is not None:
        switch_list = list()
        for fab_id in brcddb_util.convert_to_list(fid):
            switch_obj = chassis_obj.r_switch_obj_for_fid(fab_id)
            if switch_obj is None:
                brcdapi_log.log('FID ' + str(fab_id) + ' not found', True)
            else:
                switch_list.append(switch_obj)
    else:
        switch_list = chassis_obj.r_switch_objects()

    # Now process all the switch (FID) level commands.
    for switch_obj in switch_list:
        for kpi in [kpi for kpi in kl if brcdapi_util.uri_map[kpi]['fid']]:
            results_action(switch_obj,
                           get_rest(session, kpi, switch_obj, brcddb_switch.switch_fid(switch_obj)), kpi)
Ejemplo n.º 8
0
def _fabric_fdmi_hba_case(objx, obj, uri):
    fab_obj = objx.r_fabric_obj()
    for obj in brcddb_util.convert_to_list(obj.get('hba')):
        try:
            for wwn in obj.get('hba-port-list').get('wwn'):
                fab_obj.s_add_fdmi_port(wwn)
        except:
            pass
        _update_brcddb_obj(fab_obj.s_add_fdmi_node(obj.get('hba-id')), obj, uri)
Ejemplo n.º 9
0
def _add_ls_switch_to_chassis_case(chassis_obj, obj, uri):
    existing_switch_wwns = chassis_obj.r_switch_keys()
    for switch in brcddb_util.convert_to_list(obj.get(uri.split('/').pop())):
        wwn = switch.get('switch-wwn')
        if wwn in existing_switch_wwns:
            continue  # The switch is already there. This method is not intended to modify an existing switch object
        switch_obj = chassis_obj.s_add_switch(wwn)
        _update_brcddb_obj_from_list(switch_obj, switch, uri)
        try:
            for port in brcddb_util.convert_to_list(switch.get('port-member-list').get('port-member')):
                switch_obj.s_add_port(port)
        except:
            pass
        try:
            for port in brcddb_util.convert_to_list(switch.get('ge-port-member-list').get('port-member')):
                switch_obj.s_add_ge_port(port)
        except:
            pass
Ejemplo n.º 10
0
def _fdmi_port_obj_for_login(obj):
    """Returns the FDMI port object in a list for a login obj. See _obj_self() for parameter detail."""
    fab_obj = obj.r_fabric_obj()
    if fab_obj is None:
        return list()
    return [
        mem for mem in brcddb_util.convert_to_list(
            fab_obj.r_fdmi_port_obj(obj.r_obj_key())) if mem is not None
    ]
Ejemplo n.º 11
0
def _fdmi_port_for_fdmi_node(obj):
    """Returns a list of FDMI port objects for a zonecfg. See _obj_self() for parameter detail."""
    fab_obj = obj.r_fabric_obj()
    if fab_obj is None:
        return list()
    return [
        mem for mem in brcddb_util.convert_to_list(
            fab_obj.r_fdmi_port_obj(obj.r_obj_key())) if mem is not None
    ]
Ejemplo n.º 12
0
def s_switch_trunk_case(switch_obj, k):  # Not used yet
    rl = list()
    for obj in brcddb_util.convert_to_list(switch_obj.r_get(k)):
        port_obj = switch_obj.r_port_object_for_index(obj.get('source-port'))
        ps_name = 'Index: ' + obj.get('source-port') if port_obj is None else port_obj.r_obj_key()
        d_switch_obj = switch_obj.r_project_obj().r_switch_obj(obj.get('neighbor-wwn'))
        port_obj = None if d_switch_obj is None else d_switch_obj.r_port_object_for_index(obj.get('destination-port'))
        pd_name = 'Index: ' + str(obj.get('destination-port')) if port_obj is None else port_obj.r_obj_key()
        rl.append('From ' + ps_name + ' to ' + obj.get('neighbor-switch-name') + ' ' + pd_name)
    return '\n'.join(rl)
Ejemplo n.º 13
0
def _defined_zonecfg_case(objx, obj, uri):
    fab_obj = objx.r_fabric_obj()
    if fab_obj is None:
        return  # The switch is not in a fabric if it's disabled. We also get here if the principal switch is unkonwn
    dobj = obj.get('defined-configuration')
    if dobj is not None:
        for zobj in brcddb_util.convert_to_list(dobj.get('cfg')):
            zonecfg_obj = fab_obj.s_add_zonecfg(zobj.get('cfg-name'), zobj.get('member-zone').get('zone-name'))
            _update_brcddb_obj(zonecfg_obj, zobj, uri)
        for zobj in brcddb_util.convert_to_list(dobj.get('zone')):
            if 'member-entry' in zobj:
                mem_list = zobj.get('member-entry').get('entry-name')
                pmem_list = zobj.get('member-entry').get('principal-entry-name')
            else:
                mem_list = None
                pmem_list = None
            zone_obj = fab_obj.s_add_zone(zobj.get('zone-name'), zobj.get('zone-type'), mem_list, pmem_list)
        for zobj in brcddb_util.convert_to_list(dobj.get('alias')):
            mem_list = zobj.get('member-entry').get('alias-entry-name') if 'member-entry' in zobj else None
            alais_obj = fab_obj.s_add_alias(zobj.get('alias-name'), mem_list)
Ejemplo n.º 14
0
def _fabric_switch_case(switch_obj, obj, uri):
    proj_obj = switch_obj.r_project_obj()
    tl = uri.split('/')
    leaf = tl[len(tl)-1]
    wwn_ref = 'switch-wwn' if leaf == 'fibrechannel-logical-switch' else 'name'
    for switch in brcddb_util.convert_to_list(obj.get('fibrechannel-switch')):
        wwn = switch.get(wwn_ref)
        if brcddb_util.is_wwn(wwn):  # Yes, got bit by a bad WWN once
            s_obj = proj_obj.s_add_switch(wwn)
            if switch.get('principal'):
                fab_obj = proj_obj.s_add_fabric(wwn)
            _update_brcddb_obj_from_list(switch_obj, switch, uri)
        else:
            brcdapi_log.log('Bad switch WWN, , returned from ' + uri + ' for switch ' +
                            brcddb_switch.best_switch_name(switch_obj), True)
Ejemplo n.º 15
0
def maps_dashboard_alerts(proj_obj):
    """Looks through the MAPS alerts dashboard and adds an alert to the associated object.

    **WARNING:** As of 21 April 2019, there was not a reliable means of correlating MAPS alerts in the dashbaoard to a
    specific object. This just parses the dashboard for some obvious ones. An RFE was submitted
    :param proj_obj: Project object
    :type proj_obj: brcddb.classes.project.ProjectObj
    """
    for switch_obj in proj_obj.r_switch_objects():
        for dash_obj in brcddb_util.convert_to_list(
                switch_obj.r_get('brocade-maps/dashboard-rule')):
            if dash_obj.get('category') in _maps_category:
                _maps_category[dash_obj.get('category')](switch_obj, dash_obj)
            else:
                _unknown_category(switch_obj, dash_obj)
Ejemplo n.º 16
0
def _add_fab_switch_to_chassis_case(chassis_obj, obj, uri):
    proj_obj = chassis_obj.r_project_obj()
    fab_obj = None
    sl = list()
    for switch in brcddb_util.convert_to_list(obj.get(uri.split('/').pop())):
        c_obj = proj_obj.s_add_chassis(switch.get('chassis-wwn'))
        s_wwn = switch.get('name')
        switch_obj = c_obj.s_add_switch(s_wwn)
        sl.append(switch_obj)
        _update_brcddb_obj_from_list(switch_obj, switch, uri)
        if switch.get('principal'):
            fab_obj = proj_obj.s_add_fabric(s_wwn)
    if fab_obj is not None:
        for switch_obj in sl:
            switch_obj.s_fabric_key(fab_obj.r_obj_key())
            fab_obj.s_add_switch(switch_obj.r_obj_key())
Ejemplo n.º 17
0
def _bp_special_list(obj_list, t_obj):
    """Processes special best practice tests. Similar to _bp_special() but the associated methods return a list of all
    objects matching the test criteria and the same alert is applied to

    :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 t_obj: Best practice rules. See brcddb.app_data.bp_tables for details
    :type t_obj: dict
    """
    global _alert_tbl

    anum = t_obj.get('m')
    k = brcddb_util.convert_to_list(t_obj.get('l'))[0].get('k')
    p0 = t_obj.get('p0')
    p1 = t_obj.get('p1')
    for obj in _bp_special_list_case_tbl[t_obj.get('s')](obj_list, t_obj):
        obj.s_add_alert(_alert_tbl, anum, k, obj.r_get(p0), obj.r_get(p1))
Ejemplo n.º 18
0
def _effective_zonecfg_case(objx, obj, uri):
    if 'effective-configuration' in obj:  # None when there is no zone configuration enabled
        fab_obj = objx.r_fabric_obj()
        if fab_obj is None:
            return  # This happens when the principal switch in the fabric is unknown.
        dobj = obj.get('effective-configuration')
        if not isinstance(dobj, dict):
            return
        _update_brcddb_obj_from_list(fab_obj, dobj, uri, ['enabled-zone'])
        for zobj in brcddb_util.convert_to_list(dobj.get('enabled-zone')):
            if 'member-entry' in zobj:
                zone_obj = fab_obj.s_add_eff_zone(zobj.get('zone-name'), zobj.get('zone-type'),
                            zobj.get('member-entry').get('entry-name'),
                            zobj.get('member-entry').get('principal-entry-name'))
            else:  # I don't know how there can be items in the enabled-zone without a 'member-entry'. Just in case ...
                zone_obj = fab_obj.s_add_eff_zone(zobj.get('zone-name'))
            _update_brcddb_obj(zone_obj, zobj, uri)
        fab_obj.s_add_eff_zonecfg(fab_obj.r_eff_zone_keys())
Ejemplo n.º 19
0
def _switch_port_case(objx, obj, uri):
    """Parses port data into the switch object

    :param objx: Switch object
    :type objx: brcddb.classes.switch.SwitchObj
    :param obj: Object returned from the API
    :type obj: dict
    """
    tl = uri.split('/')
    leaf = tl[len(tl)-1]
    for port in brcddb_util.convert_to_list(obj.get(leaf)):
        port_obj = _port_case_case[leaf](objx, port)
        if port_obj is not None:
            d = port_obj.r_get(leaf)
            if d is None:
                port_obj.s_new_key(leaf, dict())
                d = port_obj.r_get(leaf)
            for k, v in port.items():
                d.update({k: v})
Ejemplo n.º 20
0
def port_obj_for_wwn(obj, wwn):
    """Returns the port object for a logged in WWN

    :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 index: Port index
    :type index: int
    :return: Port object. None if not found
    :rtype: brcddb.classes.port.PortObj, None
    """
    if not brcddb_util.is_wwn(wwn):
        return None
    for port_obj in obj.r_port_objects():
        for port_wwn in brcddb_util.convert_to_list(
                port_obj.r_get('fibrechannel/neighbor/wwn')):
            if port_wwn is not None and port_wwn == wwn:
                return port_obj

    return None  # If we got this far, we didn't find it.
Ejemplo n.º 21
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)
Ejemplo n.º 22
0
def port_best_desc(port_obj):
    """Finds the first descriptor for what's attached to the port in this order:
        1   If E-Port, the upstream switch & port
        2   FDMI  Node descriptor
        3   FDMI Port descriptor
        4   Name server node descriptor
        5   Name server port descriptor

    :param port_obj: Port Object
    :type port_obj: brcddb.classes.port.PortObj
    :return: desc
    :rtype: str
    """
    if port_obj is None:
        return 'Unknown'
    wwn_list = brcddb_util.convert_to_list(
        port_obj.r_get('fibrechannel/neighbor/wwn'))
    if len(wwn_list) == 0:
        return ''

    # Try E-Port
    fab_obj = port_obj.r_fabric_obj()
    if fab_obj is None:
        return ''
    if port_obj.c_login_type() in ('E-Port', 'AE-Port'):
        brcddb_util.build_login_port_map(fab_obj.r_project_obj())
        pobj = fab_obj.r_get('_port_map').get(wwn_list[0])
        return '' if pobj is None else brcddb_switch.best_switch_name(
            pobj.r_switch_obj()) + ' port ' + pobj.r_obj_key()

    # Try Node, then port
    login_obj = fab_obj.r_login_obj(wwn_list[0])
    if login_obj is None:
        return ''
    buf = brcddb_login.login_best_node_desc(login_obj)
    if len(buf) > 2:
        return buf
    return brcddb_login.login_best_port_desc(login_obj)
Ejemplo n.º 23
0
def match_test(obj_list, test_obj, logic=None):
    """Performs a pre-defined complex test using match() and test_threshold.

    Any key collected from the API and put into an object can be evaluated for an exact match, a regex match, a regex
    search, and wild card match on str value types. Numbers can use comparitive operators >, <, >=, <=, !=, and ==.
    Types bool can only be evaluated for True or False.

    :param obj_list: A list of dictionaries or brcddb objects to search
    :type obj_list: dict, list, tuple
    :param test_obj: Pre-defined test. See comments below.
    :type test_obj: dict, list, tuple
    :param logic: Logic to apply to items in 'l'. May be 'and', 'or', 'nand', or 'nor'. If None, default is 'and'
    :type logic: str or None
    :return: Subset of obj_list whose objects meet the test criteria
    :rtype: list
    """
    # test_obj (pre-defined test) dict or list/tuple of dict that defines the logical tests to perform:
    #
    # 'skip'    Optional. Bool. Default is False. If True, effectively comments out the test case.
    #
    # 'l'       Optional. Same as test_obj. When specified, iteratively calls match_test(). This is useful for complex
    #           matches. You can nest these as deep as Python allows which is much deeper than any useful search you can
    #           dream of.
    #
    # 'k'       Required. str. This is the key for the value in the object from the obj_list to test for the match to
    #           what is specifed in 'v'
    #
    # 'v'       Required if 's' not specified. (str, int, float, bool). This is the value to compare against. The value
    #           type must be consistent with the type of value associated with obj.get('k').
    #
    # 's'       Optional. str. NOT YET IMPLEMENTED. Same as 'v' except this is a referenced value. The most common use
    #           is to compare against MAPS policies. Only 'v' or 's' is compared. If both are present, 's' is ignored.
    #
    # 't'       Required. str. This is the type of comparison (test) to make. Comparison types may be:
    #               int types: '>', '<', '<=', '>=', '!=', '==', and, for sloppy programmers, '='.
    #               str types:  'exact'     exact match
    #                           'wild'      Uses Pythons standard fnmatch library for wild card matching.
    #                           'regex-m'   Uses Pythons standard re library (re) for regex matching
    #                           'regex-s'   Uses Pythons standard re library (re) for regex searching
    #                           'bool'      True/False test
    # 'i'       Optional. Bool. Only relevant to str matching. Possible values are:
    #               True - ignore case.
    #               False - Default. match case.
    #
    # 'logic'   Optionial. Logic to apply to items in 'l'. Although the logic is moot for single items in 'l', 'and' is
    #           the most effecient to process the logic. Defined as follows:
    #           'and'   Default. All tests specified in 'l' must evaluate True
    #           'or'    Any test specified in 'l' must evaluate True
    #           'nand'  Opposite of 'and'.
    #           'nor'   Opposfite of 'or'

    w_list = list() if obj_list is None else [obj_list] if not isinstance(obj_list, (list, tuple)) else obj_list
    lg = 'and' if logic is None else logic
    t_list = brcddb_util.convert_to_list(test_obj)  # This is the list of objects to test against
    o_list = list()  # This is the NAND and OR list when 'nand' or 'or' logic is specified

    for t_obj in t_list:
        m_list = list()
        if len(w_list) == 0:
            break
        if 'l' in t_obj:
            m_list = match_test(w_list, t_obj.get('l'), t_obj.get('logic'))
        if 'k' in t_obj and 't' in t_obj and 'v' in t_obj:
            ic = False if t_obj.get('i') is None else t_obj.get('i')

            # Perform the test and put results in m_list
            if t_obj.get('t') in ('bool', 'wild', 'regex-m', 'regex-s', 'exact'):
                m_list = match(w_list, t_obj.get('k'), t_obj.get('v'), ic, t_obj.get('t'))
            elif t_obj.get('t') in ('>', '<', '<=', '>=', '==', '=', '!='):
                m_list = test_threshold(w_list, t_obj.get('k'), t_obj.get('t'), t_obj.get('v'))
            else:
                brcdapi_log.exception('Invalid search key, ' + t_obj.get('t'), True)
                return list()

        # Apply the test logic
        if lg == 'and':
            # All tests must evaluate True so modify w_list to only contain objects for tests that evaluated True
            w_list = m_list
        elif lg == 'nand':
            w_list = [obj for obj in w_list if obj not in m_list]
        elif lg == 'or':
            # Any test that evaluates True means the object should be included in the return list and there is no
            # point in performing additional tests so remove it from w_list.
            o_list.extend(m_list)
        elif lg == 'nor':
            # All tests must evaluate False so remove any test that evaluates True from w_list.
            w_list = [obj for obj in w_list if obj not in m_list]
        else:
            brcdapi_log.exception('Invalid logic, ' + lg, True)
            return list()

    if lg == 'or':
    # if lg == 'nand' or lg == 'or':
        w_list = o_list

    return list(w_list)
Ejemplo n.º 24
0
def match(search_objects, search_key, in_search_term, ignore_case=False, stype='exact'):
    """Performs a regex match/search or wild card search in dict or brcddb class object(s). If search_key is a list of
        more than one, OR logic applies. Performs an iteritive search on any list, tuple, dict, or brcddb object found
        after the last search key. If a list is encountered, an iteritive search is performed on the list. If the search
        keys have not been exhausted, then the remaining search keys are applied to the iteritive searches.
        **WARNING:** Circular references will result in Python stack overflow issues. Since all brcddb objects have a
        link back to the main project object, at least one key must be used to avoid this circular reference

    :param search_objects: Required. These are the objects to search in. Usually a list
    :type search_objects: str, tuple, list, dict or any brcddb object
    :param search_key: Required. The key, or list of keys, in the objects in search_objects to match against. OR logic
    :type search_key: str, list, tuple
    :param in_search_term: Required. This is what to look for.
    :type in_search_term: str, list, tuple, bool
    :param ignore_case: Default is False. If True, ignores case in search_term. Not that keys are always case sensitive
    :type ignore_case: bool
    :param stype: Valid options are: 'exact', 'wild', 'regex-m', or 'regex-s' ('-m' for match and -s for search)
    :param stype: str
    :return return_list:  List of matching the search criteria - subset of search_objects
    :rtype: list
    """

    # Summary of wild card strings (search the web for 'python fnmatch.fnmatch' for additional informaiton):
    # *         matches everything
    # ?         matches any single character
    # [seq]     matches any character in seq
    # [!seq]    matches any character not in seq

    # Summary of ReGex strings (search the web for 'regex' for additional information:
    # abc…          Letters
    # 123…          Digits
    # \d            Any Digit
    # \D            Any Non - digit character
    # .             Any Character
    # \.            Period
    # [abc]         Only a, b, or c
    # [ ^ abc]      Not a, b, nor c
    # [a - z]       Characters a to z
    # [0 - 9]       Numbers 0 to 9
    # \w            Any Alphanumeric character
    # \W            Any Non - alphanumeric character
    # {m}           m Repetitions
    # {m, n}        m to n Repetitions
    # *             Zero or more repetitions
    # +             One or more repetitions
    # ?             Optional character
    # \s            Any Whitespace
    # \S            Any Non - whitespace character
    # ^ …$          Starts and ends
    # (…)           Capture Group
    # (a(bc))       Capture Sub - group
    # (.*)          Capture all
    # (abc | def )  Matches abc or def

    # Programmers tip: The Python re and fmatch are quite effecient. In order to search for anything in any data
    # structure, this method does not make use of list comprehensions. If you need something more effecient, create
    # a seperate method for a more specific purpose and leave this as a general purpose search and match method.

    return_list = list()
    search_term = in_search_term.lower() if ignore_case else in_search_term

    # Validate user input
    if not isinstance(search_term, (str, list, tuple, bool)):
        brcdapi_log.exception('Invalid search_term type: ' + str(type(search_term)), True)
        return return_list
    if isinstance(stype, str):
        if stype in ('regex-m', 'regex-s'):
            regex_obj = re.compile(search_term, re.IGNORECASE) if ignore_case else re.compile(search_term)
        elif stype not in ('wild', 'exact', 'bool'):
            brcdapi_log.exception('Invalid search type: ' + stype, True)
            return return_list
    else:
        brcdapi_log.exception('Search type must be str. Search type is: ' + str(type(stype)),
                              True)
        return return_list

    search_key_list = brcddb_util.convert_to_list(search_key)
    obj_list = brcddb_util.convert_to_list(search_objects)
    for obj in obj_list:
        for sk in search_key_list:
            sub_obj = brcddb_util.get_key_val(obj, sk)
            if sub_obj is not None:
                if isinstance(sub_obj, dict):
                    if len(match(sub_obj, list(sub_obj.keys()), search_term, ignore_case, stype)) > 0:
                        return_list.append(obj)
                elif isinstance(sub_obj, (str, list, tuple)):
                    for buf in brcddb_util.convert_to_list(sub_obj):  # Any match within that list is a match
                        if isinstance(buf, str):
                            test_buf = buf.lower() if ignore_case else buf
                            if stype == 'regex-m':
                                if regex_obj.match(test_buf):
                                    return_list.append(obj)
                                    break
                            elif stype == 'regex-s':
                                if regex_obj.search(test_buf):
                                    return_list.append(obj)
                                    break
                            elif stype == 'exact':
                                if search_term == test_buf:
                                    return_list.append(obj)
                                    break
                            elif stype == 'wild':
                                if fnmatch.fnmatch(test_buf, search_term):
                                    return_list.append(obj)
                                    break
                            elif stype == 'bool':
                                if isinstance(buf, bool) and isinstance(search_term, bool):
                                    if bool({search_term: buf}):
                                        return_list.append(obj)
                                        break
                        elif isinstance(buf, dict):
                            if len(match([buf.get(k) for k in buf], None, search_term, ignore_case, stype)) > 0:
                                return_list.append(obj)
                                break
                        elif isinstance(buf, (list, tuple)):
                            if len(match(buf, None, search_term, ignore_case, stype)) > 0:
                                return_list.append(obj)
                                break
                elif isinstance(sub_obj, bool):
                    if (search_term and sub_obj) or (not search_term and not sub_obj):
                        return_list.append(obj)
                        break

    if len(return_list) > 0 and 'brcddb' in str(type(return_list[0])):
        return brcddb_util.remove_duplicates(return_list)
    else:
        return return_list
Ejemplo n.º 25
0
def _fabric_obj(obj):
    """Returns a list of fabric objects associated with obj. See _obj_self() for parameter detail."""
    try:
        return obj.r_fabric_objects()
    except:
        return brcddb_util.convert_to_list(obj.r_fabric_obj())
Ejemplo n.º 26
0
def _project_obj(obj):
    """Returns the project object associated with obj in a list. See _obj_self() for parameter detail."""
    return brcddb_util.convert_to_list(obj.r_project_obj())
Ejemplo n.º 27
0
def _login_obj_for_fdmi(obj):
    """Returns a the switch object in a list for an FDMI node or port obj. See _obj_self() for parameter detail."""
    fab_obj = obj.r_fabric_obj()
    if fab_obj is None:
        return list()
    return brcddb_util.convert_to_list(fab_obj.r_login_obj(obj.r_obj_key()))
Ejemplo n.º 28
0
def _zonecfg_obj(obj):
    """Returns a list of zone configuration objects associated with obj. See _obj_self() for parameter detail."""
    try:
        return obj.r_zonecfg_objects()
    except:
        return brcddb_util.convert_to_list(obj.r_zonecfg_obj())
Ejemplo n.º 29
0
def _fabric_ns_case(objx, obj, uri):
    fab_obj = objx.r_fabric_obj()
    for ns_obj in brcddb_util.convert_to_list(obj.get('fibrechannel-name-server')):
        login_obj = fab_obj.s_add_login(ns_obj.get('port-name'))
        _update_brcddb_obj(login_obj, ns_obj, uri)
Ejemplo n.º 30
0
def _fabric_fdmi_port_case(objx, obj, uri):
    fab_obj = objx.r_fabric_obj()
    for obj in brcddb_util.convert_to_list(obj.get('port')):
        _update_brcddb_obj(fab_obj.s_add_fdmi_port(obj.get('port-name')), obj, uri)