From 9eeac24792ed8a6431e2e8693508262dcfc9a070 Mon Sep 17 00:00:00 2001 From: a-dubs Date: Thu, 13 Mar 2025 12:05:24 -0400 Subject: [PATCH 01/15] commiting local changes --- .../schemas/schema-network-config-v1.json | 4 +++ .../schemas/schema-network-config-v2.json | 4 +++ cloudinit/net/cmdline.py | 5 ++-- cloudinit/net/netplan.py | 2 ++ cloudinit/sources/DataSourceOracle.py | 27 +++---------------- 5 files changed, 17 insertions(+), 25 deletions(-) diff --git a/cloudinit/config/schemas/schema-network-config-v1.json b/cloudinit/config/schemas/schema-network-config-v1.json index 99e8c68b55b..f127b47a011 100644 --- a/cloudinit/config/schemas/schema-network-config-v1.json +++ b/cloudinit/config/schemas/schema-network-config-v1.json @@ -40,6 +40,10 @@ "accept-ra": { "type": "boolean", "description": "Whether to accept IPv6 Router Advertisements (RA) on this interface. If unset, it will not be rendered" + }, + "critical" : { + "type": "boolean", + "description": "Designate the connection as “critical to the system”, meaning that special care will be taken by to not release the assigned IP when the daemon is restarted. (not recognised by NetworkManager)." } } }, diff --git a/cloudinit/config/schemas/schema-network-config-v2.json b/cloudinit/config/schemas/schema-network-config-v2.json index d8532f23f1f..72afb8a5f01 100644 --- a/cloudinit/config/schemas/schema-network-config-v2.json +++ b/cloudinit/config/schemas/schema-network-config-v2.json @@ -151,6 +151,10 @@ } } } + }, + "critical" : { + "type": "boolean", + "description": "Designate the connection as “critical to the system”, meaning that special care will be taken by to not release the assigned IP when the daemon is restarted. (not recognised by NetworkManager)." } } }, diff --git a/cloudinit/net/cmdline.py b/cloudinit/net/cmdline.py index c2c1d5af45b..a17f0cbc4c4 100644 --- a/cloudinit/net/cmdline.py +++ b/cloudinit/net/cmdline.py @@ -219,8 +219,9 @@ def config_from_klibc_net_cfg(files=None, mac_addrs=None): names[name] = {"files": [cfg_file], "entry": entry} entries.append(entry) - return {"config": entries, "version": 1} - + r = {"config": entries, "version": 1} + logging.debug("klibc config: %s", r) + return r def read_initramfs_config(): """ diff --git a/cloudinit/net/netplan.py b/cloudinit/net/netplan.py index 50af17694d5..0f8022d8559 100644 --- a/cloudinit/net/netplan.py +++ b/cloudinit/net/netplan.py @@ -437,6 +437,8 @@ def _render_content(self, network_state: NetworkState) -> str: "set-name": ifname, "match": ifcfg.get("match", None), } + if "critical" in ifcfg: + eth["critical"] = ifcfg["critical"] if eth["match"] is None: macaddr = ifcfg.get("mac_address", None) if macaddr is not None: diff --git a/cloudinit/sources/DataSourceOracle.py b/cloudinit/sources/DataSourceOracle.py index 988fc7d2d07..bf2ef705b70 100644 --- a/cloudinit/sources/DataSourceOracle.py +++ b/cloudinit/sources/DataSourceOracle.py @@ -296,6 +296,10 @@ def network_config(self): # this is v1 if self._is_iscsi_root(): self._network_config = self._get_iscsi_config() + logging.debug( + "Instance is using iSCSI root, setting primary NIC as critical" + ) + self._network_config["config"][0]["critical"] = True if not self._has_network_config(): LOG.warning( "Could not obtain network configuration from initramfs. " @@ -416,29 +420,6 @@ def _add_network_config_from_opc_imds(self, set_primary: bool = False): "subnets": subnets, } self._network_config["config"].append(interface_config) - elif self._network_config["version"] == 2: - # Why does this elif exist??? - # Are there plans to switch to v2? - interface_config = { - "mtu": MTU, - "match": {"macaddress": mac_address}, - } - self._network_config["ethernets"][name] = interface_config - - interface_config["dhcp6"] = is_primary and is_ipv6_only - interface_config["dhcp4"] = is_primary and not is_ipv6_only - if not is_primary: - interface_config["addresses"] = [] - if vnic_dict.get("privateIp"): - interface_config["addresses"].append( - f"{vnic_dict['privateIp']}/{network.prefixlen}" - ) - if vnic_dict.get("ipv6Addresses"): - interface_config["addresses"].append( - f"{vnic_dict['ipv6Addresses'][0]}/" - f"{network.prefixlen}" - ) - self._network_config["ethernets"][name] = interface_config class DataSourceOracleNet(DataSourceOracle): From 98ea16d51509f18959a07255c9ed3017fa1485fa Mon Sep 17 00:00:00 2001 From: a-dubs Date: Thu, 13 Mar 2025 16:01:53 -0400 Subject: [PATCH 02/15] added handling of critical for physical entries to network_state class --- cloudinit/net/netplan.py | 2 ++ cloudinit/net/network_state.py | 1 + 2 files changed, 3 insertions(+) diff --git a/cloudinit/net/netplan.py b/cloudinit/net/netplan.py index 0f8022d8559..64216569b7a 100644 --- a/cloudinit/net/netplan.py +++ b/cloudinit/net/netplan.py @@ -430,6 +430,8 @@ def _render_content(self, network_state: NetworkState) -> str: # filter None (but not False) entries up front ifcfg = dict(filter(lambda it: it[1] is not None, config.items())) + logging.debug("config for %s:\n%s", ifname, ifcfg) + if_type = ifcfg.get("type") if if_type == "physical": # required_keys = ['name', 'mac_address'] diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py index 2bdd2b614c0..781dd837536 100644 --- a/cloudinit/net/network_state.py +++ b/cloudinit/net/network_state.py @@ -428,6 +428,7 @@ def handle_physical(self, command): "accept-ra": accept_ra, "wakeonlan": wakeonlan, "optional": optional, + "critical": command.get("critical"), } ) iface_key = command.get("config_id", command.get("name")) From 5434721d3eee092591f178716ce1da5ee0975506 Mon Sep 17 00:00:00 2001 From: a-dubs Date: Mon, 17 Mar 2025 13:05:29 -0400 Subject: [PATCH 03/15] remove critical key from v2 schema --- cloudinit/config/schemas/schema-network-config-v2.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cloudinit/config/schemas/schema-network-config-v2.json b/cloudinit/config/schemas/schema-network-config-v2.json index 72afb8a5f01..d8532f23f1f 100644 --- a/cloudinit/config/schemas/schema-network-config-v2.json +++ b/cloudinit/config/schemas/schema-network-config-v2.json @@ -151,10 +151,6 @@ } } } - }, - "critical" : { - "type": "boolean", - "description": "Designate the connection as “critical to the system”, meaning that special care will be taken by to not release the assigned IP when the daemon is restarted. (not recognised by NetworkManager)." } } }, From 3a11907b32bf37e6bb8955ca2abb29411e368f8b Mon Sep 17 00:00:00 2001 From: a-dubs Date: Mon, 17 Mar 2025 14:04:33 -0400 Subject: [PATCH 04/15] rename critical key in V1 to keep_configuration --- cloudinit/config/schemas/schema-network-config-v1.json | 4 ++-- cloudinit/net/netplan.py | 6 ++---- cloudinit/net/network_state.py | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cloudinit/config/schemas/schema-network-config-v1.json b/cloudinit/config/schemas/schema-network-config-v1.json index f127b47a011..767da7ed3c8 100644 --- a/cloudinit/config/schemas/schema-network-config-v1.json +++ b/cloudinit/config/schemas/schema-network-config-v1.json @@ -41,9 +41,9 @@ "type": "boolean", "description": "Whether to accept IPv6 Router Advertisements (RA) on this interface. If unset, it will not be rendered" }, - "critical" : { + "keep_configuration" : { "type": "boolean", - "description": "Designate the connection as “critical to the system”, meaning that special care will be taken by to not release the assigned IP when the daemon is restarted. (not recognised by NetworkManager)." + "description": "Designate the connection as “critical to the system”, meaning that special care will be taken not to release the assigned IP when the daemon is restarted. (not recognised by NetworkManager)." } } }, diff --git a/cloudinit/net/netplan.py b/cloudinit/net/netplan.py index 64216569b7a..816deb45883 100644 --- a/cloudinit/net/netplan.py +++ b/cloudinit/net/netplan.py @@ -430,8 +430,6 @@ def _render_content(self, network_state: NetworkState) -> str: # filter None (but not False) entries up front ifcfg = dict(filter(lambda it: it[1] is not None, config.items())) - logging.debug("config for %s:\n%s", ifname, ifcfg) - if_type = ifcfg.get("type") if if_type == "physical": # required_keys = ['name', 'mac_address'] @@ -439,8 +437,8 @@ def _render_content(self, network_state: NetworkState) -> str: "set-name": ifname, "match": ifcfg.get("match", None), } - if "critical" in ifcfg: - eth["critical"] = ifcfg["critical"] + if "keep_configuration" in ifcfg: + eth["critical"] = ifcfg["keep_configuration"] if eth["match"] is None: macaddr = ifcfg.get("mac_address", None) if macaddr is not None: diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py index 781dd837536..9fd51e42916 100644 --- a/cloudinit/net/network_state.py +++ b/cloudinit/net/network_state.py @@ -428,7 +428,7 @@ def handle_physical(self, command): "accept-ra": accept_ra, "wakeonlan": wakeonlan, "optional": optional, - "critical": command.get("critical"), + "keep_configuration": command.get("keep_configuration"), } ) iface_key = command.get("config_id", command.get("name")) From 83f6bb68f0a1d04f3c862ce79f1b4bea43c8334e Mon Sep 17 00:00:00 2001 From: a-dubs Date: Mon, 17 Mar 2025 14:20:00 -0400 Subject: [PATCH 05/15] add integration test for keep_configuration option --- .../datasources/test_oci_networking.py | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/tests/integration_tests/datasources/test_oci_networking.py b/tests/integration_tests/datasources/test_oci_networking.py index 9b807927668..d68418004d6 100644 --- a/tests/integration_tests/datasources/test_oci_networking.py +++ b/tests/integration_tests/datasources/test_oci_networking.py @@ -157,3 +157,63 @@ def test_oci_networking_system_cfg(client: IntegrationInstance, tmpdir): netplan_cfg = yaml.safe_load(netplan_yaml) expected_netplan_cfg = yaml.safe_load(SYSTEM_CFG) assert expected_netplan_cfg == netplan_cfg + + +# look for "/run/systemd/network/10-netplan-*.network" +# and look for KeepConfiguration=true in the file +# Example: +# [Match] +# PermanentMACAddress=02:00:17:19:f6:8b +# Name=ens3 + +# [Network] +# DHCP=ipv4 +# LinkLocalAddressing=ipv6 +# DNS=169.254.169.254 +# KeepConfiguration=true + +# [DHCP] +# ClientIdentifier=mac +# RouteMetric=100 +# UseMTU=true + +import logging + +logger = logging.getLogger(__name__) + +@pytest.mark.skipif(PLATFORM != "oci", reason="Test is OCI specific") +def test_oci_keep_configuration_networking_config( + session_cloud: IntegrationCloud, +): + """ + Test to ensure the keep_configuration is applied on Oracle ISCSI instances. + + This test launches a Baremetal OCI instance so that ISCSI is used, and + checks that the primary systemd network configuration file contains the + 'KeepConfiguration=true' directive, which indicates that the network + configuration is preserved as expected. + + Assertions: + - At least one netplan file exists under '/run/systemd/network'. + - The primary systemd network configuration file includes the + 'KeepConfiguration=true' directive. + """ + with session_cloud.launch( + launch_kwargs={ + "instance_type": "BM.Optimized3.36", + }, + ) as client: + r = client.execute("ls /run/systemd/network/10-netplan-*.network") + assert r.ok, "No netplan files found under /run/systemd/network" + logger.info(f"Found netplan files:\n{r.stdout}") + primary_systemd_file: str = r.stdout.strip().splitlines()[0] + systemd_config = client.read_from_file(primary_systemd_file) + assert "KeepConfiguration=true" in systemd_config, ( + f"KeepConfiguration=true not found in {primary_systemd_file}" + ) + netplan_config = client.read_from_file( + "/etc/netplan/50-cloud-init.yaml", + ) + assert "critical: true" in netplan_config, ( + "critical: true not found in netplan config" + ) From 5a6e92463960d65d5f1fe9e3e840d903535f2e2c Mon Sep 17 00:00:00 2001 From: a-dubs Date: Tue, 18 Mar 2025 11:56:31 -0400 Subject: [PATCH 06/15] fixup! rename critical key in V1 to keep_configuration --- cloudinit/sources/DataSourceOracle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudinit/sources/DataSourceOracle.py b/cloudinit/sources/DataSourceOracle.py index bf2ef705b70..8ac885088e2 100644 --- a/cloudinit/sources/DataSourceOracle.py +++ b/cloudinit/sources/DataSourceOracle.py @@ -299,7 +299,7 @@ def network_config(self): logging.debug( "Instance is using iSCSI root, setting primary NIC as critical" ) - self._network_config["config"][0]["critical"] = True + self._network_config["config"][0]["keep_configuration"] = True if not self._has_network_config(): LOG.warning( "Could not obtain network configuration from initramfs. " From 3f13682de2e0fc2bda4d04471d8aa3067ec0135a Mon Sep 17 00:00:00 2001 From: a-dubs Date: Tue, 18 Mar 2025 12:13:39 -0400 Subject: [PATCH 07/15] fixup! add integration test for keep_configuration option --- tests/integration_tests/datasources/test_oci_networking.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration_tests/datasources/test_oci_networking.py b/tests/integration_tests/datasources/test_oci_networking.py index d68418004d6..1804a7d5b1d 100644 --- a/tests/integration_tests/datasources/test_oci_networking.py +++ b/tests/integration_tests/datasources/test_oci_networking.py @@ -197,6 +197,7 @@ def test_oci_keep_configuration_networking_config( - At least one netplan file exists under '/run/systemd/network'. - The primary systemd network configuration file includes the 'KeepConfiguration=true' directive. + - The netplan configuration includes the 'critical: true' directive. """ with session_cloud.launch( launch_kwargs={ From 8240d4d5adf095fcc108fed652a58949ab2969b1 Mon Sep 17 00:00:00 2001 From: a-dubs Date: Mon, 24 Mar 2025 14:55:06 -0400 Subject: [PATCH 08/15] cleanup unnecessary v2 code block --- cloudinit/sources/DataSourceOracle.py | 69 +++++++++++++-------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/cloudinit/sources/DataSourceOracle.py b/cloudinit/sources/DataSourceOracle.py index 8ac885088e2..02b8ec53227 100644 --- a/cloudinit/sources/DataSourceOracle.py +++ b/cloudinit/sources/DataSourceOracle.py @@ -384,42 +384,41 @@ def _add_network_config_from_opc_imds(self, set_primary: bool = False): else: network = ipaddress.ip_network(vnic_dict["subnetCidrBlock"]) - if self._network_config["version"] == 1: - if is_primary: - if is_ipv6_only: - subnets = [{"type": "dhcp6"}] - else: - subnets = [{"type": "dhcp"}] + if is_primary: + if is_ipv6_only: + subnets = [{"type": "dhcp6"}] else: - subnets = [] - if vnic_dict.get("privateIp"): - subnets.append( - { - "type": "static", - "address": ( - f"{vnic_dict['privateIp']}/" - f"{network.prefixlen}" - ), - } - ) - if vnic_dict.get("ipv6Addresses"): - subnets.append( - { - "type": "static", - "address": ( - f"{vnic_dict['ipv6Addresses'][0]}/" - f"{network.prefixlen}" - ), - } - ) - interface_config = { - "name": name, - "type": "physical", - "mac_address": mac_address, - "mtu": MTU, - "subnets": subnets, - } - self._network_config["config"].append(interface_config) + subnets = [{"type": "dhcp"}] + else: + subnets = [] + if vnic_dict.get("privateIp"): + subnets.append( + { + "type": "static", + "address": ( + f"{vnic_dict['privateIp']}/" + f"{network.prefixlen}" + ), + } + ) + if vnic_dict.get("ipv6Addresses"): + subnets.append( + { + "type": "static", + "address": ( + f"{vnic_dict['ipv6Addresses'][0]}/" + f"{network.prefixlen}" + ), + } + ) + interface_config = { + "name": name, + "type": "physical", + "mac_address": mac_address, + "mtu": MTU, + "subnets": subnets, + } + self._network_config["config"].append(interface_config) class DataSourceOracleNet(DataSourceOracle): From 6548b3f0c7fd0ad7b616609b7322ced80fdaffb9 Mon Sep 17 00:00:00 2001 From: a-dubs Date: Mon, 24 Mar 2025 15:06:47 -0400 Subject: [PATCH 09/15] fixup! rename critical key in V1 to keep_configuration --- cloudinit/config/schemas/schema-network-config-v1.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cloudinit/config/schemas/schema-network-config-v1.json b/cloudinit/config/schemas/schema-network-config-v1.json index 767da7ed3c8..16dd03b212d 100644 --- a/cloudinit/config/schemas/schema-network-config-v1.json +++ b/cloudinit/config/schemas/schema-network-config-v1.json @@ -41,9 +41,9 @@ "type": "boolean", "description": "Whether to accept IPv6 Router Advertisements (RA) on this interface. If unset, it will not be rendered" }, - "keep_configuration" : { + "keep_configuration": { "type": "boolean", - "description": "Designate the connection as “critical to the system”, meaning that special care will be taken not to release the assigned IP when the daemon is restarted. (not recognised by NetworkManager)." + "description": "Designate the connection as 'critical to the system', meaning that special care will be taken not to release the assigned IP when the daemon is restarted. (not recognised by NetworkManager)." } } }, From 33da9ee277093823b5d14378452dde67ff68c84b Mon Sep 17 00:00:00 2001 From: a-dubs Date: Mon, 24 Mar 2025 15:11:03 -0400 Subject: [PATCH 10/15] remove debug code from cmdline.py --- cloudinit/net/cmdline.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cloudinit/net/cmdline.py b/cloudinit/net/cmdline.py index a17f0cbc4c4..c2c1d5af45b 100644 --- a/cloudinit/net/cmdline.py +++ b/cloudinit/net/cmdline.py @@ -219,9 +219,8 @@ def config_from_klibc_net_cfg(files=None, mac_addrs=None): names[name] = {"files": [cfg_file], "entry": entry} entries.append(entry) - r = {"config": entries, "version": 1} - logging.debug("klibc config: %s", r) - return r + return {"config": entries, "version": 1} + def read_initramfs_config(): """ From 52ff7ebc40bdba76a6a248a6c3a8fa9f8ee6239b Mon Sep 17 00:00:00 2001 From: a-dubs Date: Mon, 24 Mar 2025 15:11:18 -0400 Subject: [PATCH 11/15] fixup! add integration test for keep_configuration option --- .../datasources/test_oci_networking.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/integration_tests/datasources/test_oci_networking.py b/tests/integration_tests/datasources/test_oci_networking.py index 1804a7d5b1d..9a1181807bc 100644 --- a/tests/integration_tests/datasources/test_oci_networking.py +++ b/tests/integration_tests/datasources/test_oci_networking.py @@ -181,6 +181,7 @@ def test_oci_networking_system_cfg(client: IntegrationInstance, tmpdir): logger = logging.getLogger(__name__) + @pytest.mark.skipif(PLATFORM != "oci", reason="Test is OCI specific") def test_oci_keep_configuration_networking_config( session_cloud: IntegrationCloud, @@ -195,7 +196,7 @@ def test_oci_keep_configuration_networking_config( Assertions: - At least one netplan file exists under '/run/systemd/network'. - - The primary systemd network configuration file includes the + - The primary systemd network configuration file includes the 'KeepConfiguration=true' directive. - The netplan configuration includes the 'critical: true' directive. """ @@ -209,12 +210,12 @@ def test_oci_keep_configuration_networking_config( logger.info(f"Found netplan files:\n{r.stdout}") primary_systemd_file: str = r.stdout.strip().splitlines()[0] systemd_config = client.read_from_file(primary_systemd_file) - assert "KeepConfiguration=true" in systemd_config, ( - f"KeepConfiguration=true not found in {primary_systemd_file}" - ) + assert ( + "KeepConfiguration=true" in systemd_config + ), f"KeepConfiguration=true not found in {primary_systemd_file}" netplan_config = client.read_from_file( "/etc/netplan/50-cloud-init.yaml", ) - assert "critical: true" in netplan_config, ( - "critical: true not found in netplan config" - ) + assert ( + "critical: true" in netplan_config + ), "critical: true not found in netplan config" From f7aac83b9a1aeb5e982f64c6121de8627572f1eb Mon Sep 17 00:00:00 2001 From: a-dubs Date: Tue, 25 Mar 2025 13:12:20 -0400 Subject: [PATCH 12/15] fixup! add integration test for keep_configuration option --- .../datasources/test_oci_networking.py | 28 +++---------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/tests/integration_tests/datasources/test_oci_networking.py b/tests/integration_tests/datasources/test_oci_networking.py index 9a1181807bc..04981cebdea 100644 --- a/tests/integration_tests/datasources/test_oci_networking.py +++ b/tests/integration_tests/datasources/test_oci_networking.py @@ -1,3 +1,4 @@ +import logging import re from typing import Iterator, Set @@ -15,6 +16,8 @@ configure_secondary_nics: {configure_secondary_nics} """ +logger = logging.getLogger(__name__) + def customize_environment( client: IntegrationInstance, @@ -159,29 +162,6 @@ def test_oci_networking_system_cfg(client: IntegrationInstance, tmpdir): assert expected_netplan_cfg == netplan_cfg -# look for "/run/systemd/network/10-netplan-*.network" -# and look for KeepConfiguration=true in the file -# Example: -# [Match] -# PermanentMACAddress=02:00:17:19:f6:8b -# Name=ens3 - -# [Network] -# DHCP=ipv4 -# LinkLocalAddressing=ipv6 -# DNS=169.254.169.254 -# KeepConfiguration=true - -# [DHCP] -# ClientIdentifier=mac -# RouteMetric=100 -# UseMTU=true - -import logging - -logger = logging.getLogger(__name__) - - @pytest.mark.skipif(PLATFORM != "oci", reason="Test is OCI specific") def test_oci_keep_configuration_networking_config( session_cloud: IntegrationCloud, @@ -207,7 +187,7 @@ def test_oci_keep_configuration_networking_config( ) as client: r = client.execute("ls /run/systemd/network/10-netplan-*.network") assert r.ok, "No netplan files found under /run/systemd/network" - logger.info(f"Found netplan files:\n{r.stdout}") + logger.info("Found netplan files:\n%s", r.stdout) primary_systemd_file: str = r.stdout.strip().splitlines()[0] systemd_config = client.read_from_file(primary_systemd_file) assert ( From 6bf2e2a6519923c7b7dc30ec7321d1def4811d95 Mon Sep 17 00:00:00 2001 From: a-dubs Date: Tue, 25 Mar 2025 16:02:18 -0400 Subject: [PATCH 13/15] remove old v2 oracle ds unit tests --- tests/unittests/sources/test_oracle.py | 90 -------------------------- 1 file changed, 90 deletions(-) diff --git a/tests/unittests/sources/test_oracle.py b/tests/unittests/sources/test_oracle.py index d773acf7717..4e7e13d3f29 100644 --- a/tests/unittests/sources/test_oracle.py +++ b/tests/unittests/sources/test_oracle.py @@ -485,48 +485,6 @@ def test_imds_nic_setup_v1(self, set_primary, oracle_ds): assert "10.0.0.231/24" == secondary_cfg["subnets"][0]["address"] assert "static" == secondary_cfg["subnets"][0]["type"] - @pytest.mark.parametrize( - "set_primary", - [True, False], - ) - def test_secondary_nic_v2(self, set_primary, oracle_ds): - oracle_ds._vnics_data = json.loads(OPC_VM_SECONDARY_VNIC_RESPONSE) - oracle_ds._network_config = { - "version": 2, - "ethernets": {"primary": {"nic": {}}}, - } - with mock.patch( - f"{DS_PATH}.get_interfaces_by_mac", - return_value={ - "02:00:17:05:d1:db": "ens3", - "00:00:17:02:2b:b1": "ens4", - }, - ): - oracle_ds._add_network_config_from_opc_imds( - set_primary=set_primary - ) - - nic_cfg = oracle_ds.network_config["ethernets"] - if set_primary: - assert "ens3" in nic_cfg - primary_cfg = nic_cfg["ens3"] - - assert primary_cfg["dhcp4"] is True - assert primary_cfg["dhcp6"] is False - assert "02:00:17:05:d1:db" == primary_cfg["match"]["macaddress"] - assert 9000 == primary_cfg["mtu"] - assert "addresses" not in primary_cfg - - assert "ens4" in nic_cfg - secondary_cfg = nic_cfg["ens4"] - assert secondary_cfg["dhcp4"] is False - assert secondary_cfg["dhcp6"] is False - assert "00:00:17:02:2b:b1" == secondary_cfg["match"]["macaddress"] - assert 9000 == secondary_cfg["mtu"] - - assert 1 == len(secondary_cfg["addresses"]) - assert "10.0.0.231/24" == secondary_cfg["addresses"][0] - @pytest.mark.parametrize( "set_primary", [ @@ -577,54 +535,6 @@ def test_imds_nic_setup_v1_ipv6_only(self, set_primary, oracle_ds): == secondary_cfg["subnets"][0]["address"] ) assert "static" == secondary_cfg["subnets"][0]["type"] - - @pytest.mark.parametrize( - "set_primary", - [True, False], - ) - def test_secondary_nic_v2_ipv6_only(self, set_primary, oracle_ds): - oracle_ds._vnics_data = json.loads( - OPC_VM_IPV6_ONLY_SECONDARY_VNIC_RESPONSE - ) - oracle_ds._network_config = { - "version": 2, - "ethernets": {"primary": {"nic": {}}}, - } - with mock.patch( - f"{DS_PATH}.get_interfaces_by_mac", - return_value={ - "02:00:17:0d:6b:be": "ens3", - "02:00:17:18:f6:ff": "ens4", - }, - ): - oracle_ds._add_network_config_from_opc_imds( - set_primary=set_primary - ) - - nic_cfg = oracle_ds.network_config["ethernets"] - if set_primary: - assert "ens3" in nic_cfg - primary_cfg = nic_cfg["ens3"] - - assert primary_cfg["dhcp4"] is False - assert primary_cfg["dhcp6"] is True - assert "02:00:17:0d:6b:be" == primary_cfg["match"]["macaddress"] - assert 9000 == primary_cfg["mtu"] - assert "addresses" not in primary_cfg - - assert "ens4" in nic_cfg - secondary_cfg = nic_cfg["ens4"] - assert secondary_cfg["dhcp4"] is False - assert secondary_cfg["dhcp6"] is False - assert "02:00:17:18:f6:ff" == secondary_cfg["match"]["macaddress"] - assert 9000 == secondary_cfg["mtu"] - - assert 1 == len(secondary_cfg["addresses"]) - assert ( - "2603:c020:400d:5d7e:aacc:8e5f:3b1b:3a4a/128" - == secondary_cfg["addresses"][0] - ) - @pytest.mark.parametrize("error_add_network", [None, Exception]) @pytest.mark.parametrize( "configure_secondary_nics", From 70e8dbf6ad3b1b89a8db67973af225a63aad01f2 Mon Sep 17 00:00:00 2001 From: a-dubs Date: Wed, 26 Mar 2025 14:06:04 -0400 Subject: [PATCH 14/15] fix linting on test_oracle --- tests/unittests/sources/test_oracle.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unittests/sources/test_oracle.py b/tests/unittests/sources/test_oracle.py index 4e7e13d3f29..871a9e1b38b 100644 --- a/tests/unittests/sources/test_oracle.py +++ b/tests/unittests/sources/test_oracle.py @@ -535,6 +535,7 @@ def test_imds_nic_setup_v1_ipv6_only(self, set_primary, oracle_ds): == secondary_cfg["subnets"][0]["address"] ) assert "static" == secondary_cfg["subnets"][0]["type"] + @pytest.mark.parametrize("error_add_network", [None, Exception]) @pytest.mark.parametrize( "configure_secondary_nics", From 857d727e907f2afffe3cbec1558e3e27f5e2e5b8 Mon Sep 17 00:00:00 2001 From: a-dubs Date: Wed, 26 Mar 2025 15:34:29 -0400 Subject: [PATCH 15/15] made james' changes --- .../config/schemas/schema-network-config-v1.json | 2 +- .../datasources/test_oci_networking.py | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/cloudinit/config/schemas/schema-network-config-v1.json b/cloudinit/config/schemas/schema-network-config-v1.json index 16dd03b212d..6058e6c07a5 100644 --- a/cloudinit/config/schemas/schema-network-config-v1.json +++ b/cloudinit/config/schemas/schema-network-config-v1.json @@ -43,7 +43,7 @@ }, "keep_configuration": { "type": "boolean", - "description": "Designate the connection as 'critical to the system', meaning that special care will be taken not to release the assigned IP when the daemon is restarted. (not recognised by NetworkManager)." + "description": "Designate the connection as 'critical to the system', meaning that special care will be taken not to release the assigned IP when the daemon is restarted. (only recognized by Netplan renderer)." } } }, diff --git a/tests/integration_tests/datasources/test_oci_networking.py b/tests/integration_tests/datasources/test_oci_networking.py index 04981cebdea..10ba27bb0ec 100644 --- a/tests/integration_tests/datasources/test_oci_networking.py +++ b/tests/integration_tests/datasources/test_oci_networking.py @@ -1,4 +1,3 @@ -import logging import re from typing import Iterator, Set @@ -16,8 +15,6 @@ configure_secondary_nics: {configure_secondary_nics} """ -logger = logging.getLogger(__name__) - def customize_environment( client: IntegrationInstance, @@ -186,8 +183,12 @@ def test_oci_keep_configuration_networking_config( }, ) as client: r = client.execute("ls /run/systemd/network/10-netplan-*.network") - assert r.ok, "No netplan files found under /run/systemd/network" - logger.info("Found netplan files:\n%s", r.stdout) + assert r.ok, ( + "No netplan files found under /run/systemd/network. We are looking" + " for netplan files here to check that the underlying " + "'KeepConfiguration=true' directive is actually being applied to " + "the systemd network configuration." + ) primary_systemd_file: str = r.stdout.strip().splitlines()[0] systemd_config = client.read_from_file(primary_systemd_file) assert (