|
|
ef3f20 |
From a298fd775b537839214802f161634215d2f827a8 Mon Sep 17 00:00:00 2001
|
|
|
ef3f20 |
From: Chad Smith <chad.smith@canonical.com>
|
|
|
ef3f20 |
Date: Tue, 9 May 2017 20:23:05 -0600
|
|
|
ef3f20 |
Subject: [PATCH] sysconfig: Raise ValueError when multiple default gateways
|
|
|
ef3f20 |
are present.
|
|
|
ef3f20 |
|
|
|
ef3f20 |
Fixed setting Route.has_set_default_ipv6 or *_ipv4 to track whether a
|
|
|
ef3f20 |
route already has a default gateway defined. The code was setting
|
|
|
ef3f20 |
Route.has_set_default which wasn't checked when raising "duplicate
|
|
|
ef3f20 |
gateway" ValueErrors. Added unit tests to exercise this expected raised
|
|
|
ef3f20 |
ValueError. Also moved is_ipv6 = subnet.get('ipv6') logic out of a for
|
|
|
ef3f20 |
loop because we don't need to recalculate the same value every route
|
|
|
ef3f20 |
iteration.
|
|
|
ef3f20 |
|
|
|
ef3f20 |
LP: #1687485
|
|
|
ef3f20 |
(cherry picked from commit dd03bb411c9a6f10854a3bbc3223b204c3d4d174)
|
|
|
ef3f20 |
|
|
|
ef3f20 |
Resolves: rhbz#1438082
|
|
|
ef3f20 |
---
|
|
|
ef3f20 |
cloudinit/net/sysconfig.py | 14 ++++-----
|
|
|
ef3f20 |
tests/unittests/test_net.py | 76 +++++++++++++++++++++++++++++++++++++++++++++
|
|
|
ef3f20 |
2 files changed, 83 insertions(+), 7 deletions(-)
|
|
|
ef3f20 |
|
|
|
ef3f20 |
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
|
|
ef3f20 |
index 29c906f..d521d5c 100644
|
|
|
ef3f20 |
--- a/cloudinit/net/sysconfig.py
|
|
|
ef3f20 |
+++ b/cloudinit/net/sysconfig.py
|
|
|
ef3f20 |
@@ -230,12 +230,8 @@ class Renderer(renderer.Renderer):
|
|
|
ef3f20 |
iface_cfg.name))
|
|
|
ef3f20 |
if 'netmask' in subnet:
|
|
|
ef3f20 |
iface_cfg['NETMASK'] = subnet['netmask']
|
|
|
ef3f20 |
+ is_ipv6 = subnet.get('ipv6')
|
|
|
ef3f20 |
for route in subnet.get('routes', []):
|
|
|
ef3f20 |
- if subnet.get('ipv6'):
|
|
|
ef3f20 |
- gw_cfg = 'IPV6_DEFAULTGW'
|
|
|
ef3f20 |
- else:
|
|
|
ef3f20 |
- gw_cfg = 'GATEWAY'
|
|
|
ef3f20 |
-
|
|
|
ef3f20 |
if _is_default_route(route):
|
|
|
ef3f20 |
if (
|
|
|
ef3f20 |
(subnet.get('ipv4') and
|
|
|
ef3f20 |
@@ -256,8 +252,12 @@ class Renderer(renderer.Renderer):
|
|
|
ef3f20 |
# also provided the default route?
|
|
|
ef3f20 |
iface_cfg['DEFROUTE'] = True
|
|
|
ef3f20 |
if 'gateway' in route:
|
|
|
ef3f20 |
- iface_cfg[gw_cfg] = route['gateway']
|
|
|
ef3f20 |
- route_cfg.has_set_default = True
|
|
|
ef3f20 |
+ if is_ipv6:
|
|
|
ef3f20 |
+ iface_cfg['IPV6_DEFAULTGW'] = route['gateway']
|
|
|
ef3f20 |
+ route_cfg.has_set_default_ipv6 = True
|
|
|
ef3f20 |
+ else:
|
|
|
ef3f20 |
+ iface_cfg['GATEWAY'] = route['gateway']
|
|
|
ef3f20 |
+ route_cfg.has_set_default_ipv4 = True
|
|
|
ef3f20 |
else:
|
|
|
ef3f20 |
gw_key = 'GATEWAY%s' % route_cfg.last_idx
|
|
|
ef3f20 |
nm_key = 'NETMASK%s' % route_cfg.last_idx
|
|
|
ef3f20 |
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
|
|
ef3f20 |
index ce13664..262c6d5 100755
|
|
|
ef3f20 |
--- a/tests/unittests/test_net.py
|
|
|
ef3f20 |
+++ b/tests/unittests/test_net.py
|
|
|
ef3f20 |
@@ -515,6 +515,82 @@ USERCTL=no
|
|
|
ef3f20 |
""".lstrip()
|
|
|
ef3f20 |
self.assertEqual(expected_content, content)
|
|
|
ef3f20 |
|
|
|
ef3f20 |
+ def test_multiple_ipv4_default_gateways(self):
|
|
|
ef3f20 |
+ """ValueError is raised when duplicate ipv4 gateways exist."""
|
|
|
ef3f20 |
+ net_json = {
|
|
|
ef3f20 |
+ "services": [{"type": "dns", "address": "172.19.0.12"}],
|
|
|
ef3f20 |
+ "networks": [{
|
|
|
ef3f20 |
+ "network_id": "dacd568d-5be6-4786-91fe-750c374b78b4",
|
|
|
ef3f20 |
+ "type": "ipv4", "netmask": "255.255.252.0",
|
|
|
ef3f20 |
+ "link": "tap1a81968a-79",
|
|
|
ef3f20 |
+ "routes": [{
|
|
|
ef3f20 |
+ "netmask": "0.0.0.0",
|
|
|
ef3f20 |
+ "network": "0.0.0.0",
|
|
|
ef3f20 |
+ "gateway": "172.19.3.254",
|
|
|
ef3f20 |
+ }, {
|
|
|
ef3f20 |
+ "netmask": "0.0.0.0", # A second default gateway
|
|
|
ef3f20 |
+ "network": "0.0.0.0",
|
|
|
ef3f20 |
+ "gateway": "172.20.3.254",
|
|
|
ef3f20 |
+ }],
|
|
|
ef3f20 |
+ "ip_address": "172.19.1.34", "id": "network0"
|
|
|
ef3f20 |
+ }],
|
|
|
ef3f20 |
+ "links": [
|
|
|
ef3f20 |
+ {
|
|
|
ef3f20 |
+ "ethernet_mac_address": "fa:16:3e:ed:9a:59",
|
|
|
ef3f20 |
+ "mtu": None, "type": "bridge", "id":
|
|
|
ef3f20 |
+ "tap1a81968a-79",
|
|
|
ef3f20 |
+ "vif_id": "1a81968a-797a-400f-8a80-567f997eb93f"
|
|
|
ef3f20 |
+ },
|
|
|
ef3f20 |
+ ],
|
|
|
ef3f20 |
+ }
|
|
|
ef3f20 |
+ macs = {'fa:16:3e:ed:9a:59': 'eth0'}
|
|
|
ef3f20 |
+ render_dir = self.tmp_dir()
|
|
|
ef3f20 |
+ network_cfg = openstack.convert_net_json(net_json, known_macs=macs)
|
|
|
ef3f20 |
+ ns = network_state.parse_net_config_data(network_cfg,
|
|
|
ef3f20 |
+ skip_broken=False)
|
|
|
ef3f20 |
+ renderer = sysconfig.Renderer()
|
|
|
ef3f20 |
+ with self.assertRaises(ValueError):
|
|
|
ef3f20 |
+ renderer.render_network_state(ns, render_dir)
|
|
|
ef3f20 |
+ self.assertEqual([], os.listdir(render_dir))
|
|
|
ef3f20 |
+
|
|
|
ef3f20 |
+ def test_multiple_ipv6_default_gateways(self):
|
|
|
ef3f20 |
+ """ValueError is raised when duplicate ipv6 gateways exist."""
|
|
|
ef3f20 |
+ net_json = {
|
|
|
ef3f20 |
+ "services": [{"type": "dns", "address": "172.19.0.12"}],
|
|
|
ef3f20 |
+ "networks": [{
|
|
|
ef3f20 |
+ "network_id": "public-ipv6",
|
|
|
ef3f20 |
+ "type": "ipv6", "netmask": "",
|
|
|
ef3f20 |
+ "link": "tap1a81968a-79",
|
|
|
ef3f20 |
+ "routes": [{
|
|
|
ef3f20 |
+ "gateway": "2001:DB8::1",
|
|
|
ef3f20 |
+ "netmask": "::",
|
|
|
ef3f20 |
+ "network": "::"
|
|
|
ef3f20 |
+ }, {
|
|
|
ef3f20 |
+ "gateway": "2001:DB9::1",
|
|
|
ef3f20 |
+ "netmask": "::",
|
|
|
ef3f20 |
+ "network": "::"
|
|
|
ef3f20 |
+ }],
|
|
|
ef3f20 |
+ "ip_address": "2001:DB8::10", "id": "network1"
|
|
|
ef3f20 |
+ }],
|
|
|
ef3f20 |
+ "links": [
|
|
|
ef3f20 |
+ {
|
|
|
ef3f20 |
+ "ethernet_mac_address": "fa:16:3e:ed:9a:59",
|
|
|
ef3f20 |
+ "mtu": None, "type": "bridge", "id":
|
|
|
ef3f20 |
+ "tap1a81968a-79",
|
|
|
ef3f20 |
+ "vif_id": "1a81968a-797a-400f-8a80-567f997eb93f"
|
|
|
ef3f20 |
+ },
|
|
|
ef3f20 |
+ ],
|
|
|
ef3f20 |
+ }
|
|
|
ef3f20 |
+ macs = {'fa:16:3e:ed:9a:59': 'eth0'}
|
|
|
ef3f20 |
+ render_dir = self.tmp_dir()
|
|
|
ef3f20 |
+ network_cfg = openstack.convert_net_json(net_json, known_macs=macs)
|
|
|
ef3f20 |
+ ns = network_state.parse_net_config_data(network_cfg,
|
|
|
ef3f20 |
+ skip_broken=False)
|
|
|
ef3f20 |
+ renderer = sysconfig.Renderer()
|
|
|
ef3f20 |
+ with self.assertRaises(ValueError):
|
|
|
ef3f20 |
+ renderer.render_network_state(ns, render_dir)
|
|
|
ef3f20 |
+ self.assertEqual([], os.listdir(render_dir))
|
|
|
ef3f20 |
+
|
|
|
ef3f20 |
def test_openstack_rendering_samples(self):
|
|
|
ef3f20 |
tmp_dir = tempfile.mkdtemp()
|
|
|
ef3f20 |
self.addCleanup(shutil.rmtree, tmp_dir)
|