Exemple #1
0
def showNetwork(bridge):
    _netinfo = NetInfo()
    if bridge not in _netinfo.networks:
        print "Bridge %r doesn't exist" % bridge
        return

    nics, vlan, bonding = _netinfo.getNicsVlanAndBondingForNetwork(bridge)
    print "Bridge %s: vlan=%s, bonding=%s, nics=%s" % (bridge, vlan, bonding, nics)
Exemple #2
0
def delNetwork(bridge, force=False, configWriter=None, **options):
    _netinfo = NetInfo()

    validateBridgeName(bridge)
    if bridge not in _netinfo.networks:
        raise ConfigNetworkError(
            ne.ERR_BAD_BRIDGE,
            "Cannot delete bridge %r: It doesn't exist" % bridge)

    nics, vlan, bonding = _netinfo.getNicsVlanAndBondingForNetwork(bridge)

    logging.info(
        "Removing bridge %s with vlan=%s, bonding=%s, nics=%s. options=%s" %
        (bridge, vlan, bonding, nics, options))

    if not _isTrue(force):
        if bonding:
            validateBondingName(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:
            #assertVlan(vlan)
            validateVlanId(vlan)
        assertBridgeClean(bridge, vlan, bonding, nics)

    if configWriter is None:
        configWriter = ConfigWriter()

    if bridge:
        ifdown(bridge)
        subprocess.call([constants.EXT_BRCTL, 'delbr', bridge])
    if vlan:
        vlandev = (bonding or nics[0]) + '.' + vlan
        ifdown(vlandev)
        subprocess.call([constants.EXT_VCONFIG, 'rem', vlandev],
                        stderr=subprocess.PIPE)
    if bonding:
        if not bondingOtherUsers(bridge, vlan, bonding):
            ifdown(bonding)
    for nic in nics:
        if not nicOtherUsers(bridge, vlan, bonding, nic):
            ifdown(nic)
    for nic in nics:
        if nicOtherUsers(bridge, vlan, bonding, nic):
            continue

        configWriter.removeNic(nic)
    if bonding:
        if not bondingOtherUsers(bridge, vlan, bonding):
            configWriter.removeBonding(bonding)
    if vlan:
        configWriter.removeVlan(vlan, bonding or nics[0])
    if bridge:
        configWriter.removeBridge(bridge)
Exemple #3
0
def showNetwork(bridge):
    _netinfo = NetInfo()
    if bridge not in _netinfo.networks:
        print "Bridge %r doesn't exist" % bridge
        return

    nics, vlan, bonding = _netinfo.getNicsVlanAndBondingForNetwork(bridge)
    print "Bridge %s: vlan=%s, bonding=%s, nics=%s" % (bridge, vlan, bonding,
                                                       nics)
Exemple #4
0
def delNetwork(bridge, force=False, configWriter=None, **options):
    _netinfo = NetInfo()

    validateBridgeName(bridge)
    if bridge not in _netinfo.networks:
        raise ConfigNetworkError(ne.ERR_BAD_BRIDGE, "Cannot delete bridge %r: It doesn't exist" % bridge)

    nics, vlan, bonding = _netinfo.getNicsVlanAndBondingForNetwork(bridge)

    logging.info(
        "Removing bridge %s with vlan=%s, bonding=%s, nics=%s. options=%s" % (bridge, vlan, bonding, nics, options)
    )

    if not _isTrue(force):
        if bonding:
            validateBondingName(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:
            # assertVlan(vlan)
            validateVlanId(vlan)
        assertBridgeClean(bridge, vlan, bonding, nics)

    if configWriter is None:
        configWriter = ConfigWriter()

    if bridge:
        ifdown(bridge)
        subprocess.call([constants.EXT_BRCTL, "delbr", bridge])
    if vlan:
        vlandev = (bonding or nics[0]) + "." + vlan
        ifdown(vlandev)
        subprocess.call([constants.EXT_VCONFIG, "rem", vlandev], stderr=subprocess.PIPE)
    if bonding:
        if not bondingOtherUsers(bridge, vlan, bonding):
            ifdown(bonding)
    for nic in nics:
        if not nicOtherUsers(bridge, vlan, bonding, nic):
            ifdown(nic)
    for nic in nics:
        if nicOtherUsers(bridge, vlan, bonding, nic):
            continue

        configWriter.removeNic(nic)
    if bonding:
        if not bondingOtherUsers(bridge, vlan, bonding):
            configWriter.removeBonding(bonding)
    if vlan:
        configWriter.removeVlan(vlan, bonding or nics[0])
    if bridge:
        configWriter.removeBridge(bridge)
Exemple #5
0
def _validateNetworkSetup(networks={}, bondings={}, explicitBonding=False):
    _netinfo = NetInfo()

    # Step 1: Initial validation (validate names, existence of params, etc.)
    for network, networkAttrs in networks.iteritems():
        validateBridgeName(network)

        if networkAttrs.get("remove", False):
            if set(networkAttrs) - set(["remove"]):
                raise ConfigNetworkError(ne.ERR_BAD_PARAMS, "Cannot specify any attribute when removing")
            if network not in _netinfo.networks:
                raise ConfigNetworkError(ne.ERR_BAD_BRIDGE, "Cannot remove bridge %s: Doesn't exist" % network)
            continue

        vlan = networkAttrs.get("vlan", None)
        ipaddr = networkAttrs.get("ipaddr", None)
        netmask = networkAttrs.get("netmask", None)
        gateway = networkAttrs.get("gateway", None)
        if vlan:
            validateVlanId(vlan)

        # Check ip, netmask, gateway
        if ipaddr:
            if not netmask:
                raise ConfigNetworkError(ne.ERR_BAD_ADDR, "Must specify netmask to configure ip for bridge")
            validateIpAddress(ipaddr)
            validateNetmask(netmask)
            if gateway:
                validateGateway(gateway)
        else:
            if netmask or gateway:
                raise ConfigNetworkError(ne.ERR_BAD_ADDR, "Specified netmask or gateway but not ip")

        # check nic or bonding
        nic = networkAttrs.get("nic", None)
        bonding = networkAttrs.get("bonding", None)

        if nic and bonding:
            raise ConfigNetworkError(ne.ERR_BAD_PARAMS, "Don't specify both nic and bonding")
        if not nic and not bonding:
            raise ConfigNetworkError(ne.ERR_BAD_PARAMS, "Must specify either nic or bonding")

        if nic and nic not in _netinfo.nics:
            raise ConfigNetworkError(ne.ERR_BAD_NIC, "unknown nic: %r" % nic)

    for bonding, bondingAttrs in bondings.iteritems():
        validateBondingName(bonding)
        if "options" in bondingAttrs:
            validateBondingOptions(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))

    # Step 2: Make sure we have complete information about the Setup, more validation
    # (if explicitBonding==False we complete the missing information ourselves, else we raise an exception)
    nics = defaultdict(lambda: {"networks": [], "bonding": None})
    for network, networkAttrs in networks.iteritems():
        if networkAttrs.get("remove", False):
            continue

        if "bonding" in networkAttrs:
            assert "nic" not in networkAttrs

            bonding = networkAttrs["bonding"]
            if bonding not in bondings:
                if explicitBonding:
                    raise ConfigNetworkError(
                        ne.ERR_BAD_PARAMS, "Network %s requires unspecified bonding %s" % (network, bonding)
                    )

                # fill in bonding info
                bondings[bonding] = {"nics": _netinfo.bondings[bonding]["slaves"]}

            if "_networks" not in bondings[bonding]:
                bondings[bonding]["_networks"] = []
            bondings[bonding]["_networks"].append(network)
        else:
            assert "nic" in networkAttrs

            nics[networkAttrs["nic"]]["networks"].append(network)

    for bonding, bondingAttrs in bondings.iteritems():
        if bondingAttrs.get("remove", False):
            continue
        connectedNetworks = _netinfo.getNetworksForNic(bonding)

        for network in connectedNetworks:
            if network not in networks:
                if explicitBonding:
                    raise ConfigNetworkError(
                        ne.ERR_BAD_PARAMS, "Bonding %s is associated with unspecified network %s" % (bonding, network)
                    )
                # fill in network info
                _, vlan, bonding2 = _netinfo.getNicsVlanAndBondingForNetwork(network)
                assert bonding == bonding2
                networks[network] = {"bonding": bonding, "vlan": vlan}

        for nic in bondingAttrs["nics"]:
            if nics[nic]["bonding"]:
                raise ConfigNetworkError(
                    ne.ERR_BAD_BONDING,
                    "Nic %s is attached to two different bondings in setup: %s, %s"
                    % (nic, bonding, nics[nic]["bonding"]),
                )
            nics[nic]["bonding"] = bonding

    # At this point the state may be contradictory.

    # Step 3: Apply removals (We're not iterating because we change the dictionary size)
    queue = []
    for network, networkAttrs in networks.items():
        if networkAttrs.get("remove", False):
            del networks[network]
        else:
            queue.append(("network", network, networkAttrs))
    for bonding, bondingAttrs in bondings.items():
        if bondingAttrs.get("remove", False):
            del bondings[bonding]
        else:
            queue.append(("bonding", bonding, bondingAttrs))

    # Step 4: Verify Setup
    for nic, nicAttrs in nics.iteritems():
        if nicAttrs["networks"] and nicAttrs["bonding"]:
            raise ConfigNetworkError(ne.ERR_USED_NIC, "Setup attached both network and bonding to nic %s" % (nic))
        if len(networks) > 1:
            for network, networkAttrs in networks.iteritems():
                if not networkAttrs.get("vlan", None):
                    raise ConfigNetworkError(
                        ne.ERR_USED_NIC,
                        "Setup attached more than one network to nic %s, some of which aren't vlans" % (nic),
                    )

    for bonding, bondingAttrs in bondings.iteritems():
        networks = bondingAttrs["_networks"]
        if len(networks) > 1:
            for network, networkAttrs in networks.iteritems():
                if not networkAttrs.get("vlan", None):
                    raise ConfigNetworkError(
                        ne.ERR_BAD_BONDING,
                        "Setup attached more than one network to bonding %s, some of which aren't vlans" % (bonding),
                    )
Exemple #6
0
def _validateNetworkSetup(networks={}, bondings={}, explicitBonding=False):
    _netinfo = NetInfo()

    # Step 1: Initial validation (validate names, existence of params, etc.)
    for network, networkAttrs in networks.iteritems():
        validateBridgeName(network)

        if networkAttrs.get('remove', False):
            if set(networkAttrs) - set(['remove']):
                raise ConfigNetworkError(
                    ne.ERR_BAD_PARAMS,
                    "Cannot specify any attribute when removing")
            if network not in _netinfo.networks:
                raise ConfigNetworkError(
                    ne.ERR_BAD_BRIDGE,
                    'Cannot remove bridge %s: Doesn\'t exist' % network)
            continue

        vlan = networkAttrs.get('vlan', None)
        ipaddr = networkAttrs.get('ipaddr', None)
        netmask = networkAttrs.get('netmask', None)
        gateway = networkAttrs.get('gateway', None)
        if vlan:
            validateVlanId(vlan)

        # Check ip, netmask, gateway
        if ipaddr:
            if not netmask:
                raise ConfigNetworkError(
                    ne.ERR_BAD_ADDR,
                    "Must specify netmask to configure ip for bridge")
            validateIpAddress(ipaddr)
            validateNetmask(netmask)
            if gateway:
                validateGateway(gateway)
        else:
            if netmask or gateway:
                raise ConfigNetworkError(
                    ne.ERR_BAD_ADDR, "Specified netmask or gateway but not ip")

        # check nic or bonding
        nic = networkAttrs.get('nic', None)
        bonding = networkAttrs.get('bonding', None)

        if nic and bonding:
            raise ConfigNetworkError(ne.ERR_BAD_PARAMS,
                                     "Don't specify both nic and bonding")
        if not nic and not bonding:
            raise ConfigNetworkError(ne.ERR_BAD_PARAMS,
                                     "Must specify either nic or bonding")

        if nic and nic not in _netinfo.nics:
            raise ConfigNetworkError(ne.ERR_BAD_NIC, "unknown nic: %r" % nic)

    for bonding, bondingAttrs in bondings.iteritems():
        validateBondingName(bonding)
        if 'options' in bondingAttrs:
            validateBondingOptions(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))

    # Step 2: Make sure we have complete information about the Setup, more validation
    # (if explicitBonding==False we complete the missing information ourselves, else we raise an exception)
    nics = defaultdict(lambda: {'networks': [], 'bonding': None})
    for network, networkAttrs in networks.iteritems():
        if networkAttrs.get('remove', False):
            continue

        if 'bonding' in networkAttrs:
            assert 'nic' not in networkAttrs

            bonding = networkAttrs['bonding']
            if bonding not in bondings:
                if explicitBonding:
                    raise ConfigNetworkError(
                        ne.ERR_BAD_PARAMS,
                        "Network %s requires unspecified bonding %s" %
                        (network, bonding))

                # fill in bonding info
                bondings[bonding] = {
                    'nics': _netinfo.bondings[bonding]['slaves']
                }

            if '_networks' not in bondings[bonding]:
                bondings[bonding]['_networks'] = []
            bondings[bonding]['_networks'].append(network)
        else:
            assert 'nic' in networkAttrs

            nics[networkAttrs['nic']]['networks'].append(network)

    for bonding, bondingAttrs in bondings.iteritems():
        if bondingAttrs.get('remove', False):
            continue
        connectedNetworks = _netinfo.getNetworksForNic(bonding)

        for network in connectedNetworks:
            if network not in networks:
                if explicitBonding:
                    raise ConfigNetworkError(
                        ne.ERR_BAD_PARAMS,
                        "Bonding %s is associated with unspecified network %s"
                        % (bonding, network))
                # fill in network info
                _, vlan, bonding2 = _netinfo.getNicsVlanAndBondingForNetwork(
                    network)
                assert bonding == bonding2
                networks[network] = {'bonding': bonding, 'vlan': vlan}

        for nic in bondingAttrs['nics']:
            if nics[nic]['bonding']:
                raise ConfigNetworkError(
                    ne.ERR_BAD_BONDING,
                    "Nic %s is attached to two different bondings in setup: %s, %s"
                    % (nic, bonding, nics[nic]['bonding']))
            nics[nic]['bonding'] = bonding

    # At this point the state may be contradictory.

    # Step 3: Apply removals (We're not iterating because we change the dictionary size)
    queue = []
    for network, networkAttrs in networks.items():
        if networkAttrs.get('remove', False):
            del networks[network]
        else:
            queue.append(('network', network, networkAttrs))
    for bonding, bondingAttrs in bondings.items():
        if bondingAttrs.get('remove', False):
            del bondings[bonding]
        else:
            queue.append(('bonding', bonding, bondingAttrs))

    # Step 4: Verify Setup
    for nic, nicAttrs in nics.iteritems():
        if nicAttrs['networks'] and nicAttrs['bonding']:
            raise ConfigNetworkError(
                ne.ERR_USED_NIC,
                "Setup attached both network and bonding to nic %s" % (nic))
        if len(networks) > 1:
            for network, networkAttrs in networks.iteritems():
                if not networkAttrs.get('vlan', None):
                    raise ConfigNetworkError(
                        ne.ERR_USED_NIC,
                        "Setup attached more than one network to nic %s, some of which aren't vlans"
                        % (nic))

    for bonding, bondingAttrs in bondings.iteritems():
        networks = bondingAttrs['_networks']
        if len(networks) > 1:
            for network, networkAttrs in networks.iteritems():
                if not networkAttrs.get('vlan', None):
                    raise ConfigNetworkError(
                        ne.ERR_BAD_BONDING,
                        "Setup attached more than one network to bonding %s, some of which aren't vlans"
                        % (bonding))