def _add_data_to_db(proj_obj): """Captures data from switch and adds it to the project object :param proj_obj: The project object :type proj_obj: brcddb.classes.project.ProjectObj """ for switch_obj in proj_obj.r_switch_objects(): switch_wwn = switch_obj.r_obj_key() for port_obj in switch_obj.r_port_objects(): port_num = port_obj.r_obj_key() # brcddb_port.port_best_desc(port_obj) returns a description of what's attached to the port port_desc = brcddb_port.port_best_desc(port_obj) port_desc = '(nothing attached)' if port_desc == '' else '(' + port_desc + ')' port_desc = port_obj.r_obj_key() + ' ' + port_desc _db_add(switch_wwn, port_num, '_description', port_desc) # Now add all the individual port configuration parameters, statistics, and SFP info. for kpi in ('fibrechannel', 'fibrechannel-statistics', 'media-rdp'): d = port_obj.r_get(kpi) if isinstance(d, dict): # It could be None if no ports or no SFPs in the logical switch for k, v in d.items(): # I think 'neighbor' is the only type that fails the test below. if isinstance(v, (str, int, float)): # Note that bool is a subtype of int. _db_add(switch_wwn, port_num, k, v)
def _add_ports(wb, tc_page, t_content, start_i, switch_obj): """Add the individual port pages to the workbook :param wb: Excel workbook object :type wb: Workbook object :param tc_page: Name of table of contents page :type tc_page: str :param t_content: Table of contents :type t_content: list :param start_i: Starting index (where first port goes) :param switch_obj: Base switch object :type switch_obj: brcddb.classes.switch.SwitchObj :rtype: None """ global _sheet_map, _port_stats sheet_index = start_i proj_obj = switch_obj.r_project_obj() switch_obj_l = [ proj_obj.r_switch_obj(wwn) for wwn in proj_obj.r_get('switch_list') ] if _DEBUG: switch_obj_l = switch_obj_l[:6] for port_obj in brcddb_util.sort_ports(switch_obj.r_port_objects()): # Create the port page port_num = port_obj.r_obj_key() sname = port_num.replace('/', '_') brcdapi_log.log('Processing port: ' + port_num, True) port_list = [obj.r_port_obj(port_num) for obj in switch_obj_l] sheet = report_port.port_page(wb, tc_page, sname, sheet_index, 'Port: ' + port_num, port_list, _port_stats, rt.Port.port_display_tbl, False) _sheet_map.update({port_num: sheet}) # Add the port page to the table of contents t_content.append( dict(new_row=False, font='link', align='wrap', hyper='#' + sname + '!A1', disp=port_num)) t_content.append( dict(new_row=False, font='std', align='wrap', disp=port_obj.r_port_name())) t_content.append( dict(new_row=False, font='std', align='wrap', disp=port_obj.c_login_type())) v = port_obj.r_get('fibrechannel/operational-status') try: buf = brcddb_common.port_conversion_tbl[ 'fibrechannel/operational-status'][v] except KeyError: buf = 'Unknown' t_content.append( dict(new_row=False, font='std', align='wrap', disp=buf)) t_content.append( dict(font='std', align='wrap', disp=brcddb_port.port_best_desc(port_obj))) sheet_index += 1
def performance_dashboard(wb, tc, sheet_name, sheet_i, sheet_title, content): """Creates a dashboard worksheet for the Excel report. :param wb: Workbook object :type wb: class :param tc: Table of context page. A link to this page is place in cell A1 :type tc: str, None :param sheet_name: Sheet (tab) name :type sheet_name: str :param sheet_i: Sheet index where page is to be placed. :type sheet_i: int :param sheet_title: Title to be displayed in large font, hdr_1, at the top of the sheet :type sheet_title: str :param content: Caller defined content. List of lists or tuples to add to the title page. For example: dashboard = collections.OrderedDict() dashboard['class-3-discards'] = {'title' : 'Top 10 C3 Discards', 'port_list' : []} dashboard['in-crc-errors'] = {'title' : 'Top 10 CRC With Good EOF', 'port_list' : []} :type content: list, tuple :rtype: None """ hdr = collections.OrderedDict() # Key is the column header and value is the width hdr['Count'] = 14 hdr['Fabric'] = 22 hdr['Switch'] = 22 hdr['Port'] = 7 hdr['Type'] = 8 hdr['Description'] = 117 - (hdr['Count'] + hdr['Switch'] + hdr['Switch'] + hdr['Port'] + hdr['Type']) # Create the worksheet, add the title, and set up the column widths sheet = wb.create_sheet(index=sheet_i, title=sheet_name) sheet.page_setup.paperSize = sheet.PAPERSIZE_LETTER sheet.page_setup.orientation = sheet.ORIENTATION_LANDSCAPE col = 1 row = 1 for k, v in hdr.items(): sheet.column_dimensions[xl.get_column_letter(col)].width = v col += 1 max_col = col - 1 col = 1 if isinstance(tc, str): cell = xl.get_column_letter(col) + str(row) sheet[cell].hyperlink = '#' + tc + '!A1' sheet[cell].font = report_fonts.font_type('link') sheet[cell] = 'Contents' col += 1 cell = xl.get_column_letter(col) + str(row) sheet.merge_cells(start_row=row, start_column=col, end_row=row, end_column=max_col) sheet[cell].font = report_fonts.font_type('hdr_1') sheet[cell] = sheet_title row += 2 # Now add each dashboard item border = report_fonts.border_type('thin') font = report_fonts.font_type('std') alignment = report_fonts.align_type('wrap') for statistic in content.keys(): db = content.get(statistic) col = 1 # The individual dashboard title sheet.merge_cells(start_row=row, start_column=1, end_row=row, end_column=max_col) for i in range(col, max_col + 1): cell = xl.get_column_letter(i) + str(row) sheet[cell].border = border cell = xl.get_column_letter(col) + str(row) sheet[cell].font = report_fonts.font_type('hdr_2') sheet[cell].fill = report_fonts.fill_type('lightblue') sheet[cell] = db.get('title') col = 1 row += 1 # Now the individual dashboard headers for k in hdr.keys(): cell = xl.get_column_letter(col) + str(row) sheet[cell].border = border sheet[cell].font = report_fonts.font_type('bold') sheet[cell] = k col += 1 # Now add the dashboard content port_list = db.get('port_list') if len(port_list) == 0: row += 1 for port_obj in port_list: # Statistic col = 1 cell = xl.get_column_letter(col) + str(row) sheet[cell].border = border sheet[cell].font = font sheet[cell].alignment = alignment sheet[cell] = port_obj.r_get('fibrechannel-statistics/' + statistic) col += 1 # Fabric cell = xl.get_column_letter(col) + str(row) sheet[cell].border = border sheet[cell].font = font sheet[cell].alignment = alignment sheet[cell] = brcddb_fabric.best_fab_name( port_obj.r_switch_obj().r_fabric_obj()) col += 1 # Switch cell = xl.get_column_letter(col) + str(row) sheet[cell].border = border sheet[cell].font = font sheet[cell].alignment = alignment sheet[cell] = brcddb_switch.best_switch_name( port_obj.r_switch_obj()) col += 1 # Port cell = xl.get_column_letter(col) + str(row) sheet[cell].border = border sheet[cell].font = font sheet[cell].alignment = alignment sheet[cell] = port_obj.r_obj_key() col += 1 # Port Type cell = xl.get_column_letter(col) + str(row) sheet[cell].border = border sheet[cell].font = font sheet[cell].alignment = alignment sheet[cell] = port_obj.c_login_type() col += 1 # Description - Try FDMI first, then name server cell = xl.get_column_letter(col) + str(row) sheet[cell].border = border sheet[cell].font = font sheet[cell].alignment = alignment sheet[cell] = brcddb_port.port_best_desc(port_obj) row += 1 row += 1
def p_port_desc_case(port_obj, k, wwn): return brcddb_port.port_best_desc(port_obj)
def _add_remove_ports(session, switch_obj, switch_d, force, echo): """Add and remove ports from a logical switch :param session: Session object, or list of session objects, returned from brcdapi.fos_auth.login() :type session: dict :param switch_obj: Chassis object :type switch_obj: brcddb.classes.switch.SwitchObj :param switch_d: Switch object as returned from report_utils.parse_switch_file() :type switch_d: dict :param force: Move the port whether it's online or not. :type force: bool :param echo: If True, echo switch configuration details to STD_OUT :type echo: bool """ # Load common use stuff into local variables ec = brcddb_common.EXIT_STATUS_OK chassis_obj = switch_obj.r_chassis_obj() fid = switch_d['fid'] # Figure out what ports to add or remove _ports_to_move(switch_obj, switch_d, force) # Report any ports that could not be moved. ml = list() for d in [ dict(port_l=switch_d['not_found_ports'], m='were not found:'), dict(port_l=switch_d['online_ports'], m='are online:') ]: if len(d['port_l']) > 0: ml.append('The following ports were not moved because they ' + d['m']) for port in brcddb_util.sp_port_sort(d['port_l']): port_obj = chassis_obj.r_port_obj(port) if port_obj is not None: ml.append( brcddb_port.best_port_name(port_obj, True) + ', ' + brcddb_port.port_best_desc(port_obj)) else: ml.append(port) ec = brcddb_common.EXIT_STATUS_ERROR if len(ml) > 0: brcdapi_log.log(ml, True) default_fid = chassis_obj.r_default_switch_fid() # $ToDo brcdapi_switch.add_ports doesn't remove GE ports # Remove ports obj = brcdapi_switch.add_ports(session, default_fid, fid, switch_d['remove_ports'], None, echo) if fos_auth.is_error(obj): ml = [ 'Error moving ports from FID ' + str('fid') + ' to ' + str(default_fid), fos_auth.formatted_error_msg(obj) ] brcdapi_log.log(ml, True) ec = brcddb_common.EXIT_STATUS_ERROR # Add ports for from_fid, port_d in switch_d['add_ports'].items(): obj = brcdapi_switch.add_ports(session, fid, from_fid, port_d['ports'], port_d['ge_ports'], echo) if fos_auth.is_error(obj): ml = [ 'Error moving ports from FID ' + from_fid + ' to ' + str(fid), fos_auth.formatted_error_msg(obj) ] brcdapi_log.log(ml, True) ec = brcddb_common.EXIT_STATUS_ERROR return ec
def _ports_to_move(switch_obj, switch_d, force): """Determine what ports are where and where they should be moved to and add the following to switch_d +-------------------+-------------------------------------------------------------------------------------------| | Key | | +===================+===========================================================================================| | not_found_ports | List of ports in s/p notation that should have been added or removed but the port does | | | not exist in the chassis. | +-------------------+-------------------------------------------------------------------------------------------| | online_ports | List of ports in s/p notation that were not moved because they were online | +-------------------+-------------------------------------------------------------------------------------------| | remove_ports | List of ports in s/p notation that need to be removed from the switch | +-------------------+-------------------------------------------------------------------------------------------| | add_ports | Dictionary: key is from_fid-. Value is dict - key is 'ports' or 'ge_ports', value is list | +-------------------+-------------------------------------------------------------------------------------------| :param switch_obj: Switch object of the switch being configured :type switch_obj: brcddb.classes.switch.SwitchObj :param switch_d: Switch object as returned from report_utils.parse_switch_file() :type switch_d: dict :param force: Move the port whether it's online or not. :type force: bool """ switch_d.update(not_found_ports=list(), online_ports=list(), remove_ports=list(), add_ports=dict()) chassis_obj = switch_obj.r_chassis_obj() switch_pl = switch_obj.r_port_keys() for port_type in ('ports', 'ge_ports'): if port_type not in switch_d: continue # Figure out which ports to remove for port in [p for p in switch_pl if p not in switch_d[port_type]]: port_obj = chassis_obj.r_port_obj(port) if port_obj is None: switch_d['not_found_ports'].append(port) elif not force and port_obj.r_get('fibrechannel/operational-status') is not None and \ port_obj.r_get('fibrechannel/operational-status') == 2: switch_d['online_ports'].append( brcddb_port.best_port_name(port_obj, True) + ', ' + brcddb_port.port_best_desc(port_obj)) else: switch_d['remove_ports'].append(port) # Figure out what ports to add for port in [ port for port in switch_d[port_type] if port not in switch_pl ]: port_obj = chassis_obj.r_port_obj(port) if port_obj is None: switch_d['not_found_ports'].append(port) switch_d['ports'].pop(port) elif port_obj.r_get('fibrechannel/operational-status') is not None and \ port_obj.r_get('fibrechannel/operational-status') == 2: switch_d['online_ports'].append(port) switch_d['ports'].pop(port) else: fid = brcddb_switch.switch_fid(port_obj.r_switch_obj()) if fid is None: switch_d['not_found_ports'].append( port) # This should never happen switch_d['ports'].pop(port) else: if fid not in switch_d['add_ports']: switch_d['add_ports'].update( {fid: dict(ports=list(), ge_ports=list())}) switch_d['add_ports'][fid][port_type].append(port)