Beispiel #1
0
def _login_obj_for_alias(obj):
    """Returns a list of login objects associated with an alias obj. See _obj_self() for parameter detail."""
    fab_obj = obj.r_fabric_obj()
    return list() if fab_obj is None else [
        fab_obj.r_login_obj(m) for m in obj.r_members()
        if brcddb_util.is_wwn(m)
    ]
Beispiel #2
0
def _fdmi_port_obj_for_alias(obj):
    """Returns a list of FDMI port objects associated with an alias obj. See _obj_self() for parameter detail."""
    rl = list()
    fab_obj = obj.r_fabric_obj()
    if fab_obj is not None:
        for mem in obj.r_members():
            if brcddb_util.is_wwn(mem):
                rl.append(fab_obj.r_fdmi_port_obj(mem))
    return [fdmi_port_obj for fdmi_port_obj in rl if fdmi_port_obj is not None]
Beispiel #3
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)
Beispiel #4
0
def _port_obj_for_alias(obj):
    """Returns a list of login objects associated with an alias obj. See _obj_self() for parameter detail."""
    fab_obj = obj.r_fabric_obj()
    if fab_obj is None:
        return list()
    rl = [
        fab_obj.r_port_obj_for_wwn(mem) for mem in obj.r_members()
        if brcddb_util.is_wwn(mem)
    ]
    rl.extend([
        fab_obj.r_port_object_for_di(mem) for mem in obj.r_members()
        if brcddb_util.is_di(mem)
    ])
    return [
        mem for mem in rl if mem is not None
    ]  # I don't think mem can ever be None but I'm not fixing working code
Beispiel #5
0
def _login_for_zone(obj):
    """Returns a list of login objects for a zone. See _obj_self() for parameter detail."""
    rl = list()
    fab_obj = obj.r_fabric_obj()
    if fab_obj is not None:
        for mem in obj.r_members() + obj.r_pmembers():
            if brcddb_util.is_wwn(mem):
                rl.append(fab_obj.r_login_obj(mem))
            elif brcddb_util.is_di(mem):
                port_obj = fab_obj.r_port_object_for_di(mem)
                if port_obj is not None:
                    rl.extend(port_obj.r_login_objects())
            else:  # Assume it's an alias
                zone_obj = fab_obj.r_zone_obj(mem)
                if zone_obj is not None:
                    rl.extend(_login_obj_for_alias(zone_obj))
    return [mem for mem in rl if mem is not None]
Beispiel #6
0
def _ports_for_zone_obj(obj):
    """Returns a list of port objects associated with a zone object. See _obj_self() for parameter detail."""
    fab_obj = obj.r_fabric_obj()
    if fab_obj is None:
        return list()
    rl = list()
    for mem in obj.r_members() + obj.r_pmembers():
        if brcddb_util.is_wwn(mem):
            rl.append(fab_obj.r_port_obj_for_wwn(mem))
        elif brcddb_util.is_di(mem):
            rl.append(fab_obj.r_port_object_for_di(mem))
        else:  # It must be an alias
            alias_obj = fab_obj.r_alias_obj(mem)
            if alias_obj is not None:
                rl.extend(_port_obj_for_alias(alias_obj))
    return [
        mem for mem in rl if mem is not None
    ]  # I don't think mem can ever be None but I'm not fixing working code
Beispiel #7
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.
Beispiel #8
0
def _alias_for_zone(obj):
    """Returns a list of alias objects for a zone. See _obj_self() for parameter detail."""
    return [
        mem for mem in obj.r_members() + obj.r_pmembers()
        if not brcddb_util.is_wwn(mem) and not brcddb_util.is_di(mem)
    ]
Beispiel #9
0
def zone_analysis(fab_obj):
    """Analyzes zoning. Finds where all members are. Adds an alert if any of the following conditions exist:
    * Calls alias_analysis() - multiple identical aliases, unused alias, and alias with no members
    * Calls zone_by_target() - Checks for speed mismatches, potential slow drain device
    * Zone has less than 2 members
    * Peer zone doesn't have at least one principal and one regular member
    * Mixed d,i and WWN zones
    * Zone member in another fabric
    * Zone is not used in any zone configuration
    * Effective zone doesn't match defined zone
    * Zone member not found
    * Base port (HBA) of NPIV logins is in a zone
    * Maximum number of devices zoned to a device. See brcddb.app_data.bp_tables.MAX_ZONE_PARTICIPATION
    * Mix of WWN and alias in the same zone
    * Peer zone property member in zone
    * Duplicate aliases
    * Calls check_ficon_zoning() - Ensures all CHPID paths are in the same zone as the CHPID

    :param fab_obj: brcddb fabric object
    :type fab_obj: brcddb.classes.fabric.FabricObj
    """
    global _CHECK_ZONE_MISMATCH, _CHECK_PEER_PROPERTY

    # $ToDo - Break this up into multiple methods or review to shorten. This is way too long
    _WWN_MEM = 0b1  # The member was entered as a WWN or d,i, not an alias
    _WWN_IN_ZONE = _WWN_MEM << 1  # A zone contains a WWN member
    _ALIAS_IN_ZONE = _WWN_IN_ZONE << 1  # A zone contains an alias member
    _DI_IN_ZONE = _ALIAS_IN_ZONE << 1  # The zone contains a d,i member
    _IN_DEFINED_ZONECFG = _DI_IN_ZONE << 1  # Zone found in defined zone
    _ZONE_MISMATCH = _IN_DEFINED_ZONECFG << 1  # The effective zone does not match the defined zone

    # We'll need to figure out where all the logins are so build a table to cross-reference all the neighbor WWNs
    brcddb_util.build_login_port_map(fab_obj.r_project_obj())
    other_fabrics = fab_obj.r_project_obj().r_fabric_objects()
    other_fabrics.remove(fab_obj)
    flag = 0b0

    # Zone analysis
    for zone_obj in fab_obj.r_zone_objects():
        pmem_list = list(
        )  # pmem_list and nmem_list was an after thought to save time resolving them again in the
        nmem_list = list(
        )  # effective zone to defined zone comparison. These are the aliases converted to WWN
        flag &= ~(_IN_DEFINED_ZONECFG | _WWN_IN_ZONE | _ALIAS_IN_ZONE
                  | _DI_IN_ZONE)

        # Is the zone used in any configuration?
        if len(zone_obj.r_zone_configurations()) == 0:
            zone_obj.s_add_alert(al.AlertTable.alertTbl,
                                 al.ALERT_NUM.ZONE_NOT_USED, None, None, None)

        # Check for mixed d,i & WWN zones and make sure the member is in the fabric
        for i in range(
                0, 2):  # 0 - Get the members, 1 - get the principal members
            mem_list = list()
            zmem_list = zone_obj.r_members(
            ) if i == 0 else zone_obj.r_pmembers()
            for zmem in zmem_list:
                if brcddb_util.is_wwn(zmem, full_check=False):
                    flag |= _WWN_MEM
                    mem_list.append(zmem)
                    if len(fab_obj.r_alias_for_wwn(zmem)) > 0:
                        # An alias was defined for this WWN, but the WWN was used to define the zone
                        zone_obj.s_add_alert(
                            al.AlertTable.alertTbl,
                            al.ALERT_NUM.ZONE_ALIAS_USE, None, zmem,
                            ', '.join(fab_obj.r_alias_for_wwn(zmem)))
                elif brcddb_util.is_di(zmem):
                    mem_list.append(zmem)
                else:  # It must be an alias
                    flag |= _ALIAS_IN_ZONE
                    a_obj = fab_obj.r_alias_obj(zmem)
                    if a_obj is None:
                        zone_obj.s_add_alert(al.AlertTable.alertTbl,
                                             al.ALERT_NUM.ZONE_UNDEFINED_ALIAS,
                                             None, zmem, zone_obj.r_obj_key())
                    else:
                        mem_list.extend(a_obj.r_members())

            for mem in mem_list:
                if i == 0:
                    nmem_list.append(mem)
                else:
                    pmem_list.append(mem)

                if brcddb_util.is_di(mem):
                    flag |= _DI_IN_ZONE  # It's a d,i member - typically FICON
                    t = mem.split(',')

                    # Is it in the fabric?
                    found_flag = False
                    for switch_obj in fab_obj.r_switch_objects():
                        if isinstance(
                                switch_obj.r_get('domain_id'),
                                int) and switch_obj.r_get('domain_id') == t[0]:
                            found_flag = True
                            break
                    if not found_flag:
                        zone_obj.s_add_alert(al.AlertTable.alertTbl,
                                             al.ALERT_NUM.ZONE_NOT_FOUND, None,
                                             mem)

                elif brcddb_util.is_wwn(mem, full_check=False):
                    flag |= _WWN_IN_ZONE
                    if _CHECK_PEER_PROPERTY and not brcddb_util.is_wwn(
                            zmem, full_check=True):
                        zone_obj.s_add_alert(al.AlertTable.alertTbl,
                                             al.ALERT_NUM.ZONE_PEER_PROPERTY,
                                             None, zmem, None)
                    # Is the member in this fabric?
                    if fab_obj.r_port_obj(mem) is None:
                        # Is it in a different fabric?
                        port_list = brcddb_util.global_port_list(
                            other_fabrics, mem)
                        if len(port_list) > 0:
                            zone_obj.s_add_alert(
                                al.AlertTable.alertTbl,
                                al.ALERT_NUM.ZONE_DIFF_FABRIC, None, mem,
                                best_fab_name(port_list[0].r_fabric_obj()))
                        else:
                            zone_obj.s_add_alert(al.AlertTable.alertTbl,
                                                 al.ALERT_NUM.ZONE_NOT_FOUND,
                                                 None, mem)
                else:
                    brcdapi.log.exception(
                        'Zone member type undetermined: ' + str(mem), True)

        # Do all the zone membership count checks
        if zone_obj.r_is_peer():  # It's a peer zone
            # Make sure there is at least one member and one principal member
            if len(pmem_list) == 0:
                zone_obj.s_add_alert(al.AlertTable.alertTbl,
                                     al.ALERT_NUM.ZONE_PEER_NO_PMEM)
            if len(nmem_list) == 0:
                zone_obj.s_add_alert(al.AlertTable.alertTbl,
                                     al.ALERT_NUM.ZONE_PEER_NO_NMEM)
        else:  # It's an old style zone (not a peer zone)
            # Make sure there are at least 2 members
            if len(nmem_list) == 0:
                zone_obj.s_add_alert(al.AlertTable.alertTbl,
                                     al.ALERT_NUM.ZONE_NO_MEMBERS)
            elif len(nmem_list) == 1:
                zone_obj.s_add_alert(al.AlertTable.alertTbl,
                                     al.ALERT_NUM.ZONE_ONE_MEMBER)
        if flag and ():
            zone_obj.s_add_alert(al.AlertTable.alertTbl,
                                 al.ALERT_NUM.ZONE_MIXED)

        # Check for single initiator zoning.
        elist = list()
        if zone_obj.r_is_peer():
            for wwn in pmem_list:
                login_obj = fab_obj.r_login_obj(wwn)
                if login_obj is not None:
                    if login_obj.r_get(
                            'brocade-name-server/name-server-device-type'
                    ) == 'Initiator':
                        elist.append(wwn)
                        break
            for wwn in nmem_list:
                login_obj = fab_obj.r_login_obj(wwn)
                if login_obj is not None:
                    if login_obj.r_get(
                            'brocade-name-server/name-server-device-type'
                    ) == 'Initiator':
                        elist.append(wwn)
                        break
        else:
            for wwn in nmem_list:
                login_obj = fab_obj.r_login_obj(wwn)
                if login_obj is not None:
                    if login_obj.r_get(
                            'brocade-name-server/name-server-device-type'
                    ) == 'Initiator':
                        elist.append(wwn)
        if len(elist) > 1:
            zone_obj.s_add_alert(al.AlertTable.alertTbl,
                                 al.ALERT_NUM.ZONE_MULTI_INITIATOR, None,
                                 ', '.join(elist))

        # Check for mixed zone members
        if flag & _DI_IN_ZONE and flag & _WWN_IN_ZONE:
            zone_obj.s_add_alert(al.AlertTable.alertTbl,
                                 al.ALERT_NUM.ZONE_MIXED)
        if flag & _WWN_MEM and flag & _ALIAS_IN_ZONE:
            zone_obj.s_add_alert(al.AlertTable.alertTbl,
                                 al.ALERT_NUM.ZONE_WWN_ALIAS)

        # Make sure the defined zone matches the effective zone
        if _CHECK_ZONE_MISMATCH:
            eff_zone_obj = fab_obj.r_eff_zone_obj(zone_obj.r_obj_key())
            if eff_zone_obj is not None:
                zone_obj.s_or_flags(brcddb_common.zone_flag_effective)
                if set(eff_zone_obj.r_pmembers()) != set(pmem_list):
                    zone_obj.s_add_alert(al.AlertTable.alertTbl,
                                         al.ALERT_NUM.ZONE_MISMATCH)
                    flag |= _ZONE_MISMATCH
                if set(eff_zone_obj.r_members()) != set(nmem_list):
                    zone_obj.s_add_alert(al.AlertTable.alertTbl,
                                         al.ALERT_NUM.ZONE_MISMATCH)
                    flag |= _ZONE_MISMATCH

    if flag & _ZONE_MISMATCH and _CHECK_ZONE_MISMATCH:
        try:
            fab_obj.r_defined_eff_zonecfg_obj().s_add_alert(
                al.AlertTable.alertTbl, al.ALERT_NUM.ZONE_MISMATCH)
        except:
            pass  # Defined configuration was deleted - I'm not certian FOS allows it so this is just to be sure

    for login_obj in fab_obj.r_login_objects():
        wwn = login_obj.r_obj_key()

        # Make sure that all logins are zoned.
        if len(fab_obj.r_zones_for_wwn(wwn)) > 0:
            if wwn in fab_obj.r_base_logins():
                login_obj.s_add_alert(al.AlertTable.alertTbl,
                                      al.ALERT_NUM.LOGIN_BASE_ZONED)
        elif wwn not in fab_obj.r_base_logins():
            login_obj.s_add_alert(al.AlertTable.alertTbl,
                                  al.ALERT_NUM.LOGIN_NOT_ZONED)

        # Check zone participation
        port_obj = login_obj.r_port_obj()
        buf = login_obj.r_get('port-properties')
        if buf is not None and buf in special_login:
            login_obj.s_add_alert(al.AlertTable.alertTbl, special_login[buf])
            continue

    # Alias analysis, zone speed analysis, and FICON analysis
    alias_analysis(fab_obj)
    zone_by_target(fab_obj)
    check_ficon_zoning(fab_obj)