Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
systemsmanagement:Uyuni:Snapshots:2023.03
cobbler
items_Fix_creation_of_default_NetworkInterface....
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File items_Fix_creation_of_default_NetworkInterface.patch of Package cobbler
From 689cb2371078196d31c739f20e3f7459d2cec3fa Mon Sep 17 00:00:00 2001 From: Bruno Travouillon <devel@travouillon.fr> Date: Fri, 3 Jun 2022 23:20:54 -0400 Subject: [PATCH 1/3] Items: Fix creation of "default" NetworkInterface Do not force creation of a network interface named `default`. Closes: #2838 From 2d04011b4535fb4011189cfae68509c2870cd2b0 Mon Sep 17 00:00:00 2001 From: Bruno Travouillon <devel@travouillon.fr> Date: Sat, 4 Jun 2022 11:27:41 -0400 Subject: [PATCH 2/3] Tests: Define default system interface explicitly Do not assume the `default` interface is implicitly created with a system. From 7ad5981fec4c7f68b847b112708f6ca6de27a9fc Mon Sep 17 00:00:00 2001 From: Bruno Travouillon <devel@travouillon.fr> Date: Tue, 7 Jun 2022 21:31:47 -0400 Subject: [PATCH 3/3] Tests: Create systems in xmlrpcapi Ensure that: - only the `default` network interface exists when no `--interface`. - only one interface exists when interface name is provided. - `--interface` is optional with several interfaces and `default`. - `--interface` is mandatory with several interfaces and no `default`. --- cobbler/items/system.py | 2 cobbler/remote.py | 18 + tests/conftest.py | 4 tests/items/system_test.py | 2 tests/modules/managers/dnsmasq_test.py | 5 tests/modules/managers/ndjbdns_test.py | 3 tests/xmlrpcapi/miscellaneous_test.py | 299 +++++++++++++++++++++++++++++++++ 7 files changed, 326 insertions(+), 7 deletions(-) Index: cobbler-3.3.3/cobbler/items/system.py =================================================================== --- cobbler-3.3.3.orig/cobbler/items/system.py +++ cobbler-3.3.3/cobbler/items/system.py @@ -743,7 +743,7 @@ class System(Item): :param api: The Cobbler API """ super().__init__(api, *args, **kwargs) - self._interfaces: Dict[str, NetworkInterface] = {"default": NetworkInterface(api)} + self._interfaces: Dict[str, NetworkInterface] = {} self._ipv6_autoconfiguration = False self._repos_enabled = False self._autoinstall = enums.VALUE_INHERITED Index: cobbler-3.3.3/cobbler/remote.py =================================================================== --- cobbler-3.3.3.orig/cobbler/remote.py +++ cobbler-3.3.3/cobbler/remote.py @@ -2151,8 +2151,22 @@ class CobblerXMLRPCInterface: system_to_edit = self.__get_object(handle) if system_to_edit is None: raise ValueError("No system found with the specified name (name given: \"%s\")!" % object_name) - # If we don't have an explicit interface name use the default interface - interface_name = attributes.get("interface", "default") + + # If we don't have an explicit interface name use the default interface or require an explicit + # interface if default cannot be found. + if ( + len(system_to_edit.interfaces) > 1 + and attributes.get("interface") is None + ): + if "default" not in system_to_edit.interfaces.keys(): + raise ValueError("Interface is required.") + interface_name = "default" + if len(system_to_edit.interfaces) == 1: + interface_name = attributes.get( + "interface", next(iter(system_to_edit.interfaces)) + ) + else: + interface_name = attributes.get("interface", "default") self.logger.debug("Interface \"%s\" is being edited.", interface_name) interface = system_to_edit.interfaces.get(interface_name) if interface is None: Index: cobbler-3.3.3/tests/conftest.py =================================================================== --- cobbler-3.3.3.orig/tests/conftest.py +++ cobbler-3.3.3/tests/conftest.py @@ -8,8 +8,8 @@ import pytest from cobbler.api import CobblerAPI from cobbler.items.distro import Distro from cobbler.items.profile import Profile -from cobbler.items.system import System from cobbler.items.image import Image +from cobbler.items.system import NetworkInterface, System @contextmanager @@ -142,6 +142,7 @@ def create_system(request, cobbler_api): test_system.profile = profile_name if image_name != "": test_system.image = image_name + test_system.interfaces = {"default": NetworkInterface(cobbler_api)} cobbler_api.add_system(test_system) return test_system Index: cobbler-3.3.3/tests/items/system_test.py =================================================================== --- cobbler-3.3.3.orig/tests/items/system_test.py +++ cobbler-3.3.3/tests/items/system_test.py @@ -644,6 +644,7 @@ def test_serial_baud_rate(cobbler_api, v def test_from_dict_with_network_interface(cobbler_api): # Arrange system = System(cobbler_api) + system.interfaces = {"default": NetworkInterface(cobbler_api)} sys_dict = system.to_dict() # Act @@ -663,6 +664,7 @@ def test_from_dict_with_network_interfac def test_is_management_supported(cobbler_api, input_mac, input_ipv4, input_ipv6, expected_result): # Arrange system = System(cobbler_api) + system.interfaces = {"default": NetworkInterface(cobbler_api)} system.interfaces["default"].mac_address = input_mac system.interfaces["default"].ip_address = input_ipv4 system.interfaces["default"].ipv6_address = input_ipv6 Index: cobbler-3.3.3/tests/modules/managers/dnsmasq_test.py =================================================================== --- cobbler-3.3.3.orig/tests/modules/managers/dnsmasq_test.py +++ cobbler-3.3.3/tests/modules/managers/dnsmasq_test.py @@ -2,7 +2,7 @@ import time from unittest.mock import MagicMock from cobbler.modules.managers import dnsmasq -from cobbler.items.system import System +from cobbler.items.system import NetworkInterface, System from cobbler.items.distro import Distro from cobbler.items.profile import Profile from cobbler.templar import Templar @@ -41,6 +41,7 @@ def test_manager_write_configs(mocker, c mock_profile = Profile(cobbler_api) mock_system = System(cobbler_api) mock_system.name = "test_manager_regen_hosts_system" + mock_system.interfaces = {"default": NetworkInterface(cobbler_api)} mock_system.interfaces["default"].dns_name = "host.example.org" mock_system.interfaces["default"].mac_address = "aa:bb:cc:dd:ee:ff" mock_system.interfaces["default"].ip_address = "192.168.1.2" @@ -74,6 +75,7 @@ def test_manager_regen_ethers(mocker, co mock_builtins_open = mocker.patch("builtins.open", mocker.mock_open()) mock_system = System(cobbler_api) mock_system.name = "test_manager_regen_ethers_system" + mock_system.interfaces = {"default": NetworkInterface(cobbler_api)} mock_system.interfaces["default"].dns_name = "host.example.org" mock_system.interfaces["default"].mac_address = "aa:bb:cc:dd:ee:ff" mock_system.interfaces["default"].ip_address = "192.168.1.2" @@ -96,6 +98,7 @@ def test_manager_regen_hosts(mocker, cob mock_builtins_open = mocker.patch("builtins.open", mocker.mock_open()) mock_system = System(cobbler_api) mock_system.name = "test_manager_regen_hosts_system" + mock_system.interfaces = {"default": NetworkInterface(cobbler_api)} mock_system.interfaces["default"].dns_name = "host.example.org" mock_system.interfaces["default"].mac_address = "AA:BB:CC:DD:EE:FF" mock_system.interfaces["default"].ip_address = "192.168.1.2" Index: cobbler-3.3.3/tests/modules/managers/ndjbdns_test.py =================================================================== --- cobbler-3.3.3.orig/tests/modules/managers/ndjbdns_test.py +++ cobbler-3.3.3/tests/modules/managers/ndjbdns_test.py @@ -2,7 +2,7 @@ import subprocess from unittest.mock import MagicMock from cobbler.modules.managers import ndjbdns -from cobbler.items.system import System +from cobbler.items.system import NetworkInterface, System from cobbler.templar import Templar @@ -36,6 +36,7 @@ def test_manager_write_configs(mocker, c mock_subproc_popen.return_value.returncode = 0 mock_system = System(cobbler_api) mock_system.name = "test_manager_regen_hosts_system" + mock_system.interfaces = {"default": NetworkInterface(cobbler_api)} mock_system.interfaces["default"].dns_name = "host.example.org" mock_system.interfaces["default"].mac_address = "aa:bb:cc:dd:ee:ff" mock_system.interfaces["default"].ip_address = "192.168.1.2" Index: cobbler-3.3.3/tests/xmlrpcapi/miscellaneous_test.py =================================================================== --- cobbler-3.3.3.orig/tests/xmlrpcapi/miscellaneous_test.py +++ cobbler-3.3.3/tests/xmlrpcapi/miscellaneous_test.py @@ -720,6 +720,305 @@ class TestMiscellaneous: # Assert assert result + def test_xapi_system_edit( + self, + remote, + token, + create_kernel_initrd, + create_distro, + create_profile, + remove_system, + ): + # Arrange + name_distro = "testsystem_xapi_edit" + name_profile = "testsystem_xapi_edit" + name_system = "testsystem_xapi_edit" + fk_kernel = "vmlinuz1" + fk_initrd = "initrd1.img" + basepath = create_kernel_initrd(fk_kernel, fk_initrd) + path_kernel = os.path.join(basepath, fk_kernel) + path_initrd = os.path.join(basepath, fk_initrd) + create_distro(name_distro, "x86_64", "suse", path_kernel, path_initrd) + create_profile(name_profile, name_distro, "a=1 b=2 c=3 c=4 c=5 d e") + + # Act + result = remote.xapi_object_edit( + "system", + name_system, + "add", + { + "name": name_system, + "profile": name_profile, + }, + token, + ) + + # Assert + assert result + assert len(remote.get_system("testsystem_xapi_edit").get("interfaces", {})) == 1 + assert "default" in remote.get_system("testsystem_xapi_edit").get( + "interfaces", {} + ) + + # Cleanup + remove_system(name_system) + + def test_xapi_system_edit_interface_name( + self, + remote, + token, + create_kernel_initrd, + create_distro, + create_profile, + remove_system, + ): + # Arrange + name_distro = "testsystem_xapi_edit" + name_profile = "testsystem_xapi_edit" + name_system = "testsystem_xapi_edit" + fk_kernel = "vmlinuz1" + fk_initrd = "initrd1.img" + basepath = create_kernel_initrd(fk_kernel, fk_initrd) + path_kernel = os.path.join(basepath, fk_kernel) + path_initrd = os.path.join(basepath, fk_initrd) + create_distro(name_distro, "x86_64", "suse", path_kernel, path_initrd) + create_profile(name_profile, name_distro, "a=1 b=2 c=3 c=4 c=5 d e") + + # Act + result = remote.xapi_object_edit( + "system", + name_system, + "add", + { + "name": name_system, + "profile": name_profile, + "interface": "eth1", + }, + token, + ) + + # Assert + assert result + assert len(remote.get_system("testsystem_xapi_edit").get("interfaces", {})) == 1 + assert "eth1" in remote.get_system("testsystem_xapi_edit").get("interfaces", {}) + + def test_xapi_system_edit_two_interfaces( + self, + remote, + token, + create_kernel_initrd, + create_distro, + create_profile, + ): + # Arrange + name_distro = "testsystem_xapi_edit" + name_profile = "testsystem_xapi_edit" + name_system = "testsystem_xapi_edit" + fk_kernel = "vmlinuz1" + fk_initrd = "initrd1.img" + basepath = create_kernel_initrd(fk_kernel, fk_initrd) + path_kernel = os.path.join(basepath, fk_kernel) + path_initrd = os.path.join(basepath, fk_initrd) + create_distro(name_distro, "x86_64", "suse", path_kernel, path_initrd) + create_profile(name_profile, name_distro, "a=1 b=2 c=3 c=4 c=5 d e") + + # Act + result_add = remote.xapi_object_edit( + "system", + name_system, + "add", + { + "name": name_system, + "profile": name_profile, + }, + token, + ) + result_edit = remote.xapi_object_edit( + "system", + name_system, + "edit", + { + "name": name_system, + "interface": "eth1", + }, + token, + ) + + # Assert + assert result_add + assert result_edit + assert len(remote.get_system("testsystem_xapi_edit").get("interfaces", {})) == 2 + assert "default" in remote.get_system("testsystem_xapi_edit").get( + "interfaces", {} + ) + assert "eth1" in remote.get_system("testsystem_xapi_edit").get("interfaces", {}) + + def test_xapi_system_edit_two_interfaces_no_default( + self, + remote, + token, + create_kernel_initrd, + create_distro, + create_profile, + ): + # Arrange + name_distro = "testsystem_xapi_edit" + name_profile = "testsystem_xapi_edit" + name_system = "testsystem_xapi_edit" + fk_kernel = "vmlinuz1" + fk_initrd = "initrd1.img" + basepath = create_kernel_initrd(fk_kernel, fk_initrd) + path_kernel = os.path.join(basepath, fk_kernel) + path_initrd = os.path.join(basepath, fk_initrd) + create_distro(name_distro, "x86_64", "suse", path_kernel, path_initrd) + create_profile(name_profile, name_distro, "a=1 b=2 c=3 c=4 c=5 d e") + + # Act + result_add = remote.xapi_object_edit( + "system", + name_system, + "add", + { + "name": name_system, + "profile": name_profile, + "interface": "eth1", + }, + token, + ) + result_edit = remote.xapi_object_edit( + "system", + name_system, + "edit", + { + "name": name_system, + "interface": "eth2", + }, + token, + ) + + # Assert + assert result_add + assert result_edit + assert len(remote.get_system("testsystem_xapi_edit").get("interfaces", {})) == 2 + assert "eth1" in remote.get_system("testsystem_xapi_edit").get("interfaces", {}) + assert "eth2" in remote.get_system("testsystem_xapi_edit").get("interfaces", {}) + + def test_xapi_system_edit_two_interfaces_default( + self, + remote, + token, + create_kernel_initrd, + create_distro, + create_profile, + ): + # Arrange + name_distro = "testsystem_xapi_edit" + name_profile = "testsystem_xapi_edit" + name_system = "testsystem_xapi_edit" + fk_kernel = "vmlinuz1" + fk_initrd = "initrd1.img" + basepath = create_kernel_initrd(fk_kernel, fk_initrd) + path_kernel = os.path.join(basepath, fk_kernel) + path_initrd = os.path.join(basepath, fk_initrd) + create_distro(name_distro, "x86_64", "suse", path_kernel, path_initrd) + create_profile(name_profile, name_distro, "a=1 b=2 c=3 c=4 c=5 d e") + remote.xapi_object_edit( + "system", + name_system, + "add", + { + "name": name_system, + "profile": name_profile, + }, + token, + ) + remote.xapi_object_edit( + "system", + name_system, + "edit", + { + "name": name_system, + "interface": "eth2", + }, + token, + ) + + # Act + result = remote.xapi_object_edit( + "system", + name_system, + "edit", + { + "name": name_system, + "mac_address": "aa:bb:cc:dd:ee:ff", + }, + token, + ) + + # Assert + assert result + assert ( + remote.get_system(name_system) + .get("interfaces", {}) + .get("default", {}) + .get("mac_address") + == "aa:bb:cc:dd:ee:ff" + ) + + def test_xapi_system_edit_two_interfaces_no_default_negative( + self, + remote, + token, + create_kernel_initrd, + create_distro, + create_profile, + ): + # Arrange + name_distro = "testsystem_xapi_edit" + name_profile = "testsystem_xapi_edit" + name_system = "testsystem_xapi_edit" + fk_kernel = "vmlinuz1" + fk_initrd = "initrd1.img" + basepath = create_kernel_initrd(fk_kernel, fk_initrd) + path_kernel = os.path.join(basepath, fk_kernel) + path_initrd = os.path.join(basepath, fk_initrd) + create_distro(name_distro, "x86_64", "suse", path_kernel, path_initrd) + create_profile(name_profile, name_distro, "a=1 b=2 c=3 c=4 c=5 d e") + remote.xapi_object_edit( + "system", + name_system, + "add", + { + "name": name_system, + "profile": name_profile, + "interface": "eth1", + }, + token, + ) + remote.xapi_object_edit( + "system", + name_system, + "edit", + { + "name": name_system, + "interface": "eth2", + }, + token, + ) + + # Act & Assert + with pytest.raises(ValueError): + remote.xapi_object_edit( + "system", + name_system, + "edit", + { + "name": name_system, + "mac_address": "aa:bb:cc:dd:ee:ff", + }, + token, + ) + @pytest.mark.usefixtures( "create_testdistro", "create_testmenu",
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor