Skip to content

Commit

Permalink
DS VMware: Fix ipv6 addr converter from netinfo to netifaces (#5029)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
PengpengSun committed Mar 12, 2024
1 parent 586ff2d commit e544a0d
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 10 deletions.
45 changes: 35 additions & 10 deletions cloudinit/sources/DataSourceVMware.py
Original file line number Diff line number Diff line change
Expand Up @@ -847,38 +847,63 @@ 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",
"bcast": "10.15.255.255",
"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),
}


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": {
Expand Down Expand Up @@ -909,9 +934,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")

Expand Down
33 changes: 33 additions & 0 deletions tests/unittests/sources/test_vmware.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@
"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",
Expand All @@ -88,6 +93,18 @@
"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):
Expand Down Expand Up @@ -147,6 +164,22 @@ def test_no_data_access_method(self):
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)
Expand Down

0 comments on commit e544a0d

Please sign in to comment.