diff -Nru cloud-init-22.3.3/ChangeLog cloud-init-22.3.4/ChangeLog --- cloud-init-22.3.3/ChangeLog 2022-09-19 17:14:49.000000000 +0000 +++ cloud-init-22.3.4/ChangeLog 2022-09-30 20:55:37.000000000 +0000 @@ -1,3 +1,6 @@ +22.3.4 + - Fix Oracle DS primary interface when using IMDS (LP: #1989686) + 22.3.3 - Fix Oracle DS not setting subnet when using IMDS (LP: #1989686) diff -Nru cloud-init-22.3.3/cloudinit/sources/DataSourceOracle.py cloud-init-22.3.4/cloudinit/sources/DataSourceOracle.py --- cloud-init-22.3.3/cloudinit/sources/DataSourceOracle.py 2022-09-19 17:14:49.000000000 +0000 +++ cloud-init-22.3.4/cloudinit/sources/DataSourceOracle.py 2022-09-30 20:55:37.000000000 +0000 @@ -287,7 +287,8 @@ vnics_data = self._vnics_data if set_primary else self._vnics_data[1:] - for vnic_dict in vnics_data: + for index, vnic_dict in enumerate(vnics_data): + is_primary = set_primary and index == 0 mac_address = vnic_dict["macAddr"].lower() if mac_address not in interfaces_by_mac: LOG.warning( @@ -296,32 +297,40 @@ ) continue name = interfaces_by_mac[mac_address] - prefix = ipaddress.ip_network( - vnic_dict["subnetCidrBlock"] - ).prefixlen + network = ipaddress.ip_network(vnic_dict["subnetCidrBlock"]) if self._network_config["version"] == 1: - subnet = { - "type": "static", - "address": f"{vnic_dict['privateIp']}/{prefix}", - } - self._network_config["config"].append( - { - "name": name, - "type": "physical", - "mac_address": mac_address, - "mtu": MTU, - "subnets": [subnet], + if is_primary: + subnet = {"type": "dhcp"} + else: + subnet = { + "type": "static", + "address": ( + f"{vnic_dict['privateIp']}/{network.prefixlen}" + ), } - ) + interface_config = { + "name": name, + "type": "physical", + "mac_address": mac_address, + "mtu": MTU, + "subnets": [subnet], + } + self._network_config["config"].append(interface_config) elif self._network_config["version"] == 2: - self._network_config["ethernets"][name] = { - "addresses": [f"{vnic_dict['privateIp']}/{prefix}"], + # Why does this elif exist??? + # Are there plans to switch to v2? + interface_config = { "mtu": MTU, - "dhcp4": False, - "dhcp6": False, "match": {"macaddress": mac_address}, + "dhcp6": False, + "dhcp4": is_primary, } + if not is_primary: + interface_config["addresses"] = [ + f"{vnic_dict['privateIp']}/{network.prefixlen}" + ] + self._network_config["ethernets"][name] = interface_config def _read_system_uuid() -> Optional[str]: diff -Nru cloud-init-22.3.3/cloudinit/version.py cloud-init-22.3.4/cloudinit/version.py --- cloud-init-22.3.3/cloudinit/version.py 2022-09-19 17:14:49.000000000 +0000 +++ cloud-init-22.3.4/cloudinit/version.py 2022-09-30 20:55:37.000000000 +0000 @@ -4,7 +4,7 @@ # # This file is part of cloud-init. See LICENSE file for license information. -__VERSION__ = "22.3.3" +__VERSION__ = "22.3.4" _PACKAGED_VERSION = "@@PACKAGED_VERSION@@" FEATURES = [ diff -Nru cloud-init-22.3.3/debian/changelog cloud-init-22.3.4/debian/changelog --- cloud-init-22.3.3/debian/changelog 2022-09-21 20:27:01.000000000 +0000 +++ cloud-init-22.3.4/debian/changelog 2022-10-03 16:17:12.000000000 +0000 @@ -1,3 +1,12 @@ +cloud-init (22.3.4-0ubuntu1~22.04.1) jammy; urgency=medium + + * New upstream bugfix release. (LP: #1987318) + + Release 22.3.4 (LP: #1986703) + + Fix Oracle DS primary interface when using IMDS (#1757) + (LP: #1989686) + + -- Brett Holman Mon, 03 Oct 2022 10:17:12 -0600 + cloud-init (22.3.3-0ubuntu1~22.04.1) jammy; urgency=medium * New upstream bugfix release. (LP: #1987318) diff -Nru cloud-init-22.3.3/tests/unittests/sources/test_oracle.py cloud-init-22.3.4/tests/unittests/sources/test_oracle.py --- cloud-init-22.3.3/tests/unittests/sources/test_oracle.py 2022-09-19 17:14:49.000000000 +0000 +++ cloud-init-22.3.4/tests/unittests/sources/test_oracle.py 2022-09-30 20:55:37.000000000 +0000 @@ -274,58 +274,90 @@ ) assert 1 == caplog.text.count(" not found; skipping") - def test_secondary_nic(self, oracle_ds): + @pytest.mark.parametrize( + "set_primary", + [True, False], + ) + def test_imds_nic_setup_v1(self, set_primary, oracle_ds): oracle_ds._vnics_data = json.loads(OPC_VM_SECONDARY_VNIC_RESPONSE) oracle_ds._network_config = { "version": 1, "config": [{"primary": "nic"}], } - mac_addr, nic_name = MAC_ADDR, "ens3" with mock.patch( - DS_PATH + ".get_interfaces_by_mac", - return_value={mac_addr: nic_name}, + 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=False) - - # The input is mutated - assert 2 == len(oracle_ds.network_config["config"]) - - secondary_nic_cfg = oracle_ds.network_config["config"][1] - assert nic_name == secondary_nic_cfg["name"] - assert "physical" == secondary_nic_cfg["type"] - assert mac_addr == secondary_nic_cfg["mac_address"] - assert 9000 == secondary_nic_cfg["mtu"] - - assert 1 == len(secondary_nic_cfg["subnets"]) - subnet_cfg = secondary_nic_cfg["subnets"][0] - # These values are hard-coded in OPC_VM_SECONDARY_VNIC_RESPONSE - assert "10.0.0.231/24" == subnet_cfg["address"] + oracle_ds._add_network_config_from_opc_imds( + set_primary=set_primary + ) + + secondary_nic_index = 1 + nic_cfg = oracle_ds.network_config["config"] + if set_primary: + primary_cfg = nic_cfg[1] + secondary_nic_index += 1 + + assert "ens3" == primary_cfg["name"] + assert "physical" == primary_cfg["type"] + assert "02:00:17:05:d1:db" == primary_cfg["mac_address"] + assert 9000 == primary_cfg["mtu"] + assert 1 == len(primary_cfg["subnets"]) + assert "address" not in primary_cfg["subnets"][0] + assert "dhcp" == primary_cfg["subnets"][0]["type"] + secondary_cfg = nic_cfg[secondary_nic_index] + assert "ens4" == secondary_cfg["name"] + assert "physical" == secondary_cfg["type"] + assert "00:00:17:02:2b:b1" == secondary_cfg["mac_address"] + assert 9000 == secondary_cfg["mtu"] + assert 1 == len(secondary_cfg["subnets"]) + assert "10.0.0.231/24" == secondary_cfg["subnets"][0]["address"] + assert "static" == secondary_cfg["subnets"][0]["type"] - def test_secondary_nic_v2(self, oracle_ds): + @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": {}}}, } - mac_addr, nic_name = MAC_ADDR, "ens3" with mock.patch( - DS_PATH + ".get_interfaces_by_mac", - return_value={mac_addr: nic_name}, + 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=False) - - # The input is mutated - assert 2 == len(oracle_ds.network_config["ethernets"]) + 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"] - secondary_nic_cfg = oracle_ds.network_config["ethernets"]["ens3"] - assert secondary_nic_cfg["dhcp4"] is False - assert secondary_nic_cfg["dhcp6"] is False - assert mac_addr == secondary_nic_cfg["match"]["macaddress"] - assert 9000 == secondary_nic_cfg["mtu"] - - assert 1 == len(secondary_nic_cfg["addresses"]) - # These values are hard-coded in OPC_VM_SECONDARY_VNIC_RESPONSE - assert "10.0.0.231/24" == secondary_nic_cfg["addresses"][0] + assert 1 == len(secondary_cfg["addresses"]) + assert "10.0.0.231/24" == secondary_cfg["addresses"][0] @pytest.mark.parametrize("error_add_network", [None, Exception]) @pytest.mark.parametrize(