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)
Example #2
0
def get_key_val(obj, keys):
    """Spins through a list of keys separated by a '/' and returns the value associated with the last key.

    :param obj: Starting point in the object
    :type obj: dict, ProjectObj, FabricObj, SwitchObj, PortObj, ZoneCfgObj, ZoneObj, PortObj, LoginObj
    :param keys: Sting of keys to look through
    :type keys: str
    :return: Value associated with last key. None if not found
    :rtype: int, float, str, list, tuple, dict
    """
    global error_asserted

    if obj is None:
        return None  # Saves the calling method of having to determine they are working on a valid object
    if hasattr(obj, 'r_get') and callable(obj.r_get):
        return obj.r_get(keys)
    if not isinstance(obj, dict):
        brcdapi_log.exception('Object type, ' + str(type(obj)) + ', not a dict or brcddb object,', True)
        error_asserted = True
        return None

    key_l = keys.split('/')
    if len(key_l) == 0:
        return None
    last_key = key_l[len(key_l)-1]
    v = obj
    for k in key_l:
        if isinstance(v, dict):
            v = v.get(k)
        elif k != last_key:
            brcdapi_log.exception('Object type, ' + str(type(v)) + ', for ' + k + ', in ' + keys +
                                  ' not a dict or brcddb object ', True)
            error_asserted = True
            return None
    return v
Example #3
0
def api_request(session, uri, http_method, content):
    """Interface in front of _api_request to handle retries when services are unavailable

    :param session: Session object returned from login()
    :type session: dict
    :param uri: full URI
    :type uri: str
    :param http_method: Method for HTTP connect.
    :param content: The content, in Python dict, to be converted to JSON and sent to switch.
    :type content: dict
    :return: Response and status in pyfos_auth.is_error() and pyfos_auth.formatted_error_msg() friendly format
    :rtype: dict
    """
    global _MAX_RETRIES

    if uri is None:  # An error occurred in _format_uri()
        buf = 'Missing URI'
        brcdapi_log.exception(buf, True)
        return pyfos_auth.create_error(brcdapi_util.HTTP_BAD_REQUEST,
                                       'Missing URI', buf)
    obj = _api_request(session, uri, http_method, content)
    retry_count = _MAX_RETRIES
    retry_flag, wait_time = _retry(obj)
    while retry_flag and retry_count > 0:
        time.sleep(wait_time)
        obj = _api_request(session, uri, http_method, content)
        retry_count -= 1
        retry_flag, wait_time = _retry(obj)
    return obj
Example #4
0
def fabric_page(wb, tc, sheet_i, sheet_name, sheet_title, fabric_obj):
    """Creates the fabric summary page

    :param wb: Workbook object
    :type wb: class
    :param tc: Table of context page. A link to this page is place in cell A1
    :type tc: str, None
    :param sheet_i: Relative location for this worksheet
    :type sheet_i: int
    :param sheet_name: Sheet (tab) name
    :type sheet_name: str
    :param sheet_title: Title for sheet
    :type sheet_title: str
    :param fabric_obj: Fabric object
    :type fabric_obj: FabricObj
    :rtype: None
    """
    # Validate the user input
    err_msg = list()
    if fabric_obj is None:
        err_msg.append('FabricObj was not defined.')
    elif brcddb_class_util.get_simple_class_type(fabric_obj) != 'FabricObj':
        err_msg.append('Wrong object type, ' + str(type(fabric_obj)) +
                       'Must be brcddb.classes.fabric.FabricObj.')
    if len(err_msg) > 0:
        brcdapi_log.exception(err_msg, True)
        return

    # Set up the worksheet and add the fabric
    _setup_worksheet(wb, tc, sheet_i, sheet_name, sheet_title)
    _fabric_summary(fabric_obj)
    _maps_dashboard(fabric_obj)
    _zone_configuration(fabric_obj)
    return
Example #5
0
def _isl_redundant(obj, t_obj):
    """Check to see if there are at least two ISLs between switch pairs. Ignores connections to AMP

    :param obj: Switch object from the object list, obj_list, passed to best_practice()
    :type obj: brcddb.classes.switch.switch_obj
    :param t_obj: Individual test item from the test_list passed to best_practice(). Not used
    :type t_obj: dict
    :return: List of alert dictionaries {'a': alert number, 'p0': p0, 'p1': p1, 'k': '_isl_map'}
    :rtype: list
    """
    r_list = list()
    # Validate input
    obj_type = brcddb_class_util.get_simple_class_type(obj)
    if obj_type is None:
        obj_type = str(type(obj))
    if obj_type != 'SwitchObj':
        brcdapi_log.exception('Invalid object type. Expected switch_obj. Received: ' + obj_type, True)
        return r_list

    proj_obj = obj.r_project_obj()
    isl_map = obj.c_trunk_map()
    for k in isl_map.keys():
        switch_pair = isl_map.get(k)
        if _amp_in_switch_pair(obj, k, switch_pair):
            continue
        if len(list(switch_pair.keys())) == 1:
            r_list.append({'a': t_obj.get('m'),
                           'p0': brcddb_switch.best_switch_name(obj),
                           'p1': brcddb_switch.best_switch_name(proj_obj.r_switch_obj(k)),
                           'k': 'trunk'})
    return r_list
Example #6
0
def switch_page(wb, tc, sheet_name, sheet_i, sheet_title, s_list, display):
    """Creates a switch detail worksheet for the Excel report.
    :param wb: Workbook object
    :type wb: class
    :param tc: Table of context page. A link to this page is place in cell A1
    :type tc: str, None
    :param sheet_name: Sheet (tab) name
    :type sheet_name: str
    :param sheet_i: Sheet index where page is to be placed.
    :type sheet_i: int
    :param sheet_title: Title to be displayed in large font, hdr_1, at the top of the sheet
    :type sheet_title: str
    :param s_list: List of switch objects (SwitchObj) to display
    :type s_list: list, tuple
    :param display: List of keys to display. Find next instance of switch_key_case. Much less complex than port_page()
    :type display: dict
    :rtype: None
    """
    # Validate the user input
    err_msg = list()
    if s_list is None:
        err_msg.append('s_list was not defined.')
    elif not isinstance(s_list, (list, tuple)):
        err_msg.append('s_list was type ' + str(type(s_list)) + '. Must be a list or tuple.')
    if display is None:
        err_msg.append('display not defined.')
    if len(err_msg) > 0:
        brcdapi_log.exception(err_msg, True)
        return

    # Set up the worksheed and add each switch
    _setup_worksheet(wb, tc, sheet_name, sheet_i, sheet_title)
    for switch_obj in s_list:
        _add_switch(switch_obj, display)
Example #7
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')
Example #8
0
def get_from_obj(obj, k):
    """Returns the value associated with a key in / notation for a dict or brcddb.class object

    :param obj: Dictionary the key is for
    :type obj: dict
    :param k: The key
    :type k: str
    :return: Value associated with the key. None is returned if the key was not found
    :rtype: int, str, list, dict, None
    """
    global error_asserted

    if isinstance(obj, dict):
        v0 = get_struct_from_obj(obj, k)
        if v0 is None:
            return None
        kl = k.split('/')
        while len(kl) > 0:
            k0 = kl.pop(0)
            v0 = v0.get(k0)
            if v0 is None:
                return None  # The key was not found if we get here
        return v0
    elif brcddb_class_util.get_simple_class_type(obj) is None:
        brcdapi_log.exception('Invalid object type.', True)
        error_asserted = True
    else:
        return obj.r_get(k)
Example #9
0
def _update_brcddb_obj(objx, obj, uri):
    global _GEN_CASE_ERROR_MSG

    if objx is None:
        return  # This happens when fabric information is polled from a switch but the principal fabric switch wasn't
                # polled and we don't know what the principal fabric switch WWN is.

    try:
        tl = uri.split('/')
        d = objx.r_get(tl[0])
        if d is None:
            d = dict()
            objx.s_new_key(tl[0], d)
        for k in obj:
            v1 = obj.get(k)
            if k in _ip_list:
                d.update({k: _convert_ip_addr(v1)})
            else:
                d.update({k: v1})
    except:
        brcdapi_log.exception(_GEN_CASE_ERROR_MSG, True)
        objx.r_project_obj().s_add_alert(al.AlertTable.alertTbl, al.ALERT_NUM.PROJ_PROGRAM_ERROR, None,
                                         _GEN_CASE_ERROR_MSG, '')
        try:
            objx.r_project_obj().s_warn_flag()
        except:
            try:
                objx.s_warn_flag()
            except:
                pass
Example #10
0
def _port_category(switch_obj, dash_obj):
    p0 = dash_obj.get('name')
    o_list = brcddb_util.get_key_val(dash_obj, 'objects/object')
    buf = o_list[0]
    if '-Port' in buf or 'SFP' in buf:
        port = buf.split(' ')[1].split(':')[0]
        port = '0/' + port if '/' not in port else port
    elif 'Pid' in buf:
        # I've stumbled across so many quirks in the MAPS dashboard, it wouldn't surprise me in a rule for a removed
        # port is still in the dashboard.
        try:
            port = switch_obj.r_port_obj_for_pid(
                buf.split(' ')[1].split(':')[0]).r_obj_key()
        except:
            return
    else:
        brcdapi_log.exception('Unknown MAPS object: ' + buf, True)
        return
    sev = dash_obj.get('event-severity') if dash_obj.get(
        'event-severity') in _event_severity else 'default'
    al_num = _event_severity[sev]
    port_obj = switch_obj.r_port_obj(port)
    if port_obj is not None and not brcddb_util.has_alert(
            port_obj, al_num, None, p0, None):
        port_obj.s_add_alert(al.AlertTable.alertTbl, al_num, None, p0, None)
Example #11
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()
Example #12
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
Example #13
0
def p_login_addr_case(port_obj, k, wwn):
    if wwn is None:
        return ''
    try:
        return port_obj.r_fabric_obj().r_login_obj(wwn).r_get(
            'brocade-name-server/port-id')
    except:
        brcdapi_log.exception(
            'No login address for ' + wwn + '. Switch ' +
            port_obj.r_switch_obj().r_obj_key() + ', port ' +
            port_obj.r_obj_key(), True)
        return 'Unknown'
Example #14
0
def align_type(x):
    """Returns the alignment defintion tuple for the openpyxl libraries
    :param x: Alignment type listed in font_tbl
    :type x: str
    :return: Alignment defintions for openpyxl library
    :rtype: tuple
    """
    if x in align_tbl:
        return align_tbl[x]
    else:
        brcdapi_log.exception('Unknown align type: ' + x, True)
        return wrap_alignment
Example #15
0
def border_type(x):
    """Returns the border defintion tuple for the openpyxl libraries
    :param x: Border type listed in font_tbl
    :type x: str
    :return: Border defintions for openpyxl library
    :rtype: tuple
    """
    if x in border_tbl:
        return border_tbl[x]
    else:
        brcdapi_log.exception('Unknown border type: ' + x, True)
        return thin_border
Example #16
0
def fill_type(x):
    """Returns the font defintion tuple for the openpyxl libraries
    :param x: Fill type listed in font_tbl
    :type x: str
    :return: Fill defintions for openpyxl library
    :rtype: tuple
    """
    if x in fill_tbl:
        return fill_tbl[x]
    else:
        brcdapi_log.exception('Unknown fill type: ' + x, True)
        return lightblue_fill
Example #17
0
def _parse_chpid(chpid):
    """Parses a CHPID macro

    :param chpid: CHPID PATH macro
    :type chpid: str
    :return tag: CHPID and CSS formatted as tag
    :rtype tag: str
    :return partition: List of partitions sharing this CHPID
    :rtype partition: list
    :return pchid: PCHID
    :rtype pchid: str
    :return switch: Switch ID
    :rtype switch: str
    """
    tag = ''
    partition = list()
    pchid = ''
    switch = ''

    # Sample CHPID macro: CHPID PATH=(CSS(0),50),SHARED,PARTITION=((SYJ3,SYJ4),(=)),SWITCH=F4,PCHID=168,TYPE=FC
    # Note that 'CHPID PATH=' is already stripped off so we just have: (CSS(0),4D),SHARED,PARTITION...
    try:

        # Tack on 'xxx=xxx' so I don't have handle any elements at the end as a special case.
        # Get the SWITCH, PARTITION and PCHID
        x = 0
        temp_l = (chpid + ',xxx=xxx').split('=')
        for buf in temp_l:
            if x + 1 >= len(temp_l):
                break
            next_buf = temp_l[x + 1]

            if 'PATH' in buf:
                l, dummy_buf = css_chpid_to_tag(next_buf)
                tag = l[0]

            if 'PARTITION' in buf:
                i = 0  # I've seen anywhwere from 0 to 2 '(' so just skip through them all
                for chr in next_buf:
                    if chr != '(':
                        break
                    i += 1
                partition = next_buf[i:next_buf.find(')')].split(',')
            elif 'PCHID' in buf:
                pchid = next_buf.split(',')[0]
            elif 'SWITCH' in buf:
                switch = next_buf.split(',')[0]
            x += 1

    except:
        brcdapi_log.exception('Unknown CHPID macro format:\n' + chpid, True)

    return tag, partition, pchid, switch
Example #18
0
def login(user_id, pw, ip_addr, https='none', proj_obj=None):
    """Log in and capture a list of supported modules.

    :param user_id: User ID
    :type user_id: str
    :param pw: Password
    :type pw: str
    :param ip_addr: IP address
    :type ip_addr: str
    :param https: If 'CA' or 'self', uses https to login. Otherwise, http.
    :type https: None, str
    :param proj_obj: Project object
    :type proj_obj: brcddb.classes.project.ProjectObj, None
    :return: session
    :rtype: dict
    """
    # Attempt to log in
    tip = brcdapi_util.mask_ip_addr(ip_addr, True)
    session = brcdapi_rest.login(user_id, pw, ip_addr, https)
    if pyfos_auth.is_error(session):
        brcdapi_log.log(tip + ' Login failed', True)
        _process_errors(session, '/rest/login', session, proj_obj)
        return session
    else:
        brcdapi_log.log(tip + ' Login succeeded', True)

    # Figure out what modules this FOS version supports
    # Step 1: Read all the module information from FOS
    uri = 'brocade-module-version'
    obj = brcdapi_rest.get_request(session, uri)
    if pyfos_auth.is_error(obj):
        brcdapi_log.log(tip + ' ERROR: ' + uri + '\n' + pyfos_auth.formatted_error_msg(obj), True)
        return session

    # Step 2: Parse the module information and add it to the session object
    kpi_list = list()
    for mod_obj in obj.get(uri).get('module'):
        name = mod_obj.get('name')
        if name is None:
            brcdapi_log.exception("'name' mising in brocade-module-version", True)
            continue
        kpi_list.append(name)
        try:  # I think 'object' will always be there, just empty when there are no objects. Try/Except just in case.
            for mod_object in mod_obj.get('objects').get('object'):
                kpi_list.append(name + '/' + mod_object)
        except:
            pass
    session.update(dict(supported_uris=kpi_list))

    return session
def pseudo_main():
    """Basically the main(). Did it this way so it can easily be modified to be called from another script.

    :return: Exit code. See exit codes in brcddb.brcddb_common
    :rtype: int
    """
    # Get the command line input
    ip_addr, user_id, pw, sec = _get_input()

    # Login
    brcdapi_log.log('Attempting login', True)
    session = brcdapi_rest.login(user_id, pw, ip_addr, sec)
    if fos_auth.is_error(session):
        brcdapi_log.log('Login failed. Error message is:', True)
        brcdapi_log.log(fos_auth.formatted_error_msg(session), True)
        return -1
    brcdapi_log.log([
        'Login succeeded', 'Getting certificates. This will take about 30 sec.'
    ], True)

    try:  # This try is to ensure the logout code gets executed regardless of what happened.
        # Get the certificates from the API
        cert_obj = brcdapi_rest.get_request(
            session, 'running/brocade-security/security-certificate')
    except BaseException as e:
        brcdapi_log.exception(
            'Unexpected error encountered. Exception is: ' + str(e), True)

    # Logout
    brcdapi_log.log('Attempting logout', True)
    obj = brcdapi_rest.logout(session)
    if fos_auth.is_error(obj):
        brcdapi_log.log('Logout failed. Error message is:', True)
        brcdapi_log.log(fos_auth.formatted_error_msg(obj), True)
        return -1
    brcdapi_log.log('Logout succeeded.', True)

    # Display the certificates
    if fos_auth.is_error(cert_obj):
        brcdapi_log.exception(
            'Failed to capture certificates.' +
            fos_auth.formatted_error_msg(cert_obj), True)
        return -1
    _cert_detail_report(cert_obj)
    _cert_summary_report(cert_obj)

    return 0
Example #20
0
def _is_error(obj, msg, echo):
    """Updates the log file if there was an error

    :param obj: Object returned from API
    :type obj: dict
    :param msg: Message to add to the log buffer
    :type msg: str
    :param echo: True - echo message to STD_OUT
    :type echo: bool
    :return: Version
    :rtype: str
    """
    if pyfos_auth.is_error(obj):
        brcdapi_log.log(msg, echo)
        brcdapi_log.exception(pyfos_auth.formatted_error_msg(obj), echo)
        return True
    return False
Example #21
0
def class_getvalue(obj, keys, flag=False):
    """Returns the value associated with a key.

    :param obj: Any brcddb.classes object
    :type obj: ChassisObj, FabricObj, LoginObj, FdmiNodeObj, FdmiPortObj, PortObj, ProjectObj, SwitchObj, ZoneCfgObj \
        ZoneObj, AliasObj
    :param keys: Key who's value is sought. None is allowed to simplify processing lists of keys that may not be present
    :type keys: str, None
    :param flag: If True, combine the first two keys into a single key. Used for port keys.
    :type flag: bool
    :return: Value associated with key
    :rtype: any
    """
    if keys is None or obj is None or len(keys) == 0:
        return None
    kl = keys.split('/')
    if flag:
        # The next key is going to be for the port which is in slot/port notation. The split above will seperate the
        # 2 keys so the code below puts the port key back together.
        if len(kl) > 1:
            kl[0] = kl.pop(0) + '/' + kl[0]
        else:
            return None  # Someone called this with missing keys if we get here.

    if hasattr(obj, '_reserved_keys') and kl[0] in obj._reserved_keys:
        # Typically get here when someone did an obj.r_get() on a reserved key
        new_obj = _class_reserved(obj, kl.pop(0), )
        if len(kl) > 0:
            s_type = get_simple_class_type(obj)
            return class_getvalue(new_obj, '/'.join(kl), True if s_type is not None and s_type == 'PortObj' else False)
        else:
            return new_obj
    elif hasattr(obj, '__dict__'):
        # This is where you go for anything added to a brcddb object
        v0 = obj
        while len(kl) > 0:
            k0 = kl.pop(0)
            try:
                v0 = v0.get(k0) if isinstance(v0, dict) else v0.__dict__.get(k0)
            except:
                return None  # The key was not found if we get here
        return v0
    else:
        brcdapi_log.exception('Unknown object type: ' + str(type(obj)) + '. keys: ' + keys, True)
Example #22
0
def obj_extract(from_obj, to_type):
    """Extracts a list of objects from an object

    :param from_obj: The brcddb object the to_obj is to be extracted from
    :type from_obj: brcddb.classes.*
    :param to_type: The object simple object type, brcddb.classes.util.get_simple_class_type(), to extract from from_obj
    :type to_type: str
    :return: List of objects extracted from from_obj associated with to_obj. Redundant objects removed
    :rtype: brcddb.classes.* (whatever type to_obj is)
    """
    from_type = brcddb_class_util.get_simple_class_type(from_obj)
    if from_type is None:
        brcdapi_log.exception('Unknown from_obj object type: ' +
                              str(type(from_type)))
        return list()
    return brcddb_util.remove_duplicates([
        obj for obj in _obj_convert_tbl[from_type][to_type](from_obj)
        if obj is not None
    ])
Example #23
0
def chassis_type(chassis_obj, type_num=False, in_oem='brcd'):
    """Returns the chassis type (ie: G720)

    :param chassis_obj: Chassis Object
    :type chassis_obj: brcddb_classes.chassis.ChassisObj
    :param type_num: If True, append (type number) to the chassis name
    :type type_num: bool
    :param in_oem: 'brcd', 'ibm', 'hpe', 'dell', 'hv', 'netapp', or 'pure'
    :type in_oem: str
    :return: Chassis type
    :rtype: str
    """
    switch_type = _chassis_type(chassis_obj)
    d = chassis_type_d[switch_type]
    if in_oem.lower() in d:
        oem = in_oem.lower()
    else:
        brcdapi_log.exception('Invalid oem, ' + str(in_oem), True)
        oem = 'brcd'
    return d[oem] + ' (' + str(switch_type) + ')' if type_num else d[oem]
Example #24
0
def test_threshold(obj_list, key, test, val):
    """Filters a list of objects based on a number (int or float) and test condition

    :param obj_list: list of brcddb classes - see brcddb.class
    :type obj_list: list
    :param key: Key for the value to be compared. To look in a substr, seperate keys with a '/'. All keys must be a \
        key to a dict or brcddb object
    :type key: str, list, tuple
    :param test: Test condition: '>', '<', '==', '=', '>=', '<=', '!=', '!', 'not'
    :param val: Value to test counter against
    :type val: int
    :return: List of objects from obj_list that meet the filter criteria in the same order as obj_list
    :rtype: list
    """
    return_list = list()

    #  Validate the inputs
    msg = list()
    if not isinstance(obj_list, (list, tuple)):
        msg.append('\nobj_list is type ' + str(type(obj_list)) + '. It must be a list or typle of brcddb objects')
    if not isinstance(key, str):
        msg.append('\nkey is type ' + str(type(key)) + '. It must be a type str')
    if isinstance(test, str):
        if test not in numerical_test_case:
            msg.append('\nUnkown "test": ' + test)
    else:
        msg.append('\n"test" must be str. Actual type is ' + str(type(test)))
    if not isinstance(val, (int, float, str)):
        msg.append('\nval is type ' + str(type(val)) + '. It must be an int, float, or reference (str)')
    if len(msg) > 0:
        brcdapi_log.exception('\nInvalid parameter passed to test_threshold\n' + '\n'.join(msg) + '\n', True)
        return None

    # Now do the test
    for obj in obj_list:
        v = brcddb_util.get_key_val(obj, key)
        c_val = val if isinstance(val, (int, float)) else brcddb_util.get_key_val(obj, val)
        if isinstance(v, (int, float)) and isinstance(c_val, (int, float)) and numerical_test_case[test](v, c_val):
            return_list.append(obj)

    return return_list
Example #25
0
def add_to_obj(obj, k, v):
    """Adds a key value pair to obj using '/' notation in the key. If the key already exists, it is overwritten.

    :param obj: Dictionary or brcddb.class object the key value pair is to be added to
    :type obj: dict
    :param k: The key
    :type k: str
    :param v: Value associated with the key.
    :type v: int, str, list, dict
    """
    global error_asserted

    if not isinstance(k, str):
        brcdapi_log.exception('Invalid key. Expected type str, received type ' + str(type(k)), True)
        error_asserted = True
        return
    key_list = k.split('/')
    if isinstance(obj, dict):
        if len(key_list) == 1:
            obj.update({k: v})
            return
        key = key_list.pop(0)
        d = obj.get(key)
        if d is None:
            d = dict()
            obj.update({key: d})
        add_to_obj(d, '/'.join(key_list), v)
    elif brcddb_class_util.get_simple_class_type(obj) is None:
        brcdapi_log.exception('Invalid object type: ' + str(type(obj)) + '. k = ' + k + ', v type: ' + str(type(v)),
                              True)
        error_asserted = True
    else:
        key = key_list.pop(0)
        if len(key_list) == 0:
            obj.s_new_key(key, v, True)
            return
        r_obj = obj.r_get(key)
        if r_obj is None:
            r_obj = dict()
            obj.s_new_key(key, r_obj)
        add_to_obj(r_obj, '/'.join(key_list), v)
Example #26
0
def _check_sfps(obj_list, t_obj):
    """Checks SFP levels and adds appropriate alerts to port objects

    :param obj_list: Port object
    :type obj_list: list
    :param t_obj: Individual test item from the test_list passed to best_practice(). Not used
    :type t_obj: dict
    """
    global _rule_template, sfp_rules, _alert_tbl

    if sfp_rules is None or obj_list is None:
        return

    # Perform all the checks for the SFPs on the switch.
    enabled_ports = brcddb_search.match_test(obj_list, bp_tables.is_enabled)  # SFP data is not valid for disabled ports
    for rule in sfp_rules:
        group = 'Unkonwn' if rule.get('Group') is None else rule.get('Group')
        try:
            pn_l = rule.get('Mfg. P/N')
            if pn_l is not None and pn_l != '':
                for pn in [p.strip() for p in pn_l.split(',')]:
                    plist = brcddb_search.match_test(enabled_ports,
                                                     {'k': 'media-rdp/part-number', 't': 'exact', 'v': pn})
                    if len(plist) > 0:
                        online_plist = brcddb_search.match_test(plist, bp_tables.is_online)
                        for k0, obj_0 in _rule_template.items():
                            for k1, obj_1 in obj_0.items():
                                val = float(rule.get(k1))  # The threshold to test against
                                m = obj_1.get('a')  # Alert number
                                tlist = online_plist if obj_1.get('l') else plist
                                for p_obj in brcddb_search.match_test(tlist, {'k': k0, 't': obj_1.get('t'), 'v': val}):
                                    p_obj.s_add_alert(_alert_tbl, m, k0, p_obj.r_get(k0), val)
            else:
                brcdapi_log.log('Missing P/N in ' + sfp_rules + ', Group: ' + str(group), True)

        except:
            brcdapi_log.exception('Invalid SFP rules file ' + sfp_rules + '. Group: ' + str(group), True)
            return

    return
Example #27
0
def _check_best_practice(obj_list, test_list):
    """Checks for defined conditions and adds an alert for every out of bounds condition.

    :param obj_list: A list of dictionaries or brcdapi objects to search. Must all be the same type
    :type obj_list: dict, list, tuple
    :param test_list: Pointer to table of best practice rules. See brcddb.app_data.bp_tables for details
    :type test_list: dict
    """
    global _alert_tbl

    # Validate user input
    if len(obj_list) == 0:
        return
    if not isinstance(test_list, (list, tuple)):
        brcdapi_log.exception('Invalid test_list type, ' + str(type(test_list)), True)
        return


    # Spin through each item in the test_list and perform the specified test
    for t_obj in test_list:
        if 'skip' in t_obj and t_obj.get('skip'):
            continue
        special = t_obj.get('s')
        if special is not None:
            if special in _bp_special_case_tbl:
                _bp_special(obj_list, t_obj)
            elif special in _bp_special_list_case_tbl:
                _bp_special_list(obj_list, t_obj)
            else:
                brcdapi_log.exception(
                    'Unknown special test case: ' + str(special) + ', type: ' + str(type(special)),
                    True)

        else:
            for obj in brcddb_search.match_test(obj_list, t_obj.get('l'), t_obj.get('logic')):
                # See documentation in brcddb.app_data.bp_tables for an explanation of 'm', 'p0', 'p0h', 'p1', & 'p1h'
                p0 = t_obj.get('p0h') if t_obj.get('p0h') is not None else obj.r_get(t_obj.get('p0'))
                p1 = t_obj.get('p1h') if t_obj.get('p1h') is not None else obj.r_get(t_obj.get('p1'))
                obj.s_add_alert(_alert_tbl, t_obj.get('m'), brcddb_util.convert_to_list(t_obj.get('l'))[0].get('k'),
                               p0, p1)
Example #28
0
def _isl_bw(obj, t_obj):
    """Check to see that all trunk masters logged in at the same speed

    :param obj: Switch object from the object list, obj_list, passed to best_practice()
    :type obj: brcddb.classes.switch.switch_obj
    :param t_obj: Individual test item from the test_list passed to best_practice(). Not used
    :type t_obj: dict
    :return: List of alert dictionaries {'a': alert number, 'p0': p0, 'p1': p1, 'k': '_isl_map'}
    :rtype: list
    """
    r_list = list()
    # Validate input
    obj_type = brcddb_class_util.get_simple_class_type(obj)
    if obj_type is None:
        obj_type = str(type(obj))
    if obj_type != 'SwitchObj':
        brcdapi_log.exception('Invalid object type. Expected switch_obj. Received: ' + obj_type, True)
        return r_list

    proj_obj = obj.r_project_obj()
    isl_map = obj.c_trunk_map()
    for k in isl_map.keys():
        switch_pair = isl_map.get(k)
        if _amp_in_switch_pair(obj, k, switch_pair):
            continue
        speeds = list()
        for k1 in switch_pair.keys():
            try:
                s = switch_pair.get(k1)[0][0].r_get('fibrechannel/speed')
                if s is not None:
                    speeds.append(s)
            except:
                pass  # We get here if all switches in the project were not polled
        if len(brcddb_util.remove_duplicates(speeds)) > 1:
            r_list.append({'a': t_obj.get('m'),
                           'p0': brcddb_switch.best_switch_name(obj),
                           'p1': brcddb_switch.best_switch_name(proj_obj.r_switch_obj(k)),
                           'k': 'trunk'})
    return r_list
Example #29
0
def _update_brcddb_obj_from_list(objx, obj, uri, skip_list=None):
    """Adds a FOS API request response that is a list. Each item in the list is added to a brcddb class object

    All parameters as in comments above except:
    :param skip_list: Skip list. List of elements to not add to objx
    :type skip_list: None, list, tuple
    """
    global _GEN_CASE_ERROR_MSG

    sl = list() if skip_list is None else skip_list

    try:
        tl = uri.split('/')
        d = objx.r_get(tl[0])
        if d is None:
            d = dict()
            objx.s_new_key(tl[0], d)
        d1 = d.get(tl[1])
        if d1 is None:
            d1 = dict()
            d.update({tl[1]: d1})
        for k in obj:
            if k not in sl:
                v1 = obj.get(k)
                if k in _ip_list:
                    d1.update({k: _convert_ip_addr(v1)})
                else:
                    d1.update({k: v1})
    except:
        brcdapi_log.exception(_GEN_CASE_ERROR_MSG, True)
        objx.r_project_obj().s_add_alert(al.AlertTable.alertTbl, al.ALERT_NUM.PROJ_PROGRAM_ERROR, None,
                                         _GEN_CASE_ERROR_MSG, '')
        try:
            objx.r_project_obj().s_warn_flag()
        except:
            try:
                objx.s_warn_flag()
            except:
                pass
Example #30
0
def paren_content(buf, p_remove=False):
    """Returns the contents of a string within matching parenthesis. First character must be '('

    :param buf: String to find text within matching parenthesis
    :type buf: str
    :param p_remove: If True, remove the leading and trailing parenthesis
    :return p_text: Text within matching parenthesis
    :rtype p_text: str
    :return x_buf: Remaind of buf after matching parenthesis have been found
    :rtype x_buf: str
    """
    global error_asserted

    p_count = 0
    r_buf = list()
    buf_len = len(buf)
    if len(buf) > 1 and buf[0] == '(':
        p_count += 1  # The first character must be (
        r_buf.append('(')
        for c in buf[1:]:
            r_buf.append(c)
            if c == '(':
                p_count += 1
            elif c == ')':
                p_count -= 1
                if p_count == 0:
                    break

    if p_count != 0:
        brcdapi_log.exception('Input string does not have matching parenthesis:\n' + buf, True)
        error_asserted = True
        r_buf = list()
    remainder = '' if len(buf) - len(r_buf) < 1 else buf[len(r_buf):]
    if len(r_buf) > 2 and p_remove:
        r_buf.pop()
        r_buf.pop(0)

    return ''.join(r_buf), remainder