sailesh1993 / rpms / cloud-init

Forked from rpms/cloud-init 10 months ago
Clone
2b0ae0
From 5ded09d5acf4d653fe2cbd54814f53063d265489 Mon Sep 17 00:00:00 2001
2b0ae0
From: Eduardo Otubo <otubo@redhat.com>
2b0ae0
Date: Thu, 29 Oct 2020 15:05:42 +0100
2b0ae0
Subject: [PATCH 1/3] Explicit set IPV6_AUTOCONF and IPV6_FORCE_ACCEPT_RA on
2b0ae0
 static6 (#634)
2b0ae0
2b0ae0
RH-Author: Eduardo Terrell Ferrari Otubo (eterrell)
2b0ae0
RH-MergeRequest: 13: [RHEL-8.4.0] Add support for ipv6_autoconf on cloud-init-20.3
2b0ae0
RH-Commit: [1/1] 41e61c35893f4487981a1ad31f9f97a9a740b397 (eterrell/cloud-init)
2b0ae0
RH-Bugzilla: 1889635
2b0ae0
2b0ae0
commit b46e4a8cff667c8441622089cf7d57aeb88220cd
2b0ae0
Author: Eduardo Otubo <otubo@redhat.com>
2b0ae0
Date:   Thu Oct 29 15:05:42 2020 +0100
2b0ae0
2b0ae0
    Explicit set IPV6_AUTOCONF and IPV6_FORCE_ACCEPT_RA on static6 (#634)
2b0ae0
2b0ae0
    The static and static6 subnet types for network_data.json were
2b0ae0
    being ignored by the Openstack handler, this would cause the code to
2b0ae0
    break and not function properly.
2b0ae0
2b0ae0
    As of today, if a static6 configuration is chosen, the interface will
2b0ae0
    still eventually be available to receive router advertisements or be set
2b0ae0
    from NetworkManager to wait for them and cycle the interface in negative
2b0ae0
    case.
2b0ae0
2b0ae0
    It is safe to assume that if the interface is manually configured to use
2b0ae0
    static ipv6 address, there's no need to wait for router advertisements.
2b0ae0
    This patch will set automatically IPV6_AUTOCONF and IPV6_FORCE_ACCEPT_RA
2b0ae0
    both to "no" in this case.
2b0ae0
2b0ae0
    This patch fixes the specific behavior only for RHEL flavor and
2b0ae0
    sysconfig renderer. It also introduces new unit tests for the specific
2b0ae0
    case as well as adjusts some existent tests to be compatible with the
2b0ae0
    new options. This patch also addresses this problem by assigning the
2b0ae0
    appropriate subnet type for each case on the openstack handler.
2b0ae0
2b0ae0
    rhbz: #1889635
2b0ae0
    rhbz: #1889635
2b0ae0
2b0ae0
    Signed-off-by: Eduardo Otubo otubo@redhat.com
2b0ae0
2b0ae0
Signed-off-by: Eduardo Otubo otubo@redhat.com
2b0ae0
---
2b0ae0
 cloudinit/net/network_state.py                 |   3 +-
2b0ae0
 cloudinit/net/sysconfig.py                     |   4 +
2b0ae0
 cloudinit/sources/helpers/openstack.py         |   8 +-
2b0ae0
 tests/unittests/test_distros/test_netconfig.py |   2 +
2b0ae0
 tests/unittests/test_net.py                    | 100 +++++++++++++++++++++++++
2b0ae0
 5 files changed, 115 insertions(+), 2 deletions(-)
2b0ae0
2b0ae0
diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py
2b0ae0
index b2f7d31..d9e7fd5 100644
2b0ae0
--- a/cloudinit/net/network_state.py
2b0ae0
+++ b/cloudinit/net/network_state.py
2b0ae0
@@ -820,7 +820,8 @@ def _normalize_subnet(subnet):
2b0ae0
 
2b0ae0
     if subnet.get('type') in ('static', 'static6'):
2b0ae0
         normal_subnet.update(
2b0ae0
-            _normalize_net_keys(normal_subnet, address_keys=('address',)))
2b0ae0
+            _normalize_net_keys(normal_subnet, address_keys=(
2b0ae0
+                'address', 'ip_address',)))
2b0ae0
     normal_subnet['routes'] = [_normalize_route(r)
2b0ae0
                                for r in subnet.get('routes', [])]
2b0ae0
 
2b0ae0
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
2b0ae0
index af093dd..c078898 100644
2b0ae0
--- a/cloudinit/net/sysconfig.py
2b0ae0
+++ b/cloudinit/net/sysconfig.py
2b0ae0
@@ -451,6 +451,10 @@ class Renderer(renderer.Renderer):
2b0ae0
                             iface_cfg[mtu_key] = subnet['mtu']
2b0ae0
                     else:
2b0ae0
                         iface_cfg[mtu_key] = subnet['mtu']
2b0ae0
+
2b0ae0
+                if subnet_is_ipv6(subnet) and flavor == 'rhel':
2b0ae0
+                    iface_cfg['IPV6_FORCE_ACCEPT_RA'] = False
2b0ae0
+                    iface_cfg['IPV6_AUTOCONF'] = False
2b0ae0
             elif subnet_type == 'manual':
2b0ae0
                 if flavor == 'suse':
2b0ae0
                     LOG.debug('Unknown subnet type setting "%s"', subnet_type)
2b0ae0
diff --git a/cloudinit/sources/helpers/openstack.py b/cloudinit/sources/helpers/openstack.py
2b0ae0
index 65e020c..3e6365f 100644
2b0ae0
--- a/cloudinit/sources/helpers/openstack.py
2b0ae0
+++ b/cloudinit/sources/helpers/openstack.py
2b0ae0
@@ -602,11 +602,17 @@ def convert_net_json(network_json=None, known_macs=None):
2b0ae0
             elif network['type'] in ['ipv6_slaac', 'ipv6_dhcpv6-stateless',
2b0ae0
                                      'ipv6_dhcpv6-stateful']:
2b0ae0
                 subnet.update({'type': network['type']})
2b0ae0
-            elif network['type'] in ['ipv4', 'ipv6']:
2b0ae0
+            elif network['type'] in ['ipv4', 'static']:
2b0ae0
                 subnet.update({
2b0ae0
                     'type': 'static',
2b0ae0
                     'address': network.get('ip_address'),
2b0ae0
                 })
2b0ae0
+            elif network['type'] in ['ipv6', 'static6']:
2b0ae0
+                cfg.update({'accept-ra': False})
2b0ae0
+                subnet.update({
2b0ae0
+                    'type': 'static6',
2b0ae0
+                    'address': network.get('ip_address'),
2b0ae0
+                })
2b0ae0
 
2b0ae0
             # Enable accept_ra for stateful and legacy ipv6_dhcp types
2b0ae0
             if network['type'] in ['ipv6_dhcpv6-stateful', 'ipv6_dhcp']:
2b0ae0
diff --git a/tests/unittests/test_distros/test_netconfig.py b/tests/unittests/test_distros/test_netconfig.py
2b0ae0
index 8d7b09c..f9fc3a1 100644
2b0ae0
--- a/tests/unittests/test_distros/test_netconfig.py
2b0ae0
+++ b/tests/unittests/test_distros/test_netconfig.py
2b0ae0
@@ -514,7 +514,9 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
2b0ae0
                 DEVICE=eth0
2b0ae0
                 IPV6ADDR=2607:f0d0:1002:0011::2/64
2b0ae0
                 IPV6INIT=yes
2b0ae0
+                IPV6_AUTOCONF=no
2b0ae0
                 IPV6_DEFAULTGW=2607:f0d0:1002:0011::1
2b0ae0
+                IPV6_FORCE_ACCEPT_RA=no
2b0ae0
                 NM_CONTROLLED=no
2b0ae0
                 ONBOOT=yes
2b0ae0
                 TYPE=Ethernet
2b0ae0
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
2b0ae0
index 9985a97..d7a7a65 100644
2b0ae0
--- a/tests/unittests/test_net.py
2b0ae0
+++ b/tests/unittests/test_net.py
2b0ae0
@@ -750,7 +750,9 @@ IPADDR=172.19.1.34
2b0ae0
 IPV6ADDR=2001:DB8::10/64
2b0ae0
 IPV6ADDR_SECONDARIES="2001:DB9::10/64 2001:DB10::10/64"
2b0ae0
 IPV6INIT=yes
2b0ae0
+IPV6_AUTOCONF=no
2b0ae0
 IPV6_DEFAULTGW=2001:DB8::1
2b0ae0
+IPV6_FORCE_ACCEPT_RA=no
2b0ae0
 NETMASK=255.255.252.0
2b0ae0
 ONBOOT=yes
2b0ae0
 TYPE=Ethernet
2b0ae0
@@ -1022,6 +1024,8 @@ NETWORK_CONFIGS = {
2b0ae0
                 IPADDR=192.168.14.2
2b0ae0
                 IPV6ADDR=2001:1::1/64
2b0ae0
                 IPV6INIT=yes
2b0ae0
+                IPV6_AUTOCONF=no
2b0ae0
+                IPV6_FORCE_ACCEPT_RA=no
2b0ae0
                 NETMASK=255.255.255.0
2b0ae0
                 ONBOOT=yes
2b0ae0
                 TYPE=Ethernet
2b0ae0
@@ -1247,6 +1251,33 @@ NETWORK_CONFIGS = {
2b0ae0
             """),
2b0ae0
         },
2b0ae0
     },
2b0ae0
+    'static6': {
2b0ae0
+        'yaml': textwrap.dedent("""\
2b0ae0
+        version: 1
2b0ae0
+        config:
2b0ae0
+          - type: 'physical'
2b0ae0
+            name: 'iface0'
2b0ae0
+            accept-ra: 'no'
2b0ae0
+            subnets:
2b0ae0
+            - type: 'static6'
2b0ae0
+              address: 2001:1::1/64
2b0ae0
+    """).rstrip(' '),
2b0ae0
+        'expected_sysconfig_rhel': {
2b0ae0
+            'ifcfg-iface0': textwrap.dedent("""\
2b0ae0
+            BOOTPROTO=none
2b0ae0
+            DEVICE=iface0
2b0ae0
+            IPV6ADDR=2001:1::1/64
2b0ae0
+            IPV6INIT=yes
2b0ae0
+            IPV6_AUTOCONF=no
2b0ae0
+            IPV6_FORCE_ACCEPT_RA=no
2b0ae0
+            DEVICE=iface0
2b0ae0
+            NM_CONTROLLED=no
2b0ae0
+            ONBOOT=yes
2b0ae0
+            TYPE=Ethernet
2b0ae0
+            USERCTL=no
2b0ae0
+            """),
2b0ae0
+        },
2b0ae0
+    },
2b0ae0
     'dhcpv6_stateless': {
2b0ae0
         'expected_eni': textwrap.dedent("""\
2b0ae0
         auto lo
2b0ae0
@@ -1636,6 +1667,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
2b0ae0
                 IPADDR=192.168.14.2
2b0ae0
                 IPV6ADDR=2001:1::1/64
2b0ae0
                 IPV6INIT=yes
2b0ae0
+                IPV6_AUTOCONF=no
2b0ae0
+                IPV6_FORCE_ACCEPT_RA=no
2b0ae0
                 IPV6_DEFAULTGW=2001:4800:78ff:1b::1
2b0ae0
                 MACADDR=bb:bb:bb:bb:bb:aa
2b0ae0
                 NETMASK=255.255.255.0
2b0ae0
@@ -2158,6 +2191,8 @@ iface bond0 inet6 static
2b0ae0
         IPADDR1=192.168.1.2
2b0ae0
         IPV6ADDR=2001:1::1/92
2b0ae0
         IPV6INIT=yes
2b0ae0
+        IPV6_AUTOCONF=no
2b0ae0
+        IPV6_FORCE_ACCEPT_RA=no
2b0ae0
         MTU=9000
2b0ae0
         NETMASK=255.255.255.0
2b0ae0
         NETMASK1=255.255.255.0
2b0ae0
@@ -2259,6 +2294,8 @@ iface bond0 inet6 static
2b0ae0
                 IPADDR1=192.168.1.2
2b0ae0
                 IPV6ADDR=2001:1::bbbb/96
2b0ae0
                 IPV6INIT=yes
2b0ae0
+                IPV6_AUTOCONF=no
2b0ae0
+                IPV6_FORCE_ACCEPT_RA=no
2b0ae0
                 IPV6_DEFAULTGW=2001:1::1
2b0ae0
                 MTU=2222
2b0ae0
                 NETMASK=255.255.255.0
2b0ae0
@@ -2341,6 +2378,9 @@ iface bond0 inet6 static
2b0ae0
                 HWADDR=52:54:00:12:34:00
2b0ae0
                 IPV6ADDR=2001:1::100/96
2b0ae0
                 IPV6INIT=yes
2b0ae0
+                IPV6_AUTOCONF=no
2b0ae0
+                IPV6_FORCE_ACCEPT_RA=no
2b0ae0
+                NM_CONTROLLED=no
2b0ae0
                 ONBOOT=yes
2b0ae0
                 TYPE=Ethernet
2b0ae0
                 USERCTL=no
2b0ae0
@@ -2352,6 +2392,9 @@ iface bond0 inet6 static
2b0ae0
                 HWADDR=52:54:00:12:34:01
2b0ae0
                 IPV6ADDR=2001:1::101/96
2b0ae0
                 IPV6INIT=yes
2b0ae0
+                IPV6_AUTOCONF=no
2b0ae0
+                IPV6_FORCE_ACCEPT_RA=no
2b0ae0
+                NM_CONTROLLED=no
2b0ae0
                 ONBOOT=yes
2b0ae0
                 TYPE=Ethernet
2b0ae0
                 USERCTL=no
2b0ae0
@@ -3151,6 +3194,61 @@ USERCTL=no
2b0ae0
         self._compare_files_to_expected(entry[self.expected_name], found)
2b0ae0
         self._assert_headers(found)
2b0ae0
 
2b0ae0
+    def test_stattic6_from_json(self):
2b0ae0
+        net_json = {
2b0ae0
+            "services": [{"type": "dns", "address": "172.19.0.12"}],
2b0ae0
+            "networks": [{
2b0ae0
+                "network_id": "dacd568d-5be6-4786-91fe-750c374b78b4",
2b0ae0
+                "type": "ipv4", "netmask": "255.255.252.0",
2b0ae0
+                "link": "tap1a81968a-79",
2b0ae0
+                "routes": [{
2b0ae0
+                    "netmask": "0.0.0.0",
2b0ae0
+                    "network": "0.0.0.0",
2b0ae0
+                    "gateway": "172.19.3.254",
2b0ae0
+                }, {
2b0ae0
+                    "netmask": "0.0.0.0",  # A second default gateway
2b0ae0
+                    "network": "0.0.0.0",
2b0ae0
+                    "gateway": "172.20.3.254",
2b0ae0
+                }],
2b0ae0
+                "ip_address": "172.19.1.34", "id": "network0"
2b0ae0
+            }, {
2b0ae0
+                "network_id": "mgmt",
2b0ae0
+                "netmask": "ffff:ffff:ffff:ffff::",
2b0ae0
+                "link": "interface1",
2b0ae0
+                "mode": "link-local",
2b0ae0
+                "routes": [],
2b0ae0
+                "ip_address": "fe80::c096:67ff:fe5c:6e84",
2b0ae0
+                "type": "static6",
2b0ae0
+                "id": "network1",
2b0ae0
+                "services": [],
2b0ae0
+                "accept-ra": "false"
2b0ae0
+            }],
2b0ae0
+            "links": [
2b0ae0
+                {
2b0ae0
+                    "ethernet_mac_address": "fa:16:3e:ed:9a:59",
2b0ae0
+                    "mtu": None, "type": "bridge", "id":
2b0ae0
+                    "tap1a81968a-79",
2b0ae0
+                    "vif_id": "1a81968a-797a-400f-8a80-567f997eb93f"
2b0ae0
+                },
2b0ae0
+            ],
2b0ae0
+        }
2b0ae0
+        macs = {'fa:16:3e:ed:9a:59': 'eth0'}
2b0ae0
+        render_dir = self.tmp_dir()
2b0ae0
+        network_cfg = openstack.convert_net_json(net_json, known_macs=macs)
2b0ae0
+        ns = network_state.parse_net_config_data(network_cfg,
2b0ae0
+                                                 skip_broken=False)
2b0ae0
+        renderer = self._get_renderer()
2b0ae0
+        with self.assertRaises(ValueError):
2b0ae0
+            renderer.render_network_state(ns, target=render_dir)
2b0ae0
+        self.assertEqual([], os.listdir(render_dir))
2b0ae0
+
2b0ae0
+    def test_static6_from_yaml(self):
2b0ae0
+        entry = NETWORK_CONFIGS['static6']
2b0ae0
+        found = self._render_and_read(network_config=yaml.load(
2b0ae0
+            entry['yaml']))
2b0ae0
+        self._compare_files_to_expected(entry[self.expected_name], found)
2b0ae0
+        self._assert_headers(found)
2b0ae0
+
2b0ae0
     def test_dhcpv6_reject_ra_config_v2(self):
2b0ae0
         entry = NETWORK_CONFIGS['dhcpv6_reject_ra']
2b0ae0
         found = self._render_and_read(network_config=yaml.load(
2b0ae0
@@ -3268,6 +3366,8 @@ USERCTL=no
2b0ae0
                    IPADDR=192.168.42.100
2b0ae0
                    IPV6ADDR=2001:db8::100/32
2b0ae0
                    IPV6INIT=yes
2b0ae0
+                   IPV6_AUTOCONF=no
2b0ae0
+                   IPV6_FORCE_ACCEPT_RA=no
2b0ae0
                    IPV6_DEFAULTGW=2001:db8::1
2b0ae0
                    NETMASK=255.255.255.0
2b0ae0
                    NM_CONTROLLED=no
2b0ae0
-- 
2b0ae0
1.8.3.1
2b0ae0