Пример #1
0
def validate_net_configuration(net, attrs, bonds, running_bonds, kernel_nics):
    """Test if network meets logical Vdsm requiremets.

    Bridgeless networks are allowed in order to support Engine requirements.

    Checked by OVS:
        - only one vlan per tag
    """
    nic = attrs.get('nic')
    bond = attrs.get('bonding')
    vlan = attrs.get('vlan')

    if vlan is None:
        if nic and nic not in kernel_nics:
            raise ne.ConfigNetworkError(
                ne.ERR_BAD_NIC, 'Nic %s does not exist' % nic)
        running_bond = bond in running_bonds
        bond2setup = bond in bonds and 'remove' not in bonds[bond]
        if bond and not running_bond and not bond2setup:
            raise ne.ConfigNetworkError(
                ne.ERR_BAD_BONDING, 'Bond %s does not exist' % bond)
    else:
        # We do not support ifaceless VLANs in Vdsm, because of legacy VLAN
        # device requires an iface to lie on. It wouldn't be a problem in OVS,
        # where we use tagged fake bridges instead of VLANs. However, ifaceless
        # VLANs are permited in order to keep feature parity.
        # TODO: This limitation could be dropped in the future.
        if not nic and not bond:
            raise ne.ConfigNetworkError(
                ne.ERR_BAD_VLAN, 'Vlan device requires a nic/bond')
Пример #2
0
def validate_static_ipv4_config(net_attrs):
    if 'ipaddr' in net_attrs:
        try:
            address = '{}/{}'.format(net_attrs['ipaddr'],
                                     net_attrs.get('netmask', ''))
            IPAddressData(address, device=None)
            if 'gateway' in net_attrs:
                IPAddressData(net_attrs['gateway'], device=None)
        except IPAddressDataError as e:
            six.reraise(
                ne.ConfigNetworkError,
                ne.ConfigNetworkError(ne.ERR_BAD_ADDR, str(e)),
            )
        if net_attrs.get('bootproto') == 'dhcp':
            raise ne.ConfigNetworkError(
                ne.ERR_BAD_ADDR,
                'mixing static ip configuration with '
                'dhcp is not allowed',
            )
    else:
        if 'gateway' in net_attrs or 'netmask' in net_attrs:
            raise ne.ConfigNetworkError(
                ne.ERR_BAD_ADDR,
                'gateway or netmask were given '
                'without ip address',
            )
Пример #3
0
def validate_southbound_devices_usages(nets, ni):
    kernel_config = KernelConfig(ni)

    for requested_net, net_info in six.viewitems(nets):
        if 'remove' in net_info:
            kernel_config.removeNetwork(requested_net)

    for requested_net, net_info in six.viewitems(nets):
        if 'remove' in net_info:
            continue
        kernel_config.setNetwork(requested_net, net_info)

    underlying_devices = []
    for net_name, net_attrs in six.viewitems(kernel_config.networks):
        vlan = net_attrs.get('vlan')
        if 'bonding' in net_attrs:
            underlying_devices.append((net_attrs['bonding'], vlan))
        elif 'nic' in net_attrs:
            underlying_devices.append((net_attrs['nic'], vlan))
        else:
            if not net_attrs['bridged']:
                raise ne.ConfigNetworkError(
                    ne.ERR_BAD_PARAMS,
                    'southbound device not specified for non-bridged '
                    'network "{}"'.format(net_name))

    if len(set(underlying_devices)) < len(underlying_devices):
        raise ne.ConfigNetworkError(
            ne.ERR_BAD_PARAMS, 'multiple networks/similar vlans cannot be'
            ' defined on a single underlying device. '
            'kernel networks: {}\nrequested networks: {}'.format(
                kernel_config.networks, nets))
Пример #4
0
def _validate_bond_addition(nics, kernel_nics):
    if nics is None or len(nics) < 2:
        raise ne.ConfigNetworkError(ne.ERR_BAD_BONDING,
                                    'OVS bond requires at least 2 slaves')
    for nic in nics:
        if nic not in kernel_nics:
            raise ne.ConfigNetworkError(ne.ERR_BAD_NIC,
                                        'Nic %s does not exist' % nic)
Пример #5
0
def _validate_bond_addition(nics, kernel_nics):
    for nic in nics:
        if nic not in kernel_nics:
            raise ne.ConfigNetworkError(
                ne.ERR_BAD_NIC, 'Nic %s does not exist' % nic)
        if dpdk.is_dpdk(nic):
            raise ne.ConfigNetworkError(
                ne.ERR_BAD_NIC,
                '%s is a dpdk device and not supported as a slave of bond'
                % nic)
Пример #6
0
def _validate_vlan_id(id):
    MAX_ID = 4094

    try:
        vlan_id = int(id)
    except ValueError:
        raise ne.ConfigNetworkError(
            ne.ERR_BAD_VLAN,
            'VLAN id must be a number between 0 and ' + MAX_ID)

    if not 0 <= vlan_id <= MAX_ID:
        raise ne.ConfigNetworkError(
            ne.ERR_BAD_VLAN,
            'VLAN id out of range: %r, must be 0..%s' % (id, MAX_ID))
Пример #7
0
def validate_bond_configuration(bond, attrs, nets, running_nets, kernel_nics):
    if 'remove' in attrs:
        _validate_bond_removal(bond, nets, running_nets)
    elif 'nics' in attrs:
        _validate_bond_addition(attrs['nics'], kernel_nics)
    else:
        raise ne.ConfigNetworkError(ne.ERR_BAD_NIC, 'Missing nics attribute')
Пример #8
0
def validate_switch_type_change(nets, bonds, running_config):
    for requests in nets, bonds:
        for attrs in six.itervalues(requests):
            if 'remove' in attrs:
                raise ne.ConfigNetworkError(
                    ne.ERR_BAD_PARAMS,
                    'Switch type change request cannot contain removals')

    if frozenset(running_config.networks) != frozenset(nets):
        raise ne.ConfigNetworkError(
            ne.ERR_BAD_PARAMS,
            'All networks must be reconfigured on switch type change')
    if frozenset(running_config.bonds) != frozenset(bonds):
        raise ne.ConfigNetworkError(
            ne.ERR_BAD_PARAMS,
            'All bondings must be reconfigured on switch type change')
Пример #9
0
 def _validate_network_remove(self):
     net_attrs_set = set(self._attrs) - {'remove', 'custom'}
     if net_attrs_set:
         raise ne.ConfigNetworkError(
             ne.ERR_BAD_PARAMS,
             'Cannot specify any attribute when removing (except custom)).',
         )
Пример #10
0
def _validate_nameservers_address(nameservers_addr):
    for addr in nameservers_addr:
        addr = _normalize_address(addr)
        try:
            IPAddressData(addr, device=None)
        except IPAddressDataError as e:
            raise ne.ConfigNetworkError(ne.ERR_BAD_ADDR, str(e))
Пример #11
0
def _validate_bond_removal(bond, nets, running_nets):
    for net in _nets_with_bond(running_nets, bond):
        to_be_removed = 'remove' in nets.get(net, {})
        if not to_be_removed:
            raise ne.ConfigNetworkError(
                ne.ERR_USED_BOND, 'Cannot remove bonding %s: used by '
                'network %s' % (bond, net))
Пример #12
0
def _validate_bond_removal(bond, desired_nets, current_nets):
    current_nets_with_bond = {
        net
        for net, attrs in six.iteritems(current_nets)
        if attrs['southbound'] == bond
    }

    add_nets_with_bond = set()
    remove_nets_with_bond = set()
    for net, attrs in six.iteritems(desired_nets):
        if 'remove' in attrs:
            if net in current_nets_with_bond:
                remove_nets_with_bond.add(net)
        elif net in current_nets:
            if net in current_nets_with_bond:
                remove_nets_with_bond.add(net)
            if attrs.get('bonding') == bond:
                add_nets_with_bond.add(net)
        elif attrs.get('bonding') == bond:
            add_nets_with_bond.add(net)

    nets_with_bond = add_nets_with_bond or (current_nets_with_bond -
                                            remove_nets_with_bond)
    if nets_with_bond:
        raise ne.ConfigNetworkError(
            ne.ERR_USED_BOND,
            'Cannot remove bonding {}: used by network ({}).'.format(
                bond, nets_with_bond))
Пример #13
0
def _validate_bond_removal(bond, nets, running_nets):
    running_nets_with_bond = set([
        net for net, attrs in six.iteritems(running_nets)
        if attrs['bond'] == bond])

    add_nets_with_bond = set()
    remove_nets_with_bond = set()
    for net, attrs in six.iteritems(nets):
        if 'remove' in attrs:
            running_bond = running_nets.get(net, {}).get('bond')
            if running_bond == bond:
                remove_nets_with_bond.add(net)
        elif net in running_nets:
            running_bond = running_nets[net].get('bond')
            if running_bond == bond:
                remove_nets_with_bond.add(net)
            if attrs.get('bonding') == bond:
                add_nets_with_bond.add(net)
        else:
            if attrs.get('bonding') == bond:
                add_nets_with_bond.add(net)

    if (add_nets_with_bond or
            (running_nets_with_bond - remove_nets_with_bond)):
        raise ne.ConfigNetworkError(
            ne.ERR_USED_BOND,
            'Cannot remove bonding {}: used by network.'.format(bond))
Пример #14
0
def run(iface, family=4, default_route=False, duid_source=None,
        blocking_dhcp=False):
    dhclient = DhcpClient(iface, family, default_route, duid_source)
    ret = dhclient.start(blocking_dhcp)
    if blocking_dhcp and ret[0]:
        raise ne.ConfigNetworkError(
            ne.ERR_FAILED_IFUP, 'dhclient%s failed' % family)
Пример #15
0
 def _validate_network_exists(self):
     if (self._name not in self._net_info.networks
             and self._name not in self._running_config.networks):
         raise ne.ConfigNetworkError(
             ne.ERR_BAD_BRIDGE,
             'Cannot delete '
             f'network {self._name}: It doesn\'t exist in the system',
         )
Пример #16
0
def _validate_default_route(default_route_nets, no_default_route_nets):
    for net, attrs in six.iteritems(RunningConfig().networks):
        if attrs['defaultRoute'] and net not in no_default_route_nets:
            default_route_nets.add(net)
    if len(default_route_nets) > 1:
        raise ne.ConfigNetworkError(
            ne.ERR_BAD_PARAMS,
            'Only a single default route network is allowed.')
Пример #17
0
def validate(nets):
    for net, attrs in six.iteritems(nets):
        if 'remove' in attrs:
            continue
        elif attrs['nameservers'] and not attrs['defaultRoute']:
            raise ne.ConfigNetworkError(
                ne.ERR_BAD_PARAMS,
                'Name servers may only be defined on the default host network')
Пример #18
0
def _validate_bond_addition(nics, current_nics):
    for nic in nics:
        _validate_nic_exists(nic, current_nics)
        if dpdk.is_dpdk(nic):
            raise ne.ConfigNetworkError(
                ne.ERR_BAD_NIC,
                '%s is a dpdk device and not supported as a slave of bond' %
                nic)
Пример #19
0
def validate_bond_configuration(bonds):
    for bond_name, bond_attrs in six.viewitems(bonds):
        if bond_attrs.get('remove', False):
            continue

        nics = bond_attrs.get('nics', [])
        if not nics:
            raise ne.ConfigNetworkError(ne.ERR_BAD_PARAMS, '{}: Must specify '
                                        'nics for bonding'.format(bond_name))
Пример #20
0
def _validate_network_remove(netname, netattrs, netinfo_networks,
                             running_config_networks):
    netattrs_set = set(netattrs)
    is_remove = netattrs.get('remove')
    if is_remove and netattrs_set - set(['remove', 'custom']):
        raise ne.ConfigNetworkError(
            ne.ERR_BAD_PARAMS,
            'Cannot specify any attribute when removing (except custom)).',
        )
    if is_remove:
        if (netname not in netinfo_networks
                and netname not in running_config_networks):
            raise ne.ConfigNetworkError(
                ne.ERR_BAD_BRIDGE,
                "Cannot delete "
                "network %r: It doesn't exist in the "
                "system" % netname,
            )
Пример #21
0
 def _validate_bond_addition(self):
     for slave in self._nics:
         _validate_nic_exists(slave, self._net_info.nics)
         if dpdk.is_dpdk(slave):
             raise ne.ConfigNetworkError(
                 ne.ERR_BAD_NIC,
                 '%s is a dpdk device and not supported as a slave of bond'
                 % slave,
             )
Пример #22
0
def validate_vlan_configuration(nets):
    for net_name, net_attrs in six.viewitems(nets):
        if net_attrs.get('remove', False):
            continue

        if 'vlan' in net_attrs:
            if 'nic' not in net_attrs and 'bonding' not in net_attrs:
                raise ne.ConfigNetworkError(
                    ne.ERR_BAD_VLAN, '{}: vlan device requires south'
                    'bound device'.format(net_name))
Пример #23
0
 def _try_writing_single_opt(self, opt, val):
     try:
         with open(BRIDGING_OPTS.format(self.name, opt), 'w') as f:
             f.write(val)
     except OSError:
         raise ne.ConfigNetworkError(
             ne.ERR_BAD_PARAMS,
             f'Trying to write custom bridge option {opt}={val}'
             f' that does not exists for bridge {self.name}',
         )
Пример #24
0
 def store_entry(name, attrs, switch_type):
     if switch_type is None:
         store_broken_entry(name, attrs)
     elif switch_type == legacy_switch.SWITCH_TYPE:
         legacy_entries[name] = attrs
     elif switch_type == ovs_switch.SWITCH_TYPE:
         ovs_entries[name] = attrs
     else:
         raise ne.ConfigNetworkError(
             ne.ERR_BAD_PARAMS, 'Invalid switch type %s' % attrs['switch'])
Пример #25
0
def _validate_bond_options(bond_options):
    mode = 'balance-rr'
    try:
        for option in bond_options.split():
            key, value = option.split('=', 1)
            if key == 'mode':
                mode = value
    except ValueError:
        raise ne.ConfigNetworkError(
            ne.ERR_BAD_BONDING,
            'Error parsing bonding options: %r' % bond_options)

    mode = sysfs_options.numerize_bond_mode(mode)
    defaults = sysfs_options.getDefaultBondingOptions(mode)

    for option in bond_options.split():
        key, _ = option.split('=', 1)
        if key not in defaults:
            raise ne.ConfigNetworkError(
                ne.ERR_BAD_BONDING, '%r is not a valid bonding option' % key)
Пример #26
0
def validate_bond_configuration(bond, bondattrs, desired_nets, current_nets,
                                current_nics):
    if 'remove' in bondattrs:
        _validate_bond_removal(bond, desired_nets, current_nets)
    elif 'nics' in bondattrs:
        _validate_bond_addition(bondattrs['nics'], current_nics)
    else:
        raise ne.ConfigNetworkError(ne.ERR_BAD_NIC, 'Missing nics attribute')

    if 'options' in bondattrs:
        _validate_bond_options(bondattrs['options'])
Пример #27
0
def validate_bond_names(nets, bonds):
    bad_bond_names = {bond for bond in bonds if
                      not re.match('^bond\w+$', bond)}
    bad_bond_names |= {net_attrs['bonding'] for net_attrs in
                       six.viewvalues(nets) if 'bonding' in net_attrs and
                       not re.match('^bond\w+$', net_attrs['bonding'])}

    if bad_bond_names:
        raise ne.ConfigNetworkError(ne.ERR_BAD_BONDING,
                                    'bad bond name(s): {}'.format(
                                        ', '.join(bad_bond_names)))
Пример #28
0
def validate_net_configuration(net, attrs, bonds, running_bonds, kernel_nics):
    """Test if network meets logical Vdsm requiremets.

    Bridgeless networks are allowed in order to support Engine requirements.

    Checked by OVS:
        - only one vlan per tag
    """
    nic = attrs.get('nic')
    bond = attrs.get('bonding')
    vlan = attrs.get('vlan')

    if vlan is None:
        if nic and nic not in kernel_nics:
            raise ne.ConfigNetworkError(
                ne.ERR_BAD_NIC, 'Nic %s does not exist' % nic)
        running_bond = bond in running_bonds
        bond2setup = bond in bonds and 'remove' not in bonds[bond]
        if bond and not running_bond and not bond2setup:
            raise ne.ConfigNetworkError(
                ne.ERR_BAD_BONDING, 'Bond %s does not exist' % bond)
Пример #29
0
    def validate(self):
        if self._remove:
            self._validate_bond_removal()
            return

        if self._nics:
            self._validate_bond_addition()
        else:
            raise ne.ConfigNetworkError(ne.ERR_BAD_NIC,
                                        'Missing nics attribute')

        if self._options:
            _validate_bond_options(self._options)
Пример #30
0
    def _validate_bond_removal(self):
        nets_with_bond = {
            net
            for net, attrs in self._desired_config.networks.items()
            if attrs.get('bonding') == self._name
        }

        if nets_with_bond:
            raise ne.ConfigNetworkError(
                ne.ERR_USED_BOND,
                'Cannot remove bonding {}: used by network ({}).'.format(
                    self._name, nets_with_bond),
            )