Exemple #1
0
def _format_uri(kpi, fid):
    """Formats a full URI for a KPI.

    :param kpi: Rest KPI
    :type kpi: str
    :param fid: Fabric ID
    :type fid: int, None
    :return: Full URI
    :rtype: str
    """
    l = kpi.split('/')
    if len(l) > 2:
        lookup_kpi = '/'.join(l[0:2])
        remaining_l = l[2:]
    else:
        lookup_kpi = kpi
        remaining_l = list()
    try:
        buf = brcdapi_util.uri_map[lookup_kpi]['uri']
        if len(remaining_l) > 0:
            buf += '/' + '/'.join(remaining_l)
        if brcdapi_util.uri_map[lookup_kpi]['fid']:
            buf += vfid_to_str(fid)
        return buf
    except:
        buf = '/rest/running/' + kpi + vfid_to_str(fid)
        brcdapi_log.log(
            'ERROR: Unknown KPI: ' + lookup_kpi + '. Using best guess: ' + buf,
            True)
        brcdapi_log.flush()
        return buf
Exemple #2
0
def _scan_fabrics(proj_obj):
    """Scan the project for each fabric and list the fabric WWN, FID , and zone configurations

    :param proj_obj: Project object
    :type proj_obj: brcddb.classes.project.ProjectObj
    :return: Status code
    :rtype: int
    """

    ec = brcddb_common.EXIT_STATUS_OK

    # Prepare the fabric display
    ml = ['', 'Fabric Scan (* indicates the effective zone config)', '']
    for fab_obj in proj_obj.r_fabric_objects():
        eff_zonecfg = fab_obj.r_defined_eff_zonecfg_key()
        ml.append(brcddb_fabric.best_fab_name(fab_obj, wwn=True))
        ml.append(
            '  FID:         ' +
            ', '.join([str(fid) for fid in brcddb_fabric.fab_fids(fab_obj)]))
        for buf in fab_obj.r_zonecfg_keys():
            if isinstance(eff_zonecfg, str) and eff_zonecfg == buf:
                ml.append('  Zone Config: ' + '*' + buf)
            elif buf != '_effective_zone_cfg':
                ml.append('  Zone Config: ' + buf)
        ml.append('')

    # Wrap up and print fabric information
    if len(ml) == 0:
        ml.append('No fabrics specified.')
        ec = brcddb_common.EXIT_STATUS_INPUT_ERROR
    brcdapi_log.log(ml, True)

    return ec
def _db_add(key_0, key_1, key_2, val):
    """Stubbed out method to add key value pairs to your database

    :param key_0: First key
    :type key_0: str
    :param key_1: Second key
    :type key_1: str
    :param key_2: Third key
    :type key_2: str
    :param val: Value associated with the keys
    :type val: str, int, float
    """
    key_list = [key.replace(':', '_').replace('/', '_') for key in (key_0, key_1, key_2)]
    # If you are new to Python, above is equivalent to:
    # key_list = list()
    # for key in (key_0, key_1, key_2):
    #     key_list.append(key.replace(':', '_').replace('/', '_'))
    # It's probably better to do the equivalent of the key.replace above with a compiled regex but for the few usec it
    # may save, this is good enough for a simple example.

    # You might want to make sure you are adding a valid value to your database.
    if not isinstance(val, (str, int, float)):
        brcdapi_log.log('Invalid value type, ' + str(type(val)) + ', for key: ' + '/'.join(key_list), True)
        return
    # It's probably a good idea to make sure the keys are valid as well. In this example, we're only going to convert
    # ':' (used in the switch WWN) and '/' (used in the port number) to an underscore, '_'. There may be other
    # characters, such as '-', that are not valid database keys that you will need to modify.

    brcdapi_log.log('Adding key: ' + '/'.join(key_list) + ', Value: ' + str(val), True)
def clear_stats(session, switch_obj):
    """Clear all statistical counters associated with a switch

    :param session: Session object returned from brcdapi.fos_auth.login()
    :type session: dict
    :param switch_obj: Switch object
    :type switch_obj: brcddb.classes.SwitchObj
    :return: Ending status code
    :rtype: int
    """
    ec = brcddb_common.EXIT_STATUS_OK
    stats_list = [
        dict(ports=switch_obj.r_port_keys(),
             content='fibrechannel-statistics'),
        dict(ports=switch_obj.r_ge_port_keys(),
             content='gigabitethernet-statistics')
    ]
    for stats in stats_list:
        if len(stats.get('ports')) > 0:
            pl = list()
            fid = brcddb_switch.switch_fid(switch_obj)
            content = {stats.get('content'): pl}
            for p in stats.get('ports'):
                d = dict()
                d.update({'name': p})
                d.update({'reset-statistics': 1})
                pl.append(d)
            obj = brcdapi_rest.send_request(
                session, 'running/brocade-interface/fibrechannel-statistics',
                'PATCH', content, fid)
            if fos_auth.is_error(obj):
                brcdapi_log.log(fos_auth.obj_error_detail(obj), True)
                ec = brcddb_common.EXIT_STATUS_ERROR

    return ec
Exemple #5
0
def _get_parameters(parms):
    """Returns a list of Excel column letters matching the list of parms

    :param parms: Parameters to plot as passed in from the command line with the -p option
    :type parms: None, str, list
    :return: List of columns matching the parameters
    :rtype: list
    """
    global _invalid_parm_ref

    # Build a header to KPI reference table
    r_map = dict()
    for k, d in rt.Port.port_display_tbl.items():
        if 'fibrechannel-statistics/' in k:
            v = d.get('d')
            if v is not None:
                r_map.update({v: k})

    # Now figure out what to return
    r = list()
    for p in parms.split(','):
        v = r_map.get(p)
        if v is None:
            brcdapi_log.log(_invalid_parm_ref + p, True)
        else:
            r.append(v)
    return r
Exemple #6
0
def _create_switch(session, chassis_obj, switch_d, echo):
    """Creates a logical switch

    :param session: Session object, or list of session objects, returned from brcdapi.fos_auth.login()
    :type session: dict
    :param chassis_obj: Chassis object
    :type chassis_obj: brcddb.classes.chassis.ChassisObj
    :param switch_d: Switch object as returned from report_utils.parse_switch_file()
    :type switch_d: dict
    :param echo: If True, echo switch configuration details to STD_OUT
    :type echo: bool
    """
    global _basic_capture_kpi_l

    fid = switch_d['fid']
    buf = 'Creating FID ' + str(
        fid
    ) + '. This will take about 20 sec per switch + 25 sec per group of 32 ports.'
    brcdapi_log.log(buf, True)
    base = True if switch_d['switch_type'] == 'base' else False
    ficon = True if switch_d['switch_type'] == 'ficon' else False
    obj = brcdapi_switch.create_switch(session, fid, base, ficon, echo)
    if fos_auth.is_error(obj):
        switch_d['err_msgs'].append('Error creating FID ' + str(fid))
        brcdapi_log.log([
            switch_d['err_msgs'][len(switch_d['err_msgs']) - 1],
            fos_auth.formatted_error_msg(obj)
        ], True)
        return brcddb_common.EXIT_STATUS_ERROR

    # re-read the chassis and logical switch data to pick up the switch we just created.
    session.pop('chassis_wwn', None)
    api_int.get_batch(session, chassis_obj.r_project_obj(),
                      _basic_capture_kpi_l, None)
    return chassis_obj.r_switch_obj_for_fid(fid)
Exemple #7
0
def _rules_to_keep(session, fid, maps_policy):
    """Get the current MAPS rules 'brocade-maps/rule' from specified policy and remove all the SFP rules.

    :param session: Session object returned from brcdapi.brcdapi_auth.login()
    :type session: dict
    :param fid: Fabric ID of the logical switch whose MAPS policy we want to modify. None if not VF enabled
    :type fid: None, str
    :param maps_policy: MAPS policy from 'brocade-maps/maps-policy' to keep
    :type maps_policy: dict
    :return: List of rule names to keep. None if error encountered
    :rtype: list
    """
    global _sfp_groups

    # Get all the MAPS rules
    obj = api_int.get_rest(session, 'brocade-maps/rule', None, fid)
    if brcdapi_auth.is_error(obj):
        brcdapi_log.log('Failed to get MAPS rules.',
                        True)  # api_int.get_rest() logs detailed error message
        return None

    # Remove all old SFP rules and add the new rules
    rule_list = maps_policy.get('rule-list').get('rule')
    return [
        rule.get('name') for rule in obj.get('rule')
        if rule.get('monitoring-system') not in _sfp_monitoring_system
        and rule.get('name') in rule_list
    ]
Exemple #8
0
def _create_new_policy(session, fid, policy, rule_list, enable_flag=False):
    """Create a new MAPS policy.

    :param session: Session object returned from brcdapi.brcdapi_auth.login()
    :type session: dict
    :param fid: Fabric ID of the logical switch whose MAPS policy we want to modify. None if not VF enabled
    :type fid: None, str
    :param policy: Name of the MAPS policy to create
    :type policy: str
    :param rule_list: List of rule names for the MAPS policy
    :type rule_list: list
    :param enable_flag: If True, enables the policy
    :type enable_flag: bool
    :return: List of new rules
    :rtype: list
    """
    new_content = {
        'name': policy,
        'rule-list': {
            'rule': rule_list
        },
        'is-active-policy': enable_flag
    }

    # Now send the new MAPS policy to the switch
    obj = brcdapi_rest.send_request(session, 'runningbrocade-maps/maps-policy',
                                    'POST', {'maps-policy': new_content}, fid)
    if brcdapi_auth.is_error(obj):
        brcdapi_log.log(
            'Failed to set MAPS policy. API response:\n' +
            brcdapi_auth.formatted_error_msg(obj), True)
        brcdapi_log.log(
            'This typically occurs when the policy already exists.', True)
        return brcddb_common.EXIT_STATUS_API_ERROR
    return brcddb_common.EXIT_STATUS_OK
Exemple #9
0
def checksum(session, fid, echo=False):
    """Gets a zoning transaction checksum

    :param session: Session object returned from brcdapi.pyfos_auth.login()
    :type session: dict
    :param fid: Logical FID number for the fabric of interest
    :type fid: int
    :param echo: If True, echoes any error messages to STD_OUT
    :type echo: bool
    :return: checksum
    :rtype: int, None
    :return: brcdapi_rest status object
    :rtype: dict
    """
    # Get the checksum - this is needed to save the configuration.
    obj = brcdapi_rest.get_request(session,
                                   'brocade-zone/effective-configuration', fid)
    if _is_error(
            obj,
            'Failed to get zone data from "brocade-zone/effective-configuration"',
            echo):
        return None, obj
    try:
        return obj.get('effective-configuration').get('checksum'), obj
    except:
        brcdapi_log.log('Failed to get checksum', echo)
        brcdapi_log.exception(pprint.pformat(obj, indent=4), echo)
        return None, pyfos_auth.create_error(
            brcdapi_util.HTTP_INT_SERVER_ERROR,
            brcdapi_util.HTTP_REASON_UNEXPECTED_RESP,
            'Missing effective-configuration/checksum')
Exemple #10
0
def _retry(obj):
    """Determines if a request should be retried.

    :param obj: Object returned from _api_request()
    :type obj: dict
    :return retry_flag: True - request should be retried. False - request should not be retried.
    :rtype retry_flag: bool
    :return delay: Time, in seconds, to wait for retrying the request
    :rtype delay: int
    """
    status = pyfos_auth.obj_status(obj)
    reason = pyfos_auth.obj_reason(obj) if isinstance(
        pyfos_auth.obj_reason(obj), str) else ''
    if isinstance(status, int) and status == 503 and isinstance(
            reason, str) and 'Service Unavailable' in reason:
        brcdapi_log.log(
            'FOS API services unavailable. Will retry in ' +
            str(_SVC_UNAVAIL_WAIT) + ' seconds.', True)
        return True, _SVC_UNAVAIL_WAIT
    if status == brcdapi_util.HTTP_BAD_REQUEST and 'The Fabric is busy' in pyfos_auth.formatted_error_msg(
            obj):
        brcdapi_log.log('Fabric is busy. Will retry in ' +
                        str(_FABRIC_BUSY_WAIT) + ' seconds.')
        return True, _FABRIC_BUSY_WAIT
    return False, 0
Exemple #11
0
def _get_policy(session, fid, policy=None):
    """Get the specified MAPS policy. If None, return the active MAPS policy

    :param session: Session object returned from brcdapi.brcdapi_auth.login()
    :type session: dict
    :param fid: Fabric ID of the logical switch whose MAPS policy we want to modify. None if not VF enabled
    :type fid: None, int
    :param policy: Name of policy to look for. If None, returns the active policy
    :type policy: str, None
    :return: Active MAPS policy. None if no active MAPS policy
    :rtype: int
    """
    # Get the policies
    obj = api_int.get_rest(session, 'brocade-maps/maps-policy', None, fid)
    if brcdapi_auth.is_error(obj):
        brcdapi_log.log('Failed to get MAPS policies.',
                        True)  # api_int.get_rest() logs detailed error message
        return brcddb_common.EXIT_STATUS_API_ERROR, None

    # Find the policy to return
    for maps_policy in obj.get('maps-policy'):
        if policy is None:
            if maps_policy.get('is-active-policy'):
                return brcddb_common.EXIT_STATUS_OK, maps_policy
        elif maps_policy.get('name') == policy:
            return brcddb_common.EXIT_STATUS_OK, maps_policy
    return brcddb_common.EXIT_STATUS_INPUT_ERROR, None  # If we got this far, we didn't find the policy
Exemple #12
0
def _print_summary(switch_d_list):
    """Enable switch

    :param switch_d_list: List of switch dictionaries
    :type switch_d_list: list
    """
    ml = ['\nSummary', '_______']
    for switch_d in switch_d_list:
        ml.append('\nFID: ' + str(switch_d.get('fid')))
        ml.append(
            '  Switch Name:            ' +
            brcddb_switch.best_switch_name(switch_d.get('switch_obj'), True))
        ml.append('  Switch Created:         ' + str(switch_d.get('created')))
        try:
            ml.append('  Ports Added:            ' +
                      str(len(switch_d['ports'].keys())))
            ml.append('  Ports Removed:          ' +
                      str(len(switch_d['remove_ports'])))
            ml.append('  Online Ports Not Moved: ' +
                      str(len(switch_d['online_ports'])))
            ml.append('  Ports Not Found:        ' +
                      str(len(switch_d['not_found_ports'])))
        except:
            pass  # We should never get here but I'm not changing working code.
        err_msgs = gen_util.convert_to_list(switch_d.get('err_msgs'))
        if len(err_msgs) > 0:
            ml.append('  Error Messages:         ')
            ml.extend(['    ' + buf for buf in err_msgs])
    brcdapi_log.log(ml, True)
Exemple #13
0
def port_enable_disable(session, fid, state, i_ports, echo=False):
    """Enables a port or list of ports.

    :param session: Session object returned from brcdapi.pyfos_auth.login()
    :type session: dict
    :param fid: Logical FID number for switch with ports. Use None if switch is not VF enabled.
    :type fid: int
    :param state: True - enable ports. False - disable ports
    :type state: bool
    :param i_ports: List of ports to enable or disable
    :type i_ports: tuple, list
    :return: The object returned from the API. If ports is an empty list, a made up good status is returned.
    :rtype: dict
    """
    ports = ports_to_list(i_ports)
    if len(ports) == 0:
        return brcdapi_util.GOOD_STATUS_OBJ

    # Now enable/disable the port(s)
    buf = 'En' if state else 'Dis'
    brcdapi_log.log(buf + 'abling ' + str(len(ports)) + ' ports.', echo)
    return brcdapi_rest.send_request(
        session, 'brocade-interface/fibrechannel', 'PATCH', {
            'fibrechannel': [{
                'name': p,
                'is-enabled-state': state
            } for p in ports]
        }, fid)
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 _db_add(key_0, key_1, key_2, val):
    """Stubbed out method to add key value pairs to your database. Derives a unique key from a hash of the 3 input keys

    :param key_0: First key (switch WWN in xx:xx:xx:xx:xx:xx:xx:xx notation)
    :type key_0: str
    :param key_1: Second key (port number in s/p notation)
    :type key_1: str
    :param key_2: Third key (value type such as CRC)
    :type key_2: str
    :param val: Value associated with the keys
    :type val: str, int, float
    """
    # You might want to make sure you are adding a valid value to your database.
    if not isinstance(val, (str, int, float)):
        brcdapi_log.log(
            'Invalid value type, ' + str(type(val)) + ', for database.', True)
        return

    # Verbose explanation of the next line of code:
    # key_list = list() - create a list to store the keys in
    # for key in (key_0, key_1, key_2):
    #     clean_key = key.replace(':', '_').replace('/', '_') - Replace ':' and '/' with '_'
    #     short_key = clean_key[11:] - removes the non-unique portion of WWN in the key
    #     key_list.append(short_key) - Add the key to key_list
    # For the Python savvy, a compiled regex would be better than .replace() above but this is good enough for a simple
    # example. Using a regex probably won't save enough time to make researching it worthwhile so if you don't
    # understand this comment, just stick with using .replace().
    key_list = [
        key.replace(':', '_').replace('/', '_')[11:]
        for key in (key_0, key_1, key_2)
    ]

    unique_key = '_'.join(
        key_list)  # Concatenates all items in key_list seperated by a '_'
    brcdapi_log.log('Adding key: ' + unique_key + ', Value: ' + str(val), True)
def _validate_obj_type(obj_l, obj_type):
    type_l = gen_util.remove_duplicates(
        [brcddb_class_util.get_simple_class_type(obj) for obj in obj_l])
    if (len(type_l) == 1 and type_l[0] == obj_type) or len(type_l) == 0:
        return True
    brcdapi_log.log(
        'Invalid report object type. Expected: ' + obj_type + '. Received: ' +
        ', '.join(type_l), True)
    return False
def _report_switch_act(obj, disp):
    global _wb, _working_obj_l

    if not _validate_obj_type(_working_obj_l, 'SwitchObj'):
        brcdapi_log.log('Invalid object type for "switch"', True)
        return

    brcdapi_log.log('Creating ' + obj['name'], True)
    report_switch.switch_page(_wb, None, obj['name'], obj.get('index'),
                              obj.get('title'), _working_obj_l)
def _logout(session):
    """Logout and post message if the logout failed

    :param session: Session object returned from brcdapi.brcdapi_auth.login()
    :type session: dict
    """
    obj = brcdapi_rest.logout(session)
    if brcdapi_auth.is_error(obj):
        brcdapi_log.log(
            'Logout failed:\n' + brcdapi_auth.formatted_error_msg(obj), True)
Exemple #19
0
def _compare(r_obj, ref, b_obj, c_obj, control_tbl):
    """Compares two dict, list, tuple, or brcddb.classes objects

    :param r_obj: Return object - Dictionary or list of changes
    :type r_obj: dict, list
    :param ref: Reference key.
    :type ref: str
    :param b_obj: Base object to compare against.
    :type b_obj: dict, list, tuple, brcddb.classes.*
    :param c_obj: Compare object
    :type c_obj: dict, list, tuple, brcddb.classes.*
    :param control_tbl: Control table.
    :type control_tbl: dict
    :return: Number of mismatches found
    :rtype: int
    """
    global _obj_type_action, _REMOVED, _NEW, _MISMATCH, _INVALID_REF

    # Make sure we have a valid reference.
    if not isinstance(ref, str):
        brcdapi_log.exception('Invalid reference type: ' + str(type(ref)),
                              True)
        _update_r_obj(r_obj, {'b': '', 'c': '', 'r': _INVALID_REF})
        return 0

    # Does the base object exist?
    if b_obj is None:
        _update_r_obj(r_obj, {'b': ref, 'c': '', 'r': _NEW})
        return 1

    # Does the compare object exist?
    if c_obj is None:
        _update_r_obj(r_obj, {'b': ref, 'c': '', 'r': _REMOVED})
        return 1

    # Are we comparing the same types? A mix of int and float is OK so that gets normalized to type 'num'
    b_type = class_util.get_simple_class_type(b_obj)
    if b_type is None:
        b_type = 'num' if isinstance(b_obj, (int, float)) else \
            str(type(b_obj)).replace('<class ', '').replace('>', '').replace("\'", '')
    c_type = class_util.get_simple_class_type(c_obj)
    if c_type is None:
        c_type = 'num' if isinstance(c_obj, (int, float)) else \
            str(type(c_obj)).replace('<class ', '').replace('>', '').replace("\'", '')
    if b_type != c_type:
        _update_r_obj(r_obj, {'b': b_type, 'c': c_type, 'r': _MISMATCH})
        return 1

    if b_type in _obj_type_action:
        return _obj_type_action[b_type](r_obj, ref, b_obj, c_obj, control_tbl)

    brcdapi_log.log('Unknown base object type: ' + b_type, True)
    _update_r_obj(r_obj, {'b': b_type, 'c': '', 'r': _INVALID_REF})
    return 1
def _report_port_act(obj, disp):
    global _wb, _working_obj_l

    if not _validate_obj_type(_working_obj_l, 'PortObj'):
        brcdapi_log.log('Invalid object type for "port"', True)
        return

    brcdapi_log.log('Creating ' + obj['name'], True)
    report_port.port_page(_wb, None, obj['name'], obj.get('index'),
                          obj.get('title'),
                          brcddb_util.sort_ports(_working_obj_l), disp)
Exemple #21
0
def _clear_dashboard(session, fid):
    """Clears the MAPS dashboard

    :return fid: Fabric ID
    :rtype fid: int
    """
    content = {'clear-data': True}
    obj = brcdapi_rest.send_request(session, 'running/brocade-maps/dashboard-misc', 'PUT', content, fid)
    if brcdapi_auth.is_error(obj):
        brcdapi_log.log(brcdapi_auth.formatted_error_msg(obj), True)
        return -1
    return 0
def _print_disp(obj):
    global _working_obj_l

    disp = gen_util.convert_to_list(obj.get('disp'))
    to_print_l = list()
    for b_obj in _working_obj_l:
        for buf in disp:
            for d in gen_util.convert_to_list(obj.get('replace')):
                buf = buf.replace(d['t'], str(b_obj.r_get(d['r'])))
            to_print_l.append(buf)
    if len(to_print_l) > 0:
        brcdapi_log.log(to_print_l, True)
def _get_chassis_data(session):
    """Capture chassis data as would be returned from (not all chassis data is being captured):

    :param session: The session object returned from brcdapi.fos_auth.login()
    :type session: dict
    :return: FID list
    :rtype: list
    """
    global _chassis_rest_data

    # Get all the chassis data
    # Note that in Gen 6 and above, the license ID, brocade-chassis/chassis/license-id, may not be the chassis WWN
    for kpi in _chassis_rest_data:  # See comments with _chassis_rest_data above
        ml = ['', kpi
              ]  # The first member as '' inserts a blank line before the KPI
        obj = brcdapi_rest.get_request(session, kpi)
        if brcdapi_auth.is_error(obj):
            ml.append(brcdapi_auth.formatted_error_msg(obj))
        else:
            ml.append(pprint.pformat(obj))
        brcdapi_log.log(ml, True)
    """This is essentially a hybrid of lscfg --show and switchshow. This is where all the logical switches and ports
    associated with those logical switches are reported. I broke this out from _chassis_rest_data because we need to
    pick out the fabric IDs of all the logical switches."""

    kpi = 'running/brocade-fibrechannel-logical-switch/fibrechannel-logical-switch'
    ml = ['', kpi]
    obj = brcdapi_rest.get_request(session, kpi)
    if brcdapi_auth.is_error(obj):
        ml.append(brcdapi_auth.formatted_error_msg(obj))
        brcdapi_log.log(ml, True)
        return list(
        )  # A return in the middle of a method is common in Python after an error is encountered.

    ml.append(pprint.pformat(obj))
    """Normally, I would build a dictionary of the ports so I could treat them as objects and add port
    configuration, port statistics, and anything else port specific to the object.
    
    I don't recall how a non-VF enabled switch responds but I don't think 'fabric-id' is present in the response.

    If you are new to Python, there is a construct referred to as a list comprehension which allows you to build a
    list in a single line of code. The code that follows this comment is equivalent to:
    
    fid_list = list()
    for ls in obj['fibrechannel-logical-switch']:
        if ls.get('fabric-id') is not None:
            fid_list.append(ls.get('fabric-id'))
    return fid_list"""

    return [
        ls.get('fabric-id') for ls in obj['fibrechannel-logical-switch']
        if ls.get('fabric-id') is not None
    ]
Exemple #24
0
def write_dump(obj, file):
    """Creates a file using json.dumps. Typical use is to convert a project object with brcddb_to_plain_copy to a plain
    Python dict.
    :param obj: Dictionary to write to file
    :type obj: dict, list
    :param file: Name of file to write to
    :type file: str
    :rtype: None
    """
    brcdapi_log.log('CALL: brcddb_util.write_dump. File: ' + file)
    with open(file, 'w') as f:
        f.write(json.dumps(obj, sort_keys=True))
    f.close()
Exemple #25
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 _DEBUG, __version__, _ZONE_CHECK

    # Get and validate user input
    inf, outf, sfp_rules, iocp, custom_parms = _get_input()
    ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list()
    ml.append('report.py version ' + __version__)
    ml.append('In file:  ' + inf)
    ml.append('Out file: ' + outf)
    ml.append('SFP rules file: ' + str(sfp_rules))
    if sfp_rules is not None:
        ml.append("The 'User Warning: Data Validation ...' can be ignored.")
        brcddb_bp.sfp_rules = report_utils.parse_sfp_file(sfp_rules)
    ml.append('custom_parms:     ' + str(custom_parms))
    brcdapi_log.log(ml, True)

    # Get the project object
    try:
        proj_obj = brcddb_project.read_from(inf)
    except FileNotFoundError:
        brcdapi_log.log('Input file, ' + inf + ', not found', True)
        return brcddb_common.EXIT_STATUS_ERROR
    if proj_obj is None:
        return brcddb_common.EXIT_STATUS_ERROR

    # Perform all pre-processing (parse IOCPs, build references, ...)
    brcdapi_log.log('Building cross references', True)
    brcddb_project.build_xref(proj_obj)
    brcddb_project.add_custom_search_terms(proj_obj)
    brcdapi_log.log('Performing mainframe checks', True)
    for file in brcapi_file.read_directory(iocp):
        brcddb_iocp.parse_iocp(proj_obj, iocp + '/' + file)
    brcddb_bp.best_practice(al.AlertTable.alertTbl, proj_obj)
    if _ZONE_CHECK:
        for obj in proj_obj.r_fabric_objects(
        ):  # Get a zone analysis on all fabrics
            brcdapi_log.log(
                'Performing zone analysis for fabric ' +
                brcddb_fabric.best_fab_name(obj), True)
            brcddb_fabric.zone_analysis(obj)

    # Generate the report
    brcddb_report.report(proj_obj, outf)
    _custom_report(proj_obj, custom_parms)
    return brcddb_common.EXIT_STATUS_ERROR if proj_obj.r_is_any_error(
    ) else brcddb_common.EXIT_STATUS_OK
Exemple #26
0
def _create_new_rules(session, fid, new_sfp_rules):
    """Create all new SFP rules

    :param session: Session object returned from brcdapi.brcdapi_auth.login()
    :type session: dict
    :param fid: Fabric ID of the logical switch whose MAPS policy we want to modify. None if not VF enabled
    :type fid: None, str
    :param new_sfp_rules: List of dictionaries of rules returned from report_utils.parse_sfp_file_for_rules()
    :type new_sfp_rules: list
    :return: List of new rules created.
    """
    # Build the new rules content for the API POST request
    sum_new_rules = list()
    num_rules = len(new_sfp_rules)
    # After writing the code, I was getting HTTP connection timeouts so I had to batch the number of rules to add.
    i = 0
    while i < num_rules:
        x = i + _MAX_RULE_BATCH if i + _MAX_RULE_BATCH <= num_rules else num_rules
        new_rules = new_sfp_rules[i:x]
        obj = brcdapi_rest.send_request(session, 'running/brocade-maps/rule',
                                        'POST', dict(rule=new_rules), fid)
        if brcdapi_auth.is_error(obj):
            # If the rule already exists, you cannot use POST or PATCH to write over it and PUT is not supported. I'm
            # assuming you could DELETE then POST and I could also check to see if the rule is changing but this simple
            # example on how to modify a MAPS policy is already getting to complicated so I just post warnings.
            er_l = list()
            er_obj = dict(errors=dict(error=er_l))
            if 'errors' in obj and isinstance(obj['errors'].get('error'),
                                              list):
                for d in obj['errors']['error']:
                    buf = d.get('error-message')
                    if buf is not None and buf == 'Rule name is present.' and isinstance(
                            d.get('error-path'), str):
                        brcdapi_log.log(
                            'Rule ' + d['error-path'].replace(
                                '/rule/name/', '').replace('/', '') +
                            ' already exists. Not changed.', True)
                    else:
                        er_l.append(d)
            if len(er_l) > 0:
                brcdapi_log.log(
                    'Failed to create rules. API response:' +
                    brcdapi_auth.formatted_error_msg(er_obj), True)
                return sum_new_rules  # If we get here, something is really wrong so just bail out
        # rule.get('name') should never be None in the line below. I'm just extra cautious
        sum_new_rules.extend([
            rule.get('name') for rule in new_rules
            if rule.get('name') is not None
        ])
        i = x
    return sum_new_rules
def _cert_detail_report(obj):
    """Generates a user friendly cert report.

    :param obj: Object returned from the API.
    :type obj: dict
    :rtype: None
    """
    # For each certificate, display the full cert if present
    for cert_d in obj['security-certificate']:
        hexdump = cert_d.get('certificate-verbose')
        if isinstance(hexdump, str) and len(hexdump) > 0:
            buf = cert_d['certificate-entity'] + ', ' + cert_d[
                'certificate-type'] + ' Detail:'
            brcdapi_log.log(['', buf, '', hexdump], True)
Exemple #28
0
def read_dump(file):
    """Reads in a file using json.load. Typical use is to read back in a project object file writen with write_dump and
    then convert back to a project object with plain_copy_to_brcddb_copy
    Python dict.
    :param file: Name of file to write to
    :type file: str
    :return:
    :rtype: dict, list, None
    """
    brcdapi_log.log('CALL: brcddb_util.read_dump. File: ' + file)
    f = open(file, 'r')
    obj = json.load(f)
    f.close()
    return obj
def _report_act(obj):
    global _report_name, _report_display

    # Validate the users filter file
    if not isinstance(_report_name, str):
        brcdapi_log.log('"report" action found before "def_report" action.',
                        True)
        return
    report_disp = None
    disp = obj.get('disp')
    if disp is not None:
        if not isinstance(disp, str):
            buf = 'Invalid "disp" type, ' + str(type(
                disp)) + ', in "report" action. The value associated with '
            buf += '"disp" must be a string. Using default display tables.'
            brcdapi_log.log(buf, True)
        else:
            report_disp = _report_display.get(disp)
            if report_disp is None:
                buf = '"disp", ' + disp + ', in "report" action not found in "def_report". Using default display '\
                                          'tables.'
                brcdapi_log.log(buf, True)

    if _has_sheet_name(obj, 'worksheet'):
        obj_type = obj.get('type')
        if obj_type is not None and obj_type in _report_action_d:
            _report_action_d[obj_type](obj, report_disp)
        else:
            brcdapi_log.log(
                'Invalid "type", "' + str(obj.get('type')) +
                '" in "report" action', True)
Exemple #30
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()