summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorHarald <hjensas@redhat.com>2022-02-08 15:49:00 +0100
committerGitHub <noreply@github.com>2022-02-08 08:49:00 -0600
commitb97a30f0a05c1dea918c46ca9c05c869d15fe2d5 (patch)
tree95e739f709fd130a8e35885875d048617836f757 /tests
parent339c3b0977363afcf160c564cbf446c4093525fb (diff)
downloadvyos-cloud-init-b97a30f0a05c1dea918c46ca9c05c869d15fe2d5.tar.gz
vyos-cloud-init-b97a30f0a05c1dea918c46ca9c05c869d15fe2d5.zip
Fix IPv6 netmask format for sysconfig (#1215)
This change converts the IPv6 netmask from the network_data.json[1] format to the CIDR style, <IPv6_addr>/<prefix>. Using an IPv6 address like ffff:ffff:ffff:ffff:: does not work with NetworkManager, nor networkscripts. NetworkManager will ignore the route, logging: ifcfg-rh: ignoring invalid route at \ "::/:: via fd00:fd00:fd00:2::fffe dev $DEV" \ (/etc/sysconfig/network-scripts/route6-$DEV:3): \ Argument for "::/::" is not ADDR/PREFIX format Similarly if using networkscripts, ip route fail with error: Error: inet6 prefix is expected rather than \ "fd00:fd00:fd00::/ffff:ffff:ffff:ffff::". Also a bit of refactoring ... cloudinit.net.sysconfig.Route.to_string: * Move a couple of lines around to reduce repeated code. * if "ADDRESS" not in key -> continute, so that the code block following it can be de-indented. cloudinit.net.network_state: * Refactors the ipv4_mask_to_net_prefix, ipv6_mask_to_net_prefix removes mask_to_net_prefix methods. Utilize ipaddress library to do some of the heavy lifting. LP: #1959148
Diffstat (limited to 'tests')
-rw-r--r--tests/unittests/net/test_init.py4
-rw-r--r--tests/unittests/net/test_network_state.py58
-rw-r--r--tests/unittests/test_net.py78
3 files changed, 134 insertions, 6 deletions
diff --git a/tests/unittests/net/test_init.py b/tests/unittests/net/test_init.py
index b245da94..18b3fe59 100644
--- a/tests/unittests/net/test_init.py
+++ b/tests/unittests/net/test_init.py
@@ -629,7 +629,9 @@ class TestEphemeralIPV4Network(CiTestCase):
with net.EphemeralIPv4Network(**params):
pass
error = context_manager.exception
- self.assertIn("Cannot setup network: netmask", str(error))
+ self.assertIn(
+ "Cannot setup network, invalid prefix or netmask: ", str(error)
+ )
self.assertEqual(0, m_subp.call_count)
def test_ephemeral_ipv4_network_performs_teardown(self, m_subp):
diff --git a/tests/unittests/net/test_network_state.py b/tests/unittests/net/test_network_state.py
index 88da9f94..471d969a 100644
--- a/tests/unittests/net/test_network_state.py
+++ b/tests/unittests/net/test_network_state.py
@@ -1,5 +1,5 @@
# This file is part of cloud-init. See LICENSE file for license information.
-
+import ipaddress
from unittest import mock
import pytest
@@ -163,4 +163,60 @@ class TestNetworkStateParseNameservers:
] == sorted(config.dns_searchdomains)
+class TestNetworkStateHelperFunctions(CiTestCase):
+ def test_mask_to_net_prefix_ipv4(self):
+ netmask_value = "255.255.255.0"
+ expected = 24
+ prefix_value = network_state.ipv4_mask_to_net_prefix(netmask_value)
+ assert prefix_value == expected
+
+ def test_mask_to_net_prefix_all_bits_ipv4(self):
+ netmask_value = "255.255.255.255"
+ expected = 32
+ prefix_value = network_state.ipv4_mask_to_net_prefix(netmask_value)
+ assert prefix_value == expected
+
+ def test_mask_to_net_prefix_to_many_bits_ipv4(self):
+ netmask_value = "33"
+ self.assertRaises(
+ ValueError, network_state.ipv4_mask_to_net_prefix, netmask_value
+ )
+
+ def test_mask_to_net_prefix_all_bits_ipv6(self):
+ netmask_value = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
+ expected = 128
+ prefix_value = network_state.ipv6_mask_to_net_prefix(netmask_value)
+ assert prefix_value == expected
+
+ def test_mask_to_net_prefix_ipv6(self):
+ netmask_value = "ffff:ffff:ffff:ffff::"
+ expected = 64
+ prefix_value = network_state.ipv6_mask_to_net_prefix(netmask_value)
+ assert prefix_value == expected
+
+ def test_mask_to_net_prefix_raises_value_error(self):
+ netmask_value = "ff:ff:ff:ff::"
+ self.assertRaises(
+ ValueError, network_state.ipv6_mask_to_net_prefix, netmask_value
+ )
+
+ def test_mask_to_net_prefix_to_many_bits_ipv6(self):
+ netmask_value = "129"
+ self.assertRaises(
+ ValueError, network_state.ipv6_mask_to_net_prefix, netmask_value
+ )
+
+ def test_mask_to_net_prefix_ipv4_object(self):
+ netmask_value = ipaddress.IPv4Address("255.255.255.255")
+ expected = 32
+ prefix_value = network_state.ipv4_mask_to_net_prefix(netmask_value)
+ assert prefix_value == expected
+
+ def test_mask_to_net_prefix_ipv6_object(self):
+ netmask_value = ipaddress.IPv6Address("ffff:ffff:ffff::")
+ expected = 48
+ prefix_value = network_state.ipv6_mask_to_net_prefix(netmask_value)
+ assert prefix_value == expected
+
+
# vi: ts=4 expandtab
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 66a47b0f..47e4ba00 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -2421,10 +2421,10 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
routes:
- gateway: 2001:67c:1562:1
network: 2001:67c:1
- netmask: ffff:ffff:0
+ netmask: "ffff:ffff::"
- gateway: 3001:67c:1562:1
network: 3001:67c:1
- netmask: ffff:ffff:0
+ netmask: "ffff:ffff::"
metric: 10000
"""
),
@@ -2712,8 +2712,8 @@ iface bond0 inet6 static
"""\
# Created by cloud-init on instance boot automatically, do not edit.
#
- 2001:67c:1/ffff:ffff:0 via 2001:67c:1562:1 dev bond0
- 3001:67c:1/ffff:ffff:0 via 3001:67c:1562:1 metric 10000 dev bond0
+ 2001:67c:1/32 via 2001:67c:1562:1 dev bond0
+ 3001:67c:1/32 via 3001:67c:1562:1 metric 10000 dev bond0
"""
),
"route-bond0": textwrap.dedent(
@@ -3729,6 +3729,76 @@ USERCTL=no
renderer.render_network_state(ns, target=render_dir)
self.assertEqual([], os.listdir(render_dir))
+ def test_invalid_network_mask_ipv6(self):
+ net_json = {
+ "services": [{"type": "dns", "address": "172.19.0.12"}],
+ "networks": [
+ {
+ "network_id": "public-ipv6",
+ "type": "ipv6",
+ "netmask": "",
+ "link": "tap1a81968a-79",
+ "routes": [
+ {
+ "gateway": "2001:DB8::1",
+ "netmask": "ff:ff:ff:ff::",
+ "network": "2001:DB8:1::1",
+ },
+ ],
+ "ip_address": "2001:DB8::10",
+ "id": "network1",
+ }
+ ],
+ "links": [
+ {
+ "ethernet_mac_address": "fa:16:3e:ed:9a:59",
+ "mtu": None,
+ "type": "bridge",
+ "id": "tap1a81968a-79",
+ "vif_id": "1a81968a-797a-400f-8a80-567f997eb93f",
+ },
+ ],
+ }
+ macs = {"fa:16:3e:ed:9a:59": "eth0"}
+ network_cfg = openstack.convert_net_json(net_json, known_macs=macs)
+ with self.assertRaises(ValueError):
+ network_state.parse_net_config_data(network_cfg, skip_broken=False)
+
+ def test_invalid_network_mask_ipv4(self):
+ net_json = {
+ "services": [{"type": "dns", "address": "172.19.0.12"}],
+ "networks": [
+ {
+ "network_id": "public-ipv4",
+ "type": "ipv4",
+ "netmask": "",
+ "link": "tap1a81968a-79",
+ "routes": [
+ {
+ "gateway": "172.20.0.1",
+ "netmask": "255.234.255.0",
+ "network": "172.19.0.0",
+ },
+ ],
+ "ip_address": "172.20.0.10",
+ "id": "network1",
+ }
+ ],
+ "links": [
+ {
+ "ethernet_mac_address": "fa:16:3e:ed:9a:59",
+ "mtu": None,
+ "type": "bridge",
+ "id": "tap1a81968a-79",
+ "vif_id": "1a81968a-797a-400f-8a80-567f997eb93f",
+ },
+ ],
+ }
+ macs = {"fa:16:3e:ed:9a:59": "eth0"}
+ network_cfg = openstack.convert_net_json(net_json, known_macs=macs)
+ with self.assertRaises(ValueError):
+ network_state.parse_net_config_data(network_cfg, skip_broken=False)
+
def test_openstack_rendering_samples(self):
for os_sample in OS_SAMPLES:
render_dir = self.tmp_dir()