def _validateNetworkSetup(networks, bondings): for network, networkAttrs in networks.iteritems(): if networkAttrs.get('remove', False): if set(networkAttrs) - set(['remove']): raise ConfigNetworkError(ne.ERR_BAD_PARAMS, 'Cannot specify ' 'any attribute when removing') currentBondings = netinfo.bondings() currentNicsSet = set(netinfo.nics()) for bonding, bondingAttrs in bondings.iteritems(): Bond.validateName(bonding) if 'options' in bondingAttrs: Bond.validateOptions(bonding, bondingAttrs['options']) if bondingAttrs.get('remove', False): if bonding not in currentBondings: raise ConfigNetworkError(ne.ERR_BAD_BONDING, "Cannot remove " "bonding %s: Doesn't exist" % bonding) continue nics = bondingAttrs.get('nics', None) if not nics: raise ConfigNetworkError(ne.ERR_BAD_PARAMS, "Must specify nics for bonding") if not set(nics).issubset(currentNicsSet): raise ConfigNetworkError(ne.ERR_BAD_NIC, "Unknown nics in: %r" % list(nics))
def _handleBondings(bondings, configurator): """ Add/Edit/Remove bond interface """ logger = logging.getLogger("_handleBondings") _netinfo = netinfo.NetInfo() edition = [] addition = [] for name, attrs in bondings.items(): if 'remove' in attrs: bond = Bond.objectivize(name, configurator, attrs.get('options'), attrs.get('nics'), mtu=None, _netinfo=_netinfo, destroyOnMasterRemoval='remove' in attrs) bond.remove() del _netinfo.bondings[name] elif name in _netinfo.bondings: edition.append((name, attrs)) else: addition.append((name, attrs)) for name, attrs in edition: bond = Bond.objectivize(name, configurator, attrs.get('options'), attrs.get('nics'), mtu=None, _netinfo=_netinfo, destroyOnMasterRemoval='remove' in attrs) logger.debug("Editing bond %r with options %s", bond, bond.options) configurator.editBonding(bond, _netinfo) for name, attrs in addition: bond = Bond.objectivize(name, configurator, attrs.get('options'), attrs.get('nics'), mtu=None, _netinfo=_netinfo, destroyOnMasterRemoval='remove' in attrs) logger.debug("Creating bond %r with options %s", bond, bond.options) configurator.configureBond(bond)
def _validateNetworkSetup(networks, bondings): _netinfo = netinfo.NetInfo() for network, networkAttrs in networks.iteritems(): if networkAttrs.get('remove', False): if set(networkAttrs) - set(['remove']): raise ConfigNetworkError( ne.ERR_BAD_PARAMS, 'Cannot specify ' 'any attribute when removing') for bonding, bondingAttrs in bondings.iteritems(): Bond.validateName(bonding) if 'options' in bondingAttrs: Bond.validateOptions(bonding, bondingAttrs['options']) if bondingAttrs.get('remove', False): if bonding not in _netinfo.bondings: raise ConfigNetworkError( ne.ERR_BAD_BONDING, "Cannot remove " "bonding %s: Doesn't exist" % bonding) continue nics = bondingAttrs.get('nics', None) if not nics: raise ConfigNetworkError(ne.ERR_BAD_PARAMS, "Must specify nics for bonding") if not set(nics).issubset(set(_netinfo.nics)): raise ConfigNetworkError(ne.ERR_BAD_NIC, "Unknown nics in: %r" % list(nics))
def testValidateBondingOptions(self): if not os.path.exists(netinfo.BONDING_MASTERS): raise SkipTest("bonding kernel module could not be found.") opts = 'mode=802.3ad miimon=150' badOpts = 'foo=bar badopt=one' with self.assertRaises(neterrors.ConfigNetworkError) as cne: Bond.validateOptions('bond0', badOpts) self.assertEqual(cne.exception.errCode, neterrors.ERR_BAD_BONDING) self.assertEqual(Bond.validateOptions('bond0', opts), None)
def testIsBondingNameValid(self): bondNames = ('badValue', ' bond14', 'bond14 ', 'bond14a', 'bond0 0') for bondName in bondNames: with self.assertRaises(neterrors.ConfigNetworkError) \ as cneContext: Bond.validateName(bondName) self.assertEqual(cneContext.exception.errCode, neterrors.ERR_BAD_BONDING) self.assertEqual(Bond.validateName('bond11'), None) self.assertEqual(Bond.validateName('bond11128421982'), None)
def _handleBondings(bondings, configurator): """ Add/Edit/Remove bond interface """ logger = logging.getLogger("_handleBondings") _netinfo = netinfo.NetInfo() for bondName, bondAttrs in bondings.items(): bond = Bond.objectivize(bondName, configurator, bondAttrs.get('options'), bondAttrs.get('nics'), mtu=None, _netinfo=_netinfo, destroyOnMasterRemoval='remove' in bondAttrs) if 'remove' in bondAttrs: logger.debug("Removing bond %s with attributes %s", bondName, bondAttrs) configurator.removeBond(bond) del bondings[bondName] del _netinfo.bondings[bondName] elif bondName in _netinfo.bondings: logger.debug("Editing bond %s with attributes %s", bondName, bondAttrs) configurator.editBonding(bond, _netinfo) else: logger.debug("Creating bond %s with attributes %s", bondName, bondAttrs) configurator.configureBond(bond)
def testTextualRepr(self): _netinfo = { 'networks': {}, 'vlans': {}, 'nics': ['testnic1', 'testnic2'], 'bondings': {} } fakeInfo = netinfo.NetInfo(_netinfo) nic1 = Nic('testnic1', None, _netinfo=fakeInfo) nic2 = Nic('testnic2', None, _netinfo=fakeInfo) bond1 = Bond('bond42', None, slaves=(nic1, nic2)) vlan1 = Vlan(bond1, '4', None) bridge1 = Bridge('testbridge', None, port=vlan1) self.assertEqual( '%r' % bridge1, 'Bridge(testbridge: Vlan(bond42.4: ' 'Bond(bond42: (Nic(testnic1), Nic(testnic2)))))')
def objectivizeNetwork(bridge=None, vlan=None, bonding=None, bondingOptions=None, nics=None, mtu=None, ipaddr=None, netmask=None, gateway=None, bootproto=None, ipv6addr=None, ipv6gateway=None, ipv6autoconf=None, dhcpv6=None, defaultRoute=None, _netinfo=None, configurator=None, blockingdhcp=None, implicitBonding=None, **opts): """ Constructs an object hierarchy that describes the network configuration that is passed in the parameters. :param bridge: name of the bridge. :param vlan: vlan tag id. :param bonding: name of the bond. :param bondingOptions: bonding options separated by spaces. :param nics: list of nic names. :param mtu: the desired network maximum transmission unit. :param ipaddr: IPv4 address in dotted decimal format. :param netmask: IPv4 mask in dotted decimal format. :param gateway: IPv4 address in dotted decimal format. :param bootproto: protocol for getting IP config for the net, e.g., 'dhcp' :param ipv6addr: IPv6 address in format address[/prefixlen]. :param ipv6gateway: IPv6 address in format address[/prefixlen]. :param ipv6autoconf: whether to use IPv6's stateless autoconfiguration. :param dhcpv6: whether to use DHCPv6. :param _netinfo: network information snapshot. :param configurator: instance to use to apply the network configuration. :param blockingdhcp: whether to acquire dhcp IP config in a synced manner. :param implicitBonding: whether the bond's existance is tied to it's master's. :param defaultRoute: Should this network's gateway be set in the main routing table? :returns: the top object of the hierarchy. """ if configurator is None: configurator = ConfiguratorClass() if _netinfo is None: _netinfo = netinfo.NetInfo() if bondingOptions and not bonding: raise ConfigNetworkError(ne.ERR_BAD_BONDING, 'Bonding options ' 'specified without bonding') topNetDev = None if bonding: topNetDev = Bond.objectivize(bonding, configurator, bondingOptions, nics, mtu, _netinfo, implicitBonding) elif nics: try: nic, = nics except ValueError: raise ConfigNetworkError(ne.ERR_BAD_BONDING, 'Multiple nics ' 'require a bonding device') else: bond = _netinfo.getBondingForNic(nic) if bond: raise ConfigNetworkError(ne.ERR_USED_NIC, 'nic %s already ' 'enslaved to %s' % (nic, bond)) topNetDev = Nic(nic, configurator, mtu=mtu, _netinfo=_netinfo) if vlan is not None: topNetDev = Vlan(topNetDev, vlan, configurator, mtu=mtu) if bridge: topNetDev = Bridge(bridge, configurator, port=topNetDev, mtu=mtu, stp=opts.get('stp')) if topNetDev is None: raise ConfigNetworkError(ne.ERR_BAD_PARAMS, 'Network defined without ' 'devices.') ipv6 = IPv6(ipv6addr, ipv6gateway, defaultRoute) ipv4 = IPv4(ipaddr, netmask, gateway, defaultRoute) topNetDev.ip = IpConfig(inet4=ipv4, inet6=ipv6, bootproto=bootproto, blocking=utils.tobool(blockingdhcp), ipv6autoconf=ipv6autoconf, dhcpv6=dhcpv6) return topNetDev
def objectivizeNetwork(bridge=None, vlan=None, bonding=None, bondingOptions=None, nics=None, mtu=None, ipaddr=None, netmask=None, gateway=None, bootproto=None, _netinfo=None, configurator=None, blockingdhcp=None, implicitBonding=None, defaultRoute=None, **opts): """ Constructs an object hierarchy that describes the network configuration that is passed in the parameters. :param bridge: name of the bridge. :param vlan: vlan tag id. :param bonding: name of the bond. :param bondingOptions: bonding options separated by spaces. :param nics: list of nic names. :param mtu: the desired network maximum transmission unit. :param ipaddr: IPv4 address in dotted decimal format. :param netmask: IPv4 mask in dotted decimal format. :param gateway: IPv4 address in dotted decimal format. :param bootproto: protocol for getting IP config for the net, e.g., 'dhcp' :param _netinfo: network information snapshot. :param configurator: instance to use to apply the network configuration. :param blockingdhcp: whether to acquire dhcp IP config in a synced manner. :param implicitBonding: whether the bond's existance is tied to it's master's. :param defaultRoute: Should this network's gateway be set in the main routing table? :returns: the top object of the hierarchy. """ if configurator is None: configurator = Ifcfg() if _netinfo is None: _netinfo = netinfo.NetInfo() if bondingOptions and not bonding: raise ConfigNetworkError( ne.ERR_BAD_BONDING, 'Bonding options ' 'specified without bonding') topNetDev = None if bonding: topNetDev = Bond.objectivize(bonding, configurator, bondingOptions, nics, mtu, _netinfo, implicitBonding) elif nics: try: nic, = nics except ValueError: raise ConfigNetworkError( ne.ERR_BAD_BONDING, 'Multiple nics ' 'require a bonding device') else: bond = _netinfo.getBondingForNic(nic) if bond: raise ConfigNetworkError( ne.ERR_USED_NIC, 'nic %s already ' 'enslaved to %s' % (nic, bond)) topNetDev = Nic(nic, configurator, mtu=mtu, _netinfo=_netinfo) if vlan: topNetDev = Vlan(topNetDev, vlan, configurator, mtu=mtu) if bridge: topNetDev = Bridge(bridge, configurator, port=topNetDev, mtu=mtu, stp=opts.get('stp'), forwardDelay=int(opts.get('forward_delay', 0))) if topNetDev is None: raise ConfigNetworkError(ne.ERR_BAD_PARAMS, 'Network defined without' 'devices.') topNetDev.ip = IpConfig(inet=IPv4(ipaddr, netmask, gateway, defaultRoute), bootproto=bootproto, blocking=utils.tobool(blockingdhcp)) return topNetDev
def objectivizeNetwork(bridge=None, vlan=None, bonding=None, bondingOptions=None, nics=None, mtu=None, ipaddr=None, netmask=None, gateway=None, bootproto=None, _netinfo=None, configurator=None, blockingdhcp=None, **opts): """ Constructs an object hierarchy that describes the network configuration that is passed in the parameters. :param bridge: name of the bridge. :param vlan: vlan tag id. :param bonding: name of the bond. :param bondingOptions: bonding options separated by spaces. :param nics: list of nic names. :param mtu: the desired network maximum transmission unit. :param ipaddr: IPv4 address in dotted decimal format. :param netmask: IPv4 mask in dotted decimal format. :param gateway: IPv4 address in dotted decimal format. :param bootproto: protocol for getting IP config for the net, e.g., 'dchp' :param _netinfo: network information snapshot. :param configurator: instance to use to apply the network configuration. :param blockingdhcp: whether to acquire dhcp IP config in a synced manner. :returns: the top object of the hierarchy. """ if configurator is None: configurator = Ifcfg() if _netinfo is None: _netinfo = netinfo.NetInfo() if bondingOptions and not bonding: raise ConfigNetworkError(ne.ERR_BAD_BONDING, 'Bonding options ' 'specified without bonding') topNetDev = None if bonding: topNetDev = Bond.objectivize(bonding, configurator, bondingOptions, nics, mtu, _netinfo) elif nics: try: nic, = nics except ValueError: raise ConfigNetworkError(ne.ERR_BAD_BONDING, 'Multiple nics ' 'require a bonding device') else: bond = _netinfo.getBondingForNic(nic) if bond: raise ConfigNetworkError(ne.ERR_USED_NIC, 'nic %s already ' 'enslaved to %s' % (nic, bond)) topNetDev = Nic(nic, configurator, mtu=mtu, _netinfo=_netinfo) if vlan: topNetDev = Vlan(topNetDev, vlan, configurator, mtu=mtu) if bridge: topNetDev = Bridge(bridge, configurator, port=topNetDev, mtu=mtu, stp=opts.get('stp'), forwardDelay=opts.get('forward_delay', 0)) if topNetDev is None: raise ConfigNetworkError(ne.ERR_BAD_PARAMS, 'Network defined without' 'devices.') topNetDev.ip = IpConfig(inet=IPv4(ipaddr, netmask, gateway), bootproto=bootproto, blocking=utils.tobool(blockingdhcp)) return topNetDev
def delNetwork(network, vlan=None, bonding=None, nics=None, force=False, configWriter=None, implicitBonding=True, _netinfo=None, **options): if _netinfo is None: _netinfo = netinfo.NetInfo() if configWriter is None: configWriter = ConfigWriter() if network not in _netinfo.networks: logging.info("Network %r: doesn't exist in libvirt database", network) if network in netinfo.bridges(): configWriter.removeBridge(network) else: raise ConfigNetworkError(ne.ERR_BAD_BRIDGE, "Cannot delete network" " %r: It doesn't exist in the system" % network) if vlan: configWriter.removeVlan(vlan, bonding or nics[0]) return nics, vlan, bonding = _netinfo.getNicsVlanAndBondingForNetwork(network) bridged = _netinfo.networks[network]['bridged'] logging.info("Removing network %s with vlan=%s, bonding=%s, nics=%s," "options=%s" % (network, vlan, bonding, nics, options)) if not utils.tobool(force): if bonding: Bond.validateName(bonding) if set(nics) != set(_netinfo.bondings[bonding]["slaves"]): raise ConfigNetworkError(ne.ERR_BAD_NIC, 'delNetwork: %s are ' 'not all nics enslaved to %s' % (nics, bonding)) if vlan: Vlan.validateTag(vlan) if bridged: assertBridgeClean(network, vlan, bonding, nics) configWriter.setNewMtu(network=network, bridged=bridged, _netinfo=_netinfo) configWriter.removeLibvirtNetwork(network) # We need to gather NetInfo again to refresh networks info from libvirt. # The deleted bridge should never be up at this stage. _netinfo = netinfo.NetInfo() if network in _netinfo.networks: raise ConfigNetworkError(ne.ERR_USED_BRIDGE, 'delNetwork: bridge %s ' 'still exists' % network) if network and bridged: configWriter.removeBridge(network) nic = nics[0] if nics else None iface = bonding if bonding else nic if iface: ifdown(iface) if vlan: configWriter.removeVlan(vlan, iface) else: cf = netinfo.NET_CONF_PREF + iface if not bridged: # When removing bridgeless non-VLANed network # we need to remove IP/NETMASK from the cfg file for key in ('IPADDR', 'NETMASK', 'GATEWAY', 'BOOTPROTO'): configWriter._updateConfigValue(cf, key, '', True) else: # When removing bridged non-VLANed network # we need to remove BRIDGE from the cfg file configWriter._updateConfigValue(cf, 'BRIDGE', '', True) # Now we can restart changed interface ifup(iface) # The (relatively) new setupNetwork verb allows to remove a network # defined on top of an bonding device without break the bond itself. _netinfo = netinfo.NetInfo() if implicitBonding: if bonding and not _netinfo.ifaceUsers(bonding): ifdown(bonding) configWriter.removeBonding(bonding) _removeUnusedNics(network, vlan, bonding, nics, configWriter) elif not bonding: _removeUnusedNics(network, vlan, bonding, nics, configWriter) elif not _netinfo.ifaceUsers(bonding): ifdown(bonding) configWriter.setBondingMtu(bonding, DEFAULT_MTU) ifup(bonding)