Beispiel #1
0
def main(config_path=None):
    cfg = Config(config_path)
    for sw_info in cfg.yield_sw_data_access_info():
        switch = SwitchFactory.factory(sw_info[1],
                                       sw_info[2],
                                       sw_info[3],
                                       sw_info[4],
                                       mode='active')
        switch.clear_mac_address_table()
Beispiel #2
0
def main(log):
    sw = SwitchFactory.factory(log,
                               'lenovo',
                               ip_addr='192.168.32.20',
                               mode='passive',
                               outfile='switch2_cmds.txt')

    sw.set_switchport_mode('trunk', 18)

    vlan_info = sw.show_vlans()
    print('vlan info: ')
    print(vlan_info)
    print()

    print('MAC address table: ')
    print(sw.show_mac_address_table())
    print()

    print('MAC address table dictionary: ')
    print_dict(sw.show_mac_address_table(format='dict'))
    print()

    print('Is pingable: ' + str(sw.is_pingable()))

    sw.set_switchport_mode('trunk', 18)
    resp = sw.is_port_in_trunk_mode(18)
    print('Port 18 is in trunk mode: ' + str(resp))
    print('Port 18 native vlan: ' + str(sw.show_native_vlan(18)))
    sw.set_switchport_native_vlan(1, 45)
    print('Port 45 native vlan: ' + str(sw.show_native_vlan(45)))
    sw.set_switchport_native_vlan(16, 45)
    print('Port 45 native vlan: ' + str(sw.show_native_vlan(45)))
    sys.exit(0)

    sw2 = SwitchFactory.factory(log, 'mellanox', '192.168.16.25', 'admin',
                                'admin')
    vlan_info = sw2.show_vlans()
    print(vlan_info)
    print(sw2.show_mac_address_table())

    sw3 = SwitchFactory.factory(log, 'mellanox', '192.168.16.30', 'admin',
                                'admin')
    print(sw3.show_vlans())
    print(sw3.show_mac_address_table())
    def _build_port_table_pxe(self, mac_list):
        """ Build table of discovered nodes.  The responding mac addresses
        discovered by tcpdump are correlated to switch ports from cluster
        switches. If nodes have taken an ip address (via dnsmasq) the ip
        address is included in the table.
        Args:
            node_list (list of str): IPV4 addresses
        Returns:
            table (AttrDict): switch, switch port, IPV4 address, MAC address
        """
        dhcp_leases = GetDhcpLeases(self.dhcp_pxe_leases_file)
        dhcp_mac_ip = dhcp_leases.get_mac_ip()

        dhcp_mac_table = AttrDict()
        for mac in mac_list:
            for item in dhcp_mac_ip.items():
                if mac in item:
                    dhcp_mac_table[item[0]] = item[1]
        self.log.debug('pxe dhcp mac table')
        self.log.debug(dhcp_mac_table)

        for sw_ai in self.cfg.yield_sw_mgmt_access_info():
            sw = SwitchFactory.factory(*sw_ai[1:])
            sw_label = sw_ai[0]
            pxe_ports = self._get_pxe_ports(sw_label)
            mgmt_sw_mac_lists = \
                sw.show_mac_address_table(format='std')

            # Get switch pxe port mac address table
            # Logic below maintains same port order as config.yml
            sw_pxe_mac_table = AttrDict()
            for port in pxe_ports:
                if port in mgmt_sw_mac_lists:
                    sw_pxe_mac_table[port] = mgmt_sw_mac_lists[port]
            self.log.debug('Switch pxe port mac table')
            self.log.debug(sw_pxe_mac_table)

            # self.node_table_pxe is structured around switches
            if sw_label not in self.node_table_pxe.keys():
                self.node_table_pxe[sw_label] = []

            for mac in mac_list:
                _port = '-'
                for port in sw_pxe_mac_table:
                    if mac in sw_pxe_mac_table[port]:
                        _port = port
                        break
                if mac in dhcp_mac_table:
                    ip = dhcp_mac_table[mac]
                else:
                    ip = '-'
                if not self._is_val_in_table(
                        self.node_table_pxe[sw_label], mac):
                    self.node_table_pxe[sw_label].append(
                        [_port, mac, ip])
Beispiel #4
0
 def __init__(self, dhcp_leases_file, port_type, config_path=None):
     self.log = logger.getlogger()
     self.cfg = Config(config_path)
     self.dhcp_leases_file = dhcp_leases_file
     self.port_type = port_type
     self.inv = Inventory(cfg_file=config_path)
     self.log.debug('Add ports, port type: {}'.format(self.port_type))
     self.sw_dict = {}
     for sw_ai in self.cfg.yield_sw_mgmt_access_info():
         label = sw_ai[0]
         self.sw_dict[label] = SwitchFactory.factory(*sw_ai[1:])
    def _get_port_table_ipmi(self, node_list):
        """ Build table of discovered nodes.  The responding IP addresses are
        correlated to MAC addresses in the dnsmasq.leases file.  The MAC
        address is then used to correlate the IP address to a switch port.
        Args:
            node_list (list of str): IPV4 addresses
        Returns:
            table (AttrDict): switch, switch port, IPV4 address, MAC address
        """
        dhcp_leases = GetDhcpLeases(self.dhcp_ipmi_leases_file)
        dhcp_mac_ip = dhcp_leases.get_mac_ip()

        dhcp_mac_table = AttrDict()
        for ip in node_list:
            for item in dhcp_mac_ip.items():
                if ip in item:
                    dhcp_mac_table[item[0]] = item[1]
        self.log.debug('ipmi mac-ip table')
        self.log.debug(dhcp_mac_table)

        for sw_ai in self.cfg.yield_sw_mgmt_access_info():
            sw = SwitchFactory.factory(*sw_ai[1:])
            label = sw_ai[0]
            ipmi_ports = self._get_ipmi_ports(label)
            mgmt_sw_cfg_mac_lists = \
                sw.show_mac_address_table(format='std')
            # Get switch ipmi port mac address table
            # Logic below maintains same port order as config.yml
            sw_ipmi_mac_table = AttrDict()
            for port in ipmi_ports:
                if port in mgmt_sw_cfg_mac_lists:
                    sw_ipmi_mac_table[port] = mgmt_sw_cfg_mac_lists[port]
            self.log.debug('Switch ipmi port mac table')
            self.log.debug(sw_ipmi_mac_table)

            if label not in self.node_table_ipmi.keys():
                self.node_table_ipmi[label] = []

            for port in sw_ipmi_mac_table:
                for mac in dhcp_mac_table:
                    if mac in sw_ipmi_mac_table[port]:
                        if not self._is_port_in_table(
                                self.node_table_ipmi[label], port):
                            self.node_table_ipmi[label].append(
                                [port, mac, dhcp_mac_table[mac]])
Beispiel #6
0
def main(config_path=None):
    log = logger.getlogger()
    cfg = Config(config_path)
    inv = Inventory(config_path)

    macs = {}
    for sw_info in cfg.yield_sw_data_access_info():
        switch = SwitchFactory.factory(sw_info[1],
                                       sw_info[2],
                                       sw_info[3],
                                       sw_info[4],
                                       mode='active')
        port_to_macs = switch.show_mac_address_table(format='std')
        log.debug(("Data switch port to MAC mapping - "
                   "Switch: '{}', Class: '{}' - IP: '{}' - {}").format(
                       sw_info[0], sw_info[1], sw_info[2], port_to_macs))
        macs.update({sw_info[0]: port_to_macs})
    inv.add_macs_data(macs)

    if not inv.check_data_interfaces_macs():
        _print_data_macs(inv)
    def validate_data_switches(self):
        self.log.info('Verifying data switches')

        sw_cnt = self.cfg.get_sw_data_cnt()
        self.log.debug(
            'Number of data switches defined in config file: {}'.format(
                sw_cnt))

        for index, switch_label in enumerate(self.cfg.yield_sw_data_label()):
            print('.', end="")
            sys.stdout.flush()
            label = self.cfg.get_sw_data_label(index)
            self.log.debug('switch_label: {}'.format(switch_label))

            switch_class = self.cfg.get_sw_data_class(index)
            if not switch_class:
                self.log.error('No switch class found')
                return False
            userid = None
            password = None
            rc = True

            try:
                userid = self.cfg.get_sw_data_userid(index)
            except AttributeError:
                self.log.info('Passive switch mode specified')
                return True

            try:
                password = self.cfg.get_sw_data_password(index)
            except AttributeError:
                try:
                    self.cfg.get_sw_data_ssh_key(index)
                except AttributeError:
                    return True
                else:
                    self.log.error(
                        'Switch authentication via ssh keys not yet supported')
                    return False
            # Verify communication on each defined interface
            for ip in self.cfg.yield_sw_data_interfaces_ip(index):
                self.log.debug('Verifying switch communication on ip'
                               ' address: {}'.format(ip))
                sw = SwitchFactory.factory(switch_class, ip, userid, password,
                                           'active')
                if sw.is_pingable():
                    self.log.debug(
                        'Successfully pinged data switch \"%s\" at %s' %
                        (label, ip))
                else:
                    self.log.warning(
                        'Failed to ping data switch \"%s\" at %s' %
                        (label, ip))
                    rc = False
                try:
                    vlans = sw.show_vlans()
                    if vlans and len(vlans) > 1:
                        self.log.debug(
                            'Successfully communicated with data switch \"%s\"'
                            ' at %s' % (label, ip))
                    else:
                        self.log.warning(
                            'Failed to communicate with data switch \"%s\"'
                            'at %s' % (label, ip))
                        rc = False
                except (SwitchException, SSH_Exception):
                    self.log.error('Failed communicating with data switch'
                                   ' at address {}'.format(ip))
                    rc = False
        print()
        if rc:
            self.log.debug(' OK - All data switches verified')
        else:
            raise UserException('Failed verification of data switches')
def configure_mgmt_switches(config_file=None):

    LOG = logger.getlogger()
    cfg = Config(config_file)
    LOG.debug(
        '------------------- configure_mgmt_switches -------------------')

    for index, switch_label in enumerate(cfg.yield_sw_mgmt_label()):
        mode = ACTIVE

        label = cfg.get_sw_mgmt_label(index)
        LOG.info('Configuring switch: {}'.format(switch_label))

        switch_class = cfg.get_sw_mgmt_class(index)
        if not switch_class:
            LOG.error('Unrecognized switch class')
            raise UserCriticalException('Unrecognized switch class')
        userid = None
        password = None
        switch_ip = None

        if cfg.is_passive_mgmt_switches():
            mode = PASSIVE

        try:
            userid = cfg.get_sw_mgmt_userid(index)
        except AttributeError:
            pass

        try:
            password = cfg.get_sw_mgmt_password(index)
        except AttributeError:
            try:
                cfg.get_sw_mgmt_ssh_key(index)
            except AttributeError:
                pass
            else:
                LOG.error(
                    'Switch authentication via ssh keys not yet supported')
                raise UserCriticalException(
                    'Switch authentication via ssh keys not yet supported')

        if mode == PASSIVE:
            sw = SwitchFactory.factory(switch_class, mode)

        elif mode == ACTIVE:
            # Try all ipaddrs in switches.interfaces
            for ip in cfg.yield_sw_mgmt_interfaces_ip(index):
                sw = SwitchFactory.factory(switch_class, ip, userid, password)
                # Get the enumerations needed to call set_switchport_mode() and
                # allowed_vlans_port()
                port_mode, allow_op = sw.get_enums()

                if sw.is_pingable():
                    LOG.debug(
                        'Sucessfully pinged management switch \"%s\" at %s' %
                        (label, ip))
                    switch_ip = ip
                    break

                LOG.debug('Failed to ping management switch \"%s\" at %s' %
                          (label, ip))

            else:
                LOG.error('Management switch is not responding to pings')
                raise UserCriticalException(
                    'Management switch at address {} is not responding to '
                    'pings'.format(ip))

        LOG.debug('%d: \"%s\" (%s) %s %s/%s' %
                  (index, switch_label, mode, switch_ip, userid, password))

        ports_cfg = sw.show_ports(format='std')

        sw_vlans = []
        for port in ports_cfg:
            if int(ports_cfg[str(port)]['nvlan']) not in sw_vlans:
                sw_vlans.append(int(port))
            avlans = ports_cfg[str(port)]['avlans'].split(', ')
            for avlan in avlans:
                if avlan and int(avlan) not in sw_vlans:
                    sw_vlans.append(int(avlan))

        vlan_mgmt = cfg.get_depl_netw_mgmt_vlan()
        vlan_mgmt = [x for x in vlan_mgmt if x is not None]
        LOG.debug('Management vlans: {}'.format(vlan_mgmt))

        vlan_client = cfg.get_depl_netw_client_vlan()
        LOG.debug('vlan_mgmt: {} , vlan_client: {}'.format(
            vlan_mgmt, vlan_client))
        for vlan in vlan_mgmt + vlan_client:
            if vlan and vlan not in sw_vlans:
                print('.', end="")
                sys.stdout.flush()
                sw.create_vlan(vlan)

        for intf_i, ip in enumerate(cfg.yield_sw_mgmt_interfaces_ip(index)):
            if ip != switch_ip:
                vlan = cfg.get_sw_mgmt_interfaces_vlan(index, intf_i)
                if vlan is None:
                    vlan = vlan_mgmt[0]
                netmask = cfg.get_sw_mgmt_interfaces_netmask(index, intf_i)

                try:
                    LOG.debug(
                        "Configuring mgmt switch \"%s\" inband interface. "
                        "(ip=%s netmask=%s vlan=%s)" %
                        (label, ip, netmask, vlan))
                    # sw.configure_interface(ip, netmask, vlan, port)
                    sw.configure_interface(ip, netmask, vlan)
                except SwitchException as exc:
                    LOG.warning(exc)

        for target_i, target in (enumerate(
                cfg.yield_sw_mgmt_links_target(index))):
            port = cfg.get_sw_mgmt_links_port(index, target_i)
            if target.lower() == 'deployer':
                vlans = vlan_mgmt + vlan_client
                if ports_cfg[str(port)]['mode'] != 'trunk':
                    try:
                        print('.', end="")
                        sys.stdout.flush()
                        LOG.debug('Adding vlans {} to port {}'.format(
                            vlans, port))
                        sw.set_switchport_mode(port, port_mode.TRUNK)
                    except SwitchException as exc:
                        LOG.error(exc)
                else:
                    LOG.debug('Port {} already in trunk mode'.format(port))
                port_vlans = ports_cfg[str(port)]['avlans'].split(', ')
                add_vlans = False
                for vlan in vlan_client:
                    if str(vlan) not in port_vlans:
                        add_vlans = True
                if (vlan_mgmt
                        and str(vlan_mgmt) not in port_vlans) or add_vlans:
                    try:
                        sw.allowed_vlans_port(port, allow_op.ADD, vlans)
                    except SwitchException as exc:
                        LOG.error(exc)
            else:
                vlan = cfg.get_sw_mgmt_links_vlan(index, target_i)
                if vlan is None:
                    if not vlan_mgmt:
                        vlan = 1
                    else:
                        vlan = vlan_mgmt[0]
                if ports_cfg[str(port)]['mode'] != 'trunk' or \
                        str(vlan) not in ports_cfg[str(port)]['avlans'].split(', '):
                    try:
                        sw.set_switchport_mode(port, port_mode.TRUNK)
                        sw.allowed_vlans_port(port, allow_op.NONE)
                        sw.allowed_vlans_port(port, allow_op.ADD, vlan)
                        sw.set_switchport_mode(port, port_mode.TRUNK, vlan)
                    except SwitchException as exc:
                        LOG.error(exc)

        for if_type in ['ipmi', 'pxe']:
            vlan = cfg.get_depl_netw_client_vlan(if_type=if_type)[0]

            for port in cfg.yield_client_switch_ports(switch_label, if_type):
                if mode == 'passive':
                    LOG.debug(
                        'Set switchport mode - switch is in passive mode.')
                else:
                    print('.', end="")
                    sys.stdout.flush()
                    if vlan != int(ports_cfg[str(port)]['nvlan']):
                        try:
                            LOG.debug(
                                'Setting port {} into {} mode with access '
                                'vlan {}'.format(port, port_mode.ACCESS, vlan))
                            sw.set_switchport_mode(port, port_mode.ACCESS,
                                                   vlan)
                        except SwitchException as exc:
                            LOG.error(exc)
                    else:
                        LOG.debug(
                            '\n{} port {} access vlan already configured.'.
                            format(if_type, port))
            # Remove (optionally) access vlan from ports in pxe or ipmi vlan that
            # are not listed in the config file.
            ports = cfg.get_client_switch_ports(switch_label, if_type)
            resp = 'y'
            for port in ports_cfg:
                if int(port) not in ports and ports_cfg[port]['nvlan'] == str(
                        vlan):
                    msg = (
                        'Port {} on switch {} configured with vlan {} but is '
                        'not specified in the {} network in your cluster config '
                        'file '.format(port, switch_label, vlan, if_type))
                    print()
                    LOG.warning(msg)
                    if resp not in ('yta', 'nta'):
                        resp = rlinput(
                            '\nOK to remove port {} from {} vlan '
                            '(y/yta/n/nta)? '.format(port, if_type), 'y')
                    if resp in ('y', 'yta'):
                        sw.set_switchport_mode(port, port_mode.ACCESS, 1)
def configure_mgmt_switches(config_file=None):

    LOG = logger.getlogger()
    cfg = Config(config_file)
    LOG.debug(
        '------------------- configure_mgmt_switches -------------------')

    for index, switch_label in enumerate(cfg.yield_sw_mgmt_label()):
        mode = ACTIVE

        label = cfg.get_sw_mgmt_label(index)
        LOG.info('Configuring switch: {}'.format(switch_label))

        switch_class = cfg.get_sw_mgmt_class(index)
        if not switch_class:
            LOG.error('Unrecognized switch class')
            raise UserCriticalException('Unrecognized switch class')
        userid = None
        password = None
        switch_ip = None

        if cfg.is_passive_mgmt_switches():
            mode = PASSIVE

        try:
            userid = cfg.get_sw_mgmt_userid(index)
        except AttributeError:
            pass

        try:
            password = cfg.get_sw_mgmt_password(index)
        except AttributeError:
            try:
                cfg.get_sw_mgmt_ssh_key(index)
            except AttributeError:
                pass
            else:
                LOG.error(
                    'Switch authentication via ssh keys not yet supported')
                raise UserCriticalException(
                    'Switch authentication via ssh keys not yet supported')

        if mode == PASSIVE:
            sw = SwitchFactory.factory(switch_class, mode)

        elif mode == ACTIVE:
            # Try all ipaddrs in switches.interfaces
            for ip in cfg.yield_sw_mgmt_interfaces_ip(index):
                sw = SwitchFactory.factory(switch_class, ip, userid, password)
                # Get the enumerations needed to call set_switchport_mode() and
                # allowed_vlans_port()
                port_mode, allow_op = sw.get_enums()

                if sw.is_pingable():
                    LOG.debug(
                        'Sucessfully pinged management switch \"%s\" at %s' %
                        (label, ip))
                    switch_ip = ip
                    break

                LOG.debug('Failed to ping management switch \"%s\" at %s' %
                          (label, ip))

            else:
                LOG.error('Management switch is not responding to pings')
                raise UserCriticalException(
                    'Management switch at address {} is not responding to '
                    'pings'.format(ip))

        LOG.debug('%d: \"%s\" (%s) %s %s/%s' %
                  (index, switch_label, mode, switch_ip, userid, password))

        vlan_mgmt = cfg.get_depl_netw_mgmt_vlan()
        vlan_mgmt = [x for x in vlan_mgmt if x is not None]
        LOG.debug('Management vlans: {}'.format(vlan_mgmt))

        vlan_client = cfg.get_depl_netw_client_vlan()
        LOG.debug('vlan_mgmt: {} , vlan_client: {}'.format(
            vlan_mgmt, vlan_client))
        for vlan in vlan_mgmt + vlan_client:
            if vlan:
                print('.', end="")
                sys.stdout.flush()
                sw.create_vlan(vlan)

        for intf_i, ip in enumerate(cfg.yield_sw_mgmt_interfaces_ip(index)):
            if ip != switch_ip:
                vlan = cfg.get_sw_mgmt_interfaces_vlan(index, intf_i)
                if vlan is None:
                    vlan = vlan_mgmt[0]
                netmask = cfg.get_sw_mgmt_interfaces_netmask(index, intf_i)

                try:
                    LOG.debug(
                        "Configuring mgmt switch \"%s\" inband interface. "
                        "(ip=%s netmask=%s vlan=%s)" %
                        (label, ip, netmask, vlan))
                    # sw.configure_interface(ip, netmask, vlan, port)
                    sw.configure_interface(ip, netmask, vlan)
                except SwitchException as exc:
                    LOG.warning(exc)

        for target_i, target in (enumerate(
                cfg.yield_sw_mgmt_links_target(index))):
            port = cfg.get_sw_mgmt_links_port(index, target_i)
            if target.lower() == 'deployer':
                try:
                    print('.', end="")
                    sys.stdout.flush()
                    vlans = vlan_mgmt + vlan_client
                    LOG.debug('Adding vlans {} to port {}'.format(vlans, port))
                    sw.set_switchport_mode(port, port_mode.TRUNK)
                except SwitchException as exc:
                    LOG.error(exc)
                try:
                    sw.allowed_vlans_port(port, allow_op.ADD, vlans)
                except SwitchException as exc:
                    LOG.error(exc)
            else:
                vlan = cfg.get_sw_mgmt_links_vlan(index, target_i)
                if vlan is None:
                    if not vlan_mgmt:
                        vlan = 1
                    else:
                        vlan = vlan_mgmt[0]
                try:
                    sw.set_switchport_mode(port, port_mode.TRUNK)
                    sw.allowed_vlans_port(port, allow_op.NONE)
                    sw.allowed_vlans_port(port, allow_op.ADD, vlan)
                    sw.set_switchport_mode(port, port_mode.TRUNK, vlan)
                except SwitchException as exc:
                    LOG.error(exc)
        for if_type in ['ipmi', 'pxe']:
            vlan = cfg.get_depl_netw_client_vlan(if_type=if_type)[0]

            for port in cfg.yield_client_switch_ports(switch_label, if_type):
                if mode == 'passive':
                    LOG.debug(
                        'Set switchport mode - switch is in passive mode.')
                else:
                    print('.', end="")
                    sys.stdout.flush()
                    try:
                        LOG.debug('Setting port {} into {} mode with access '
                                  'vlan {}'.format(port, port_mode.ACCESS,
                                                   vlan))
                        sw.set_switchport_mode(port, port_mode.ACCESS, vlan)
                    except SwitchException as exc:
                        LOG.error(exc)
Beispiel #10
0
def main(_class, host):
    """Allows for interactive test of switch methods as well as
    interactive display of switch information.  A config file
    is created for each switch class and entered values are
    remembered to allow for rapid rerunning of tests.
    Can be called from the command line with 0 arguments.
    """

    log = logger.getlogger()
    cfg_file_path = GEN_PATH + 'scripts/python/switch-cfg-{}.yml'
    try:
        cfg = yaml.load(open(cfg_file_path.format(_class)))
    except:
        print('Could not load file: ' + cfg_file_path.format(_class))
        print('Copying from template file')
        try:
            copyfile(GEN_PATH + 'scripts/python/switch-cfg-template.yml',
                     cfg_file_path.format(_class))
            cfg = yaml.load(open(cfg_file_path.format(_class)))
        except:
            print('Could not load file: ' + cfg_file_path.format(_class))
            sys.exit(1)

    try:
        test = cfg['test']
        vlan = cfg['vlan']
        vlans = cfg['vlans']
        ifc_addr = cfg['ifc_addr']
        ifc_netmask = cfg['ifc_netmask']
        port = cfg['port']
        ports = cfg['ports']
        switchport_mode = cfg['switchport_mode']
        mlag_ifc = cfg['mlag_ifc']
        lag_ifc = cfg['lag_ifc']
        operation = cfg['operation']
    except KeyError:
        test = '1'
        vlan = 20
        vlans = 20, 21
        ifc_addr = '192.168.32.20'
        ifc_netmask = '255.255.255.0'
        port = 1
        ports = 1, 2
        switchport_mode = 'access'
        mlag_ifc = 36
        lag_ifc = 1
        operation = 'ADD'

    sw = SwitchFactory.factory(_class, host, 'admin', 'admin', mode='active')
    # Get needed enumerations
    port_mode, allow_op = sw.get_enums()
    test = 1

    def show_menu():
        menu = {}
        menu[0.1] = 'Available tests (0 to exit) :\n'
        menu[1] = {'desc': 'Ping switch', 'func': '_ping_switch'}
        menu[2] = {'desc': 'Show MAC address table', 'func': '_show_macs'}
        menu[4] = {'desc': 'Show VLANs', 'func': '_show_vlans'}
        menu[3] = {'desc': 'show port information', 'func': '_show_ports'}
        menu[5] = {'desc': 'Create VLANs', 'func': '_create_vlans'}
        menu[6] = {'desc': 'Delete VLANs', 'func': '_delete_vlans'}
        menu[8] = {
            'desc': 'Is port in trunk mode',
            'func': '_is_port_in_trunk_mode'
        }
        menu[9] = {
            'desc': 'Is port in access mode',
            'func': '_is_port_in_access_mode'
        }
        menu[7] = {
            'desc': 'Set switchport mode',
            'func': '_set_switchport_mode'
        }
        menu[10] = {
            'desc': 'Set allowed VLANs on port',
            'func': '_set_allowed_vlans'
        }
        menu[11] = {
            'desc': 'Is VLAN(s) allowed on port',
            'func': '_is_vlan_allowed'
        }
        menu[12] = {
            'desc': 'Show native / access VLAN',
            'func': '_show_native_vlan'
        }
        menu[13] = {'desc': 'Set MTU on port', 'func': '_set_mtu'}
        menu[13.1] = '{}       Mgmt interface functions {}'.format(
            Color.bold, Color.endc)
        menu[14] = {
            'desc': 'Create an in-band interface',
            'func': '_create_inband_ifc'
        }
        menu[15] = {
            'desc': 'Delete an in-band interface',
            'func': '_delete_inband_ifc'
        }
        menu[16] = {
            'desc': 'show in-band interface(s)',
            'func': '_show_inband_ifc'
        }
        menu[30.1] = '{}       Port channel functions  {}'.format(
            Color.bold, Color.endc)
        menu[31] = {
            'desc': 'Show port channels',
            'func': '_show_port_channel_interfaces'
        }
        menu[32] = {
            'desc': 'Create port channel',
            'func': '_create_port_channel_interface'
        }
        menu[33] = {
            'desc': 'Add ports to port channel',
            'func': '_add_ports_to_port_channel'
        }
        menu[34] = {
            'desc': 'Delete port channel',
            'func': '_delete_port_channel'
        }
        menu[35] = {
            'desc': 'Set port channel mode',
            'func': '_set_port_channel_mode'
        }
        menu[36] = {
            'desc': 'Set allowed vlans on port channel',
            'func': '_set_allowed_vlans_port_channel'
        }
        menu[40.1] = '{}       vPC / MLAG functions{}'.format(
            Color.bold, Color.endc)
        menu[41] = {'desc': 'Is MLAG configured on switch', 'func': '_is_mlag'}
        menu[42] = {'desc': 'Show MLAG interfaces', 'func': '_show_mlag_ifcs'}
        menu[43] = {
            'desc': 'Create MLAG interface',
            'func': '_create_mlag_ifc'
        }
        menu[44] = {
            'desc': 'Delete MLAG interface',
            'func': '_delete_mlag_ifc'
        }
        menu[45] = {
            'desc': 'Add ports to MLAG port channel',
            'func': '_add_ports_to_mlag_port_channel'
        }
        menu[46] = {
            'desc': 'Set allowed vlans on MLAG port channel',
            'func': '_set_allowed_vlans_mlag_port_channel'
        }
        print('\n\n')
        for item in sorted(menu.keys()):
            if not isinstance(item, int):
                print(menu[item])
            elif isinstance(menu[item], dict):
                print(item, ' - ', menu[item]['desc'])
        return menu

    def _ping_switch(cfg):
        print('\nPinging switch at {}'.format(host))
        pingable = sw.is_pingable()
        if not pingable:
            print('Switch not responding to pings.')
        else:
            print('Switch {} is pingable: {} '.format(host, pingable))

    def _create_inband_ifc(cfg):
        print('\nTesting in-band interface creation')
        cfg['vlan'] = int(rlinput('Enter interface vlan: ', str(cfg['vlan'])))
        cfg['ifc_addr'] = rlinput('Enter interface address: ', cfg['ifc_addr'])
        cfg['ifc_netmask'] = rlinput('Enter interface netmask: ',
                                     cfg['ifc_netmask'])
        try:
            sw.configure_interface(cfg['ifc_addr'], cfg['ifc_netmask'],
                                   cfg['vlan'])
            print('Created interface vlan {}'.format(cfg['vlan']))
        except SwitchException as exc:
            print(exc)

    def _delete_inband_ifc(cfg):
        print('Testing remove interface')
        cfg['vlan'] = int(rlinput('Enter interface vlan: ', str(cfg['vlan'])))
        cfg['ifc_addr'] = rlinput('Enter interface address: ', cfg['ifc_addr'])
        cfg['ifc_netmask'] = rlinput('Enter interface netmask: ',
                                     cfg['ifc_netmask'])
        try:
            sw.remove_interface(cfg['vlan'], cfg['ifc_addr'],
                                cfg['ifc_netmask'])
            print('Removed interface vlan {}'.format(cfg['vlan']))
        except SwitchException as exc:
            print(exc)

    def _show_inband_ifc(cfg):
        print('\nTesting show in-band interfaces')
        ifc = rlinput('Enter interface # or vlan (leave blank to show all): ',
                      '')
        format = rlinput('Enter format ("std" or leave blank ): ', 'std')
        if format == '':
            format = None
        ifcs = sw.show_interfaces(ifc, format=format)
        if format is None:
            print(ifcs)
        else:
            for ifc in ifcs:
                print(ifc)

    def _show_macs(cfg):
        print('Test show mac address table: ')
        format = rlinput('Enter desired return format (std, dict or raw): ',
                         'std')
        macs = sw.show_mac_address_table(format=format)
        if format == 'raw':
            print(macs)
        elif format == 'dict' or format == 'std':
            print_dict(macs)

    def _show_ports(cfg):
        print('\nTesting show ports')
        format = rlinput('Enter format ("std" or "raw" ): ', 'std')
        ports = sw.show_ports(format=format)
        if format == 'raw':
            print(ports)
        else:
            print_dict(ports)

    def _show_vlans(cfg):
        print(sw.show_vlans())

    def _create_vlans(cfg):
        print('\nTest create vlan')
        cfg['vlan'] = int(rlinput('Enter vlan: ', str(cfg['vlan'])))
        try:
            sw.create_vlan(cfg['vlan'])
            print('Created vlan {}'.format(cfg['vlan']))
        except SwitchException as exc:
            print(exc)

    # Test delete vlan
    def _delete_vlans(cfg):
        print('\nTest deleting vlan')
        cfg['vlan'] = int(rlinput('Enter vlan: ', str(cfg['vlan'])))
        try:
            sw.delete_vlan(vlan)
            print('Deleted vlan {}'.format(cfg['vlan']))
        except SwitchException as exc:
            print(exc)

    # Test is port in trunk mode
    def _is_port_in_trunk_mode(cfg):
        print('\nTesting is port in trunk mode')
        cfg['port'] = rlinput('Enter port #: ', str(cfg['port']))
        print(sw.is_port_in_trunk_mode(cfg['port']))

    # Test is port in access mode
    def _is_port_in_access_mode(cfg):
        print('\nTesting is port in access mode')
        cfg['port'] = rlinput('Enter port #: ', str(cfg['port']))
        print(sw.is_port_in_access_mode(cfg['port']))

    # Test set switchport mode
    def _set_switchport_mode(cfg):
        print('\nTesting set switchport mode')
        cfg['port'] = rlinput('Enter port #: ', str(cfg['port']))
        cfg['switchport_mode'] = rlinput(
            'Enter switchport mode(TRUNK|HYBRID|'
            'ACCESS): ', cfg['switchport_mode'])
        if cfg['switchport_mode'] in ('TRUNK', 'HYBRID'):
            prompt = 'Enter native vlan / PVID (blank for None): '
        else:
            prompt = 'Enter access vlan (blank for default): '
        vlan = rlinput(prompt, str(cfg['vlan']))
        if vlan == '':
            vlan = None
        else:
            cfg['vlan'] = int(vlan)
        try:
            sw.set_switchport_mode(port, port_mode[cfg['switchport_mode']],
                                   vlan)
            print('Set switchport mode to ' + cfg['switchport_mode'])
        except SwitchException as exc:
            print(exc)

    # Test set  vlans on trunk / hybrid port
    def _set_allowed_vlans(cfg):
        print('\nTest set vlans on port')
        cfg['operation'] = rlinput(
            'Enter operation (ADD|ALL|EXCEPT|NONE|REMOVE): ', cfg['operation'])
        cfg['port'] = rlinput('Enter port #: ', str(cfg['port']))
        cfg['vlans'] = rlinput("Enter vlans (ex: '4' or '4,6' or '2-5'): ",
                               str(cfg['vlans']))
        try:
            sw.allowed_vlans_port(cfg['port'], allow_op[cfg['operation']],
                                  cfg['vlans'].split())
            print('{} vlans {} to port interface {}'.format(
                allow_op[cfg['operation']], cfg['vlans'], cfg['port']))
        except SwitchException as exc:
            print(exc)

    # Test is/are vlan(s) allowed for trunk port
    def _is_vlan_allowed(cfg):
        print('\nTesting is vlan allowed for port')
        cfg['port'] = rlinput('Enter port #: ', str(cfg['port']))
        cfg['vlans'] = rlinput('Enter vlan(s): ', str(cfg['vlans']))
        print(sw.is_vlan_allowed_for_port(cfg['vlans'], cfg['port']))

    def _show_native_vlan(cfg):
        print('\nTesting show native vlan')
        cfg['port'] = rlinput('Enter port #: ', str(cfg['port']))
        print('Native vlan: {}'.format(sw.show_native_vlan(cfg['port'])))

    # Test set mtu for port
    def _set_mtu(cfg):
        print('\nSet port mtu')
        cfg['port'] = rlinput('Enter port #: ', str(cfg['port']))
        mtu = rlinput('Enter mtu (0 for default mtu): ', 0)
        print(sw.set_mtu_for_port(cfg['port'], mtu))

    # Test show port channel (LAG) interfaces summary
    def _show_port_channel_interfaces(cfg):
        print(sw.show_port_channel_interfaces())

    # Test create port channel (LAG) interface
    def _create_port_channel_interface(cfg):
        print('\nTest create port channel interface')
        cfg['lag_ifc'] = int(
            rlinput('Enter port channel #: ', str(cfg['lag_ifc'])))
        try:
            sw.create_lag_interface(cfg['lag_ifc'])
            print('Created port channel ifc {}'.format(cfg['lag_ifc']))
        except SwitchException as exc:
            print(exc)

    # Test set port channel mode
    def _set_port_channel_mode(cfg):
        print('\nTest set port channel mode')
        cfg['lag_ifc'] = rlinput('Enter port channel #: ', str(cfg['lag_ifc']))
        cfg['switchport_mode'] = rlinput(
            'Enter switchport mode(trunk | access): ', cfg['switchport_mode'])
        try:
            sw.set_port_channel_mode(lag_ifc,
                                     port_mode[cfg['switchport_mode']])
        except SwitchException as exc:
            print(exc)

    # Test reserved
    def _add_ports_to_port_channel(cfg):
        cfg['lag_ifc'] = rlinput('Enter lag ifc #: ', str(cfg['lag_ifc']))
        cfg['ports'] = rlinput('Enter ports: ', str(cfg['ports']))
        ports = cfg['ports'].split()
        try:
            sw.add_ports_to_port_channel_ifc(ports, cfg['lag_ifc'])
            print('Added ports {} to lag interface {}'.format(
                cfg['ports'], cfg['lag_ifc']))
        except SwitchException as exc:
            print(exc)

    # Test set vlans on port channel (LAG)
    def _set_allowed_vlans_port_channel(cfg):
        print('\nTest set vlans on port channel')
        cfg['operation'] = rlinput(
            'Enter operation (ADD|ALL|EXCEPT|NONE|REMOVE): ', cfg['operation'])
        cfg['lag_ifc'] = rlinput('Enter port channel ifc #: ',
                                 str(cfg['lag_ifc']))
        cfg['vlans'] = rlinput("Enter vlans (ex: '4' or '4 6' or '2-5'): ",
                               str(cfg['vlans']))
        try:
            sw.allowed_vlans_port_channel(cfg['lag_ifc'],
                                          allow_op[cfg['operation']],
                                          cfg['vlans'].split())
            print('{} vlans {} to port channel interface {}'.format(
                cfg['operation'], cfg['vlans'], cfg['lag_ifc']))
        except SwitchException as exc:
            print(exc)

    # Test remove LAG interface
    def _delete_port_channel(cfg):
        print('\nTest remove LAG interface')
        cfg['lag_ifc'] = int(rlinput('Enter lag ifc #: ', str(cfg['lag_ifc'])))
        try:
            sw.remove_lag_interface(cfg['lag_ifc'])
            print('Deleted lag ifc {}'.format(cfg['lag_ifc']))
        except SwitchException as exc:
            print(exc)

    def _is_mlag(cfg):
        print(sw.is_mlag_configured())

    # Test show MLAG interfaces summary
    def _show_mlag_ifcs(cfg):
        print(sw.show_mlag_interfaces())

    # Test create MLAG interface (MLAG port channel)
    def _create_mlag_ifc(cfg):
        print('\nTest create MLAG interface')
        cfg['mlag_ifc'] = int(
            rlinput('Enter mlag ifc #: ', str(cfg['mlag_ifc'])))
        try:
            sw.create_mlag_interface(cfg['mlag_ifc'])
            print('Created mlag ifc {}'.format(cfg['mlag_ifc']))
        except SwitchException as exc:
            print(exc)

    def _add_ports_to_mlag_port_channel(cfg):
        cfg['lag_ifc'] = rlinput('Enter lag ifc #: ', str(cfg['lag_ifc']))
        cfg['ports'] = rlinput('Enter ports: ', str(cfg['ports']))
        ports = cfg['ports'].split()
        try:
            sw.bind_ports_to_mlag_interface(ports, cfg['lag_ifc'])
            print('Added ports {} to lag interface {}'.format(
                cfg['ports'], cfg['lag_ifc']))
        except SwitchException as exc:
            print(exc)

    def _set_allowed_vlans_mlag_port_channel(cfg):
        print('\nTest set vlans on port channel')
        cfg['operation'] = rlinput(
            'Enter operation (ADD|ALL|EXCEPT|NONE|REMOVE): ', cfg['operation'])
        cfg['lag_ifc'] = rlinput('Enter port channel ifc #: ',
                                 str(cfg['lag_ifc']))
        cfg['vlans'] = rlinput("Enter vlans (ex: '4' or '4,6' or '2-5'): ",
                               str(cfg['vlans']))
        try:
            sw.allowed_vlans_mlag_port_channel(cfg['lag_ifc'],
                                               allow_op[cfg['operation']],
                                               cfg['vlans'].split())
            print('{} vlans {} to port channel interface {}'.format(
                cfg['operation'], cfg['vlans'], cfg['lag_ifc']))
        except SwitchException as exc:
            print(exc)

    # Test remove MLAG interface
    def _delete_mlag_ifc(cfg):
        print('\nTest remove MLAG interface')
        cfg['mlag_ifc'] = int(
            rlinput('Enter mlag ifc #: ', str(cfg['mlag_ifc'])))
        try:
            sw.remove_mlag_interface(cfg['mlag_ifc'])
            print('Deleted mlag ifc {}'.format(cfg['mlag_ifc']))
        except SwitchException as exc:
            print(exc)

    # Test deconfigure MLAG interface
    def _deconfigure_mlag(cfg):
        try:
            sw.deconfigure_mlag()
        except SwitchException as exc:
            print(exc)

    test = ''
    while test != 0:
        if not test:
            menu = show_menu()
            test = rlinput(
                '{}\nEnter a test to run: {}'.format(Color.blue, Color.endc),
                '')
        try:
            test = int(test)
        except ValueError:
            test = 99

        if test == 0:
            sys.exit(0)

        if test != 99:
            func_name = menu[test]['func']
            func_to_call = locals()[func_name]
            func_to_call(cfg)

            yaml.dump(cfg,
                      open(cfg_file_path.format(_class), 'w'),
                      default_flow_style=False)
        test = rlinput('\nPress enter to continue or a test to run ', '')
    def __init__(self, log, inv_file):
        self.inv = Inventory(log, inv_file)
        self.log = log
        self.userid = self.inv.get_userid_data_switch()
        self.password = self.inv.get_password_data_switch()
        self.switch_dict = {}
        self.switch_name = self.inv.get_data_switch_name()

        for ipv4 in self.inv.yield_data_switch_ip():
            self.switch_dict[ipv4] = self.switch = SwitchFactory.factory(
                log,
                self.switch_name,
                ipv4,
                self.userid,
                self.password,
                mode='active')

        for self.ipv4, userid, password, vlans in self.inv.yield_data_vlans(self.userid, self.password):
            for vlan in vlans:
                self.switch_dict[self.ipv4].create_vlan(vlan)

        switch_index = 0
        for self.ipv4, port_vlans, port_mtu, port_bonds \
                in self.inv.yield_data_switch_ports(self.userid, self.password):
            if port_bonds:
                for ports in port_bonds.values():
                    for port in ports:
                        # Set port mode and add VLANs
                        if port in port_vlans:
                            self.switch_dict[self.ipv4].add_vlans_to_port(port, port_vlans[port])
                        # Specify MTU
                        if port in port_mtu:
                            self.switch_dict[self.ipv4].set_mtu_for_port(port, port_mtu[port])
            else:
                for port, vlans in port_vlans.items():
                    # Set port mode and add VLANs
                    self.switch_dict[self.ipv4].set_switchport_mode('trunk', port)
                    self.switch_dict[self.ipv4].add_vlans_to_port(port, vlans)
                for port, mtu in port_mtu.items():
                    # Specify MTU
                    self.switch_dict[self.ipv4].set_mtu_for_port(port, mtu)

            if port_bonds:
                # Enable LACP
                self.switch_dict[self.ipv4].enable_lacp()
                # Configure port for MLAG
                if self.inv.is_mlag():
                    vlan = self.inv.get_mlag_vlan()
                    port_channel = self.inv.get_mlag_port_channel()
                    cidr_mlag_ipl = self.inv.get_cidr_mlag_ipl(switch_index)
                    ipaddr_mlag_ipl_peer = self.inv.get_ipaddr_mlag_ipl_peer(switch_index)
                    ipaddr_mlag_vip = self.inv.get_ipaddr_mlag_vip()
                    mlag_ports = self.inv.get_mlag_ports(switch_index)
                    self.switch_dict[self.ipv4].configure_mlag(
                        vlan,
                        port_channel,
                        cidr_mlag_ipl,
                        ipaddr_mlag_ipl_peer,
                        ipaddr_mlag_vip,
                        mlag_ports)
                    for port_channel, ports in port_bonds.items():
                        # Remove any channel-group from port
                        self.switch_dict[self.ipv4].remove_channel_group(ports[0])
                        self.switch_dict[self.ipv4].create_mlag_interface(port_channel)
                        if ports[0] in port_vlans:
                            self.switch_dict[self.ipv4].add_vlans_to_mlag_port_channel(
                                port_channel, port_vlans[ports[0]])
                        if ports[0] in port_mtu:
                            self.switch_dict[self.ipv4].set_mtu_for_mlag_port_channel(
                                port_channel, port_mtu[ports[0]])
                        self.switch_dict[self.ipv4].bind_port_to_mlag_interface(port_channel)
                    # Enable MLAG
                    self.switch_dict[self.ipv4].enable_mlag()
                # Configure port for LAG
                else:
                    for port_channel, ports in port_bonds.items():
                        for port in ports:
                            self.switch_dict[self.ipv4].remove_channel_group(port)
                        if ports[0] in port_vlans:
                            self.switch_dict[self.ipv4].add_vlans_to_lag_port_channel(
                                port_channel, port_vlans[ports[0]])
                        if ports[0] in port_mtu:
                            self.switch_dict[self.ipv4].set_mtu_for_lag_port_channel(
                                port_channel, port_mtu[ports[0]])
                        self.switch_dict[self.ipv4].create_lag(port_channel)
                        self.switch_dict[self.ipv4].activate_lag(port_channel, ports)

            switch_index += 1

        if self.inv.is_write_switch_memory():
            switch = WriteSwitchMemory(LOG, INV_FILE)
            switch.write_data_switch_memory()
def deconfigure_data_switch(config_path):
    """ Deconfigures data (access) switches.  Deconfiguration is driven by the
    config.yml file. Generally deconfiguration is done in reverse order of
    configuration.
    Args:

    Returns:
    """
    log = logger.getlogger()
    global CFG
    CFG = Config(config_path)

    port_vlans = _get_vlan_list()
    mtu_list = _get_mtu_list()
    chan_ports = _get_port_chan_list()
    mlag_list = _get_mlag_info()

    # Create switch class instances for each switch
    sw_dict = {}
    port_mode = {}
    allow_op = {}
    for sw_ai in CFG.yield_sw_data_access_info():
        label = sw_ai[0]
        sw_dict[label] = SwitchFactory.factory(*sw_ai[1:])
        port_mode[label], allow_op[label] = sw_dict[label].get_enums()

    # Deconfigure channel ports and MLAG channel ports
    for bond in chan_ports:
        for ntmpl in chan_ports[bond]:
            for mstr_sw in chan_ports[bond][ntmpl]:
                if len(chan_ports[bond][ntmpl][mstr_sw]) == 2:
                    # Deconfigure mlag channel ports
                    for sw in chan_ports[bond][ntmpl][mstr_sw]:
                        if sw_dict[sw].is_mlag_configured():
                            for idx, port_grp in enumerate(
                                    chan_ports[bond][ntmpl][mstr_sw][sw]):
                                chan_num = _get_channel_num(port_grp)
                                log.info('Deleting mlag interface: {} on'
                                         ' switch: {}'.format(chan_num, sw))
                                sw_dict[sw].remove_mlag_interface(chan_num)
                else:
                    # deconfigure LAG channel ports
                    for sw in chan_ports[bond][ntmpl][mstr_sw]:
                        for port_grp in chan_ports[bond][ntmpl][mstr_sw][sw]:
                            chan_num = _get_channel_num(port_grp)
                            log.info('Deleting Lag interface {} on switch: {}'.
                                     format(chan_num, sw))
                            sw_dict[sw].remove_port_channel_ifc(chan_num)
    # Deconfigure MLAG
    for mstr_sw in mlag_list:
        for sw in mlag_list[mstr_sw]:
            is_mlag = sw_dict[sw].is_mlag_configured()
            log.info('vPC/MLAG configured on sw {}: {}'.format(sw, is_mlag))
            if is_mlag:
                print(
                    '\n\nDo you wish to deconfigure MLAG on switch {}?'.format(
                        sw))
                print(
                    'This will stop all MLAG communication on all switch ports'
                )
                print('OK to deconfigure MLAG?')
                resp = raw_input("Enter (Y/yes/n): ")
                if resp in ['Y', 'yes']:
                    log.info('Deconfiguring MLAG on switch: {}'.format(sw))
                    sw_dict[sw].deconfigure_mlag()
            else:
                log.debug('\nMLAG not configured on switch: {}'.format(sw))

    # Deconfigure switch vlans - first remove from ports
    for switch in port_vlans:
        for port in port_vlans[switch]:
            log.info('switch: {}, port: {}, removing vlans: {}'.format(
                switch, port, port_vlans[switch][port]))
            sw_dict[switch].allowed_vlans_port(port, allow_op[switch].REMOVE,
                                               port_vlans[switch][port])
            log.info('Switch {}, setting port: {} to access mode'.format(
                switch, port))
            sw_dict[switch].set_switchport_mode(port, port_mode[switch].ACCESS)
    # Delete the vlans
    for switch in port_vlans:
        vlans = []
        for port in port_vlans[switch]:
            for vlan in port_vlans[switch][port]:
                if vlan not in vlans:
                    vlans.append(vlan)
                    sw_dict[switch].delete_vlan(vlan)
                    log.info('Switch: {}, deleting vlan: {}'.format(
                        switch, vlan))

    # Deconfigure switch mtu
    for switch in mtu_list:
        for mtu in mtu_list[switch]:
            for port in mtu_list[switch][mtu]:
                sw_dict[switch].set_mtu_for_port(port, 0)
                log.info('switch: {}, port: {}, setting mtu: {}'.format(
                    switch, port, 'default mtu'))
def configure_data_switch(config_path):
    """ Configures data (access) switches.  Configuration is driven by the
    config.yml file.
    Args:

    Returns:
    """
    log = logger.getlogger()
    global CFG
    CFG = Config(config_path)

    port_vlans = _get_vlan_list()
    mtu_list = _get_mtu_list()
    chan_ports = _get_port_chan_list()
    mlag_list = _get_mlag_info()

    # Create switch class instances for each switch
    sw_dict = {}
    # create dictionaries to hold enumerations for each switch
    port_mode = {}
    allow_op = {}
    for sw_ai in CFG.yield_sw_data_access_info():
        label = sw_ai[0]
        sw_dict[label] = SwitchFactory.factory(*sw_ai[1:])
        port_mode[label], allow_op[label] = sw_dict[label].get_enums()

    # Program switch vlans
    for switch in port_vlans:
        vlans = []
        for port in port_vlans[switch]:
            print('.', end="")
            sys.stdout.flush()
            for vlan in port_vlans[switch][port]:
                if vlan not in vlans:
                    vlans.append(vlan)
                    sw_dict[switch].create_vlan(vlan)
                    log.debug('Creating vlan {} on switch {}'.format(
                        vlan, switch))
            try:
                sw_dict[switch].set_switchport_mode(port,
                                                    port_mode[switch].TRUNK)
            except SwitchException as exc:
                log.warning(
                    'Switch: {}. Failed setting port {} to trunk mode'.format(
                        switch, port))
            try:
                sw_dict[switch].allowed_vlans_port(port, allow_op[switch].ADD,
                                                   port_vlans[switch][port])
            except SwitchException as exc:
                log.warning(
                    'Switch: {}. Failed adding vlans {} to port {}'.format(
                        switch, port_vlans[switch][port], port))
                log.warning(exc.message)
            log.debug('switch: {} port: {} vlans: {}'.format(
                switch, port, port_vlans[switch][port]))

    # Program switch mtu
    for switch in mtu_list:
        for mtu in mtu_list[switch]:
            for port in mtu_list[switch][mtu]:
                sw_dict[switch].set_mtu_for_port(port, mtu)
                log.debug('port: {} set mtu: {}'.format(port, mtu))

    # Configure MLAG
    for mstr_sw in mlag_list:
        log.debug('Configuring MLAG.  mlag switch mstr: ' + mstr_sw)
        for sw in mlag_list[mstr_sw]:
            is_mlag = sw_dict[sw].is_mlag_configured()
            log.debug('vPC/MLAG configured on switch: {}, {}'.format(
                sw, is_mlag))
            if not is_mlag:
                print('.', end="")
                sys.stdout.flush()
                log.debug('Configuring MLAG on switch {}'.format(sw))
                sw_dict[sw].configure_mlag(
                    mlag_list[mstr_sw][sw]['vlan'],
                    min(mlag_list[mstr_sw][mstr_sw]['ports']),
                    mlag_list[mstr_sw][sw]['cidr'],
                    mlag_list[mstr_sw][sw]['peer_ip'],
                    mlag_list[mstr_sw][sw]['vip'],
                    mlag_list[mstr_sw][sw]['ports'])
            else:
                log.debug('MLAG already configured. Skipping'
                          ' MLAG configuration on switch {}.'.format(sw))
        for sw in mlag_list[mstr_sw]:
            if sw_dict[sw].is_mlag_configured():
                sw_dict[sw].enable_mlag()

    # Configure port channels and MLAG port channels
    for bond in chan_ports:
        for ntmpl in chan_ports[bond]:
            for mstr_sw in chan_ports[bond][ntmpl]:
                if len(chan_ports[bond][ntmpl][mstr_sw]) == 2:
                    # MLAG
                    for sw in chan_ports[bond][ntmpl][mstr_sw]:
                        for idx, port_grp in enumerate(
                                chan_ports[bond][ntmpl][mstr_sw][sw]):
                            chan_num = _get_channel_num(port_grp)
                            log.debug(
                                'create mlag interface {} on switch {}'.format(
                                    chan_num, sw))
                            sw_dict[sw].remove_mlag_interface(chan_num)
                            sw_dict[sw].create_mlag_interface(chan_num)
                            print('.', end="")
                            sys.stdout.flush()
                            # All ports in a port group should have the same vlans
                            # So use any one for setting the MLAG port channel vlans
                            vlan_port = chan_ports[bond][ntmpl][mstr_sw][sw][
                                idx][0]
                            vlans = _get_port_vlans(sw, vlan_port, port_vlans)
                            _port_mode = port_mode[sw].TRUNK if vlans \
                                else port_mode[sw].ACCESS
                            sw_dict[sw].set_mlag_port_channel_mode(
                                chan_num, _port_mode)
                            mtu = _get_port_mtu(sw, chan_num, mtu_list)
                            if vlans:
                                log.debug(
                                    'Switch {}, add vlans {} to mlag port '
                                    'channel {}.'.format(sw, vlans, chan_num))
                                sw_dict[sw].allowed_vlans_mlag_port_channel(
                                    chan_num, allow_op[sw].NONE)
                                sw_dict[sw].allowed_vlans_mlag_port_channel(
                                    chan_num, allow_op[sw].ADD, vlans)
                            if mtu:
                                log.debug(
                                    'set_mtu_for_mlag_port_channel: {}'.format(
                                        mtu))
                                sw_dict[sw].set_mtu_for_lag_port_channel(
                                    chan_num, mtu)
                            log.debug(
                                'Switch {}, adding ports {} to mlag chan '
                                'num: {}'.format(sw, port_grp, chan_num))
                            try:
                                sw_dict[sw].bind_ports_to_mlag_interface(
                                    port_grp, chan_num)
                            except SwitchException as exc:
                                log.warning(
                                    'Failure configuring port in switch:'
                                    ' {}.\n{}'.format(sw, exc.message))
                else:
                    # Configure LAG
                    for sw in chan_ports[bond][ntmpl][mstr_sw]:
                        for port_grp in chan_ports[bond][ntmpl][mstr_sw][sw]:
                            chan_num = _get_channel_num(port_grp)
                            print('.', end="")
                            sys.stdout.flush()
                            log.debug(
                                'Lag channel group: {} on switch: {}'.format(
                                    chan_num, sw))
                            sw_dict[sw].create_port_channel_ifc(chan_num)
                            vlans = _get_port_vlans(sw, port_grp[0],
                                                    port_vlans)
                            _port_mode = port_mode[sw].TRUNK if vlans else \
                                port_mode[sw].ACCESS
                            sw_dict[sw].set_port_channel_mode(
                                chan_num, _port_mode)
                            mtu = _get_port_mtu(sw, chan_num, mtu_list)
                            if vlans:
                                log.debug(
                                    'switch {}, add vlans {} to lag port '
                                    'channel {}'.format(sw, vlans, chan_num))
                                sw_dict[sw].allowed_vlans_port_channel(
                                    chan_num, allow_op[sw].NONE)
                                sw_dict[sw].allowed_vlans_port_channel(
                                    chan_num, allow_op[sw].ADD, vlans)
                            if mtu:
                                log.debug(
                                    'set mtu for port channel: {}'.format(mtu))
                                sw_dict[sw].set_mtu_for_port_channel(
                                    chan_num, mtu)

                            log.debug(
                                'Switch: {}, adding port(s) {} to lag chan'
                                ' num: {}'.format(sw, port_grp, chan_num))
                            try:
                                sw_dict[sw].remove_ports_from_port_channel_ifc(
                                    port_grp)
                                sw_dict[sw].add_ports_to_port_channel_ifc(
                                    port_grp, chan_num)
                            except SwitchException as exc:
                                log.warning(
                                    'Failure configuring port in switch:'
                                    '{}.\n {}'.format(sw, exc.message))
Beispiel #14
0
    def get_ports(self):
        dhcp_leases = GetDhcpLeases(self.dhcp_leases_file)
        dhcp_mac_ip = dhcp_leases.get_mac_ip()
        self.log.debug('DHCP leases: {}'.format(dhcp_mac_ip))

        mgmt_sw_cfg_mac_lists = AttrDict()

        if self.cfg.is_passive_mgmt_switches():
            self.log.debug('passive mode')
            for switch_label in self.cfg.yield_sw_mgmt_label():
                file_path = os.path.join(GEN_PASSIVE_PATH, switch_label)
                mac_info = {}
                try:
                    with open(file_path, 'r') as f:
                        mac_info = f.read()

                except IOError as error:
                    self.log.error(
                        'Passive switch MAC address table file not found {}'
                        .format(error))
                    raise
                mgmt_sw_cfg_mac_lists[switch_label] = \
                    SwitchCommon.get_port_to_mac(mac_info, self.log)
        else:
            for sw_ai in self.cfg.yield_sw_mgmt_access_info():
                self.log.debug('switch ai: {}'.format(sw_ai))
                sw = SwitchFactory.factory(*sw_ai[1:])
                label = sw_ai[0]
                mgmt_sw_cfg_mac_lists[label] = \
                    sw.show_mac_address_table(format='std')

        self.log.debug('Management switches MAC address tables: {}'.format(
            mgmt_sw_cfg_mac_lists))

        # Remove all the mac address table entries which do not have a matching
        # MAC address in the DHCP leases table, then remove any MAC addresses
        # which do not have a  DHCP table entry.
        for switch in mgmt_sw_cfg_mac_lists.keys():
            for port in mgmt_sw_cfg_mac_lists[switch]:
                port_macs = mgmt_sw_cfg_mac_lists[switch][port]
                found_mac = False
                for mac in dhcp_mac_ip.keys():
                    if mac in port_macs:
                        found_mac = True
                        # keep only the mac which has a dhcp address
                        mgmt_sw_cfg_mac_lists[switch][port] = [mac]
                if not found_mac:
                    del mgmt_sw_cfg_mac_lists[switch][port]
        self.log.debug('Management switches MAC address table of ports with'
                       'dhcp leases: {}'.format(mgmt_sw_cfg_mac_lists))

        if self.port_type == "ipmi":
            self.inv.add_macs_ipmi(mgmt_sw_cfg_mac_lists)
            self.inv.add_ipaddrs_ipmi(dhcp_mac_ip)
        elif self.port_type == "pxe":
            self.inv.add_macs_pxe(mgmt_sw_cfg_mac_lists)
            self.inv.add_ipaddrs_pxe(dhcp_mac_ip)

        if self.port_type == 'ipmi':
            self.node_table, self.ports_found, self.ports_total = \
                self._build_node_table_ipmi(self.cfg, dhcp_mac_ip, mgmt_sw_cfg_mac_lists)

        if self.port_type == 'pxe':
            self.node_table, self.ports_found, self.ports_total = \
                self._build_node_table_pxe(self.cfg, dhcp_mac_ip, mgmt_sw_cfg_mac_lists)