From 86930b77ad18aa8dbad8908ddad8852447db0242 Mon Sep 17 00:00:00 2001 From: PengpengSun <40026211+PengpengSun@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:26:55 +0800 Subject: [PATCH 3/3] DS VMware: Fix ipv6 addr converter from netinfo to netifaces (#5029) RH-Author: Ani Sinha RH-MergeRequest: 80: refactor: remove dependency on netifaces (#4634) RH-Jira: RHEL-34518 RH-Acked-by: xiachen RH-Acked-by: Cathy Avery RH-Commit: [2/2] d718522dec4c77dd153fb239d2d0a6bd9ef581a2 (anisinha/cloud-init) Found an issue when verifying PR 4634 on vSphere platform, which is failing to convert ipv6 addr from netinfo format to netifaces format due to 'bcast' is not existing in ipv6. This PR is fixing this by updating ipv4 converter function and adding a new ipv6 converter function, also adding unit tests. (cherry picked from commit e544a0db82caee17ee19465f8689ce02e564286f) Signed-off-by: Ani Sinha --- cloudinit/sources/DataSourceVMware.py | 45 ++++++++++++++++++++------ tests/unittests/sources/test_vmware.py | 33 +++++++++++++++++++ 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/cloudinit/sources/DataSourceVMware.py b/cloudinit/sources/DataSourceVMware.py index 6ed6a6a5..888060c9 100644 --- a/cloudinit/sources/DataSourceVMware.py +++ b/cloudinit/sources/DataSourceVMware.py @@ -859,19 +859,18 @@ def is_valid_ip_addr(val): ) -def convert_to_netifaces_format(addr): +def convert_to_netifaces_ipv4_format(addr: dict) -> dict: """ Takes a cloudinit.netinfo formatted address and converts to netifaces format, since this module was originally written with netifaces as the network introspection module. - netifaces format: + netifaces ipv4 format: { "broadcast": "10.15.255.255", "netmask": "255.240.0.0", "addr": "10.0.1.4" } - - cloudinit.netinfo format: + cloudinit.netinfo ipv4 format: { "ip": "10.0.1.4", "mask": "255.240.0.0", @@ -879,10 +878,37 @@ def convert_to_netifaces_format(addr): "scope": "global", } """ + if not addr.get("ip"): + return {} + return { + "broadcast": addr.get("bcast"), + "netmask": addr.get("mask"), + "addr": addr.get("ip"), + } + + +def convert_to_netifaces_ipv6_format(addr: dict) -> dict: + """ + Takes a cloudinit.netinfo formatted address and converts to netifaces + format, since this module was originally written with netifaces as the + network introspection module. + netifaces ipv6 format: + { + "netmask": "ffff:ffff:ffff:ffff::/64", + "addr": "2001:db8:abcd:1234::1" + } + cloudinit.netinfo ipv6 format: + { + "ip": "2001:db8:abcd:1234::1/64", + "scope6": "global", + } + """ + if not addr.get("ip"): + return {} + ipv6 = ipaddress.IPv6Interface(addr.get("ip")) return { - "broadcast": addr["bcast"], - "netmask": addr["mask"], - "addr": addr["ip"], + "netmask": f"{ipv6.netmask}/{ipv6.network.prefixlen}", + "addr": str(ipv6.ip), } @@ -890,7 +916,6 @@ def get_host_info(): """ Returns host information such as the host name and network interfaces. """ - # TODO(look to promote netifices use up in cloud-init netinfo funcs) host_info = { "network": { "interfaces": { @@ -921,9 +946,9 @@ def get_host_info(): af_inet4 = [] af_inet6 = [] for addr in ifaces[dev_name]["ipv4"]: - af_inet4.append(convert_to_netifaces_format(addr)) + af_inet4.append(convert_to_netifaces_ipv4_format(addr)) for addr in ifaces[dev_name]["ipv6"]: - af_inet6.append(convert_to_netifaces_format(addr)) + af_inet6.append(convert_to_netifaces_ipv6_format(addr)) mac = ifaces[dev_name].get("hwaddr") diff --git a/tests/unittests/sources/test_vmware.py b/tests/unittests/sources/test_vmware.py index 33193f89..cfeff6d5 100644 --- a/tests/unittests/sources/test_vmware.py +++ b/tests/unittests/sources/test_vmware.py @@ -77,6 +77,11 @@ VMW_IPV4_NETDEV_ADDR = { "mask": "255.255.255.0", "scope": "global", } +VMW_IPV4_NETIFACES_ADDR = { + "broadcast": "10.85.130.255", + "netmask": "255.255.255.0", + "addr": "10.85.130.116", +} VMW_IPV6_ROUTEINFO = { "destination": "::/0", "flags": "UG", @@ -88,6 +93,18 @@ VMW_IPV6_NETDEV_ADDR = { "ip": "fd42:baa2:3dd:17a:216:3eff:fe16:db54/64", "scope6": "global", } +VMW_IPV6_NETIFACES_ADDR = { + "netmask": "ffff:ffff:ffff:ffff::/64", + "addr": "fd42:baa2:3dd:17a:216:3eff:fe16:db54", +} +VMW_IPV6_NETDEV_PEER_ADDR = { + "ip": "fd42:baa2:3dd:17a:216:3eff:fe16:db54", + "scope6": "global", +} +VMW_IPV6_NETIFACES_PEER_ADDR = { + "netmask": "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128", + "addr": "fd42:baa2:3dd:17a:216:3eff:fe16:db54", +} def generate_test_netdev_data(ipv4=None, ipv6=None): @@ -147,6 +164,22 @@ class TestDataSourceVMware(CiTestCase): ret = ds.get_data() self.assertFalse(ret) + def test_convert_to_netifaces_ipv4_format(self): + netifaces_format = DataSourceVMware.convert_to_netifaces_ipv4_format( + VMW_IPV4_NETDEV_ADDR + ) + self.assertEqual(netifaces_format, VMW_IPV4_NETIFACES_ADDR) + + def test_convert_to_netifaces_ipv6_format(self): + netifaces_format = DataSourceVMware.convert_to_netifaces_ipv6_format( + VMW_IPV6_NETDEV_ADDR + ) + self.assertEqual(netifaces_format, VMW_IPV6_NETIFACES_ADDR) + netifaces_format = DataSourceVMware.convert_to_netifaces_ipv6_format( + VMW_IPV6_NETDEV_PEER_ADDR + ) + self.assertEqual(netifaces_format, VMW_IPV6_NETIFACES_PEER_ADDR) + @mock.patch("cloudinit.sources.DataSourceVMware.get_default_ip_addrs") def test_get_host_info_ipv4(self, m_fn_ipaddr): m_fn_ipaddr.return_value = ("10.10.10.1", None) -- 2.39.3