Esempio n. 1
0
def addNetwork(network, vlan=None, bonding=None, nics=None, ipaddr=None,
               netmask=None, prefix=None, mtu=None, gateway=None,
               ipv6addr=None, ipv6gateway=None, force=False,
               configurator=None, bondingOptions=None, bridged=True,
               _netinfo=None, qosInbound=None, qosOutbound=None, **options):
    nics = nics or ()
    if _netinfo is None:
        _netinfo = netinfo.NetInfo()
    bridged = utils.tobool(bridged)
    vlan = _vlanToInternalRepresentation(vlan)

    if mtu:
        mtu = int(mtu)

    if prefix:
        if netmask:
            raise ConfigNetworkError(ne.ERR_BAD_PARAMS,
                                     'Both PREFIX and NETMASK supplied')
        else:
            try:
                netmask = netinfo.prefix2netmask(int(prefix))
            except ValueError as ve:
                raise ConfigNetworkError(ne.ERR_BAD_ADDR, "Bad prefix: %s" %
                                         ve)

    if not utils.tobool(force):
        logging.debug('validating network...')
        if network in _netinfo.networks:
            raise ConfigNetworkError(ne.ERR_USED_BRIDGE,
                                     'Network already exists')
        if bonding:
            _validateInterNetworkCompatibility(_netinfo, vlan, bonding,
                                               bridged)
        else:
            for nic in nics:
                _validateInterNetworkCompatibility(_netinfo, vlan, nic,
                                                   bridged)

    logging.info("Adding network %s with vlan=%s, bonding=%s, nics=%s,"
                 " bondingOptions=%s, mtu=%s, bridged=%s, options=%s",
                 network, vlan, bonding, nics, bondingOptions,
                 mtu, bridged, options)

    if configurator is None:
        configurator = Ifcfg()

    bootproto = options.pop('bootproto', None)

    defaultRoute = network == constants.MANAGEMENT_NETWORK

    netEnt = objectivizeNetwork(network if bridged else None, vlan, bonding,
                                bondingOptions, nics, mtu, ipaddr, netmask,
                                gateway, bootproto, ipv6addr, ipv6gateway,
                                _netinfo=_netinfo, configurator=configurator,
                                defaultRoute=defaultRoute, **options)

    netEnt.configure(**options)
    configurator.configureLibvirtNetwork(network, netEnt,
                                         qosInbound=qosInbound,
                                         qosOutbound=qosOutbound)
Esempio n. 2
0
def addNetwork(network, vlan=None, bonding=None, nics=None, ipaddr=None,
               netmask=None, prefix=None, mtu=None, gateway=None, force=False,
               configurator=None, bondingOptions=None, bridged=True,
               _netinfo=None, qosInbound=None, qosOutbound=None, **options):
    nics = nics or ()
    if _netinfo is None:
        _netinfo = netinfo.NetInfo()
    bridged = utils.tobool(bridged)

    if mtu:
        mtu = int(mtu)

    if prefix:
        if netmask:
            raise ConfigNetworkError(ne.ERR_BAD_PARAMS,
                                     'Both PREFIX and NETMASK supplied')
        else:
            try:
                netmask = netinfo.prefix2netmask(int(prefix))
            except ValueError as ve:
                raise ConfigNetworkError(ne.ERR_BAD_ADDR, "Bad prefix: %s" %
                                         ve)

    if not utils.tobool(force):
        logging.debug('validating network...')
        if network in _netinfo.networks:
            raise ConfigNetworkError(ne.ERR_USED_BRIDGE,
                                     'Network already exists')
        if bonding:
            _validateInterNetworkCompatibility(_netinfo, vlan, bonding,
                                               bridged)
        else:
            for nic in nics:
                _validateInterNetworkCompatibility(_netinfo, vlan, nic,
                                                   bridged)
    logging.info("Adding network %s with vlan=%s, bonding=%s, nics=%s,"
                 " bondingOptions=%s, mtu=%s, bridged=%s, options=%s",
                 network, vlan, bonding, nics, bondingOptions,
                 mtu, bridged, options)

    if configurator is None:
        configurator = Ifcfg()

    bootproto = options.pop('bootproto', None)

    netEnt = objectivizeNetwork(network if bridged else None, vlan, bonding,
                                bondingOptions, nics, mtu, ipaddr, netmask,
                                gateway, bootproto, _netinfo, configurator,
                                **options)

    # libvirt net addition must be done before creation so that on dhcp ifup
    # the dhcp hook will already see the network as belonging to vdsm.
    configurator.configureLibvirtNetwork(network, netEnt,
                                         qosInbound=qosInbound,
                                         qosOutbound=qosOutbound)
    netEnt.configure(**options)
Esempio n. 3
0
def delNetwork(network,
               vlan=None,
               bonding=None,
               nics=None,
               force=False,
               configurator=None,
               implicitBonding=True,
               _netinfo=None,
               **options):
    if _netinfo is None:
        _netinfo = netinfo.NetInfo()

    if configurator is None:
        configurator = Ifcfg()

    if network not in _netinfo.networks:
        logging.info("Network %r: doesn't exist in libvirt database", network)
        _delNonVdsmNetwork(network, vlan, bonding, nics, _netinfo,
                           configurator)
        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):
        _validateDelNetwork(network, vlan, bonding, nics, bridged, _netinfo)

    netEnt = objectivizeNetwork(bridge=network if bridged else None,
                                vlan=vlan,
                                bonding=bonding,
                                nics=nics,
                                _netinfo=_netinfo,
                                configurator=configurator,
                                implicitBonding=implicitBonding)
    netEnt.ip.bootproto = netinfo.getBootProtocol(netEnt.name)

    # We must first remove the libvirt network and then the network entity.
    # Otherwise if we first remove the network entity while the libvirt
    # network is still up, the network entity (In some flows) thinks that
    # it still has users and thus does not allow its removal
    configurator.removeLibvirtNetwork(network)
    netEnt.remove()

    # 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)
Esempio n. 4
0
def editNetwork(oldBridge, newBridge, vlan=None, bonding=None, nics=None,
                **options):
    configurator = Ifcfg()
    try:
        delNetwork(oldBridge, configurator=configurator, **options)
        addNetwork(newBridge, vlan=vlan, bonding=bonding, nics=nics,
                   configurator=configurator, **options)
    except:
        configurator.rollback()
        raise
    if utils.tobool(options.get('connectivityCheck', False)):
        if not clientSeen(int(options.get('connectivityTimeout',
                                          CONNECTIVITY_TIMEOUT_DEFAULT))):
            delNetwork(newBridge, force=True)
            configurator.rollback()
            return define.errCode['noConPeer']['status']['code']
Esempio n. 5
0
def delNetwork(network, vlan=None, bonding=None, nics=None, force=False,
               configurator=None, implicitBonding=True, _netinfo=None,
               **options):
    if _netinfo is None:
        _netinfo = netinfo.NetInfo()

    if configurator is None:
        configurator = Ifcfg()

    if network not in _netinfo.networks:
        logging.info("Network %r: doesn't exist in libvirt database", network)
        vlan = _vlanToInternalRepresentation(vlan)
        _delNonVdsmNetwork(network, vlan, bonding, nics, _netinfo,
                           configurator)
        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):
        _validateDelNetwork(network, vlan, bonding, nics, bridged, _netinfo)

    netEnt = objectivizeNetwork(bridge=network if bridged else None, vlan=vlan,
                                bonding=bonding, nics=nics, _netinfo=_netinfo,
                                configurator=configurator,
                                implicitBonding=implicitBonding)
    netEnt.ip.bootproto = netinfo.getBootProtocol(netEnt.name)

    # We must first remove the libvirt network and then the network entity.
    # Otherwise if we first remove the network entity while the libvirt
    # network is still up, the network entity (In some flows) thinks that
    # it still has users and thus does not allow its removal
    configurator.removeLibvirtNetwork(network)
    netEnt.remove()

    # 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)
Esempio n. 6
0
def editNetwork(oldBridge,
                newBridge,
                vlan=None,
                bonding=None,
                nics=None,
                **options):
    configurator = Ifcfg()
    try:
        delNetwork(oldBridge, configurator=configurator, **options)
        addNetwork(newBridge,
                   vlan=vlan,
                   bonding=bonding,
                   nics=nics,
                   configurator=configurator,
                   **options)
    except:
        configurator.rollback()
        raise
    if utils.tobool(options.get('connectivityCheck', False)):
        if not clientSeen(
                int(
                    options.get('connectivityTimeout',
                                CONNECTIVITY_TIMEOUT_DEFAULT))):
            delNetwork(newBridge, force=True)
            configurator.rollback()
            return define.errCode['noConPeer']['status']['code']
Esempio n. 7
0
def delNetwork(network, vlan=None, bonding=None, nics=None, force=False,
               configurator=None, implicitBonding=True, _netinfo=None,
               **options):
    if _netinfo is None:
        _netinfo = netinfo.NetInfo()

    if configurator is None:
        configurator = Ifcfg()

    if network not in _netinfo.networks:
        logging.info("Network %r: doesn't exist in libvirt database", network)
        _delNonVdsmNetwork(network, vlan, bonding, nics, _netinfo,
                           configurator)
        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):
        _validateDelNetwork(network, vlan, bonding, nics, bridged, _netinfo)

    netEnt = objectivizeNetwork(bridge=network if bridged else None, vlan=vlan,
                                bonding=bonding, nics=nics, _netinfo=_netinfo,
                                configurator=configurator,
                                implicitBonding=implicitBonding)
    netEnt.ip.bootproto = netinfo.getBootProtocol(netEnt.name)
    netEnt.remove()
    # libvirt net removal must be done after removal so that on dhcp ifdown
    # the dhcp hook still sees the network as belonging to vdsm.
    configurator.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)
Esempio n. 8
0
def setupNetworks(networks, bondings, **options):
    """Add/Edit/Remove configuration for networks and bondings.

    Params:
        networks - dict of key=network, value=attributes
            where 'attributes' is a dict with the following optional items:
                        vlan=<id>
                        bonding="<name>" | nic="<name>"
                        (bonding and nics are mutually exclusive)
                        ipaddr="<ip>"
                        netmask="<ip>"
                        gateway="<ip>"
                        bootproto="..."
                        delay="..."
                        onboot="yes"|"no"
                        (other options will be passed to the config file AS-IS)
                        -- OR --
                        remove=True (other attributes can't be specified)

        bondings - dict of key=bonding, value=attributes
            where 'attributes' is a dict with the following optional items:
                        nics=["<nic1>" , "<nic2>", ...]
                        options="<bonding-options>"
                        -- OR --
                        remove=True (other attributes can't be specified)

        options - dict of options, such as:
                        force=0|1
                        connectivityCheck=0|1
                        connectivityTimeout=<int>

    Notes:
        When you edit a network that is attached to a bonding, it's not
        necessary to re-specify the bonding (you need only to note
        the attachment in the network's attributes). Similarly, if you edit
        a bonding, it's not necessary to specify its networks.
    """
    logger = logging.getLogger("setupNetworks")
    _netinfo = netinfo.NetInfo()
    configurator = Ifcfg()
    networksAdded = set()

    logger.debug("Setting up network according to configuration: "
                 "networks:%r, bondings:%r, options:%r" %
                 (networks, bondings, options))

    force = options.get('force', False)
    if not utils.tobool(force):
        logging.debug("Validating configuration")
        _validateNetworkSetup(dict(networks), dict(bondings))

    logger.debug("Applying...")
    try:
        libvirt_nets = netinfo.networks()
        # Remove edited networks and networks with 'remove' attribute
        for network, networkAttrs in networks.items():
            if network in _netinfo.networks:
                logger.debug("Removing network %r" % network)
                delNetwork(network,
                           configurator=configurator,
                           force=force,
                           implicitBonding=False)
                if 'remove' in networkAttrs:
                    del networks[network]
                    del libvirt_nets[network]
            elif network in libvirt_nets:
                # If the network was not in _netinfo but is in the networks
                # returned by libvirt, it means that we are dealing with
                # a broken network.
                logger.debug('Removing broken network %r' % network)
                _delBrokenNetwork(network,
                                  libvirt_nets[network],
                                  configurator=configurator)
                if 'remove' in networkAttrs:
                    del networks[network]
                    del libvirt_nets[network]
            elif 'remove' in networkAttrs:
                raise ConfigNetworkError(
                    ne.ERR_BAD_BRIDGE, "Cannot delete "
                    "network %r: It doesn't exist in the "
                    "system" % network)
            else:
                networksAdded.add(network)

        _handleBondings(bondings, configurator)

        # We need to use the newest host info
        _ni = netinfo.NetInfo()
        for network, networkAttrs in networks.iteritems():
            d = dict(networkAttrs)
            if 'bonding' in d:
                d.update(_buildBondOptions(d['bonding'], bondings, _ni))
            else:
                d['nics'] = [d.pop('nic')]
            d['force'] = force

            logger.debug("Adding network %r" % network)
            addNetwork(network,
                       configurator=configurator,
                       implicitBonding=True,
                       **d)

        if utils.tobool(options.get('connectivityCheck', True)):
            logger.debug('Checking connectivity...')
            if not clientSeen(
                    int(
                        options.get('connectivityTimeout',
                                    CONNECTIVITY_TIMEOUT_DEFAULT))):
                logger.info('Connectivity check failed, rolling back')
                for network in networksAdded:
                    # If the new added network was created on top of
                    # existing bond, we need to keep the bond on rollback
                    # flow, else we will break the new created bond.
                    delNetwork(network,
                               force=True,
                               implicitBonding=networks[network].get('bonding')
                               in bondings)
                raise ConfigNetworkError(ne.ERR_LOST_CONNECTION,
                                         'connectivity check failed')
    except:
        configurator.rollback()
        raise
Esempio n. 9
0
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
Esempio n. 10
0
def addNetwork(network,
               vlan=None,
               bonding=None,
               nics=None,
               ipaddr=None,
               netmask=None,
               prefix=None,
               mtu=None,
               gateway=None,
               force=False,
               configurator=None,
               bondingOptions=None,
               bridged=True,
               _netinfo=None,
               qosInbound=None,
               qosOutbound=None,
               **options):
    nics = nics or ()
    if _netinfo is None:
        _netinfo = netinfo.NetInfo()
    bridged = utils.tobool(bridged)

    if mtu:
        mtu = int(mtu)

    if prefix:
        if netmask:
            raise ConfigNetworkError(ne.ERR_BAD_PARAMS,
                                     'Both PREFIX and NETMASK supplied')
        else:
            try:
                netmask = netinfo.prefix2netmask(int(prefix))
            except ValueError as ve:
                raise ConfigNetworkError(ne.ERR_BAD_ADDR,
                                         "Bad prefix: %s" % ve)

    if not utils.tobool(force):
        logging.debug('validating network...')
        if network in _netinfo.networks:
            raise ConfigNetworkError(ne.ERR_USED_BRIDGE,
                                     'Network already exists')
        if bonding:
            _validateInterNetworkCompatibility(_netinfo, vlan, bonding,
                                               bridged)
        else:
            for nic in nics:
                _validateInterNetworkCompatibility(_netinfo, vlan, nic,
                                                   bridged)

    logging.info(
        "Adding network %s with vlan=%s, bonding=%s, nics=%s,"
        " bondingOptions=%s, mtu=%s, bridged=%s, options=%s", network, vlan,
        bonding, nics, bondingOptions, mtu, bridged, options)

    if configurator is None:
        configurator = Ifcfg()

    bootproto = options.pop('bootproto', None)

    defaultRoute = network == constants.MANAGEMENT_NETWORK

    netEnt = objectivizeNetwork(network if bridged else None,
                                vlan,
                                bonding,
                                bondingOptions,
                                nics,
                                mtu,
                                ipaddr,
                                netmask,
                                gateway,
                                bootproto,
                                _netinfo,
                                configurator,
                                defaultRoute=defaultRoute,
                                **options)

    netEnt.configure(**options)
    configurator.configureLibvirtNetwork(network,
                                         netEnt,
                                         qosInbound=qosInbound,
                                         qosOutbound=qosOutbound)
Esempio n. 11
0
def setupNetworks(networks, bondings, **options):
    """Add/Edit/Remove configuration for networks and bondings.

    Params:
        networks - dict of key=network, value=attributes
            where 'attributes' is a dict with the following optional items:
                        vlan=<id>
                        bonding="<name>" | nic="<name>"
                        (bonding and nics are mutually exclusive)
                        ipaddr="<ip>"
                        netmask="<ip>"
                        gateway="<ip>"
                        bootproto="..."
                        delay="..."
                        onboot="yes"|"no"
                        (other options will be passed to the config file AS-IS)
                        -- OR --
                        remove=True (other attributes can't be specified)

        bondings - dict of key=bonding, value=attributes
            where 'attributes' is a dict with the following optional items:
                        nics=["<nic1>" , "<nic2>", ...]
                        options="<bonding-options>"
                        -- OR --
                        remove=True (other attributes can't be specified)

        options - dict of options, such as:
                        force=0|1
                        connectivityCheck=0|1
                        connectivityTimeout=<int>

    Notes:
        When you edit a network that is attached to a bonding, it's not
        necessary to re-specify the bonding (you need only to note
        the attachment in the network's attributes). Similarly, if you edit
        a bonding, it's not necessary to specify its networks.
    """
    logger = logging.getLogger("setupNetworks")
    _netinfo = netinfo.NetInfo()
    configurator = Ifcfg()
    networksAdded = set()

    logger.debug("Setting up network according to configuration: "
                 "networks:%r, bondings:%r, options:%r" % (networks,
                                                           bondings, options))

    force = options.get('force', False)
    if not utils.tobool(force):
        logging.debug("Validating configuration")
        _validateNetworkSetup(dict(networks), dict(bondings))

    logger.debug("Applying...")
    try:
        libvirt_nets = netinfo.networks()
        # Remove edited networks and networks with 'remove' attribute
        for network, networkAttrs in networks.items():
            if network in _netinfo.networks:
                logger.debug("Removing network %r" % network)
                delNetwork(network, configurator=configurator, force=force,
                           implicitBonding=False)
                if 'remove' in networkAttrs:
                    del networks[network]
                    del libvirt_nets[network]
            elif network in libvirt_nets:
                # If the network was not in _netinfo but is in the networks
                # returned by libvirt, it means that we are dealing with
                # a broken network.
                logger.debug('Removing broken network %r' % network)
                _delBrokenNetwork(network, libvirt_nets[network],
                                  configurator=configurator)
                if 'remove' in networkAttrs:
                    del networks[network]
                    del libvirt_nets[network]
            elif 'remove' in networkAttrs:
                raise ConfigNetworkError(ne.ERR_BAD_BRIDGE, "Cannot delete "
                                         "network %r: It doesn't exist in the "
                                         "system" % network)
            else:
                networksAdded.add(network)

        _handleBondings(bondings, configurator)

        # We need to use the newest host info
        _ni = netinfo.NetInfo()
        for network, networkAttrs in networks.iteritems():
            d = dict(networkAttrs)
            if 'bonding' in d:
                d.update(_buildBondOptions(d['bonding'], bondings, _ni))
            else:
                d['nics'] = [d.pop('nic')]
            d['force'] = force

            logger.debug("Adding network %r" % network)
            addNetwork(network, configurator=configurator,
                       implicitBonding=True, **d)

        if utils.tobool(options.get('connectivityCheck', True)):
            logger.debug('Checking connectivity...')
            if not clientSeen(int(options.get('connectivityTimeout',
                                  CONNECTIVITY_TIMEOUT_DEFAULT))):
                logger.info('Connectivity check failed, rolling back')
                for network in networksAdded:
                    # If the new added network was created on top of
                    # existing bond, we need to keep the bond on rollback
                    # flow, else we will break the new created bond.
                    delNetwork(network, force=True,
                               implicitBonding=networks[network].
                               get('bonding') in bondings)
                raise ConfigNetworkError(ne.ERR_LOST_CONNECTION,
                                         'connectivity check failed')
    except:
        configurator.rollback()
        raise