Esempio n. 1
0
    def test_bond_sort_slaves(self):
        iface_info1 = self._gen_iface_info()
        iface_info2 = self._gen_iface_info()
        iface_info2[Bond.CONFIG_SUBTREE][Bond.SLAVES].reverse()

        assert iface_info2 != iface_info1
        assert (BondIface(iface_info1).state_for_verify() == BondIface(
            iface_info2).state_for_verify())
Esempio n. 2
0
    def test_remove_slave(self):
        iface = BondIface(self._gen_iface_info())
        expected_iface_info = self._gen_iface_info()
        expected_iface_info[Bond.CONFIG_SUBTREE][Bond.SLAVES] = [
            SLAVE2_IFACE_NAME
        ]

        iface.remove_slave(SLAVE1_IFACE_NAME)

        assert iface.to_dict() == expected_iface_info
Esempio n. 3
0
 def test_is_mac_restricted_mode(self):
     iface_info = self._gen_iface_info()
     iface_info[Bond.CONFIG_SUBTREE][Bond.MODE] = BondMode.ACTIVE_BACKUP
     iface_info[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE] = {
         "fail_over_mac": "active"
     }
     assert BondIface(iface_info).is_mac_restricted_mode
Esempio n. 4
0
    def test_normalize_bond_option_str_to_integer(self):
        iface_info = self._gen_iface_info()
        iface_info[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE] = {
            "miimon": "140"
        }
        expected_iface_info = self._gen_iface_info()
        expected_iface_info[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE] = {
            "miimon": 140
        }

        assert BondIface(iface_info).to_dict() == expected_iface_info
Esempio n. 5
0
    def test_normalize_bond_named_option_invalid_choice_preserved_as_int(self):
        iface_info = self._gen_iface_info()
        iface_info[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE] = {
            "ad_select": "99",
        }
        expected_iface_info = self._gen_iface_info()
        expected_iface_info[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE] = {
            "ad_select": 99
        }

        assert BondIface(iface_info).to_dict() == expected_iface_info
Esempio n. 6
0
    def test_include_arp_ip_target_explictly_when_disable_in_verify(self):
        iface_info = self._gen_iface_info()
        iface_info[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE] = {
            "arp_interval": 0,
        }
        expected_iface_info = self._gen_iface_info()
        expected_iface_info[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE] = {
            "arp_interval": 0,
            "arp_ip_target": "",
        }

        assert BondIface(iface_info).state_for_verify() == expected_iface_info
Esempio n. 7
0
    def test_normalize_bond_option_int_str_to_named(self, option_name,
                                                    name_value, int_value):
        iface_info = self._gen_iface_info()
        iface_info[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE] = {
            option_name: f"{int_value}",
        }
        expected_iface_info = self._gen_iface_info()
        expected_iface_info[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE] = {
            option_name: name_value
        }

        assert BondIface(iface_info).to_dict() == expected_iface_info
Esempio n. 8
0
    def test_validate_mac_restriced_mode_with_desire_has_no_mac(self):
        cur_iface_info = self._gen_iface_info()
        cur_iface_info[Interface.MAC] = MAC_ADDRESS1
        cur_iface = BondIface(cur_iface_info)
        iface_info = self._gen_iface_info()
        iface_info[Bond.CONFIG_SUBTREE][Bond.MODE] = BondMode.ACTIVE_BACKUP
        iface_info[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE] = {
            "fail_over_mac": "active"
        }
        iface = BondIface(iface_info)

        iface.merge(cur_iface)
        iface.pre_edit_validation_and_cleanup()
Esempio n. 9
0
File: bond.py Progetto: tyll/nmstate
def create_setting(options, wired_setting):
    bond_setting = NM.SettingBond.new()
    _fix_bond_option_arp_interval(options)
    for option_name, option_value in options.items():
        if wired_setting and BondIface.is_mac_restricted_mode(
                options.get(Bond.MODE), options):
            # When in MAC restricted mode, MAC address should be unset.
            wired_setting.props.cloned_mac_address = None
        if option_value != SYSFS_EMPTY_VALUE:
            success = bond_setting.add_option(option_name, str(option_value))
            if not success:
                raise NmstateValueError(
                    "Invalid bond option: '{}'='{}'".format(
                        option_name, option_value))

    return bond_setting
Esempio n. 10
0
    def test_validate_mac_restriced_mode_with_desire_has_mac_only(self):
        cur_iface_info = self._gen_iface_info()
        cur_iface_info[Bond.CONFIG_SUBTREE][Bond.MODE] = BondMode.ACTIVE_BACKUP
        cur_iface_info[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE] = {
            "fail_over_mac": "active"
        }
        cur_iface = BondIface(cur_iface_info)
        iface_info = self._gen_iface_info()
        iface_info[Bond.CONFIG_SUBTREE].pop(Bond.MODE)
        iface_info[Bond.CONFIG_SUBTREE].pop(Bond.OPTIONS_SUBTREE)
        iface_info[Interface.MAC] = MAC_ADDRESS1
        iface = BondIface(iface_info)

        iface.merge(cur_iface)
        with pytest.raises(NmstateValueError):
            iface.pre_edit_validation_and_cleanup()
Esempio n. 11
0
def _set_ifaces_admin_state(context, ifaces_desired_state, con_profiles):
    """
    Control interface admin state by activating, deactivating and deleting
    devices connection profiles.

    The `absent` state results in deactivating the device and deleting
    the connection profile.

    For new virtual devices, the `up` state is handled by activating the
    new connection profile. For existing devices, the device is activated,
    leaving it to choose the correct profile.

    In order to activate correctly the interfaces, the order is significant:
    - Master-less master interfaces.
    - New interfaces (virtual interfaces, but not OVS ones).
    - Master interfaces.
    - OVS ports.
    - OVS internal.
    - All the rest.
    """
    con_profiles_by_devname = _index_profiles_by_devname(con_profiles)
    new_ifaces = _get_new_ifaces(context, con_profiles)
    new_ifaces_to_activate = set()
    new_vlan_ifaces_to_activate = set()
    new_vxlan_ifaces_to_activate = set()
    new_ovs_interface_to_activate = set()
    new_ovs_port_to_activate = set()
    new_master_not_enslaved_ifaces = set()
    master_ifaces_to_edit = set()
    ifaces_to_edit = set()
    devs_to_deactivate = {}
    devs_to_delete_profile = {}
    devs_to_delete = {}
    devs_to_deactivate_beforehand = []
    profiles_to_delete = []

    current_profiles = context.client.get_connections()

    for iface_desired_state in ifaces_desired_state:
        ifname = iface_desired_state[Interface.NAME]
        nmdev = context.get_nm_dev(ifname)
        if not nmdev:
            if (ifname in new_ifaces and iface_desired_state[Interface.STATE]
                    == InterfaceState.UP):
                if _is_master_iface(
                        iface_desired_state
                ) and not _is_slave_iface(iface_desired_state):
                    new_master_not_enslaved_ifaces.add(ifname)
                elif (iface_desired_state[Interface.TYPE] ==
                      InterfaceType.OVS_INTERFACE):
                    new_ovs_interface_to_activate.add(ifname)
                elif (iface_desired_state[Interface.TYPE] ==
                      InterfaceType.OVS_PORT):
                    new_ovs_port_to_activate.add(ifname)
                elif iface_desired_state[Interface.TYPE] == InterfaceType.VLAN:
                    new_vlan_ifaces_to_activate.add(ifname)
                elif (iface_desired_state[Interface.TYPE] ==
                      InterfaceType.VXLAN):
                    new_vxlan_ifaces_to_activate.add(ifname)
                else:
                    new_ifaces_to_activate.add(ifname)
            elif iface_desired_state[Interface.STATE] == InterfaceState.ABSENT:
                # Delete the down profiles
                iface_name = iface_desired_state[Interface.NAME]
                for current_profile in current_profiles:
                    if current_profile.get_interface_name() == iface_name:
                        profile = connection.ConnectionProfile(
                            context, current_profile)
                        profiles_to_delete.append(profile)

        else:
            if iface_desired_state[Interface.STATE] == InterfaceState.UP:
                if (iface_desired_state.get(
                        Interface.TYPE) == InterfaceType.BOND):
                    iface = BondIface(iface_desired_state)
                    if iface.is_bond_mode_changed:
                        # NetworkManager leaves leftover in sysfs for bond
                        # options when changing bond mode, bug:
                        # https://bugzilla.redhat.com/show_bug.cgi?id=1819137
                        # Workaround: delete the bond interface from kernel and
                        # create again via full deactivation beforehand.
                        logging.debug(
                            f"Bond interface {ifname} is changing bond mode, "
                            "will do full deactivation before applying changes"
                        )
                        devs_to_deactivate_beforehand.append(nmdev)

                if _is_master_iface(iface_desired_state):
                    master_ifaces_to_edit.add(
                        (nmdev, con_profiles_by_devname[ifname].profile))
                else:
                    ifaces_to_edit.add(
                        (nmdev, con_profiles_by_devname[ifname].profile))
            elif iface_desired_state[Interface.STATE] in (
                    InterfaceState.DOWN,
                    InterfaceState.ABSENT,
            ):
                nmdevs = _get_affected_devices(context, iface_desired_state)
                is_absent = (iface_desired_state[Interface.STATE] ==
                             InterfaceState.ABSENT)
                for affected_nmdev in nmdevs:
                    devs_to_deactivate[
                        affected_nmdev.get_iface()] = affected_nmdev
                    if is_absent:
                        devs_to_delete_profile[
                            affected_nmdev.get_iface()] = affected_nmdev
                if (is_absent and nmdev.is_software()
                        and nmdev.get_device_type() != NM.DeviceType.VETH):
                    devs_to_delete[nmdev.get_iface()] = nmdev
            else:
                raise NmstateValueError(
                    "Invalid state {} for interface {}".format(
                        iface_desired_state[Interface.STATE],
                        iface_desired_state[Interface.NAME],
                    ))

    for dev in devs_to_deactivate_beforehand:
        device.deactivate(context, dev)

    # Do not remove devices that are marked for editing.
    for dev, _ in itertools.chain(master_ifaces_to_edit, ifaces_to_edit):
        devs_to_deactivate.pop(dev.get_iface(), None)
        devs_to_delete_profile.pop(dev.get_iface(), None)
        devs_to_delete.pop(dev.get_iface(), None)

    for profile in profiles_to_delete:
        profile.delete()
        context.wait_all_finish()

    for ifname in new_master_not_enslaved_ifaces:
        device.activate(context, dev=None, connection_id=ifname)
    context.wait_all_finish()

    for ifname in new_ifaces_to_activate:
        device.activate(context, dev=None, connection_id=ifname)
    context.wait_all_finish()

    for dev, con_profile in master_ifaces_to_edit:
        device.modify(context, dev, con_profile)
    context.wait_all_finish()

    for ifname in new_ovs_port_to_activate:
        device.activate(context, dev=None, connection_id=ifname)
    context.wait_all_finish()

    for ifname in new_ovs_interface_to_activate:
        device.activate(context, dev=None, connection_id=ifname)
    context.wait_all_finish()

    for dev, con_profile in ifaces_to_edit:
        device.modify(context, dev, con_profile)
    context.wait_all_finish()

    for ifname in new_vlan_ifaces_to_activate:
        device.activate(context, dev=None, connection_id=ifname)
    context.wait_all_finish()

    for ifname in new_vxlan_ifaces_to_activate:
        device.activate(context, dev=None, connection_id=ifname)
    context.wait_all_finish()

    for dev in devs_to_deactivate.values():
        device.deactivate(context, dev)
    context.wait_all_finish()

    for dev in devs_to_delete_profile.values():
        device.delete(context, dev)
    context.wait_all_finish()

    for dev in devs_to_delete.values():
        device.delete_device(context, dev)
    context.wait_all_finish()
Esempio n. 12
0
    def test_validate_bond_mode_undefined(self):
        iface_info = self._gen_iface_info()
        iface_info[Bond.CONFIG_SUBTREE].pop(Bond.MODE)

        with pytest.raises(NmstateValueError):
            BondIface(iface_info).pre_edit_validation_and_cleanup()
Esempio n. 13
0
 def test_get_bond_mode(self):
     assert BondIface(self._gen_iface_info()).bond_mode == TEST_BOND_MODE
Esempio n. 14
0
 def test_is_virtual(self):
     assert BondIface(self._gen_iface_info()).is_virtual
Esempio n. 15
0
 def test_is_master(self):
     assert BondIface(self._gen_iface_info()).is_master
Esempio n. 16
0
 def test_get_slaves(self):
     assert BondIface(self._gen_iface_info()).slaves == TEST_SLAVES