summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Harper <ryan.harper@canonical.com>2020-01-08 11:30:17 -0600
committerChad Smith <chad.smith@canonical.com>2020-01-08 10:30:17 -0700
commitdacdd30080bd8183d1f1c1dc9dbcbc8448301529 (patch)
treeba79741418d3fb6f5c779fe37674263a3545c131
parent6aa14766a7039333aac6f75dc442fa58dc4e692f (diff)
downloadvyos-cloud-init-dacdd30080bd8183d1f1c1dc9dbcbc8448301529.tar.gz
vyos-cloud-init-dacdd30080bd8183d1f1c1dc9dbcbc8448301529.zip
net: fix rendering of 'static6' in network config (#77)
* net: fix rendering of 'static6' in network config A V1 static6 network typo was misrendered in eni, it's not valid. It was ignored in sysconfig and netplan. This branch fixes eni, updates sysconfig, netplan to render it correctly and adds unittests for all cases. Reported-by: Raphaƫl Enrici LP: #1850988 * net: add comment about static6 type in subnet_is_ipv6 Co-authored-by: Chad Smith <blackboxsw@gmail.com> Co-authored-by: Daniel Watkins <daniel@daniel-watkins.co.uk>
-rw-r--r--cloudinit/net/eni.py4
-rw-r--r--cloudinit/net/netplan.py2
-rw-r--r--cloudinit/net/network_state.py2
-rw-r--r--cloudinit/net/sysconfig.py4
-rw-r--r--tests/unittests/test_distros/test_netconfig.py55
5 files changed, 61 insertions, 6 deletions
diff --git a/cloudinit/net/eni.py b/cloudinit/net/eni.py
index 70771060..2f714563 100644
--- a/cloudinit/net/eni.py
+++ b/cloudinit/net/eni.py
@@ -429,7 +429,9 @@ class Renderer(renderer.Renderer):
iface['mode'] = 'auto'
# Use stateless DHCPv6 (0=off, 1=on)
iface['dhcp'] = '0'
- elif subnet_is_ipv6(subnet) and subnet['type'] == 'static':
+ elif subnet_is_ipv6(subnet):
+ # mode might be static6, eni uses 'static'
+ iface['mode'] = 'static'
if accept_ra is not None:
# Accept router advertisements (0=off, 1=on)
iface['accept_ra'] = '1' if accept_ra else '0'
diff --git a/cloudinit/net/netplan.py b/cloudinit/net/netplan.py
index 14d3999f..89855270 100644
--- a/cloudinit/net/netplan.py
+++ b/cloudinit/net/netplan.py
@@ -98,7 +98,7 @@ def _extract_addresses(config, entry, ifname, features=None):
entry.update({sn_type: True})
elif sn_type in IPV6_DYNAMIC_TYPES:
entry.update({'dhcp6': True})
- elif sn_type in ['static']:
+ elif sn_type in ['static', 'static6']:
addr = "%s" % subnet.get('address')
if 'prefix' in subnet:
addr += "/%d" % subnet.get('prefix')
diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py
index f3e8e250..9b126100 100644
--- a/cloudinit/net/network_state.py
+++ b/cloudinit/net/network_state.py
@@ -941,7 +941,7 @@ def subnet_is_ipv6(subnet):
# 'static6', 'dhcp6', 'ipv6_dhcpv6-stateful', 'ipv6_dhcpv6-stateless' or
# 'ipv6_slaac'
if subnet['type'].endswith('6') or subnet['type'] in IPV6_DYNAMIC_TYPES:
- # This is a request for DHCPv6.
+ # This is a request either static6 type or DHCPv6.
return True
elif subnet['type'] == 'static' and is_ipv6_addr(subnet.get('address')):
return True
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index 310cdf01..3e06af01 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -367,7 +367,7 @@ class Renderer(renderer.Renderer):
iface_cfg['IPV6_AUTOCONF'] = True
elif subnet_type in ['dhcp4', 'dhcp']:
iface_cfg['BOOTPROTO'] = 'dhcp'
- elif subnet_type == 'static':
+ elif subnet_type in ['static', 'static6']:
# grep BOOTPROTO sysconfig.txt -A2 | head -3
# BOOTPROTO=none|bootp|dhcp
# 'bootp' or 'dhcp' cause a DHCP client
@@ -419,7 +419,7 @@ class Renderer(renderer.Renderer):
continue
elif subnet_type in IPV6_DYNAMIC_TYPES:
continue
- elif subnet_type == 'static':
+ elif subnet_type in ['static', 'static6']:
if subnet_is_ipv6(subnet):
ipv6_index = ipv6_index + 1
ipv6_cidr = "%s/%s" % (subnet['address'], subnet['prefix'])
diff --git a/tests/unittests/test_distros/test_netconfig.py b/tests/unittests/test_distros/test_netconfig.py
index a1611a07..aeaadaa0 100644
--- a/tests/unittests/test_distros/test_netconfig.py
+++ b/tests/unittests/test_distros/test_netconfig.py
@@ -110,13 +110,31 @@ auto eth1
iface eth1 inet dhcp
"""
+V1_NET_CFG_IPV6_OUTPUT = """\
+# This file is generated from information provided by the datasource. Changes
+# to it will not persist across an instance reboot. To disable cloud-init's
+# network configuration capabilities, write a file
+# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
+# network: {config: disabled}
+auto lo
+iface lo inet loopback
+
+auto eth0
+iface eth0 inet6 static
+ address 2607:f0d0:1002:0011::2/64
+ gateway 2607:f0d0:1002:0011::1
+
+auto eth1
+iface eth1 inet dhcp
+"""
+
V1_NET_CFG_IPV6 = {'config': [{'name': 'eth0',
'subnets': [{'address':
'2607:f0d0:1002:0011::2',
'gateway':
'2607:f0d0:1002:0011::1',
'netmask': '64',
- 'type': 'static'}],
+ 'type': 'static6'}],
'type': 'physical'},
{'name': 'eth1',
'subnets': [{'control': 'auto',
@@ -142,6 +160,23 @@ network:
dhcp4: true
"""
+V1_TO_V2_NET_CFG_IPV6_OUTPUT = """\
+# This file is generated from information provided by the datasource. Changes
+# to it will not persist across an instance reboot. To disable cloud-init's
+# network configuration capabilities, write a file
+# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
+# network: {config: disabled}
+network:
+ version: 2
+ ethernets:
+ eth0:
+ addresses:
+ - 2607:f0d0:1002:0011::2/64
+ gateway6: 2607:f0d0:1002:0011::1
+ eth1:
+ dhcp4: true
+"""
+
V2_NET_CFG = {
'ethernets': {
'eth7': {
@@ -344,6 +379,14 @@ class TestNetCfgDistroUbuntuEni(TestNetCfgDistroBase):
V1_NET_CFG,
expected_cfgs=expected_cfgs.copy())
+ def test_apply_network_config_ipv6_ub(self):
+ expected_cfgs = {
+ self.eni_path(): V1_NET_CFG_IPV6_OUTPUT
+ }
+ self._apply_and_verify_eni(self.distro.apply_network_config,
+ V1_NET_CFG_IPV6,
+ expected_cfgs=expected_cfgs.copy())
+
class TestNetCfgDistroUbuntuNetplan(TestNetCfgDistroBase):
def setUp(self):
@@ -387,6 +430,16 @@ class TestNetCfgDistroUbuntuNetplan(TestNetCfgDistroBase):
V1_NET_CFG,
expected_cfgs=expected_cfgs.copy())
+ def test_apply_network_config_v1_ipv6_to_netplan_ub(self):
+ expected_cfgs = {
+ self.netplan_path(): V1_TO_V2_NET_CFG_IPV6_OUTPUT,
+ }
+
+ # ub_distro.apply_network_config(V1_NET_CFG_IPV6, False)
+ self._apply_and_verify_netplan(self.distro.apply_network_config,
+ V1_NET_CFG_IPV6,
+ expected_cfgs=expected_cfgs.copy())
+
def test_apply_network_config_v2_passthrough_ub(self):
expected_cfgs = {
self.netplan_path(): V2_TO_V2_NET_CFG_OUTPUT,