def pseudo_main(): """Basically the main(). Did it this way so it can easily be used as a standalone module or called from another. :return: Exit code. See exist codes in brcddb.brcddb_common :rtype: int """ ip, user_id, pw, sec, log, nl = parse_args() if sec is None: sec = 'none' if not nl: brcdapi_log.open_log(log) ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ml.append('IP: ' + brcdapi_util.mask_ip_addr(ip, True)) ml.append('ID: ' + user_id) ml.append('security: ' + sec) brcdapi_log.log(ml, True) # Login brcdapi_log.log('Attempting login', True) session = brcdapi_rest.login(user_id, pw, ip, sec) if brcdapi_auth.is_error(session): brcdapi_log.log('Login failed. Error message is:', True) brcdapi_log.log(brcdapi_auth.formatted_error_msg(session), True) return -1 # Logout brcdapi_log.log('Login succeeded. Attempting logout', True) obj = brcdapi_rest.logout(session) if brcdapi_auth.is_error(obj): brcdapi_log.log('Logout failed. Error message is:', True) brcdapi_log.log(brcdapi_auth.formatted_error_msg(obj), True) return -1 brcdapi_log.log('Logout succeeded.', True) return 1
def _setup_log(folder, no_log): """Demonstrate setup and provide examples on use of the logging methods :param folder: The folder to put log files in. If None, use the local directory :type folder: str, None :param no_log: If True, do not create a log file :type no_log: bool """ global _DEBUG_IP, _DEBUG_ID, _DEBUG_VERBOSE, __version__, _DEBUG_EXCEPTION # Set up the folder to use for logging. if not no_log: brcdapi_log.open_log(folder) # As an example, echo the module variables ml = [ 'Module : cli_poll_to_api', 'Version : ' + __version__, 'User ID : ' + _DEBUG_ID, 'Password : xxxxxx', 'IP address: ' + brcdapi_util.mask_ip_addr(_DEBUG_IP, keep_last=True) ] # Every call to brcdapi_log.log is preceded with a time stamp so this list gets onetime stamp brcdapi_log.log(ml, echo=True) if _DEBUG_VERBOSE: brcdapi_log.log('Verbose debug enabled', True) # This gets it's own time stampe # exception() precedes the message, or list of message, with a stack trace, calls log(), and flushes the file cache. if _DEBUG_EXCEPTION: buf = 'Ignore the preceding stack trace. It is only to illustrate the use of the brcdapi.log.expection() method' brcdapi_log.exception(buf, True)
def pseudo_main(): """Basically the main(). Did it this way so it can easily be used as a standalone module or called from another. :return: Exit code. See exist codes in brcddb.brcddb_common :rtype: int """ global _generic_table_add, _key_conv_tbl, _control_tables # Get and validate the user inputs. bf, cf, rf, s_flag, log, nl = parse_args() if s_flag: brcdapi_log.set_suppress_all() if not nl: brcdapi_log.open_log(log) rf = brcdapi_file.full_file_name(rf, '.xlsx') bf = brcdapi_file.full_file_name(bf, '.json') cf = brcdapi_file.full_file_name(cf, '.json') ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ml.append(':START: Compare Report:') ml.append(' Base file: ' + bf) ml.append(' Compare file: ' + cf) ml.append(' Report file: ' + rf) brcdapi_log.log(ml, True) # Read the projects to compare and build the cross references ml = list() b_proj_obj = brcddb_project.read_from(bf) c_proj_obj = brcddb_project.read_from(cf) if b_proj_obj is None: ml.append('Missing or invalid base project.') if c_proj_obj is None: ml.append('Missing or invalid compare project.') if len(ml) > 0: brcdapi_log.log(ml, True) return brcddb_common.EXIT_STATUS_ERROR brcddb_project.build_xref(b_proj_obj) brcddb_project.build_xref(c_proj_obj) # Build out the key conversion tables. Used in _format_disp() for k, v in brcddb_rt.Port.port_display_tbl.items(): if k[0] != '_': # Make sure it's not a custom key _key_conv_tbl.update({'_port_objs/s/p/' + k: v.get('d')}) for k, v in brcddb_rt.Login.login_display_tbl.items(): if k[0] != '_': # Make sure it's not a custom key _key_conv_tbl.update({k: v.get('d')}) for table_obj in _generic_table_add: for k, v in table_obj.items(): if k[0] != '_': # Make sure it's not a custom key if isinstance(v, dict): for k1, v1 in v.items(): _key_conv_tbl.update({k + '/' + k1: v1}) else: _key_conv_tbl.update({k: v}) # Compare the two projects brcdapi_log.log('Please wait. The comparison may take several seconds', True) c, compare_obj = brcddb_compare.compare(b_proj_obj, c_proj_obj, None, _control_tables) _new_report(c, b_proj_obj, c_proj_obj, _project_scrub(compare_obj), rf) return brcddb_common.EXIT_STATUS_OK
def pseudo_main(): """Basically the main(). :return: Exit code :rtype: int """ ec = 0 # Get and condition the command line input ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ip, user_id, pw, sec, fid, echo, vd, log, nl = parse_args() if vd: brcdapi_rest.verbose_debug = True if sec is None: sec = 'none' ml.append('Access: HTTP') else: ml.append('Access: HTTPS') if not nl: brcdapi_log.open_log(log) try: fid = int(fid) if fid < 1 or fid > 128: raise except ValueError: brcdapi_log.log('Invalid fid. FID must be an integer between 1-128', True) return -1 ml.append('FID: ' + str(fid)) brcdapi_log.log(ml, True) echo = False if echo is None else echo # Login brcdapi_log.log('Attempting login', True) session = brcdapi_rest.login(user_id, pw, ip, sec) if brcdapi_auth.is_error(session): brcdapi_log.log(['Login failed. API error message is:', brcdapi_auth.formatted_error_msg(session)], True) return -1 brcdapi_log.log('Login succeeded.', True) # Delete the switch try: # I always do a try in code development so that if there is a code bug, I still log out. buf = 'Deleting FID ' + str(fid) + '. This will take about 20 sec per switch + 25 sec per group of 32 ports.' brcdapi_log.log(buf, True) obj = brcdapi_switch.delete_switch(session, fid, echo) if brcdapi_auth.is_error(obj): ml = ['Error deleting FID ' + str(fid)] ml.append(brcdapi_auth.formatted_error_msg(obj)) brcdapi_log.log(ml, True) ec = -1 except: # Bare because I don't care what went wrong. I just want to logout brcdapi_log.log('Encountered a programming error', True) ec = -1 # Logout obj = brcdapi_rest.logout(session) if brcdapi_auth.is_error(obj): brcdapi_log.log(['Logout failed. API error message is:', brcdapi_auth.formatted_error_msg(obj)], True) return ec
def pseudo_main(): """Basically the main(). Did it this way so it can easily be used as a standalone module or called from another. :return: Exit code. See exist codes in brcddb.brcddb_common :rtype: int """ ip, user_id, pw, outf, sec, s_flag, vd, c_file, fid, log, nl = parse_args() if vd: brcdapi_rest.verbose_debug = True if s_flag: brcdapi_log.set_suppress_all() if not nl: brcdapi_log.open_log(log) if sec is None: sec = 'none' fid_l = None if fid is None else fid.split(',') ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ml.append('IP: ' + brcdapi_util.mask_ip_addr(ip, True)) ml.append('ID: ' + user_id) ml.append('security: ' + sec) ml.append('Output file: ' + outf) ml.append('KPI file: ' + str(c_file)) ml.append('FID List: ' + str(fid)) brcdapi_log.log(ml, True) outf = brcdapi_file.full_file_name(outf, '.json') # Create project proj_obj = brcddb_project.new( "Captured_data", datetime.datetime.now().strftime('%d %b %Y %H:%M:%S')) proj_obj.s_python_version(sys.version) proj_obj.s_description("This is a test") # Login session = api_int.login(user_id, pw, ip, sec, proj_obj) if brcdapi_auth.is_error(session): return brcddb_common.EXIT_STATUS_API_ERROR # Collect the data try: api_int.get_batch(session, proj_obj, _kpi_list(session, c_file), fid_l) except BaseException as e: brcdapi_log.exception( 'Programming error encountered. Exception is: ' + str(e), True) # Logout obj = brcdapi_rest.logout(session) if brcdapi_auth.is_error(obj): brcdapi_log.log(brcdapi_auth.formatted_error_msg(obj), True) # Dump the database to a file if _WRITE: brcdapi_log.log('Saving project to: ' + outf, True) plain_copy = dict() brcddb_copy.brcddb_to_plain_copy(proj_obj, plain_copy) brcdapi_file.write_dump(plain_copy, outf) brcdapi_log.log('Save complete', True) return proj_obj.r_exit_code()
def combine_main(): """Basically the main(). Did it this way so it can easily be used as a standalone module or called from another. :return: Exit code :rtype: int """ global _DEBUG # Get and validate user input inf, outf, s_flag, log, nl = parse_args() if s_flag: brcdapi_log.set_suppress_all() if not nl: brcdapi_log.open_log(log) ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ml.append('Directory, -i: ' + inf) ml.append('Output file, -o: ' + outf) brcdapi_log.log(ml, True) # Create project proj_obj = brcddb_project.new( inf, datetime.datetime.now().strftime('%Y_%m_%d_%H_%M_%S')) proj_obj.s_python_version(sys.version) proj_obj.s_description('Captured data from ' + inf) # Get a list of files - Filter out directories is just to protect the user. It shouldn't be necessary. outf = brcdapi_file.full_file_name(outf, '.json') files = brcdapi_file.read_directory(inf) if outf in files: brcdapi_log.log( 'Combined output file, ' + outf + ', already exists in: ' + inf + '. Processing halted', True) proj_obj.s_error_flag() else: x = len('.json') for file in [ f for f in files if len(f) > x and f.lower()[len(f) - x:] == '.json' ]: brcdapi_log.log('Processing file: ' + file, True) obj = brcdapi_file.read_dump(inf + '/' + file) brcddb_copy.plain_copy_to_brcddb(obj, proj_obj) # Now save the combined file plain_copy = dict() brcddb_copy.brcddb_to_plain_copy(proj_obj, plain_copy) try: brcdapi_file.write_dump(plain_copy, inf + '/' + outf) except FileNotFoundError: brcdapi_log.log(['', 'Folder not found: ' + inf, ''], True) return brcddb_common.EXIT_STATUS_OK
def pseudo_main(): """Basically the main(). Did it this way to use with IDE :return: Exit code :rtype: int """ global _kpi_l # Get the command line input ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() in_file, fid_str, vd, log, nl = parse_args() if vd: brcdapi_rest.verbose_debug = True if not nl: brcdapi_log.open_log(log) ml.append('FID: ' + str(fid_str)) fid_l = None if fid_str is None else fid_str.split(',') brcdapi_log.log(ml, True) # Read the file with the login credentials switch_list = _parse_login_credentials(in_file) # Create a project object proj_obj = brcddb_project.new("Captured_data", datetime.datetime.now().strftime('%d %b %Y %H:%M:%S')) # Poll all the switches ec_l = list() for switch in switch_list: # Collect the data for each switch ec_l.append(_capture_data(proj_obj, _kpi_l, fid_l, switch['id'], switch['pw'], switch['ip'], switch['sec'])) # Build cross references. This associates name server logins with a physical port. It is necessary in this example # because what is attached to the port is used as the port description added to the database. brcdapi_log.log('Building cross references', True) brcddb_project.build_xref(proj_obj) # Add the data to your database brcdapi_log.log('Adding data to database', True) _add_data_to_db(proj_obj) # Return the first error status encountered for ec in ec_l: if ec != brcddb_common.EXIT_STATUS_OK: return ec return ec # If we get this far, everything was good
def pseudo_main(): """Basically the main(). :return: Exit code :rtype: int """ ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ip, user_id, pw, sec, fids, vd, log, nl = parse_args() if vd: brcdapi_rest.verbose_debug = True if not nl: brcdapi_log.open_log(log) fid = int(fids) ml.append('FID: ' + fids) if sec is None: sec = 'none' brcdapi_log.log(ml, True) # Login brcdapi_log.log('Attempting login', True) session = brcdapi_rest.login(user_id, pw, ip, sec) if brcdapi_auth.is_error(session): brcdapi_log.log('Login failed', True) brcdapi_log.log(brcdapi_auth.formatted_error_msg(session), True) return -1 brcdapi_log.log('Login succeeded', True) try: ec = _clear_dashboard(session, fid) except: # Base except because I don't care what went wrong, I just want to make sure we logout. brcdapi_log.exception('Encountered a programming error', True) ec = -1 obj = brcdapi_rest.logout(session) if brcdapi_auth.is_error(obj): brcdapi_log.log('Logout failed:\n' + brcdapi_auth.formatted_error_msg(obj), True) return ec
def _get_input(): """Parses the module load command line, performs basic parameter validation checks, and sets up the log file. :return ip_addr: IP address of switch :rtype ip_addr: str :return user_id: User login ID :rtype user_id: str :return pw: Login password :rtype pw: str :return sec: 'self' for self signed certificate (HTTPS) or 'none' (HTTP) :rtype sec: str """ global _DEBUG_ip, _DEBUG_id, _DEBUG_pw, _DEBUG_s, _DEBUG_d, _DEBUG_log, _DEBUG_nl if _DEBUG: args_ip, args_id, args_pw, args_s, args_d, args_log, args_nl = \ _DEBUG_ip, _DEBUG_id, _DEBUG_pw, _DEBUG_s, _DEBUG_d, _DEBUG_log, _DEBUG_nl else: buf = 'Displays the results from GET running/brocade-security/security-certificate. In addition to security '\ 'certificates, this URL also returns CSRs. Usually, this done to validate certificates so the CSRs '\ 'would be filtered out or ignored.' parser = argparse.ArgumentParser(description=buf) parser.add_argument('-ip', help='(Required) IP address', required=True) parser.add_argument('-id', help='(Required) User ID', required=True) parser.add_argument('-pw', help='(Required) Password', required=True) parser.add_argument( '-s', help="(Optional) Default is HTTP. Use self for HTTPS mode.", required=False) buf = '(Optional) Enable debug logging. Prints the formatted data structures (pprint) to the log and console.' parser.add_argument('-d', help=buf, action='store_true', required=False) buf = '(Optional) Directory where log file is to be created. Default is to use the current directory. The log' \ ' file name will always be "Log_xxxx" where xxxx is a time and date stamp.' parser.add_argument( '-log', help=buf, required=False, ) buf = '(Optional) No parameters. When set, a log file is not created. The default is to create a log file.' parser.add_argument('-nl', help=buf, action='store_true', required=False) args = parser.parse_args() args_ip, args_id, args_pw, args_s, args_d, args_log, args_nl = \ args.ip, args.id, args.pw, args.s, args.d, args.log, args.nl # Set up the log file if not args_nl: brcdapi_log.open_log(args_log) if args_d: # Verbose debug brcdapi_rest.verbose_debug = True # Condition the input if args_s is None: args_s = 'none' # User feedback about input. ml = ['WARNING: Debug mode is enabled'] if _DEBUG else list() ml.extend([ 'IP, -ip: ' + brcdapi_util.mask_ip_addr(args_ip, True), 'ID, -id: ' + args_id, 'Security, -sec: ' + args_s, '' ]) brcdapi_log.log(ml, True) return args_ip, args_id, args_pw, args_s
def psuedo_main(): """Basically the main(). Did it this way so it can easily be used as a standalone module or called from another. :return: Exit code. See exist codes in brcddb.brcddb_common :rtype: int """ global _DEBUG addl_parms_all, addl_parms_capture, addl_parms_report = list(), list( ), list() # Get and parse the input data ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ml.append(os.path.basename(__file__) + ' version: ' + __version__) in_file, folder, sfp, iocp, report_flag, kpi_file, s_flag, vd, log, nl = parse_args( ) if kpi_file is not None: addl_parms_capture.extend(['-c', kpi_file]) if vd: brcdapi_rest.verbose_debug = True addl_parms_capture.append('-d') if s_flag: brcdapi_log.set_suppress_all() addl_parms_all.append('-sup') if nl: addl_parms_all.append('-nl') else: brcdapi_log.open_log(log) if log is not None: addl_parms_all.extend(['-log', log]) if iocp is not None: addl_parms_report.extend(['-iocp', iocp]) ml.append('Input file: ' + in_file) date_str = '_' + datetime.datetime.now().strftime('%Y_%m_%d_%H_%M_%S') if folder is None: folder = '_capture' + date_str ml.append('Output Folder: (Automatic) ' + folder) else: ml.append('Output Folder: ' + folder) ml.append('SFP: ' + str(sfp)) ml.append('IOCP: ' + str(iocp)) ml.append('Report: ' + str(report_flag)) ml.append('KPI File: ' + str(kpi_file)) ml.append('Suppress: ' + str(s_flag)) ml.append('Verbose Debug: ' + str(vd)) brcdapi_log.log(ml, True) # Read the file with login credentials and perform some basic validation ml, switch_parms = list(), list() if sfp is not None: addl_parms_report.extend(['-sfp', sfp]) file = brcdapi_file.full_file_name(in_file, '.xlsx') try: for d in excel_util.parse_parameters(sheet_name='parameters', hdr_row=0, wb_name=file)['content']: buf = brcdapi_file.full_file_name( d['name'].split('/').pop().split('\\').pop(), '.json') # Just file name switch_parms.append([ '-id', d['user_id'], '-pw', d['pw'], '-ip', d['ip_addr'], '-s', 'none' if d['security'] is None else d['security'], '-f', folder + '/' + buf ]) except FileNotFoundError: ml.extend(['', file + ' not found.']) # Create the folder try: os.mkdir(folder) except FileExistsError: ml.extend('Folder ' + folder + ' already exists.') except FileNotFoundError: ml.extend(['', folder + ' contains a path that does not exist.']) if len(ml) > 0: brcdapi_log.log(ml, True) return brcddb_common.EXIT_STATUS_INPUT_ERROR # Kick off all the data captures pid_l = list() for temp_l in switch_parms: params = ['python.exe', 'capture.py' ] + temp_l + addl_parms_capture + addl_parms_all if _DEBUG: brcdapi_log.log(' '.join(params), True) pid_l.append(subprocess.Popen(params)) # Below waits for all processes to complete before generating the report. pid_done = [p.wait() for p in pid_l] for i in range(0, len(pid_done)): brcdapi_log.log( 'Completed switch capture at index ' + str(i) + '. Ending status: ' + str(pid_done[i]), True) # Combine the captured data brcdapi_log.log('Combining captured data. This may take several seconds', True) params = ['python.exe', 'combine.py', '-i', folder, '-o', 'combined.json' ] + addl_parms_all if _DEBUG: brcdapi_log.log('DEBUG: ' + ' '.join(params), True) ec = subprocess.Popen(params).wait() brcdapi_log.log('Combine completed with status: ' + str(ec), True) # Generate the report if report_flag and ec == brcddb_common.EXIT_STATUS_OK: brcdapi_log.log('Data collection complete. Generating report.', True) buf = folder + '/report_' + date_str + '.xlsx' params = [ 'python.exe', 'report.py', '-i', folder + '/combined.json', '-o', buf ] params.extend(addl_parms_report + addl_parms_all) if _DEBUG: brcdapi_log.log('DEBUG: ' + ' '.join(params), True) ec = subprocess.Popen(params).wait() return ec
def pseudo_main(): """Basically the main(). :return: Exit code :rtype: int """ global _DEBUG, _sfp_monitoring_system # Get and validate the command line input ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ip, user_id, pw, sec, fid, new_policy, file, mp, enable_flag, s_flag, vd, log, nl = parse_args( ) if vd: brcdapi_rest.verbose_debug = True if not nl: brcdapi_log.open_log(log) if s_flag: brcdapi_log.set_suppress_all() fid = int(fid) if sec is None: sec = 'none' ml.extend([ 'FID: ' + str(fid), 'New policy: ' + new_policy, 'SFP rules file: ' + str(file), 'Policy to clone: ' + 'Active' if mp is None else mp, 'Activate new policy: ' + 'Yes' if enable_flag else 'No', 'The \'User Warning: Data Validation ...\' can be ignored.', ]) brcdapi_log.log(ml, True) # Login session = api_int.login(user_id, pw, ip, sec) if brcdapi_auth.is_error( session): # api_int.login() logs detailed error message return brcddb_common.EXIT_STATUS_API_ERROR # try/except used during development to ensure logout due to programming errors. ec = brcddb_common.EXIT_STATUS_ERROR # Return code normally gets overwritten try: if file is None: sfp_rules = list() else: file = brcdapi_file.full_file_name(file, '.xlsx') brcdapi_log.log( 'Adding rules can take up to a minute. Please be patient.', True) _sfp_monitoring_system = [ 'CURRENT', 'RXP', 'SFP_TEMP', 'TXP', 'VOLTAGE' ] sfp_rules = report_utils.parse_sfp_file_for_rules( file, _get_groups(session, fid)) if sfp_rules is None: brcdapi_log.log('Error opening or reading ' + file, True) else: ec = _modify_maps(session, fid, sfp_rules, new_policy, mp, enable_flag) except BaseException as e: brcdapi_log.log( 'Programming error encountered. Exception is: ' + str(e), True) obj = brcdapi_rest.logout(session) if brcdapi_auth.is_error(obj): brcdapi_log.log( 'Logout failed. API response:\n' + brcdapi_auth.formatted_error_msg(obj), True) ec = brcddb_common.EXIT_STATUS_API_ERROR return ec
def _get_input(): """Parses the module load command line :return i: Input file name :rtype i: str :return o: Output file name :rtype o: str :return sfp: Name of SFP rules file :rtype sfp: str, None :return iocp: Name of folder containing IOCP files :rtype iocp: str, None :return c: Custom report parameters passed to _custom_report(). Typically not used. :rtype c: str, None """ global _DEBUG, _DEBUG_i, _DEBUG_o, _DEBUG_sfp, _DEBUG_sup, _DEBUG_iocp, _DEBUG_log, _DEBUG_nl, _DEBUG_c if _DEBUG: args_i, args_o, args_sfp, args_sup, args_iocp, args_log, args_nl, args_c =\ _DEBUG_i, _DEBUG_o, _DEBUG_sfp, _DEBUG_sup, _DEBUG_iocp, _DEBUG_log, _DEBUG_nl, _DEBUG_c else: parser = argparse.ArgumentParser( description='Create a general report in Excel.') buf = 'Required. Name of input file generated by capture.py, combine.py, or multi_capture.py. Extension '\ '".json" is automatically added if no extension present.' parser.add_argument('-i', help=buf, required=True) parser.add_argument( '-o', help= 'Required. Name of report file. ".xlsx" automatically appended.', required=True) buf = 'Optional. Name of the Excel Workbook with SFP thresholds. This is the same file used as input to '\ 'applications.maps_config. This is useful for checking SFPs against the new recommended MAPS rules '\ 'before implementing them or filling in missing rules.' parser.add_argument('-sfp', help=buf, required=False) buf = 'Optional. For FICON environments only. Name of folder with IOCP files. All files in this folder must '\ 'be IOCP files (build I/O configuration statements from HCD) and must begin with the CEC serial number'\ ' followed by \'_\'. Leading 0s are not required. Example, for a CEC with serial number '\ '12345: 12345_M90_iocp.txt' parser.add_argument('-iocp', help=buf, required=False) buf = 'Optional. Suppress all output to STD_IO except the exit code and argument parsing errors. Useful with '\ 'batch processing where only the exit status code is desired. Messages are still printed to the log file'\ '. No operands.' parser.add_argument('-sup', help=buf, action='store_true', required=False) buf = '(Optional) Directory where log file is to be created. Default is to use the current directory. The ' \ 'log file name will always be "Log_xxxx" where xxxx is a time and date stamp.' parser.add_argument( '-log', help=buf, required=False, ) buf = '(Optional) No parameters. When set, a log file is not created. The default is to create a log file.' parser.add_argument('-nl', help=buf, action='store_true', required=False) parser.add_argument( '-c', help='(Optional) Custom parameter to be used with _custom_report', required=False) args = parser.parse_args() args_i, args_o, args_sfp, args_sup, args_iocp, args_log, args_nl, args_c =\ args.i, args.o, args.sfp, args.sup, args.iocp, args.log, args.nl, args.c # Set up log file and debug if args_sup: brcdapi_log.set_suppress_all() if not args_nl: brcdapi_log.open_log(args_log) return brcapi_file.full_file_name(args_i, '.json'), \ brcapi_file.full_file_name(args_o, '.xlsx'), \ brcapi_file.full_file_name(args_sfp, '.xlsx'), \ args_iocp, \ args_c
def _get_input(): """Parses the module load command line :return ec: Status code. :rtype ec: int :return proj_obj: Project object :rtype proj_obj: brcddb.classes.project.ProjectObj :return filter_obj: Filter file contents converted to standard Python type :rtype filter_obj: dict, list """ global _DEBUG, _DEBUG_i, _DEBUG_f, _DEBUG_eh, _DEBUG_v, _DEBUG_log, _DEBUG_nl proj_obj, filter_obj, ml, ec = None, None, list( ), brcddb_common.EXIT_STATUS_OK if _DEBUG: proj_file, filter_file, eh, v_flag, log_file, log_nl = \ _DEBUG_i, _DEBUG_f, _DEBUG_eh, _DEBUG_v, _DEBUG_log, _DEBUG_nl ml.append('WARNING!!! Debug is enabled') else: parser = argparse.ArgumentParser( description= 'Convert supportshow output to equivalent capture output.') parser.add_argument( '-i', help= 'Required. Name of project file. ".json" is automatically appended', required=False) buf = 'Required. Name of filter file. If the file extension is not ".json", a file extension of ".txt" is '\ 'assumed. Invoke with the -eh option for additional help' parser.add_argument('-f', help=buf, required=False) buf = 'Optional. No parameters. When specified, extended help for the filter file, -f, is displayed and '\ 'processing is terminated.' parser.add_argument('-eh', help=buf, action='store_true', required=False) buf = 'Optional. No parameters. When specified, attempts to read and convert the filter file, -f, only. No '\ 'other processing is performed.' parser.add_argument('-v', help=buf, action='store_true', required=False) buf = '(Optional) Directory where log file is to be created. Default is to use the current directory. The ' \ 'log file name will always be "Log_xxxx" where xxxx is a time and date stamp.' parser.add_argument( '-log', help=buf, required=False, ) buf = '(Optional) No parameters. When set, a log file is not created. The default is to create a log file.' parser.add_argument('-nl', help=buf, action='store_true', required=False) args = parser.parse_args() proj_file, filter_file, eh, v_flag, log_file, log_nl = args.i, args.f, args.eh, args.v, args.log, args.nl if not log_nl: brcdapi_log.open_log(log_file) if eh: ml.extend(_eh) ec = brcddb_common.EXIT_STATUS_INPUT_ERROR else: if not v_flag and not isinstance(proj_file, str): ml.append('Missing project file, -i') ec = brcddb_common.EXIT_STATUS_INPUT_ERROR if not isinstance(filter_file, str): ml.append('Missing filter file, -f') ec = brcddb_common.EXIT_STATUS_INPUT_ERROR if ec == brcddb_common.EXIT_STATUS_OK: # Read in the filter file x = len('.json') if len(filter_file) <= x or filter_file[len(filter_file) - x:].lower() != '.json': filter_file = brcdapi_file.full_file_name(filter_file, '.txt') try: filter_obj = json.loads(''.join( brcdapi_file.read_file(filter_file, remove_blank=True, rc=True))) except FileNotFoundError: ml.append('Filter file, ' + filter_file + ', not found') ec = brcddb_common.EXIT_STATUS_ERROR except ValueError: ml.append('Improperly formatted JSON in ' + filter_file) ec = brcddb_common.EXIT_STATUS_ERROR if v_flag: if ec == brcddb_common.EXIT_STATUS_OK: ml.append('Successfully read ' + filter_file) ml.append( 'Validating filter file only. No other processing performed.') ec = brcddb_common.EXIT_STATUS_ERROR else: # User feedback proj_file = brcdapi_file.full_file_name(proj_file, '.json') ml.append('Project, -i: ' + str(proj_file)) ml.append('filter file, -f: ' + str(filter_file)) # Read in the project file try: proj_obj = brcddb_project.read_from(proj_file) except FileNotFoundError: ml.append('Project file, ' + proj_file + ', not found') proj_obj = None if proj_obj is None: ec = brcddb_common.EXIT_STATUS_ERROR else: brcddb_project.build_xref(proj_obj) brcddb_project.add_custom_search_terms(proj_obj) if len(ml) > 0: brcdapi_log.log(ml, True) return ec, proj_obj, filter_obj
def _get_input(): """Parses the module load command line :return ec: Error code. 0: OK, -1: Errors encountered :rtype ec: int :return ip: Switch IP address :rtype ip: str :return id: User ID :rtype id: str :return pw: User password :rtype ip: str :return sec: Secure method. None for HTTP, otherwise the certificate or 'self' if self signed :rtype sec: str, None :return content: Content for "running/brocade-chassis/management-interface-configuration". :rtype content: dict """ global _DEBUG_ip, _DEBUG_id, _DEBUG_pw, _DEBUG_s, _DEBUG_r, _DEBUG_rest_en, _DEBUG_rest_dis global _DEBUG_https_en, _DEBUG_https_dis, _DEBUG_max_rest, _DEBUG_ka_en, _DEBUG_ka_en global _DEBUG_d, _DEBUG_log, _DEBUG_nl ec = 0 if _DEBUG: args_ip, args_id, args_pw, args_s = _DEBUG_ip, _DEBUG_id, _DEBUG_pw, 'none' if _DEBUG_s is None else _DEBUG_s args_rest_en, args_rest_dis, args_https_en, args_https_dis = \ _DEBUG_rest_en, _DEBUG_rest_dis, _DEBUG_https_en, _DEBUG_https_dis args_max_rest, args_ka_en, args_ka_dis = \ _DEBUG_max_rest, _DEBUG_ka_en, _DEBUG_ka_dis args_d, args_log, args_nl = _DEBUG_d, _DEBUG_log, _DEBUG_nl else: buf = 'Useful as a programming example only on how to read and make chassis configuration changes via the '\ '"running/brocade-chassis/management-interface-configuration" URI. If the only input is the login '\ 'credentials, the parameters are displayed and no other action taken.' parser = argparse.ArgumentParser(description=buf) parser.add_argument('-ip', help='(Required) IP address', required=True) parser.add_argument('-id', help='(Required) User ID', required=True) parser.add_argument('-pw', help='(Required) Password', required=True) parser.add_argument( '-s', help='(Optional) Default is HTTP. CA or "self" for HTTPS mode.', required=False) parser.add_argument( '-rest_en', help='(Optional) No parameters. Enables the Rest interface', action='store_true', required=False) parser.add_argument( '-rest_dis', help='(Optional) No parameters. Disables the Rest interface', action='store_true', required=False) parser.add_argument('-https_en', help='(Optional) No parameters. Enable HTTPS', action='store_true', required=False) parser.add_argument('-https_dis', help='(Optional) No parameters. Disable HTTPS', action='store_true', required=False) parser.add_argument( '-max_rest', help= '(Optional) Set the maximum number of REST sessions. Valid options are 1-10', required=False) parser.add_argument('-ka_en', help='(Optional) No parameters. Enable keep-alive', action='store_true', required=False) parser.add_argument('-ka_dis', help='(Optional) No parameters. Enable keep-alive', action='store_true', required=False) buf = '(Optional) Enable debug logging. Prints the formatted data structures (pprint) to the log and console.' parser.add_argument('-d', help=buf, action='store_true', required=False) buf = '(Optional) Directory where log file is to be created. Default is to use the current directory. The log' \ ' file name will always be "Log_xxxx" where xxxx is a time and date stamp.' parser.add_argument( '-log', help=buf, required=False, ) buf = '(Optional) No parameters. When set, a log file is not created. The default is to create a log file.' parser.add_argument('-nl', help=buf, action='store_true', required=False) args = parser.parse_args() args_ip, args_id, args_pw, args_s = args.ip, args.id, args.pw, 'none' if args.s is None else args.s args_rest_en, args_rest_dis, args_https_en, args_https_dis = \ args.rest_en, args.rest_dis, args.https_en, args.https_dis args_max_rest, args_ka_en, args_ka_dis = args.max_rest, args.ka_en, args.ka_dis args_d, args_log, args_nl = args.d, args.log, args.nl # Set up the log file if not args_nl: brcdapi_log.open_log(args_log) if args_d: # Verbose debug brcdapi_rest.verbose_debug = True rd = { 'rest-enabled': True if args_rest_en else False if args_rest_dis else None, 'https-protocol-enabled': True if args_https_en else False if args_https_dis else None, 'max-rest-sessions': args_max_rest, 'https-keep-alive-enabled': True if args_ka_en else False if args_ka_dis else None } # User feedback ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ml.append('IP, -ip: ' + brcdapi_util.mask_ip_addr(args_ip, True)) ml.append('ID, -id: ' + args_id) ml.append('Security, -s: ' + args_s) ml.append('Enable Rest, -rest_en: ' + str(args_rest_en)) ml.append('Disable Rest, -rest_dis: ' + str(args_rest_dis)) ml.append('Enable HTTPS, -https_en: ' + str(args_https_en)) ml.append('Disable HTTPS, -https_en: ' + str(args_https_dis)) ml.append('Enable keep-alive, -ka_en: ' + str(args_ka_en)) ml.append('Disable keep-alive, -ka_dis: ' + str(args_ka_dis)) ml.append('Max Rest sessions, -max_rest: ' + str(args_max_rest)) # Validate the input and set up the return dictionary if args_rest_en and args_rest_dis: ml.append('-rest_en and -rest_dis are mutually exclusive.') ec = -1 if args_https_en and args_https_dis: ml.append('-https_en and -https_dis are mutually exclusive.') ec = -1 if args_ka_en and args_ka_dis: ml.append('-ka_en and -ka_dis are mutually exclusive.') ec = -1 if len(rd) == 0: ml.extend(['', 'No changes']) brcdapi_log.log(ml, True) return ec, args_ip, args_id, args_pw, args_s, rd
def pseudo_main(): """Basically the main(). :return: Exit code :rtype: int """ ec = 0 # Get and condition the command line input ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ip, user_id, pw, sec, fid, name, did, idid, xisl, base, ficon, i_ports, i_ge_ports, es, ep, echo, vd, log, nl = \ parse_args() if vd: brcdapi_rest.verbose_debug = True if sec is None: sec = 'none' ml.append('Access: HTTP') else: ml.append('Access: HTTPS') if not nl: brcdapi_log.open_log(log) try: fid = int(fid) if fid < 1 or fid > 128: raise except: brcdapi_log.log('Invalid fid. FID must be an integer between 1-128', True) return -1 if did is not None: try: did = int(did) if did < 1 or did > 239: raise except: brcdapi_log.log( 'Invalid DID. DID must be an integer between 1-239', True) return -1 ml.append('FID: ' + str(fid)) ml.append('Name: ' + str(name)) ml.append('DID: ' + str(did)) ml.append('Insistent: ' + str(idid)) ml.append('xisl: ' + str(xisl)) ml.append('base: ' + str(base)) ml.append('ficon: ' + str(ficon)) ml.append('ports: ' + str(i_ports)) ml.append('ge_ports: ' + str(i_ge_ports)) ml.append('Enable switch: ' + str(es)) ml.append('Enable ports: ' + str(ep)) brcdapi_log.log(ml, True) base = False if base is None else base ficon = False if ficon is None else ficon es = False if es is None else es ep = False if ep is None else ep echo = False if echo is None else echo # Login brcdapi_log.log('Attempting login', True) session = brcdapi_rest.login(user_id, pw, ip, sec) if brcdapi_auth.is_error(session): brcdapi_log.log([ 'Login failed. API error message is:', brcdapi_auth.formatted_error_msg(session) ], True) return -1 brcdapi_log.log('Login succeeded.', True) try: # I always do a try in code development so that if there is a code bug, I still log out. # Get a list of ports to move to the new switch port_d, ge_port_d = _parse_ports(session, fid, i_ports, i_ge_ports, echo) # We're done with conditioning the user input. Now create the logical switch. ec = create_ls(session, fid, name, did, idid, xisl, base, ficon, port_d, ge_port_d, es, ep, echo) except: brcdapi_log.log('Encountered a programming error', True) ec = -1 # Logout obj = brcdapi_rest.logout(session) if brcdapi_auth.is_error(obj): brcdapi_log.log([ 'Logout failed. API error message is:', brcdapi_auth.formatted_error_msg(obj) ], True) return ec
def pseudo_main(): """Basically the main(). Did it this way so it can easily be used as a standalone module or called from another. :return: Exit code. See exist codes in brcddb.brcddb_common :rtype: int """ ec = brcddb_common.EXIT_STATUS_OK # Get the user input ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ip, user_id, pw, sec, s_flag, fid, vd, log, nl = parse_args() if not nl: brcdapi_log.open_log(log) if vd: brcdapi_rest.verbose_debug = True if s_flag: brcdapi_log.set_suppress_all() if sec is None: sec = 'none' fid_list = None if fid is None else [int(i) for i in fid.split(',')] ml.extend([ 'IP address: ' + ip, 'User ID: ' + user_id, 'Security: ' + sec, 'Surpress: ' + str(s_flag), 'FID: ' + 'Automatic' if fid is None else fid ]) brcdapi_log.log(ml, True) # Create the project proj_obj = brcddb_project.new( 'Captured_data', datetime.datetime.now().strftime('%Y_%m_%d_%H_%M_%S')) proj_obj.s_python_version(sys.version) proj_obj.s_description('Unused ports to disable') # Login session = api_int.login(user_id, pw, ip, sec, proj_obj) if fos_auth.is_error(session): brcdapi_log.log(fos_auth.formatted_error_msg(session), True) return brcddb_common.EXIT_STATUS_ERROR # Capture data - stats are cleared on a per port basis so this is needed to determine what the ports are. try: # I always put all code after login in a try/except so that if I have a code bug, I still logout brcdapi_log.log('Capturing data', True) api_int.get_batch(session, proj_obj, chassis_uris, list(), fid_list) # Captured data is put in proj_obj chassis_obj = proj_obj.r_chassis_obj(session.get('chassis_wwn')) # Clear stats on each switch for switch_obj in chassis_obj.r_switch_objects(): fid = brcddb_switch.switch_fid(switch_obj) if fid_list is None or fid in fid_list: temp_ec = clear_stats(session, switch_obj) ec = temp_ec if ec != brcddb_common.EXIT_STATUS_OK else ec except: # Bare because I don't care what happened. I just want to logout. brcdapi_log.exception('Programming error encountered', True) ec = brcddb_common.EXIT_STATUS_ERROR # Logout obj = brcdapi_rest.logout(session) if fos_auth.is_error(obj): brcdapi_log.log(fos_auth.formatted_error_msg(obj), True) return brcddb_common.EXIT_STATUS_ERROR return ec
def pseudo_main(): """Basically the main(). :return: Exit code :rtype: int """ global _DEBUG # Get and validate command line input ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ip, user_id, pw, sec, fid_str, vd, log, nl = parse_args() if not nl: brcdapi_log.open_log(log) if vd: brcdapi_rest.verbose_debug = True if fid_str.isdigit(): fid = int(fid_str) else: brcdapi_log.log('Invalid FID: ' + fid_str, True) return -1 brcdapi_log.log(ml, True) # Login brcdapi_log.log('Attempting login', True) session = brcdapi_rest.login(user_id, pw, ip, sec) if brcdapi_auth.is_error(session): brcdapi_log.log('Login failed', True) brcdapi_log.log(brcdapi_auth.formatted_error_msg(session), True) return -1 brcdapi_log.log('Login succeeded', True) ec = 0 try: # I always do a try in code development so that if there is a code bug, I still log out. # Get FC port list for this FID by reading the configurations kpi = 'running/brocade-interface/fibrechannel' obj = brcdapi_rest.get_request(session, kpi, fid) if brcdapi_auth.is_error(obj): brcdapi_log.log('Failed to read ' + kpi + ' for fid ' + str(fid), True) ec = -1 else: fc_plist = [port.get('name') for port in obj.get('fibrechannel')] pl = list() content = {'fibrechannel': pl} for p in fc_plist: d = { 'name': p, 'user-friendly-name': 'port_' + p.replace('/', '_'), # Name port "port_s_p" 'los-tov-mode-enabled': 2 # Enable LOS_TOV } # For other port configuration parameters, search the Rest API Guide or Yang models for # brocade-interface/fibrechannel pl.append(d) # PATCH only changes specified leaves in the content for this URI. It does not replace all resources obj = brcdapi_rest.send_request( session, 'running/brocade-interface/fibrechannel', 'PATCH', content, fid) if brcdapi_auth.is_error(obj): brcdapi_log.log('Error configuring ports for FID ' + str(fid), True) brcdapi_log.log(brcdapi_auth.formatted_error_msg(obj), True) ec = -1 else: brcdapi_log.log( 'Successfully configured ports for FID ' + str(fid), True) except: # Bare because I don't care what went wrong at this point. I just want to log out no matter what happens. brcdapi_log.log('Encountered a programming error', True) ec = -1 # Logout obj = brcdapi_rest.logout(session) if brcdapi_auth.is_error(obj): brcdapi_log.log( 'Logout failed:\n' + brcdapi_auth.formatted_error_msg(obj), True) return ec
def pseudo_main(): """Basically the main(). Did it this way to use with IDE :return: Exit code :rtype: int """ ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ip, user_id, pw, sec, fids, vd, log, nl = parse_args() if vd: brcdapi_rest.verbose_debug = True if sec is None: sec = 'none' if not nl: brcdapi_log.open_log(log) fl = [int(f) for f in fids.split(',')] ml.append('FIDs: ' + fids) brcdapi_log.log(ml, True) # Login session = brcdapi_rest.login(user_id, pw, ip, sec) if brcdapi_auth.is_error(session): brcdapi_log.log( 'Login failed:\n' + brcdapi_auth.formatted_error_msg(session), True) return -1 # Get the Chassis data brcdapi_log.log('Chassis Data\n------------', True) for uri in _chassis_rest_data: brcdapi_log.log('URI: ' + uri, True) try: obj = brcdapi_rest.get_request(session, uri) if brcdapi_auth.is_error( obj): # Set breakpoint here to inspect response brcdapi_log.log(brcdapi_auth.formatted_error_msg(obj), True) except BaseException as e: brcdapi_log.exception( ['Error requesting ' + uri, 'Exception: ' + str(e)], True) # Get the Switch data for vf_id in fl: brcdapi_log.log( 'Switch data. FID: ' + str(vf_id) + '\n---------------------', True) for buf in fid_rest_data: brcdapi_log.log('URI: ' + buf, True) try: obj = brcdapi_rest.get_request(session, buf, vf_id) if brcdapi_auth.is_error( obj): # Set breakpoint here to inspect response brcdapi_log.log(brcdapi_auth.formatted_error_msg(obj), True) except BaseException as e: brcdapi_log.exception( ['Error requesting ' + buf, 'Exception: ' + str(e)], True) # Logout obj = brcdapi_rest.logout(session) if brcdapi_auth.is_error(obj): brcdapi_log.log( 'Logout failed:\n' + brcdapi_auth.formatted_error_msg(obj), True) return -1 return 0
def _get_input(): """Retrieves the command line input, reads the input Workbook, and validates the input :return ec: Error code from brcddb.brcddb_common :rtype ec: int :return sl: List of switches to poll as read from the input Workbook :rtype sl: list :return pl: List of project files to combine :rtype pl: list :return cfg_name: Name of zone configuration file to create :rtype cfg_name: str, None :return a_cfg: Activation flag. If True, activate the zone configuration specified by cfg_name :rtype a_cfg: bool :return t_flag: Test flag. If True, test only. Do not make any changes :rtype t_flag: bool :return scan_flag: Scan flag. If True, scan files and switches for fabric information :rtype scan_flag: bool :return cli_flag: If True, generate CLI :rtype cli_flag: bool :return addl_parms: Additional parameters (logging and debug flags) to pass to multi_capture.py :rtype addl_parms: list """ global _DEBUG, __version__ # Initialize the return variables ec = brcddb_common.EXIT_STATUS_OK sl = list() pl = list() addl_parms = list() # Get the user input c_file, cfg_name, a_flag, t_flag, scan_flag, cli_flag, d_flag, s_flag, log, nl = parse_args( ) if s_flag: addl_parms.append('-sup') brcdapi_log.set_suppress_all() if nl: addl_parms.append('-nl') else: brcdapi_log.open_log(log) if log is not None: addl_parms.extend(['-log', log]) if d_flag: addl_parms.append('-d') brcdapi_rest.verbose_debug = True ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ml.append('zone_merge.py version: ' + __version__) ml.append('Login credential file: ' + str(c_file)) ml.append('Common zone cfg name: ' + str(cfg_name)) ml.append('Activate zone cfg: ' + str(a_flag)) ml.append('Scan flag, -scan: ' + str(scan_flag)) ml.append('CLI flag, -cli: ' + str(cli_flag)) ml.append('Test: ' + str(t_flag)) brcdapi_log.log(ml, True) c_file = brcdapi_file.full_file_name(c_file, '.xlsx') # Parse the input file ml = list() switch_l = excel_util.parse_parameters(sheet_name='parameters', hdr_row=0, wb_name=c_file)['content'] if a_flag and not isinstance(cfg_name, str): ml.append( 'Configuration activate flag, -a, specified without a valid zone configuration name, -cfg' ) if len(ml) == 0: for i in range(0, len(switch_l)): sub_d = switch_l[i] buf = sub_d.get('project_file') if buf is None: sl.append(_condition_input(sub_d)) else: pl.append(sub_d) if not scan_flag and not gen_util.is_wwn(sub_d.get('fab_wwn'), full_check=True): ml.append('fab_wwn is not a valid WWN in row ' + str(i + 1)) if len(ml) > 0: brcdapi_log.log(ml, True) ec = brcddb_common.EXIT_STATUS_INPUT_ERROR return ec, sl, pl, cfg_name, a_flag, t_flag, scan_flag, cli_flag, addl_parms
def pseudo_main(): """Basically the main(). :return: Exit code :rtype: int """ global _DEBUG # Get and validate command line input ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ip, user_id, pw, sec, fid_str, vd, log, nl = parse_args() if not nl: brcdapi_log.open_log(log) if vd: brcdapi_rest.verbose_debug = True if fid_str.isdigit(): fid = int(fid_str) else: brcdapi_log.log('Invalid FID: ' + fid_str, True) return -1 brcdapi_log.log(ml, True) # Login brcdapi_log.log('Attempting login', True) session = brcdapi_rest.login(user_id, pw, ip, sec) if brcdapi_auth.is_error(session): brcdapi_log.log('Login failed', True) brcdapi_log.log(brcdapi_auth.formatted_error_msg(session), True) return -1 brcdapi_log.log('Login succeeded', True) ec = 0 try: # I always do a try in code development so that if there is a code bug, I still log out. # Get FC port list for this FID by reading the configurations kpi = 'running/brocade-interface/fibrechannel' obj = brcdapi_rest.get_request(session, kpi, fid) if brcdapi_auth.is_error(obj): brcdapi_log.log('Failed to read ' + kpi + ' for fid ' + str(fid), True) ec = -1 else: # Get the port lists fc_plist = [port.get('name') for port in obj.get('fibrechannel')] # Disable all ports and set to the default configuration. brcdapi_log.log( 'Disabling all ports of fid: ' + str(fid) + ' and setting to default configuration', True) obj = brcdapi_port.default_port_config(session, fid, fc_plist) if brcdapi_auth.is_error(obj): brcdapi_log.log( 'Set ports to default for FID ' + str(fid) + ' failed', True) brcdapi_log.log(brcdapi_auth.formatted_error_msg(obj), True) ec = -1 else: brcdapi_log.log( 'Successfully set all ports for FID ' + str(fid) + ' to the default configuration', True) except: brcdapi_log.log('Encountered a programming error', True) ec = -1 # Logout obj = brcdapi_rest.logout(session) if brcdapi_auth.is_error(obj): brcdapi_log.log( 'Logout failed:\n' + brcdapi_auth.formatted_error_msg(obj), True) return ec
def _get_input(): """Parses the module load command line :return ip_addr: IP address :rtype ip_addr: str :return id: User ID :rtype id: str :return pw: Password :rtype pw: str :return http_sec: Type of HTTP security :rtype http_sec: str :return fid: Fabric ID in chassis specified by -ip where the zoning information is to copied to. :rtype fid: int :return suppress_flag: True - suppress all print to STD_OUT :rtype suppress_flag: bool :return suppress_flag: True - suppress all print to STD_OUT :rtype suppress_flag: bool :return poll_time: Polling interval in seconds :return poll_time: int, None :return max_samples: Maximum number of samples to collect :rtype max_samples: int, None :return file: Name of output file where raw data is to be stored :rtype file: str """ global _DEBUG, _DEBUG_ip, _DEBUG_id, _DEBUG_pw, _DEBUG_sec, _DEBUG_fid, _DEBUG_sup global _DEBUG_p, _DEBUG_m, _DEBUG_o, _DEBUG_d, _DEBUG_log, _DEBUG_nl if _DEBUG: args_ip, args_id, args_pw, args_sec, args_fid, args_sup, args_p, args_m, args_o, args_d, args_log, args_nl =\ _DEBUG_ip, _DEBUG_id, _DEBUG_pw, _DEBUG_sec, _DEBUG_fid, _DEBUG_sup, _DEBUG_p, _DEBUG_m, _DEBUG_o, \ _DEBUG_d, _DEBUG_log, _DEBUG_nl else: buf = 'Collect port statistics at a specified poll interval. Use Control-C to stop data collection and write ' \ 'report' parser = argparse.ArgumentParser(description=buf) parser.add_argument('-ip', help='Required. IP address', required=True) parser.add_argument('-id', help='Required. User ID', required=True) parser.add_argument('-pw', help='Required. Password', required=True) buf = '(Optional) \'CA\' or \'self\' for HTTPS mode. Default is HTTP' parser.add_argument( '-s', help=buf, required=False, ) buf = 'Required. Name of output file where raw data is to be stored. ".json" extension is automatically '\ 'appended.' parser.add_argument('-o', help=buf, required=True) buf = '(Optional) Virtual Fabric ID (1 - 128) of switch to read statistics from. Default is 128' parser.add_argument('-fid', help=buf, type=int, required=False) buf = '(Optional) No arguments. Suppress all library generated output to STD_IO except the exit code. Useful '\ 'with batch processing' parser.add_argument('-sup', help=buf, action='store_true', required=False) buf = '(Optional) Polling interval in seconds. Default is '\ + str(_DEFAULT_POLL_INTERVAL) + '. The minimum is ' + str(_MIN_POLL) + ' seconds.' parser.add_argument('-p', help=buf, type=float, required=False) buf = '(Optional) Samples are collected until this maximum is reached or a Control-C keyboard interrupt is '\ 'received. Default: ' + str(_DEFAULT_MAX_SAMPLE) parser.add_argument('-m', help=buf, type=int, required=False) buf = '(Optional) No arguments. Enable debug logging' parser.add_argument('-d', help=buf, action='store_true', required=False) buf = '(Optional) Directory where log file is to be created. Default is to use the current directory. The log '\ 'file name will always be "Log_xxxx" where xxxx is a time and date stamp.' parser.add_argument( '-log', help=buf, required=False, ) buf = '(Optional) No parameters. When set, a log file is not created. The default is to create a log file.' parser.add_argument('-nl', help=buf, action='store_true', required=False) args = parser.parse_args() args_ip, args_id, args_pw, args_sec, args_fid, args_sup, args_p, args_m, args_o, args_d, args_log, args_nl =\ args.ip, args.id, args.pw, args.sec, args.fid, args.sup, args.p, args.m, args.o, args.d, args.log, args.nl # Condition input sec = 'none' if args_sec is None else args_sec # Set up the log file & debug mode if not args.nl: brcdapi_log.open_log(args.log) if args.d: brcdapi_rest.verbose_debug = True if args.sup: brcdapi_log.set_suppress_all() return args_ip, args_id, args_pw, sec, args_fid, args_p, args_m, brcdapi_file.full_file_name( args_o, '.json')
def pseudo_main(user_id, pw, ip, sec, vd, log, nl): """Basically the main(). :param user_id: User ID :type user_id: str :param pw: Password :type pw: str :param ip: IP address :type ip: str :param sec: Security. 'none' for HTTP, 'self' for self signed certificate, 'CA' for signed certificate :type sec: str :param vd: When True, enables debug logging :type vd: bool :return: Exit code :rtype: int """ fid = _DEBUG_FID save_flag = False if vd: brcdapi_rest.verbose_debug = True if not nl: brcdapi_log.open_log(log) # Login brcdapi_log.log('Attempting login', True) session = brcdapi_rest.login(user_id, pw, ip, sec) if brcdapi_auth.is_error(session): brcdapi_log.log('Login failed', True) brcdapi_log.log(brcdapi_auth.formatted_error_msg(session), True) return -1 brcdapi_log.log('Login succeeded', True) # A check sum is needed to save any updates checksum, obj = brcdapi_zone.checksum(session, fid, True) if checksum is None: _logout(session) return -1 # try/except was so that during development a bug would not cause an abort and skip the logout try: # Create aliases if _DEBUG_CREATE_ALIASES: save_flag = True brcdapi_log.log('Creating aliases for fid: ' + str(fid), True) if _is_error( session, fid, brcdapi_zone.create_aliases(session, fid, _DEBUG_ALIAS_LIST, True)): _logout(session) return -1 # Create zones if _DEBUG_CREATE_ZONES: save_flag = True brcdapi_log.log('Creating zones for fid: ' + str(fid), True) if _is_error( session, fid, brcdapi_zone.create_zones(session, fid, _DEBUG_ZONE_LIST, True)): _logout(session) return -1 # Create zone configurations if _DEBUG_CREATE_ZONECFGS: save_flag = True brcdapi_log.log( 'Creating zone configurations for fid: ' + str(fid), True) for k, v in _DEBUG_ZONECFG_LIST.items(): if _is_error( session, fid, brcdapi_zone.create_zonecfg(session, fid, k, v, True)): _logout(session) return -1 # Delete zone configurations. If you are also deleting zones and a zone is in a defined configuration, the # delete will fail. This is why the zone configuration delete is first. if _DEBUG_DELETE_ZONECFGS: save_flag = True brcdapi_log.log( 'Deleting zone configurations for fid: ' + str(fid), True) for k in _DEBUG_ZONECFG_DEL_LIST: if _is_error(session, fid, brcdapi_zone.del_zonecfg(session, fid, k, True)): _logout(session) return -1 # Delete zones. If you are also deleting aliases and an alias is in a defined zone, the delete will fail. This # is why the zone delete is before the alias delete. if _DEBUG_DELETE_ZONES: save_flag = True brcdapi_log.log('Deleting zones for fid: ' + str(fid), True) if _is_error( session, fid, brcdapi_zone.del_zones(session, fid, _DEBUG_ZONE_DEL_LIST, True)): _logout(session) return -1 # Delete aliases if _DEBUG_DELETE_ALIASES: save_flag = True brcdapi_log.log('Deleting aliases for fid: ' + str(fid), True) if _is_error( session, fid, brcdapi_zone.del_aliases(session, fid, _DEBUG_ALIAS_DEL_LIST, True)): _logout(session) return -1 if _DEBUG_MODIFY_ZONE: save_flag = True brcdapi_log.log( 'Modifying ZONE ' + _DEBUG_ZONE_MODIFY + ' in fid: ' + str(fid), True) if _is_error( session, fid, brcdapi_zone.modify_zone(session, fid, _DEBUG_ZONE_MODIFY, _DEBUG_ZONE_ADD_MEMS, _DEBUG_ZONE_DEL_MEMS, _DEBUG_ZONE_ADD_PMEMS, _DEBUG_ZONE_DEL_PMEMS, True)): _logout(session) return -1 if _DEBUG_MODIFY_ZONECFG: save_flag = True brcdapi_log.log( 'Modifying zone configuration ' + _DEBUG_ZONECFG_MODIFY + ' in fid: ' + str(fid), True) if len(_DEBUG_ZONECFG_ADD_MEMS) > 0: if _is_error( session, fid, brcdapi_zone.zonecfg_add(session, fid, _DEBUG_ZONECFG_MODIFY, _DEBUG_ZONECFG_ADD_MEMS, True)): _logout(session) return -1 if len(_DEBUG_ZONECFG_DEL_MEMS) > 0: if _is_error( session, fid, brcdapi_zone.zonecfg_remove(session, fid, _DEBUG_ZONECFG_MODIFY, _DEBUG_ZONECFG_DEL_MEMS, True)): _logout(session) return -1 if _DEBUG_DISABLE_ZONECFG: brcdapi_log.log( 'Disabling zone configuration ' + _DEBUG_ZONECFG + ', fid: ' + str(fid), True) if _is_error( session, fid, brcdapi_zone.disable_zonecfg(session, checksum, fid, _DEBUG_ZONECFG, True)): _logout(session) return -1 save_flag = False # Enabling a zone configuration does a configuration save if _DEBUG_ENABLE_ZONECFG: brcdapi_log.log( 'Enabling zone configuration ' + _DEBUG_ZONECFG + ', fid: ' + str(fid), True) if _is_error( session, fid, brcdapi_zone.enable_zonecfg(session, checksum, fid, _DEBUG_ZONECFG, True)): _logout(session) return -1 save_flag = False # Enabling a zone configuration does a configuration save if save_flag: if _is_error(session, fid, brcdapi_zone.save(session, fid, checksum, True)): _logout(session) return -1 except: brcdapi_log.log('Logging out', True) _logout(session) brcdapi_log.exception('Exception', True) return -1 brcdapi_log.log('Logging out', True) _logout(session) return 0
def pseudo_main(): """Basically the main(). Did it this way to use with IDE :return: Exit code :rtype: int """ global _DEBUG # Get the command line input ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ip, user_id, pw, sec, fid_str, vd, log, nl = parse_args() if vd: brcdapi_rest.verbose_debug = True if sec is None: sec = 'none' if not nl: brcdapi_log.open_log(log) ml.append('FID: ' + fid_str) try: fid = int(fid_str) except ValueError: brcdapi_log.log( 'Invalid FID, -f. FID must be an integer between 1-128') brcdapi_log.log(ml, True) # Login session = brcdapi_rest.login(user_id, pw, ip, sec) if brcdapi_auth.is_error(session): brcdapi_log.log( 'Login failed:\n' + brcdapi_auth.formatted_error_msg(session), True) return -1 ec = 0 # Error code. 0: No errors. -1: error encountered port_info_d = dict() # Will use this to store basic port information port_stats_d = dict() # Will use this to store port statistics in # You may want to put better error checking in your code as well as use a more efficient code. A verbose coding # style was used here for readability. try: # Get the switch WWN brcdapi_log.log('Capturing chassis Data', True) uri = 'running/brocade-fibrechannel-logical-switch/fibrechannel-logical-switch' obj = brcdapi_rest.get_request(session, uri) if brcdapi_auth.is_error(obj): brcdapi_log.log(brcdapi_auth.formatted_error_msg(obj), True) ec = -1 else: # Find the switch with the matching FID switch_wwn = None for switch_obj in obj['fibrechannel-logical-switch']: if switch_obj['fabric-id'] == fid: switch_wwn = switch_obj['switch-wwn'] break if switch_wwn is None: brcdapi_log.log( 'Logical switch for FID ' + str(fid) + 'not found', True) ec = -1 # Get some basic port information if ec == 0: # Make sure we didn't encountered any errors above # It's common to keep track of other port information, such as the user friendly name and FC address. Below # captures this basic port information. brcdapi_log.log('Capturing basic port information.', True) uri = 'running/brocade-interface/fibrechannel' port_info = brcdapi_rest.get_request(session, uri, fid) if brcdapi_auth.is_error(port_info): brcdapi_log.log(brcdapi_auth.formatted_error_msg(port_info), True) ec = -1 else: # To make it easier to match the port information with the port statistics, we're going to create a # a dictionary using the port name (port number) as the key for port_obj in port_info['fibrechannel']: port_info_d.update({port_obj['name']: port_obj}) # Capture the port statistics if ec == 0: # Make sure we didn't encountered any errors above brcdapi_log.log('Capturing port statistics', True) uri = 'running/brocade-interface/fibrechannel-statistics' port_stats = brcdapi_rest.get_request(session, uri, fid) if brcdapi_auth.is_error(port_stats): brcdapi_log.log(brcdapi_auth.formatted_error_msg(port_stats), True) ec = -1 else: # We could just add each port to the database here but since it's common to capture additional # information, such as determining the login alias(es), we'll add it to a dictionary as was done with # the basic port information for port_obj in port_stats['fibrechannel-statistics']: port_stats_d.update({port_obj['name']: port_obj}) # Add all the ports to the database if ec == 0: # Make sure we didn't encountered any errors above brcdapi_log.log('Adding key value pairs to the database.', True) for port_num, port_obj in port_info_d.items(): sub_key = 'fcid-hex' # Just using the FC address for this example _db_add(switch_wwn, port_num, sub_key, port_obj[sub_key]) for k, v in port_stats_d[port_num].items(): _db_add(switch_wwn, port_num, k, v) except: # Bare because I don't care what went wrong. I just want to logout # The brcdapi_log.exception() method precedes the passed message parameter with a stack trace brcdapi_log.exception( 'Unknown programming error occured while processing: ' + uri, True) # Logout obj = brcdapi_rest.logout(session) if brcdapi_auth.is_error(obj): brcdapi_log.log( 'Logout failed:\n' + brcdapi_auth.formatted_error_msg(obj), True) return -1 return 0
def _get_input(): """Parses the module load command line :return ip_addr: IP address :rtype ip_addr: str :return id: User ID :rtype id: str :return pw: Password :rtype pw: str :return http_sec: Type of HTTP security :rtype http_sec: str :return suppress_flag: True - suppress all print to STD_OUT :rtype suppress_flag: bool :return fid: Fabric ID in chassis specified by -ip where the zoning information is to copied to. :rtype fid: int :return suppress_flag: True - suppress all print to STD_OUT :rtype suppress_flag: bool :return report_name: Name of Excel report. :rtype report_name: str """ global _DEBUG, _DEBUG_sup, _DEBUG_r, _DEBUG_i, _DEBUG_gp, _DEBUG_gs, _DEBUG_gt, _DEBUG_log, _DEBUG_nl if _DEBUG: args_sup, args_r, args_i, args_gp, args_gs, args_gt, args_log, args_nl =\ _DEBUG_sup, _DEBUG_r, _DEBUG_i, _DEBUG_gp, _DEBUG_gs, _DEBUG_gt, _DEBUG_log, _DEBUG_nl else: buf = 'Create Excel Workbook from statistics gathered with stats_c.py. WARNING: Graphing parameters are not ' \ 'yet implemented. This module will only create the Excel Workbook with tables. You will then need to ' \ 'create your own graphs manually.' parser = argparse.ArgumentParser(description=buf) buf = 'Suppress all library generated output to STD_IO except the exit code. Useful with batch processing' parser.add_argument('-sup', help=buf, action='store_true', required=False) parser.add_argument( '-r', help='Required. Report name. ".xlsx" is automatically appended.', required=True) buf = 'Required. Name of data input file. This must be the output file, -o, from stats_c.py. ".json" is '\ 'automatically appended' parser.add_argument('-i', help=buf, required=True) buf = 'Optional. Creates a worksheet with a graph of one or more statistical counters for a port. Useful for ' \ 'analyzing performance for a specific port. Parameters that follow are the port number followed by any '\ 'of the statistical parameters in brocade-interface/fibrechannel-statistics. Only the final leaf should '\ 'be used. All parameters must be separated by a comma. Separate multiple graphs with a semi-colon. '\ 'Graphs are plotted against the sample time. For example, to graph the Tx and Rx frames for port 3/14: '\ '"-gp 3/14,in-frames,out-frames"' parser.add_argument('-gp', help=buf, required=False) buf = 'Optional. Similar to the -gp option. Creates a worksheet with a graph for a specific statistical ' \ 'counter for one or more ports. Parameters that follow are the statistical counter followed by the '\ 'ports. To automatically pick the ports with the highest peak counts in any of the individual samples, '\ 'enter top-x instead of specific ports. To automatically pick the ports with highest accumulated count '\ 'over all samples, enter avg-x. For example, to graph the 5 ports with the highest accumulated BB '\ 'credit zero counters: -gs bb-credit-zero,avg-5.' parser.add_argument('-gs', help=buf, required=False) buf = 'Optional. Specifies the graph type. Valid chart types are: ' + ', '.join( report_graph.chart_types) + '. ' buf += 'Default: line.' parser.add_argument('-gt', help=buf, required=False) buf = '(Optional) Directory where log file is to be created. Default is to use the current directory. The log '\ 'file name will always be "Log_xxxx" where xxxx is a time and date stamp.' parser.add_argument( '-log', help=buf, required=False, ) buf = '(Optional) No parameters. When set, a log file is not created. The default is to create a log file.' parser.add_argument('-nl', help=buf, action='store_true', required=False) args = parser.parse_args() args_sup, args_r, args_i, args_gp, args_gs, args_gt, args_log, args_nl =\ args.sup, args.r, args.i, args.gp, args.gs, args.gt, args.log, args.nl # Set up log file and debug if args_sup: brcdapi_log.set_suppress_all() if not args_nl: brcdapi_log.open_log(args_log) return brcddb_file.full_file_name(args_r, '.xlsx'),\ brcddb_file.full_file_name(args_i, '.json'), \ args_gp, \ args_gs, \ args_gt
def pseudo_main(): """Basically the main(). Did it this way so it can easily be used as a standalone module or called from another. :return: Exit code. See exist codes in brcddb.brcddb_common :rtype: int """ # Get and validate the input parameters. Add all input arguments to the log ip, user_id, pw, sec, cli_file, fid, t_flag, f_flag, b_flag, s_flag, vd, log, nl = parse_args( ) if not nl: brcdapi_log.open_log(log) if vd: brcdapi_rest.verbose_debug = True content = { 'fid': fid, 'ip-addr': ip, 'id': user_id, 'pw': pw, 'sec': sec, 'force': False if f_flag is None else f_flag, 'test': False if t_flag is None else t_flag, 'bulk': False if b_flag is None else b_flag, } if s_flag: brcdapi_log.set_suppress_all() ml = list() if _DEBUG: ml.append('WARNING!!! Debug is enabled') ml.append('IP: ' + brcdapi_util.mask_ip_addr(ip, True)) ml.append('ID: ' + user_id) ml.append('CLI file: ' + cli_file) ml.append('FID: ' + str(fid)) ml.append('Test flag: ' + str(t_flag)) ml.append('Force flag: ' + str(f_flag)) ml.append('Bulk flag: ' + str(b_flag)) brcdapi_log.log(ml, True) # Read in the CLI file, condition the input strings and send it ml = list() try: file_contents = brcdapi_file.read_file(cli_file) except FileNotFoundError: ml.extend([ '', 'File ' + cli_file + ' not found. Did you remember the file extension?' ]) except PermissionError: ml.extend(['', 'You do not have permission to read ' + cli_file]) if len(ml) > 0: brcdapi_log.log(ml, True) return brcddb_common.EXIT_STATUS_INPUT_ERROR content.update(changes=brcddb_util.parse_cli(file_contents)) if t_flag: content.update(test=True) response = brcddb_zone.send_zoning(content) # General information ec = brcddb_common.EXIT_STATUS_OK total_changes = total_failures = total_io = i = 0 for obj in response: if isinstance( obj, dict ): # obj is None for blank or commented our lines in the input if obj.get('changed'): total_changes += 1 if obj.get('fail'): total_failures += 1 brcdapi_log.log(_format_fault(obj, i, file_contents), True) ec = brcddb_common.EXIT_STATUS_ERROR if obj.get('io'): total_io += 1 i += 1 ml = [ '', 'Summary:', 'Total Changes : ' + str(total_changes), 'Total Failures : ' + str(total_failures), 'Total I/O : ' + str(total_io) ] brcdapi_log.log(ml, True) return ec
def _get_input(): """Retrieves the command line input, reads the input Workbook, and validates the input :return ec: Error code from brcddb.brcddb_common :rtype ec: int :return sl: List of switches to poll as read from the input Workbook :rtype sl: list :return pl: List of project files to combine :rtype pl: list :return cfg_name: Name of zone configuration file to create :rtype cfg_name: str, None :return a_cfg: Activation flag. If True, activate the zone configuration specified by cfg_name :rtype a_cfg: bool :return t_flag: Test flag. If True, test only. Do not make any changes :rtype t_flag: bool :return scan_flag: Scan flag. If True, scan files and switches for fabric information :rtype scan_flag: bool :return addl_parms: Additional parameters (logging and debug flags) to pass to multi_capture.py :rtype addl_parms: list """ global _DEBUG, __version__ # Initialize the return variables ec = brcddb_common.EXIT_STATUS_OK addl_parms = list() # Get and validate the user input ip, user_id, pw, sec, fid, cfile, wwn, a_flag, scan_flag, d_flag, s_flag, log, nl = parse_args( ) if s_flag: addl_parms.append('-sup') brcdapi_log.set_suppress_all() if nl: addl_parms.append('-nl') else: brcdapi_log.open_log(log) if log is not None: addl_parms.extend(['-log', log]) if d_flag: addl_parms.append('-d') brcdapi_rest.verbose_debug = True buf = '' if isinstance(fid, int): buf = ' INVALID. Must be an integer in the range of 1-128' if fid < 0 or fid > 128 else '' ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ml.append('zone_merge.py version: ' + __version__) ml.append('IP address: ' + brcdapi_util.mask_ip_addr(ip)) ml.append('ID: ' + str(user_id)) ml.append('HTTPS: ' + str(sec)) ml.append('FID: ' + str(fid) + buf) ml.append('Input file: ' + cfile) ml.append('WWN: ' + str(wwn)) ml.append('Activate zone cfg: ' + str(a_flag)) ml.append('Scan: ' + str(scan_flag)) brcdapi_log.log(ml, True) if len(buf) > 0: return brcddb_common.EXIT_STATUS_INPUT_ERROR if sec is None: sec = 'none' ml = list() if not scan_flag: if ip is None: ml.append(' IP address (-ip)') if user_id is None: ml.append(' User ID (-id)') if pw is None: ml.append(' Password (-pw)') if fid is None: ml.append(' FID (-fid)') if len(buf) > 0: ml.append(' FID ' + buf) if wwn is None: ml.append(' Fabric WWN (-wwn)') if len(ml) > 0: ml.insert(0, 'Missing the following required parameters:') ml.append('Use the -h option for additional help.') brcdapi_log.log(ml, True) ec = brcddb_common.EXIT_STATUS_INPUT_ERROR return ec, ip, user_id, pw, sec, scan_flag, fid, cfile, wwn, a_flag, scan_flag, addl_parms
def pseudo_main(): """Basically the main(). :return: Exit code :rtype: int """ global _DEBUG # Get and validate command line input. ec = brcddb_common.EXIT_STATUS_OK ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list() ip, user_id, pw, sec, file, force, s_flag, echo, vd, log, nl = parse_args() if vd: brcdapi_rest.verbose_debug = True if s_flag: brcdapi_log.set_suppress_all() if not nl: brcdapi_log.open_log(log) if sec is None: sec = 'none' file = brcdapi_file.full_file_name(file, '.xlsx') if ip is not None: if user_id is None: ml.append('Missing user ID, -id') ec = brcddb_common.EXIT_STATUS_INPUT_ERROR if pw is None: ml.append('Missing password, -pw') ec = brcddb_common.EXIT_STATUS_INPUT_ERROR ml.append('File: ' + file) ml.append( 'IP address: ' + brcdapi_util.mask_ip_addr(ip) if isinstance(ip, str) else str(ip)) ml.append('ID: ' + str(user_id)) ml.append('sec: ' + sec) if len(ml) > 0: brcdapi_log.log(ml, True) if ec != brcddb_common.EXIT_STATUS_OK: return ec echo = False if echo is None else echo # Read in the Workbook, generate the portaddress --bind commands, and configure the switch(es) switch_d_list = [ switch_d for switch_d in report_utils.parse_switch_file(file).values() ] session = proj_obj = None try: for switch_d in switch_d_list: switch_d.update(err_msgs=list()) # Create the bind commands if switch_d['bind']: _bind_commands(switch_d) cli_l = switch_d['bind_commands'].copy() i = 0 while i < len(cli_l): cli_l.insert(i, '') i += 16 cli_l.insert( 0, '\n# Bind commands for FID ' + str(switch_d['fid'])) cli_l.append('\n# End bind commands for FID ' + str(switch_d['fid'])) brcdapi_log.log(cli_l, True) # Create the logical switch if ip is not None and switch_d['switch_flag']: if session is None: # Login session = api_int.login(user_id, pw, ip, sec, proj_obj) if fos_auth.is_error(session): return brcddb_common.EXIT_STATUS_API_ERROR if proj_obj is None: # Create a project object proj_obj = brcddb_project.new( 'Create_LS', datetime.datetime.now().strftime('%d %b %Y %H:%M:%S')) proj_obj.s_python_version(sys.version) proj_obj.s_description('Creating logical switches from ' + os.path.basename(__file__)) api_int.get_batch(session, proj_obj, _basic_capture_kpi_l, None) if proj_obj.r_is_any_error(): switch_d['err_msgs'].append( 'Error reading logical switch information from chassis' ) brcdapi_log.log( switch_d['err_msgs'][len(switch_d['err_msgs']) - 1], True) else: ec = _configure_switch(user_id, pw, session, proj_obj, switch_d, force, echo) except BaseException as e: switch_d['err_msgs'].append( 'Programming error encountered. Exception: ' + str(e)) brcdapi_log.log(switch_d['err_msgs'][len(switch_d['err_msgs']) - 1], True) ec = brcddb_common.EXIT_STATUS_ERROR # Logout and create and print a summary report if session is not None: obj = brcdapi_rest.logout(session) if fos_auth.is_error(obj): brcdapi_log.log(fos_auth.formatted_error_msg(obj), True) ec = brcddb_common.EXIT_STATUS_API_ERROR if ip is not None: _print_summary(switch_d_list) return ec