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) ]
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]
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)
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
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]
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
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.
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) ]
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)