def _print_disp(obj): global _working_obj_l disp = gen_util.convert_to_list(obj.get('disp')) to_print_l = list() for b_obj in _working_obj_l: for buf in disp: for d in gen_util.convert_to_list(obj.get('replace')): buf = buf.replace(d['t'], str(b_obj.r_get(d['r']))) to_print_l.append(buf) if len(to_print_l) > 0: brcdapi_log.log(to_print_l, True)
def _zoneobj_add_to_content(obj, b_obj, c_obj, content): """Same as _basic_add_to_content() but assumes the data are WWNs and converts them to aliases""" start = len(content) if obj is not None: for k, v in obj.items(): buf = str(k) for mem_d in gen_util.convert_to_list(v.get('_members')): _content_append(dict(font='std', align='wrap', disp=(buf, mem_d['b'], mem_d['c'], mem_d['r'])), content) buf = '' for mem_d in gen_util.convert_to_list(v.get('_pmembers')): _content_append(dict(font='std', align='wrap', disp=(buf, mem_d['b'], mem_d['c'], mem_d['r'])), content) buf = '' if len(content) == start: content.append(dict(merge=4, font='std', align='wrap', disp=('No changes',)))
def _print_summary(switch_d_list): """Enable switch :param switch_d_list: List of switch dictionaries :type switch_d_list: list """ ml = ['\nSummary', '_______'] for switch_d in switch_d_list: ml.append('\nFID: ' + str(switch_d.get('fid'))) ml.append( ' Switch Name: ' + brcddb_switch.best_switch_name(switch_d.get('switch_obj'), True)) ml.append(' Switch Created: ' + str(switch_d.get('created'))) try: ml.append(' Ports Added: ' + str(len(switch_d['ports'].keys()))) ml.append(' Ports Removed: ' + str(len(switch_d['remove_ports']))) ml.append(' Online Ports Not Moved: ' + str(len(switch_d['online_ports']))) ml.append(' Ports Not Found: ' + str(len(switch_d['not_found_ports']))) except: pass # We should never get here but I'm not changing working code. err_msgs = gen_util.convert_to_list(switch_d.get('err_msgs')) if len(err_msgs) > 0: ml.append(' Error Messages: ') ml.extend([' ' + buf for buf in err_msgs]) brcdapi_log.log(ml, True)
def _format_fault(obj, line_num, file_content): """Formats a fault into printable text :param obj: Dictionary as defined in Return 'changes" :type obj: dict :param line_num: Line number :type line_num: int :return: Formatted text :rtype: str """ try: buf = str(file_content[line_num]) except BaseException as e: buf = 'Unknown exception: ' + str(e) msg_l = [ '', 'Line: ' + str(line_num + 1), 'Input: ' + buf, 'changed: ' + str(obj.get('changed')), 'fail: ' + str(obj.get('fail')), 'io: ' + str(obj.get('io')), 'Status: ' + str(obj.get('status')), 'Reason: ' + str(obj.get('reason')), 'err_msg:', ] msg_l.extend( [' ' + buf for buf in gen_util.convert_to_list(obj.get('err_msg'))]) return '\n'.join(msg_l)
def _cli_via_ssh(ip, user_id, pw, fid, cmd_in): """Issues CLI commands to the switch. Note: As of FOS 9.0.0b, the ability to bind port address was not yet exposed in the API so an SSH session is created to issue CLI commands to bind the port addresses. :param ip: IP address :type ip: str :param user_id: User ID :type user_id: str :param pw: Password :type pw: str :param fid: Fabric ID :type fid: int :param cmd_in: List of CLI commands to execute :type cmd_in: list, str, None :return: Exit code :rtype: int """ ec = brcddb_common.EXIT_STATUS_OK cmd_l = gen_util.convert_to_list(cmd_in) if len(cmd_l) == 0: return ec # Login brcdapi_log.log('Attempting SSH login', True) el, ssh = brcdapi_cli.login(ip, user_id, pw) if len(el) > 0: brcdapi_log.log(el, True) return brcddb_common.EXIT_STATUS_INPUT_ERROR # Send the commands # Programmers note: I don't know why setcontext didn't work so I wrapped all the commands in fosexec. brcdapi_log.log('Sending CLI commands', True) for cmd in [ 'fosexec --fid ' + str(fid) + ' -cmd "' + buf + '"' for buf in cmd_l ]: el, ml = brcdapi_cli.send_command(ssh, cmd) all_msgs = ml + el if len(el) > 0: ec = brcddb_common.EXIT_STATUS_INPUT_ERROR brcdapi_log.log(['CLI Send: ' + cmd, 'Response: '] + all_msgs) if 'failed' in ''.join(all_msgs).lower(): brcdapi_log.log('Failed: ' + cmd, True) ec = brcddb_common.EXIT_STATUS_ERROR # Logout and close the session ssh.close() brcdapi_log.log('Logout of SSH session') return ec
def _get_ports(switch_obj, ports): """Returns a list of port objects matching the user input. :param switch_obj: Project object :type switch_obj: brcddb.classes.ProjectObj :param ports: Port or list of port types. See -p parameter in parse_args() :type ports: str :return: List of port objects (brcddb.classes.PortObj) :rtype: list """ r = list() for port in gen_util.convert_to_list(ports.split(',')): if port in _port_match: r.extend(_port_match.get(port)(switch_obj)) else: r.extend(_ports(switch_obj, port)) r.extend(r) return gen_util.remove_duplicates(r)
def _add_graphs(wb, tc_page, t_content, start_i, switch_obj, graph_list): """Add the individual port pages to the workbook Note: If there is a way to add multiple lines to a graph that aren't in neighboring columns, I haven't figured out how. So what we do here is add a worksheet that is a copy of the data from the different ports and or statistics and add it to the end. If there was just one item to plot, I wouldn't have to add another sheet but this algorithm is simple. It just creates a worksheet and adds columns as necessary, even if it's just one. :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 :param graph_list: List of graph dictionaries, see graph in _write_report() for details :type graph_list: list, tuple :return: List of warnings or errors. :rtype: list """ global _sheet_map ml = list() 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] if len(switch_obj_l) < 1: brcdapi_log('Nothing to graph. No data collected.', True) return ml sheet_index = start_i last_disp = {'font': 'std', 'align': 'wrap'} std_disp = last_disp.copy() std_disp.update({'new_row': False}) graph_num = 0 for graph_obj in graph_list: # Create the graph data page and figure out the common graphing request sname = 'graph_' + str(graph_num) brcdapi_log.log('Processing graph for: ' + sname, True) data_sheet = wb.create_sheet(title=sname + '_data') data_sheet.page_setup.paperSize = data_sheet.PAPERSIZE_LETTER data_sheet.page_setup.orientation = data_sheet.ORIENTATION_LANDSCAPE port = graph_obj.get('port') stat = graph_obj.get('stat') y_name = 'Programming error. Neither port or stat specified.' title = '' last_time = '' if port is not None: # Set up the title and chart references port_obj = switch_obj.r_port_obj(port) if port_obj is None: ml.append('Statistics for port ' + port + ' were not collected. Skipping.') continue col_ref = port port_page = '=' + port.replace('/', '_') + '!' # Find all the time stamps, reference sheets, and column references for the data reference sheet rd = dict() sheet = _sheet_map[port] data_sheet['A1'] = 'Time' # Column header for the time stamp col = 2 for stat in gen_util.convert_to_list(graph_obj.get('parms')): try: stat_ref = stat if rt.Port.port_display_tbl['fibrechannel-statistics/' + stat]['d'] is None else \ rt.Port.port_display_tbl['fibrechannel-statistics/' + stat]['d'] except (ValueError, TypeError) as e: stat_ref = stat cell = report_utils.cell_match_val(sheet, stat_ref, None, 2, 1) if cell is None: ml.append('Could not find statistical count ' + stat + ' for port ' + port + '. Skipping') continue ref_col = column_index_from_string( coordinate_from_string(cell)[0]) rd.update({stat: ref_col}) data_sheet[xl.get_column_letter(col) + '1'] = port_page + cell col += 1 max_col = len(rd.keys()) # Add the time stamp x = port_obj.r_get('fibrechannel-statistics/time-generated') if x == None: ml.append('Invalid sample for port ' + port + '. Skipping.') break title = 'Statistics for port ' + port + 'beginning: ' + datetime.datetime.fromtimestamp( x).strftime('%d %b %Y, %H:%M:%S') row = 2 for port_obj in [obj.r_port_obj(port) for obj in switch_obj_l]: x = None if port_obj is None else port_obj.r_get( 'fibrechannel-statistics/time-generated') if x is None: brcdapi_log.log( 'Port ' + port + ' appears to have gone off line after ' + last_time, True) break last_time = x data_sheet['A' + str(row)] = datetime.datetime.fromtimestamp( x).strftime('%H:%M:%S') col = 2 for ref_col in rd.values(): data_sheet[xl.get_column_letter(col) + str(row)] = port_page + xl.get_column_letter(ref_col) +\ str(row + 1) col += 1 row += 1 elif stat is not None: # Figure out the title and graph Y axis title y_name = stat.split('/').pop() try: col_ref = y_name if rt.Port.port_display_tbl[stat][ 'd'] is None else rt.Port.port_display_tbl[stat]['d'] except (ValueError, TypeError) as e: col_ref = y_name # Find all the time stamps, reference sheets, and columns tl = list() rl = list() for port in gen_util.convert_to_list(graph_obj.get('parms')): port_obj = switch_obj_l[0].r_port_obj(port) if port_obj is None: ml.append('Could not find port ' + port) continue sheet = _sheet_map[port] cell = report_utils.cell_match_val(sheet, col_ref, None, 2, 1) if cell is None: ml.append('Could not find column for port ' + port + ', statistic ' + stat) continue rl.append( dict(sheet=sheet, port=port, name=port.replace('/', '_'), col=column_index_from_string( coordinate_from_string(cell)[0]))) if len(tl) == 0: try: x = switch_obj_l[0].r_port_obj(port).r_get( 'fibrechannel-statistics/time-generated') except (ValueError, TypeError) as e: x = None if x == None: ml.append('Invalid sample for port ' + port + '. Skipping') break title = 'Statistics beginning: ' + datetime.datetime.fromtimestamp( x).strftime('%d %b %Y, %H:%M:%S') for port_obj in [ obj.r_port_obj(port) for obj in switch_obj_l ]: x = port_obj.r_get( 'fibrechannel-statistics/time-generated') if x is None: brcdapi_log.log( 'Port ' + port + ' appears to have gone off line after ' + last_time, True) break last_time = x tl.append( datetime.datetime.fromtimestamp(x).strftime( '%H:%M:%S')) # Add all the data references max_col = len(rl) if max_col > 0: data_sheet['A1'] = 'Time' # Column header for the time stamp for row in range(0, len(tl)): # Fill in the time stamp. data_sheet['A' + str(row + 2)] = tl[row] for col in range(0, len(rl)): # Now add the port column headers data_sheet[xl.get_column_letter(col + 2) + '1'] = "'" + rl[col]['port'] for row in range( 0, len(switch_obj_l) ): # Now add all the statistical data for the ports col = 2 for ref in rl: # One for each port data_sheet[xl.get_column_letter(col) + str(row + 2)] = \ '=' + ref['name'] + '!' + xl.get_column_letter(ref['col']) + str(row + 3) col += 1 else: brcdapi_log.exception(y_name, True) continue # Create the Worksheet and add it to the table of contents max_row = len(switch_obj_l) + 1 report_graph.graph( wb, tc_page, sname, sheet_index, dict(sheet=data_sheet, title=title, type=graph_obj['type'], x=dict(title='Time', min_col=1, min_row=1, max_row=max_row), y=dict(title=col_ref, min_col=2, max_col=max_col + 1, min_row=1, max_row=max_row))) t_content.append( dict(merge=4, font='link', align='wrap', hyper='#' + sname + '!A1', disp=col_ref)) sheet_index += 1 graph_num += 1 return ml