Exemple #1
0
def del_zonecfg(session, fid, zonecfg_name, echo=False):
    """Deletes a zone configuration

    :param session: Session object returned from brcdapi.pyfos_auth.login()
    :type session: dict
    :param fid: Logical FID number
    :type fid: int
    :param zonecfg_name: Name of zone configuration
    :type zonecfg_name: str
    :param echo: If True, echoes any error messages to STD_OUT
    :type echo: bool
    :return: brcdapi_rest status object
    :rtype: dict
    """
    # Delete the zone configuration
    content = {
        'defined-configuration': {
            'cfg': [{
                'cfg-name': zonecfg_name,
            }]
        }
    }
    obj = brcdapi_rest.send_request(session,
                                    'brocade-zone/defined-configuration',
                                    'DELETE', content, fid)
    _is_error(obj, 'Failed to delete zone configuration ' + zonecfg_name, echo)
    return obj
Exemple #2
0
def disable_zonecfg(session, check_sum, fid, zonecfg_name, echo=False):
    """Enables a zone configuration.

    :param session: Session object returned from brcdapi.pyfos_auth.login()
    :type session: dict
    :param check_sum: Zoning database checksum
    :type check_sum: int
    :param fid: Logical FID number to be created. Valid FISs are 1-128. Will return an error if the FID already exists
    :type fid: int
    :param zonecfg_name: Name of the zone configuration to enable
    :type zonecfg_name: str
    :param echo: If True, echoes any error messages to STD_OUT
    :type echo: bool
    :return: brcdapi_rest status object
    :rtype: dict
    """
    content = {
        'effective-configuration': {
            'checksum': check_sum,
            'cfg-action': 2
        }
    }
    obj = brcdapi_rest.send_request(session,
                                    'brocade-zone/effective-configuration',
                                    'PATCH', content, fid)
    _is_error(obj, 'Failed to enable zone configuration ' + zonecfg_name, echo)
    return obj
Exemple #3
0
def save(session, fid, check_sum, echo=False):
    """Saves the contents of the zoning transaction buffer

    :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 check_sum: Zoning checksum. See checksum()
    :type check_sum: int
    :param echo: If True, echoes any error messages to STD_OUT
    :type echo: bool
    :return: brcdapi_rest status object
    :rtype: dict
    """
    content = {
        'effective-configuration': {
            'cfg-action': 1,
            'checksum': check_sum
        }
    }
    obj = brcdapi_rest.send_request(session,
                                    'brocade-zone/effective-configuration',
                                    'PATCH', content, fid)
    _is_error(obj, 'Failed to save zone configuration test_zone_cfg', echo)
    return obj
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 create_aliases(session, fid, alias_list, echo=False):
    """Creates aliases.

    _sample_alias_list = [
        {'name': 'Target_0', 'members': ['50:0c:00:11:0d:bb:42:00']},
        {'name': 'Target_1', 'members': ['50:0c:00:11:0d:bb:42:01']},
    ]
    :param session: Session object returned from brcdapi.pyfos_auth.login()
    :type session: dict
    :param fid: Logical FID number
    :type fid: int
    :param alias_list: List of dictionaries defining the aliases to create. See _sample_alias_list above.
    :type alias_list: list
    :param echo: If True, echoes any error messages to STD_OUT
    :type echo: bool
    :return: brcdapi_rest status object
    :rtype: dict
    """
    build_alias_list = list()
    for alias_obj in alias_list:
        build_alias_list.append({
            'alias-name': alias_obj.get('name'),
            'member-entry': {
                'alias-entry-name': alias_obj.get('members')
            }
        })
    content = {'defined-configuration': {'alias': build_alias_list}}
    obj = brcdapi_rest.send_request(session,
                                    'brocade-zone/defined-configuration',
                                    'POST', content, fid)
    _is_error(obj, 'Failed to create aliases', echo)
    return obj
Exemple #6
0
def del_zones(session, fid, zones, echo=False):
    """Deletes zones.

    :param session: Session object returned from brcdapi.pyfos_auth.login()
    :type session: dict
    :param fid: Logical FID number
    :type fid: int
    :param zones: List of zone names to delete
    :type zones: list
    :param echo: If True, echoes any error messages to STD_OUT
    :type echo: bool
    :return: brcdapi_rest status object
    :rtype: dict
    """
    # Delete the zones
    content = {
        'defined-configuration': {
            'zone': [{
                'zone-name': zone
            } for zone in zones]
        }
    }
    obj = brcdapi_rest.send_request(session,
                                    'brocade-zone/defined-configuration',
                                    'DELETE', content, fid)
    _is_error(obj, 'Failed to delete zone(s)', echo)
    return obj
Exemple #7
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)
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 create_zonecfg(session, fid, zonecfg_name, zone_list, echo=False):
    """Add a zone configuration.

    :param session: Session object returned from brcdapi.pyfos_auth.login()
    :type session: dict
    :param fid: Logical FID number
    :type fid: int
    :param zonecfg_name: Name of zone configuration
    :type zonecfg_name: str
    :param zone_list: List of zone names to add to the zonecfg.
    :type zone_list: list
    :param echo: If True, echoes any error messages to STD_OUT
    :type echo: bool
    :return: brcdapi_rest status object
    :rtype: dict
    """
    # Create the zone configuration
    content = {
        'defined-configuration': {
            'cfg': [{
                'cfg-name': zonecfg_name,
                'member-zone': {
                    'zone-name': zone_list
                }
            }]
        }
    }
    obj = brcdapi_rest.send_request(session,
                                    'brocade-zone/defined-configuration',
                                    'POST', content, fid)
    _is_error(obj, 'Failed to create zone configuration ' + zonecfg_name, echo)
    return obj
Exemple #10
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
Exemple #11
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
Exemple #12
0
def del_aliases(session, fid, alias_list, echo=False):
    """Deletes aliases. Same as input parameters and return as create_aliases() but only 'name' is used in alias_list"""
    content = {
        'defined-configuration': {
            'alias': [{
                'alias-name': alias_obj.get('name')
            } for alias_obj in alias_list]
        }
    }
    obj = brcdapi_rest.send_request(session,
                                    'brocade-zone/defined-configuration',
                                    'DELETE', content, fid)
    _is_error(obj, 'Failed to delete alias', echo)
    return obj
Exemple #13
0
def clear_zone(session, fid, echo=False):
    """Clears the zone database

    :param session: Session object returned from brcdapi.pyfos_auth.login()
    :type session: dict
    :param fid: Logical FID number
    :type fid: int
    :param echo: If True, echoes any error messages to STD_OUT
    :type echo: bool
    :return: brcdapi_rest status object
    :rtype: dict
    """
    content = {'effective-configuration': {'cfg-action': 3}}
    obj = brcdapi_rest.send_request(session,
                                    'brocade-zone/effective-configuration',
                                    'PATCH', content, fid)
    _is_error(obj, 'Failed to set the default zone access', echo)
    return obj
Exemple #14
0
def abort(session, fid, echo=False):
    """Aborts a zoning transaction

    :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: brcdapi_rest status object
    :rtype: dict
    """
    obj = brcdapi_rest.send_request(
        session, 'brocade-zone/effective-configuration', 'PATCH',
        {'effective-configuration': {
            'cfg-action': 4
        }}, fid)
    _is_error(obj, 'Abort failed', echo)
    return obj
Exemple #15
0
def default_zone(session, fid, access, echo=False):
    """Sets the default zone access method. Also saves pending changes

    :param session: Session object returned from brcdapi.pyfos_auth.login()
    :type session: dict
    :param fid: Logical FID number
    :type fid: int
    :param access: Access method. 0 - No Access, 1 - All Access
    :type access: int
    :param echo: If True, echoes any error messages to STD_OUT
    :type echo: bool
    :return: brcdapi_rest status object
    :rtype: dict
    """
    content = {'effective-configuration': {'default-zone-access': access}}
    obj = brcdapi_rest.send_request(session,
                                    'brocade-zone/effective-configuration',
                                    'PATCH', content, fid)
    _is_error(obj, 'Failed to set the default zone access', echo)
    return obj
Exemple #16
0
def replace_zoning(session, fab_obj, fid):
    """Replaces the zoning datbase in a fabric by clearing it and then PATCHing it with a new zoning database

     Relevant resource: 'zoning/defined-configuration'
     An error is returned if there is no zone database in in the fab_obj. Use clear_zoning() to clear out zoning.

    :param session: Login session object from brcdapi.brcdapi_rest.login()
    :type session: dict
    :param fab_obj: Fabric object whose zone database will be sent to the switch
    :type fab_obj: brcddb.classes.fabric.FabricObj
    :param fid: Fabric ID. If FID check is disabled, this must be the FID of the switch where the request is sent.
    :type fid: int
    :return: Object returned from FOS API
    :rtype: dict
    """
    # Get the dict to be converted to JSON and sent to the switch
    content = build_all_zone_content(fab_obj)
    if content is None:
        return pyfos_auth.create_error(
            400, 'No zone database in ' +
            brcddb_fabric.best_fab_name(obj.r_fabric_obj()), '')

    # Get the checksum - this is needed to save the configuration.
    checksum, obj = brcdapi_zone.checksum(session, fid, fab_obj)
    if pyfos_auth.is_error(obj):
        return obj

    # Clear the zone database
    obj = brcdapi_zone.clear_zone(session, fid)
    if not pyfos_auth.is_error(obj):
        # Send the zoning request
        obj = brcdapi_rest.send_request(session,
                                        'brocade-zone/defined-configuration',
                                        'PATCH', content, fid)
        if not pyfos_auth.is_error(obj):
            return brcdapi_zone.save(session, fid, checksum)

    # If we got this far, something went wrong so abort the transaction.
    brcdapi_zone.abort(session, fid)
    return obj
Exemple #17
0
def create_zones(session, fid, zone_list, echo=False):
    """Add zones to a fabric.

    _sample_zone_list = [
        {'name': 'T0_S0', 'type': 0, 'members': ['Target_0', 'Server_0']},
        {'name': 'T0_S1', 'type': 1, 'pmembers': ['Target_0'], 'members': ['Server_1', 'Server_2]},
    ]
    :param session: Session object returned from brcdapi.pyfos_auth.login()
    :type session: dict
    :param fid: Logical FID number
    :type fid: int
    :param zone_list: List of dictionaries defining the zones to create. See _sample_zone_list for an example.
    :type zone_list: list
    :param echo: If True, echoes any error messages to STD_OUT
    :type echo: bool
    :return: brcdapi_rest status object
    :rtype: dict
    """
    # Create the zones
    build_zone_list = list()
    for zone_obj in zone_list:
        d = dict()
        members = zone_obj.get('members')
        if isinstance(members, list):
            d.update({'entry-name': members})
        members = zone_obj.get('pmembers')
        if isinstance(members, list):
            d.update({'principal-entry-name': members})
        build_zone_list.append({
            'zone-name': zone_obj.get('name'),
            'zone-type': zone_obj.get('type'),
            'member-entry': d
        })
    content = {'defined-configuration': {'zone': build_zone_list}}
    obj = brcdapi_rest.send_request(session,
                                    'brocade-zone/defined-configuration',
                                    'POST', content, fid)
    _is_error(obj, 'Failed to create zones', echo)
    return obj
Exemple #18
0
def _zonecfg_modify(session, fid, zonecfg_name, zone_list, method, echo=False):
    """Called by zonecfg_add() or zonecfg_remove(). All parameters the same except method

    :param method:  'DELETE' for remove or 'POST' to add members
    :type method: str
    """
    # Test
    content = {
        'defined-configuration': {
            'cfg': [{
                'cfg-name': zonecfg_name,
                'member-zone': {
                    'zone-name': zone_list
                }
            }]
        }
    }
    obj = brcdapi_rest.send_request(session,
                                    'brocade-zone/defined-configuration',
                                    method, content, fid)
    _is_error(obj, 'Failed to create zone configuration ' + zonecfg_name, echo)
    return obj
Exemple #19
0
def clear_stats(session, fid, i_ports, i_ge_ports):
    """Clear all statistical counters associated with 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 i_ports: Port or list of FC ports for stats to be cleared on
    :type i_ports: list
    :param i_ge_ports: GE port or list of GE ports for stats to be cleared on
    :type i_ge_ports: list
    :return: brcdapi_rest status object
    :rtype: dict
    """
    pl = [{
        'name': p,
        'reset-statistics': 1
    } for p in ports_to_list(i_ports) + ports_to_list(i_ge_ports)]
    if len(pl) > 0:
        content = {'fibrechannel-statistics': pl}
        return brcdapi_rest.send_request(
            session, 'brocade-interface/fibrechannel-statistics', 'PATCH',
            content, fid)
    return brcdapi_util.GOOD_STATUS_OBJ
def pseudo_main():
    """Basically the main().

    :return: Exit code
    :rtype: int
    """
    global _DEBUG

    # Get and validate command line input
    ml = ['WARNING!!! Debug is enabled'] if _DEBUG else list()
    ip, user_id, pw, sec, fid_str, vd, log, nl = parse_args()
    if not nl:
        brcdapi_log.open_log(log)
    if vd:
        brcdapi_rest.verbose_debug = True
    if fid_str.isdigit():
        fid = int(fid_str)
    else:
        brcdapi_log.log('Invalid FID: ' + fid_str, True)
        return -1
    brcdapi_log.log(ml, True)

    # Login
    brcdapi_log.log('Attempting login', True)
    session = brcdapi_rest.login(user_id, pw, ip, sec)
    if brcdapi_auth.is_error(session):
        brcdapi_log.log('Login failed', True)
        brcdapi_log.log(brcdapi_auth.formatted_error_msg(session), True)
        return -1
    brcdapi_log.log('Login succeeded', True)

    ec = 0
    try:  # I always do a try in code development so that if there is a code bug, I still log out.

        # Get FC port list for this FID by reading the configurations
        kpi = 'running/brocade-interface/fibrechannel'
        obj = brcdapi_rest.get_request(session, kpi, fid)
        if brcdapi_auth.is_error(obj):
            brcdapi_log.log('Failed to read ' + kpi + ' for fid ' + str(fid),
                            True)
            ec = -1

        else:
            fc_plist = [port.get('name') for port in obj.get('fibrechannel')]
            pl = list()
            content = {'fibrechannel': pl}
            for p in fc_plist:
                d = {
                    'name': p,
                    'user-friendly-name':
                    'port_' + p.replace('/', '_'),  # Name port "port_s_p"
                    'los-tov-mode-enabled': 2  # Enable LOS_TOV
                }
                # For other port configuration parameters, search the Rest API Guide or Yang models for
                # brocade-interface/fibrechannel
                pl.append(d)
            # PATCH only changes specified leaves in the content for this URI. It does not replace all resources
            obj = brcdapi_rest.send_request(
                session, 'running/brocade-interface/fibrechannel', 'PATCH',
                content, fid)
            if brcdapi_auth.is_error(obj):
                brcdapi_log.log('Error configuring ports for FID ' + str(fid),
                                True)
                brcdapi_log.log(brcdapi_auth.formatted_error_msg(obj), True)
                ec = -1
            else:
                brcdapi_log.log(
                    'Successfully configured ports for FID ' + str(fid), True)

    except:  # Bare because I don't care what went wrong at this point. I just want to log out no matter what happens.
        brcdapi_log.log('Encountered a programming error', True)
        ec = -1

    # Logout
    obj = brcdapi_rest.logout(session)
    if brcdapi_auth.is_error(obj):
        brcdapi_log.log(
            'Logout failed:\n' + brcdapi_auth.formatted_error_msg(obj), True)
    return ec
Exemple #21
0
def default_port_config(session, fid, i_ports):
    """Disables and sets a list of FC ports to their factory default state

    :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 i_ports: List of ports in the API format of s/p. For a fixed port switch for example, port 12 is '0/12'
    :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
    """
    global default_port_config_d

    ports = ports_to_list(i_ports)
    if len(ports) == 0:
        return brcdapi_util.GOOD_STATUS_OBJ

    # Not all features are supported on all platforms. In most cases, even if you disable the unsupported feature, FOS
    # returns an error. To get around this, I read the port configuration and only add parameters to send to the switch
    # if they exist in the data returned from the switch

    # Read in the port configurations
    obj = brcdapi_rest.get_request(session, 'brocade-interface/fibrechannel',
                                   fid)
    if pyfos_auth.is_error(obj):
        brcdapi_log.log(
            'Failed to read brocade-interface/fibrechannel for fid ' +
            str(fid), True)
        return obj
    # Put all the ports in a dictionary for easy lookup
    port_d = dict()
    for port in obj['fibrechannel']:
        port_d.update({port['name']: port})

    # Figure out what ports to change
    pl = list()
    for port in ports:
        d = port_d.get(port)
        if d is None:
            brcdapi_log.exception('Port ' + port + ' not in FID ' + str(fid),
                                  True)
            continue
        port_content = collections.OrderedDict(
        )  # This may not need to be ordered.
        port_content['name'] = port
        for k, v in default_port_config_d.items():
            if k in d:
                if k == 'speed':
                    if d.get('auto-negotiate'
                             ) is not None and d['auto-negotiate'] == 0:
                        port_content[k] = 0
                elif k == 'user-friendly-name':
                    l = port.split('/')
                    port_name = 'port' + l[1]
                    if l[0] != '0':
                        port_name = 'slot' + l[0] + ' ' + port_name
                    if 'user-friendly-name' in d:
                        if d['user-friendly-name'] != port_name:
                            port_content[k] = port_name
                    else:
                        port_content[k] = port_name
                elif v != d[k]:
                    port_content[k] = v
        if len(port_content.keys()) > 1:
            pl.append(port_content)

    # Now modify the port(s)
    if len(pl) > 0:
        return brcdapi_rest.send_request(session,
                                         'brocade-interface/fibrechannel',
                                         'PATCH', {'fibrechannel': pl}, fid)
    else:
        return brcdapi_util.GOOD_STATUS_OBJ
Exemple #22
0
def create_ls(session, fid, name, did, idid, xisl, base, ficon, ports,
              ge_ports, es, ep, echo):
    """Create a logical switch. Includes options to set a few basic parameters

    :param session: Session object returned from brcdapi.pyfos_auth.login()
    :type session: dict
    :param fid: Logical FID number to be created.
    :type fid: int
    :param name: User friendly name for the switch. Use None for FOS default switch name
    :type name: None, str
    :param did: Domain ID Use None for FOS default DID.
    :type did: None, int
    :param idid: If True, sets the DID to be insistent
    :type idid: None, bool
    :param xisl: If True, sets the allow XISL bit.
    :type xisl: None, bool
    :param base: If True, set the switch type to be a base switch
    :type base: None, bool
    :param ficon: If True set the switch type to be a FICON switch
    :type ficon: None, bool
    :param ports: Dictionary of ports to add to the switch. Key: FID where the ports reside. Value: list of ports
    :type ports: None, dict
    :param ge_ports: Same as ports but for GE ports
    :type ge_ports: None, dict
    :param es: If True, enable the switch. Otherwise, the switch is left disabled.
    :type es: None, bool
    :param ep: If True, enables all the ports in the switch. Otherwise, they are left disabled.
    :type ep: None, bool
    :param echo: If True, step-by-step activity (each request) is echoed to STD_OUT
    :type echo: None, bool
    :return: Error code. 0 - Success, -1 - failure
    :rtype: int
    """
    ec = 0

    # Does the switch already exist?
    switch_list = brcdapi_switch.logical_switches(session, echo)
    if pyfos_auth.is_error(switch_list):
        brcdapi_log.log([
            'Error capturing switch list. Ports not added to FID ' + str(fid),
            pyfos_auth.formatted_error_msg(switch_list)
        ], True)
        return -1
    fid_list = [switch_d['fabric-id'] for switch_d in switch_list]

    # Create the switch if it doesn't already exist
    if fid in fid_list:
        brcdapi_log.log('Modifying FID ' + str(fid))
    else:
        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)
        obj = brcdapi_switch.create_switch(session, fid, base, ficon, echo)
        if pyfos_auth.is_error(obj):
            brcdapi_log.exception([
                'Error creating FID ' + str(fid),
                pyfos_auth.formatted_error_msg(obj)
            ], True)
            return -1

    # Set switch configuration parameters. Note: brocade-fibrechannel-switch/fibrechannel-switch requires the WWN and
    # must be an ordered dictionary. To save a little work, the ability to look up the WWN if it's not known and
    # setting up an ordered dictionary was built into one of the driver methods.
    sub_content = dict()
    if did is not None:
        if fid in fid_list:
            brcdapi_log.log(
                'Cannot modify the domain ID in an existing switch.', True)
        else:
            sub_content.update({'domain-id': did})
    if name is not None:
        sub_content.update({'user-friendly-name': name})
    if ficon:
        sub_content.update({
            'in-order-delivery-enabled': True,
            'dynamic-load-sharing': 'two-hop-lossless-dls'
        })
    # I didn't bother with a fabric name or banner in the shell interface. I have no idea why the fabric name is set and
    # read in the switch parameters, but it is.
    if _DEBUG_FAB_NAME is not None:
        sub_content.update({'fabric-user-friendly-name': _DEBUG_FAB_NAME})
    if _DEBUG_BANNER is not None:
        sub_content.update({'banner': _DEBUG_BANNER})
    # If there is nothing to update, the library will do nothing and return good status.
    obj = brcdapi_switch.fibrechannel_switch(session, fid, sub_content, None,
                                             echo)
    if pyfos_auth.is_error(obj):
        brcdapi_log.exception([
            'Failed to configure FID ' + str(fid),
            pyfos_auth.formatted_error_msg(obj)
        ], True)
        ec = -1

    # Set the fabric parameters. Note: Setting up fabric parameters is pretty straight forward so there is no driver
    # method for it.
    if fid in fid_list:
        brcdapi_log.log(
            'Changing XISL use in an existing switch is not supported by this utility.',
            True)
    elif not xisl:  # XISL (ability to use the base switch for ISLs) is enabled by default so we only need to disable it
        obj = brcdapi_rest.send_request(
            session, 'brocade-fibrechannel-configuration/switch-configuration',
            'PATCH', {'switch-configuration': {
                'xisl-enabled': False
            }}, fid)
        if pyfos_auth.is_error(obj):
            ml = [
                'Failed to disable XISL for FID ' + str(fid),
                pyfos_auth.formatted_error_msg(obj),
                'Enabling and disabling of XISLs via the API was not supported until FOS v9.0.',
                'Unless there are other error messages, all other operations are or will be completed as expected.'
            ]
            brcdapi_log.exception(ml, True)
            ec = -1

    # Insistent domain ID is set automatically with FICON switches. The API returns an error if you try to set it.
    if idid and not ficon:
        obj = brcdapi_rest.send_request(
            session, 'brocade-fibrechannel-configuration/fabric', 'PATCH',
            {'fabric': {
                'insistent-domain-id-enabled': True
            }}, fid)
        if pyfos_auth.is_error(obj):
            brcdapi_log.exception([
                'Failed to set insistent domain id for FID ' + str(fid),
                pyfos_auth.formatted_error_msg(obj)
            ], True)
            ec = -1

    # Add the ports to the switch. This has to be done one FID at a time.
    tl = list(
        ports.keys()
    )  # The keys are the FIDs so this is the list of all FIDs that have ports to be moved.
    tl.extend([k for k in ge_ports.keys()
               if k not in tl])  # Add FIDs for GE ports
    for k in tl:  # For every FID with ports to move
        obj = brcdapi_switch.add_ports(session, fid, k, ports.get(k),
                                       ge_ports.get(k), echo)
        if pyfos_auth.is_error(obj):
            brcdapi_log.log([
                'Error adding ports from FID ' + str(k),
                pyfos_auth.formatted_error_msg(obj)
            ], True)
            ec = -1

    # Enable the switch
    if es is not None and es:
        obj = brcdapi_switch.fibrechannel_switch(session, fid,
                                                 {'is-enabled-state': True},
                                                 None, echo)
        if pyfos_auth.is_error(obj):
            brcdapi_log.log([
                'Failed to enable FID ' + str(fid),
                pyfos_auth.formatted_error_msg(obj)
            ], True)
            ec = -1

    # Enable the ports we just added
    if ep is not None and ep:
        for k in tl:
            obj = brcdapi_port.enable_port(session, fid, True,
                                           ports.get(k) + ge_ports.get(k),
                                           True)
            if pyfos_auth.is_error(obj):
                brcdapi_log.log([
                    'Failed to enable ports on FID ' + str(fid),
                    pyfos_auth.formatted_error_msg(obj)
                ], True)
                ec = -1

    return ec
def pseudo_main():
    """Basically the main().

    :return: Exit code
    :rtype: int
    """
    global _DEBUG

    # Get and validate command line input
    ec, ip, user_id, pw, sec, input_d = _get_input()
    if ec != 0:
        return ec

    # Login
    brcdapi_log.log('Attempting login', True)
    session = brcdapi_rest.login(user_id, pw, ip, sec)
    if fos_auth.is_error(session):
        brcdapi_log.log(fos_auth.formatted_error_msg(session), True)
        return -1
    brcdapi_log.log('Login succeeded', True)

    ec = 0
    uri = 'running/brocade-chassis/management-interface-configuration'

    try:  # try/except so that no matter what happens, the logout code gets executed.

        # Display initial read (GET) of parameters
        brcdapi_log.log(['', 'Before Changes:'], True)
        obj = brcdapi_rest.get_request(session, uri)
        if fos_auth.is_error(obj):
            brcdapi_log.log(fos_auth.formatted_error_msg(obj), True)
            ec = -1
        else:
            brcdapi_log.log(pprint.pformat(obj), True)

        if ec == 0:

            # Make the changes
            content_d = dict()
            for k, v in input_d.items():
                if v is not None:
                    content_d.update({k: v})
            if len(content_d) == 0:
                brcdapi_log.log('No changes to make.', True)
            else:
                obj = brcdapi_rest.send_request(
                    session, uri, 'PATCH',
                    {'management-interface-configuration': content_d})
                if fos_auth.is_error(obj):
                    brcdapi_log.log(fos_auth.formatted_error_msg(obj), True)
                    ec = -1
                else:

                    # Display read (GET) after changing parameters
                    brcdapi_log.log(['', 'After Changes:'], True)
                    obj = brcdapi_rest.get_request(session, uri)
                    if fos_auth.is_error(obj):
                        brcdapi_log.log(fos_auth.formatted_error_msg(obj),
                                        True)
                        ec = -1
                    else:
                        brcdapi_log.log(pprint.pformat(obj), True)

    except BaseException as e:
        brcdapi_log.exception(
            'Programming error encountered. Exception is: ' + str(e), True)
        ec = -1

    # Logout
    obj = brcdapi_rest.logout(session)
    if fos_auth.is_error(obj):
        brcdapi_log.log('Logout failed', True)
        ec = -1
    else:
        brcdapi_log.log('Logout succeeded', True)

    return ec
Exemple #24
0
def _config_fab_and_switch(session, switch_d, echo):
    """Add and remove ports from a logical switch

    :param session: Session object, or list of session objects, returned from brcdapi.fos_auth.login()
    :type session: dict
    :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 _switch_d_to_api

    # Load common use stuff into local variables
    ec = brcddb_common.EXIT_STATUS_OK
    fid = switch_d['fid']
    idid = False if switch_d['switch_type'] == 'ficon' else switch_d['idid']

    # Set switch configuration parameters.
    sub_content = dict()
    for k, v in _switch_d_to_api.items():
        if switch_d[k] is not None:
            sub_content.update({v: switch_d[k]})
    if switch_d['switch_type'] == 'ficon':
        sub_content.update({
            'in-order-delivery-enabled': True,
            'dynamic-load-sharing': 'two-hop-lossless-dls'
        })

    # Send the changes.
    obj = brcdapi_switch.fibrechannel_switch(session, fid, sub_content, None,
                                             echo)
    if fos_auth.is_error(obj):
        # in-order-delivery-enabled and dynamic-load-sharing not supported in pre-FOS 9.0 so just try it again
        sub_content.pop('in-order-delivery-enabled', None)
        sub_content.pop('dynamic-load-sharing', None)
        obj = brcdapi_switch.fibrechannel_switch(session, fid, sub_content,
                                                 None, echo)
        if fos_auth.is_error(obj):
            brcdapi_log.log([
                'Failed to configure FID ' + str(fid),
                fos_auth.formatted_error_msg(obj)
            ], True)
            ec = brcddb_common.EXIT_STATUS_API_ERROR
        else:
            switch_d['err_msgs'].append(
                'Failed to set in order delivery and dynamic load sharing')
            buf = 'In order delivery and dynamic load sharing not supported via the API in this version of FOS. '\
                  'Remember to set these parameters manually.'
            brcdapi_log.log(buf, True)

    # Set the fabric parameters.
    # XISL (ability to use the base switch for ISLs) is enabled by default so we only need to disable it
    if not switch_d['xisl']:
        obj = brcdapi_rest.send_request(
            session,
            'running/brocade-fibrechannel-configuration/switch-configuration',
            'PATCH', {'switch-configuration': {
                'xisl-enabled': False
            }}, fid)
        if fos_auth.is_error(obj):
            switch_d['err_msgs'].append('Failed to disable XISL')
            ml = [
                'Failed to disable XISL for FID ' + str(fid),
                fos_auth.formatted_error_msg(obj),
                'Enabling and disabling of XISLs via the API was not supported until FOS v9.0.',
                'Unless there are other error messages, all other operations are or will be completed as expected.'
            ]
            brcdapi_log.log(ml, True)
            ec = brcddb_common.EXIT_STATUS_API_ERROR

    if idid:
        obj = brcdapi_rest.send_request(
            session, 'running/brocade-fibrechannel-configuration/fabric',
            'PATCH', {'fabric': {
                'insistent-domain-id-enabled': True
            }}, fid)
        if fos_auth.is_error(obj):
            switch_d['err_msgs'].append('Failed to set insistent domain id')
            brcdapi_log.log([
                'Failed to set insistent domain id for FID ' + str(fid),
                fos_auth.formatted_error_msg(obj)
            ], True)
            ec = brcddb_common.EXIT_STATUS_API_ERROR

    return ec
Exemple #25
0
def modify_zone(session,
                fid,
                zone,
                add_members,
                del_members,
                in_add_pmembers=None,
                in_del_pmembers=None,
                echo=False):
    """Adds and removes members from a zone.

    :param session: Session object returned from brcdapi.pyfos_auth.login()
    :type session: dict
    :param fid: Logical FID number
    :type fid: int
    :param zone: Name of zone to be modified
    :type zone: str
    :param add_members: Members to add to the zone
    :type add_members: list
    :param del_members: Members to delete from the zone
    :type del_members: list
    :param add_pmembers: Principal members to add to zone. Only relevant for peer zones
    :type add_pmembers: list
    :param del_pmembers: Principal members to delete from a zone. Only relevant for peer zones
    :type del_pmembers: list
    :param echo: If True, echoes any error messages to STD_OUT
    :type echo: bool
    :return: brcdapi_rest status object
    :rtype: dict
    """
    add_pmembers = list() if in_add_pmembers is None else in_add_pmembers
    del_pmembers = list() if in_del_pmembers is None else in_del_pmembers

    # This method reads the zone to change, makes the modifications in a local object, and PATCHes the change. I'm
    # assuming the type of zone could be changed but this method is just changing the membership. See "Important Notes"
    control = {
        'principal-entry-name': {
            'add_mem': add_pmembers,
            'del_mem': del_pmembers
        },
        'entry-name': {
            'add_mem': add_members,
            'del_mem': del_members
        },
    }
    # Read in the current defined zone
    obj = brcdapi_rest.get_request(
        session, 'brocade-zone/defined-configuration/zone/zone-name/' + zone,
        fid)
    if _is_error(obj, 'Failed reading zone ' + zone, echo):
        return obj

    # Modify the zone
    d = obj.get('zone')
    if d is None:
        return pyfos_auth.create_error(
            brcdapi_util.HTTP_BAD_REQUEST,
            brcdapi_util.HTTP_REASON_MAL_FORMED_OBJ,
            'Missing leaf "zone" in returned object for ' + zone)
    me = d.get('member-entry')
    if me is None:
        me = dict(
        )  # I'm not sure what FOS returns if all the members were deleted so this is just to be safe
        d.update({'member-entry': me})
    for k, v in control.items():
        ml = me.get(k)
        if len(v.get('add_mem')) + len(v.get('del_mem')) > 0:
            if ml is None:
                ml = list(
                )  # Just a safety net. Similar to 'member-entry' above.
                me.update(
                    {k: ml}
                )  # If there are principle members to a non-peer zone, FOS returns an error
            for mem in v.get('add_mem'):
                ml.append(mem)
            for mem in v.get('del_mem'):
                try:
                    ml.remove(mem)
                except:
                    pyfos_auth.create_error(
                        brcdapi_util.HTTP_BAD_REQUEST, 'Delete error',
                        'Member ' + mem + ' does not exist')

    content = {'defined-configuration': obj}
    obj = brcdapi_rest.send_request(session,
                                    'brocade-zone/defined-configuration',
                                    'PATCH', content, fid)
    _is_error(obj, 'Failed to create zones', echo)
    return obj