Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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()
Ejemplo n.º 3
0
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 exit codes in brcddb.brcddb_common
    :rtype: int
    """
    global __version__
    global _DEBUG_id, _DEBUG_pw, _DEBUG_ip

    ec, ip, user_id, pw, sec, scan_flag, fid, cfile, wwn, a_flag, scan_flag, addl_parms = _get_input(
    )

    if ec != brcddb_common.EXIT_STATUS_OK:
        return ec

    # Read the project file
    proj_obj = brcddb_project.read_from(
        brcdapi_file.full_file_name(cfile, '.json'))
    if proj_obj is None:
        return brcddb_common.EXIT_STATUS_ERROR
    fab_obj = None
    if not scan_flag:
        fab_obj = proj_obj.r_fabric_obj(wwn)
        if fab_obj is None:
            brcdapi_log.log(
                wwn + ' does not exist in ' + cfile +
                '. Try using the -scan option', True)
            return brcddb_common.EXIT_STATUS_INPUT_ERROR

    if scan_flag:
        return _scan_fabrics(proj_obj)

    # 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

    # Make the zoning change
    try:
        brcdapi_log.log('Sending zone updates to FID ' + str(fid), True)
        obj = api_zone.replace_zoning(session, fab_obj, fid)
        if fos_auth.is_error(obj):
            brcdapi_log.log(fos_auth.formatted_error_msg(obj), True)
        else:
            brcdapi_log.log('Zone restore completed successfully.', True)

    except BaseException as e:
        brcdapi_log.log(['', 'Software error.', 'Exception: ' + str(e)], True)

    # Logout
    obj = brcdapi_rest.logout(session)
    if fos_auth.is_error(obj):
        brcdapi_log.log(fos_auth.formatted_error_msg(obj), True)

    return ec
def _def_report_act(obj):
    global _wb, _report_name, _report_display

    if not _has_sheet_name(obj, 'workbook'):
        return  # Appropriate error message is logged in _has_sheet_name
    _wb = excel_util.new_report()
    _report_name = brcdapi_file.full_file_name(obj.get('name'), '.xlsx')
    for k, v in obj.items():
        if k != 'name':
            _report_display.update({k: v})
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
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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 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
Ejemplo n.º 9
0
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
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 _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 _get_project(sl, pl, addl_parms):
    """Reads or captures project data

    :param sl: List of switches to poll via the API
    :type sl: list
    :param pl: List of project files to combine
    :type pl: list
    :param addl_parms: Additional parameters (debug and logging) to be passed to capture.py.
    :type addl_parms: list
    :return rl: List of error messages
    :rtype: list
    :return proj_obj: Project object. None if there was an error obtaining the project object
    :rtype proj_obj: brcddb.classes.project.ProjObj, None
    """
    global _ZONE_KPI_FILE

    rl = list()  # Error messages

    # Create project
    proj_obj = brcddb_project.new(
        'zone_merge',
        datetime.datetime.now().strftime('%d %b %Y %H:%M:%S'))
    proj_obj.s_python_version(sys.version)
    proj_obj.s_description('Zone merge')

    # Get a unique folder name for multi_capture.py and combine.py
    folder_l = [f for f in os.listdir('.') if not isfile(f)]
    base_folder = '_zone_merge_work_folder_'
    i = 0
    work_folder = base_folder + str(i)
    while work_folder in folder_l:
        i += 1
        work_folder = base_folder + str(i)
    os.mkdir(work_folder)

    # Add the KPI file for the captures
    zone_kpi_file = work_folder + '/' + _ZONE_KPI_FILE
    f = open(zone_kpi_file, 'w')
    f.write('\n'.join(_kpis_for_capture) + '\n')
    f.close()

    # Start all the data captures for the switches to be polled so that multiple switches can be captured in parallel
    if len(sl) > 0:
        brcdapi_log.log('Collecting zoning data from switches', True)
    captured_d = dict()
    pid_l = list()
    for sub_d in sl:
        ip_addr = sub_d['ip']
        file_name = work_folder + '/switch_' + ip_addr.split(
            '.').pop() + '_' + str(len(pid_l))
        sub_d.update(file=file_name)
        file_name = brcdapi_file.full_file_name(file_name, '.json')
        d = captured_d.get(ip_addr)
        if d is None:
            sub_d_l = list()
            captured_d.update({ip_addr: dict(sub_d_l=sub_d_l, file=file_name)})
            params = [
                'python.exe', 'capture.py', '-ip', ip_addr, '-id', sub_d['id'],
                '-pw', sub_d['pw'], '-s', 'none' if sub_d['sec'] is None else
                sub_d['sec'], '-f', file_name, '-c', zone_kpi_file
            ] + addl_parms
            pid_l.append(
                dict(p=subprocess.Popen(params),
                     file_name=file_name,
                     ip=ip_addr))
        sub_d_l.append(sub_d)

    # Add the data read from this chassis to the project object
    for pid_d in pid_l:  # Wait for all captures to complete before continuing
        pid_d.update(s=pid_d['p'].wait())
        brcdapi_log.log(
            'Completed capture for ' + pid_d['file_name'] +
            '. Ending status: ' + str(pid_d['s']), True)
    for pid_d in pid_l:
        obj = brcdapi_file.read_dump(pid_d['file_name'])
        if obj is None:
            rl.append('Capture for ' + file_name + '. failed.')
        else:
            brcddb_copy.plain_copy_to_brcddb(obj, proj_obj)
            captured_d[pid_d['ip']].update(fab_keys=obj['_fabric_objs'].keys())
    if len(rl) > 0:
        return rl, proj_obj

    # Figure out the fabric WWN for all the FIDs for the polled switches
    for d in captured_d.values():
        fab_obj_l = [proj_obj.r_fabric_obj(k) for k in d['fab_keys']]
        for fab_obj in fab_obj_l:
            if fab_obj.r_get(
                    'zone_merge'
            ) is None:  # I can't think of a reason why it wouldn't be None
                fab_obj.s_new_key('zone_merge', dict(file=d['file']))
        for sub_d in d['sub_d_l']:
            found = False
            fid = sub_d['fid']
            if isinstance(
                    fid, int
            ):  # If the user is just running a scan, there won't be a fid
                for fab_obj in fab_obj_l:
                    if fid in brcddb_fabric.fab_fids(fab_obj):
                        s_buf = 'none' if sub_d['sec'] is None else sub_d['sec']
                        zm_d = fab_obj.r_get('zone_merge')
                        zm_d.update(fab_wwn=fab_obj.r_obj_key(),
                                    update=sub_d['update'],
                                    cfg=sub_d['cfg'],
                                    fid=sub_d['fid'],
                                    ip=sub_d['ip'],
                                    id=sub_d['id'],
                                    pw=sub_d['pw'],
                                    sec=s_buf)
                        fab_obj.s_new_key('zone_merge', zm_d)
                        found = True
                        break
                if not found:
                    rl.append('Could not find FID ' + str(fid) + ' in ' +
                              brcdapi_util.mask_ip_addr(sub_d['ip']))

    # Add in all the read in project files
    if len(pl) > 0:
        brcdapi_log.log('Reading project files', True)
    for sub_d in pl:
        file_name = brcdapi_file.full_file_name(sub_d['project_file'], '.json')
        obj = brcdapi_file.read_dump(file_name)
        brcddb_copy.plain_copy_to_brcddb(obj, proj_obj)
        for fab_obj in [
                proj_obj.r_fabric_obj(k) for k in obj['_fabric_objs'].keys()
        ]:
            if fab_obj.r_get(
                    'zone_merge'
            ) is None:  # It should be None. This is just future proofing.
                fab_obj.s_new_key('zone_merge', dict(file=file_name))
        fab_obj = proj_obj.r_fabric_obj(sub_d.get('fab_wwn'))
        if fab_obj is None:
            rl.append('Could not find fabric WWN ' +
                      str(sub_d.get('fab_wwn')) + ' in ' + file_name)
        else:
            fab_obj.r_get('zone_merge').update(fab_wwn=fab_obj.r_obj_key(),
                                               update=False,
                                               cfg=sub_d['cfg'])

    return rl, proj_obj
Ejemplo n.º 13
0
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