sailesh1993 / rpms / cloud-init

Forked from rpms/cloud-init 10 months ago
Clone
c3f9da
From 2f9d58439c94fe00cee951c213f14ace6da73691 Mon Sep 17 00:00:00 2001
c3f9da
From: Eduardo Otubo <otubo@redhat.com>
c3f9da
Date: Tue, 15 Sep 2020 18:00:00 +0200
c3f9da
Subject: [PATCH 2/5] network: Fix type and respect name when rendering vlan in
c3f9da
 sysconfig. (#541)
c3f9da
c3f9da
RH-Author: Eduardo Terrell Ferrari Otubo (eterrell)
c3f9da
RH-MergeRequest: 10: ifup bond0.504 Error: Connection activation failed: No suitable device found for this connection [rhel-8.3.0.z]
c3f9da
RH-Commit: [1/1] fe8bd8bc184d2391b3f9ac6af80e231649d6019a (eterrell/cloud-init)
c3f9da
RH-Bugzilla: 1890551
c3f9da
c3f9da
commit 8439b191ec2f336d544cab86dba2860f969cd5b8
c3f9da
Author: Eduardo Otubo <otubo@redhat.com>
c3f9da
Date:   Tue Sep 15 18:00:00 2020 +0200
c3f9da
c3f9da
    network: Fix type and respect name when rendering vlan in sysconfig. (#541)
c3f9da
c3f9da
    Prior to this change, vlans were rendered in sysconfig with
c3f9da
    'TYPE=Ethernet', and incorrectly rendered the PHYSDEV based on
c3f9da
    the name of the vlan device rather than the 'link' provided
c3f9da
    in the network config.
c3f9da
c3f9da
    The change here fixes:
c3f9da
     * rendering of TYPE=Ethernet for a vlan
c3f9da
     * adds a warning if the configured device name is not supported
c3f9da
       per the RHEL 7 docs "11.5. Naming Scheme for VLAN Interfaces"
c3f9da
c3f9da
    LP: #1788915
c3f9da
    LP: #1826608
c3f9da
    RHBZ: #1861871
c3f9da
c3f9da
Conflicts:
c3f9da
* A hunk on cloudinit/net/sysconfig.py could not apply cleanly as it
c3f9da
depends on a verification on the distro flavor, which is not implemented
c3f9da
on cloud-init-19.4.
c3f9da
* Couple of hunks could not apply cleanly on tests/unittests/test_net.py
c3f9da
because the definition of unit test response moved a little bit.
c3f9da
c3f9da
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
c3f9da
---
c3f9da
 cloudinit/net/sysconfig.py                     | 32 +++++++++-
c3f9da
 tests/unittests/test_distros/test_netconfig.py | 81 ++++++++++++++++++++++++++
c3f9da
 tests/unittests/test_net.py                    |  4 --
c3f9da
 3 files changed, 112 insertions(+), 5 deletions(-)
c3f9da
c3f9da
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
c3f9da
index 810b283..4b4ed09 100644
c3f9da
--- a/cloudinit/net/sysconfig.py
c3f9da
+++ b/cloudinit/net/sysconfig.py
c3f9da
@@ -95,6 +95,10 @@ class ConfigMap(object):
c3f9da
     def __len__(self):
c3f9da
         return len(self._conf)
c3f9da
 
c3f9da
+    def skip_key_value(self, key, val):
c3f9da
+        """Skip the pair key, value if it matches a certain rule."""
c3f9da
+        return False
c3f9da
+
c3f9da
     def to_string(self):
c3f9da
         buf = six.StringIO()
c3f9da
         buf.write(_make_header())
c3f9da
@@ -102,6 +106,8 @@ class ConfigMap(object):
c3f9da
             buf.write("\n")
c3f9da
         for key in sorted(self._conf.keys()):
c3f9da
             value = self._conf[key]
c3f9da
+            if self.skip_key_value(key, value):
c3f9da
+                continue
c3f9da
             if isinstance(value, bool):
c3f9da
                 value = self._bool_map[value]
c3f9da
             if not isinstance(value, six.string_types):
c3f9da
@@ -207,6 +213,7 @@ class NetInterface(ConfigMap):
c3f9da
         'bond': 'Bond',
c3f9da
         'bridge': 'Bridge',
c3f9da
         'infiniband': 'InfiniBand',
c3f9da
+        'vlan': 'Vlan',
c3f9da
     }
c3f9da
 
c3f9da
     def __init__(self, iface_name, base_sysconf_dir, templates,
c3f9da
@@ -260,6 +267,11 @@ class NetInterface(ConfigMap):
c3f9da
             c.routes = self.routes.copy()
c3f9da
         return c
c3f9da
 
c3f9da
+    def skip_key_value(self, key, val):
c3f9da
+        if key == 'TYPE' and val == 'Vlan':
c3f9da
+            return True
c3f9da
+        return False
c3f9da
+
c3f9da
 
c3f9da
 class Renderer(renderer.Renderer):
c3f9da
     """Renders network information in a /etc/sysconfig format."""
c3f9da
@@ -599,7 +611,16 @@ class Renderer(renderer.Renderer):
c3f9da
             iface_name = iface['name']
c3f9da
             iface_cfg = iface_contents[iface_name]
c3f9da
             iface_cfg['VLAN'] = True
c3f9da
-            iface_cfg['PHYSDEV'] = iface_name[:iface_name.rfind('.')]
c3f9da
+            iface_cfg.kind = 'vlan'
c3f9da
+
c3f9da
+            rdev = iface['vlan-raw-device']
c3f9da
+            supported = _supported_vlan_names(rdev, iface['vlan_id'])
c3f9da
+            if iface_name not in supported:
c3f9da
+                LOG.info(
c3f9da
+                    "Name '%s' for vlan '%s' is not officially supported"
c3f9da
+                    "by RHEL. Supported: %s",
c3f9da
+                    iface_name, rdev, ' '.join(supported))
c3f9da
+            iface_cfg['PHYSDEV'] = rdev
c3f9da
 
c3f9da
             iface_subnets = iface.get("subnets", [])
c3f9da
             route_cfg = iface_cfg.routes
c3f9da
@@ -771,6 +792,15 @@ class Renderer(renderer.Renderer):
c3f9da
                             "\n".join(netcfg) + "\n", file_mode)
c3f9da
 
c3f9da
 
c3f9da
+def _supported_vlan_names(rdev, vid):
c3f9da
+    """Return list of supported names for vlan devices per RHEL doc
c3f9da
+    11.5. Naming Scheme for VLAN Interfaces."""
c3f9da
+    return [
c3f9da
+        v.format(rdev=rdev, vid=int(vid))
c3f9da
+        for v in ("{rdev}{vid:04}", "{rdev}{vid}",
c3f9da
+                  "{rdev}.{vid:04}", "{rdev}.{vid}")]
c3f9da
+
c3f9da
+
c3f9da
 def available(target=None):
c3f9da
     sysconfig = available_sysconfig(target=target)
c3f9da
     nm = available_nm(target=target)
c3f9da
diff --git a/tests/unittests/test_distros/test_netconfig.py b/tests/unittests/test_distros/test_netconfig.py
c3f9da
index 6720995..4ea4203 100644
c3f9da
--- a/tests/unittests/test_distros/test_netconfig.py
c3f9da
+++ b/tests/unittests/test_distros/test_netconfig.py
c3f9da
@@ -526,6 +526,87 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
c3f9da
                                V1_NET_CFG_IPV6,
c3f9da
                                expected_cfgs=expected_cfgs.copy())
c3f9da
 
c3f9da
+    def test_vlan_render_unsupported(self):
c3f9da
+        """Render officially unsupported vlan names."""
c3f9da
+        cfg = {
c3f9da
+            'version': 2,
c3f9da
+            'ethernets': {
c3f9da
+                'eth0': {'addresses': ["192.10.1.2/24"],
c3f9da
+                         'match': {'macaddress': "00:16:3e:60:7c:df"}}},
c3f9da
+            'vlans': {
c3f9da
+                'infra0': {'addresses': ["10.0.1.2/16"],
c3f9da
+                           'id': 1001, 'link': 'eth0'}},
c3f9da
+        }
c3f9da
+        expected_cfgs = {
c3f9da
+            self.ifcfg_path('eth0'): dedent("""\
c3f9da
+                BOOTPROTO=none
c3f9da
+                DEVICE=eth0
c3f9da
+                HWADDR=00:16:3e:60:7c:df
c3f9da
+                IPADDR=192.10.1.2
c3f9da
+                NETMASK=255.255.255.0
c3f9da
+                NM_CONTROLLED=no
c3f9da
+                ONBOOT=yes
c3f9da
+                TYPE=Ethernet
c3f9da
+                USERCTL=no
c3f9da
+                """),
c3f9da
+            self.ifcfg_path('infra0'): dedent("""\
c3f9da
+                BOOTPROTO=none
c3f9da
+                DEVICE=infra0
c3f9da
+                IPADDR=10.0.1.2
c3f9da
+                NETMASK=255.255.0.0
c3f9da
+                NM_CONTROLLED=no
c3f9da
+                ONBOOT=yes
c3f9da
+                PHYSDEV=eth0
c3f9da
+                USERCTL=no
c3f9da
+                VLAN=yes
c3f9da
+                """),
c3f9da
+            self.control_path(): dedent("""\
c3f9da
+                NETWORKING=yes
c3f9da
+                """),
c3f9da
+        }
c3f9da
+        self._apply_and_verify(
c3f9da
+            self.distro.apply_network_config, cfg,
c3f9da
+            expected_cfgs=expected_cfgs)
c3f9da
+
c3f9da
+    def test_vlan_render(self):
c3f9da
+        cfg = {
c3f9da
+            'version': 2,
c3f9da
+            'ethernets': {
c3f9da
+                'eth0': {'addresses': ["192.10.1.2/24"]}},
c3f9da
+            'vlans': {
c3f9da
+                'eth0.1001': {'addresses': ["10.0.1.2/16"],
c3f9da
+                              'id': 1001, 'link': 'eth0'}},
c3f9da
+        }
c3f9da
+        expected_cfgs = {
c3f9da
+            self.ifcfg_path('eth0'): dedent("""\
c3f9da
+                BOOTPROTO=none
c3f9da
+                DEVICE=eth0
c3f9da
+                IPADDR=192.10.1.2
c3f9da
+                NETMASK=255.255.255.0
c3f9da
+                NM_CONTROLLED=no
c3f9da
+                ONBOOT=yes
c3f9da
+                TYPE=Ethernet
c3f9da
+                USERCTL=no
c3f9da
+                """),
c3f9da
+            self.ifcfg_path('eth0.1001'): dedent("""\
c3f9da
+                BOOTPROTO=none
c3f9da
+                DEVICE=eth0.1001
c3f9da
+                IPADDR=10.0.1.2
c3f9da
+                NETMASK=255.255.0.0
c3f9da
+                NM_CONTROLLED=no
c3f9da
+                ONBOOT=yes
c3f9da
+                PHYSDEV=eth0
c3f9da
+                USERCTL=no
c3f9da
+                VLAN=yes
c3f9da
+                """),
c3f9da
+            self.control_path(): dedent("""\
c3f9da
+                NETWORKING=yes
c3f9da
+                """),
c3f9da
+        }
c3f9da
+        self._apply_and_verify(
c3f9da
+            self.distro.apply_network_config, cfg,
c3f9da
+            expected_cfgs=expected_cfgs)
c3f9da
+
c3f9da
 
c3f9da
 class TestNetCfgDistroOpensuse(TestNetCfgDistroBase):
c3f9da
 
c3f9da
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
c3f9da
index a931a3e..2eedb12 100644
c3f9da
--- a/tests/unittests/test_net.py
c3f9da
+++ b/tests/unittests/test_net.py
c3f9da
@@ -1496,7 +1496,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
c3f9da
                 ONBOOT=yes
c3f9da
                 PHYSDEV=bond0
c3f9da
                 STARTMODE=auto
c3f9da
-                TYPE=Ethernet
c3f9da
                 USERCTL=no
c3f9da
                 VLAN=yes"""),
c3f9da
             'ifcfg-br0': textwrap.dedent("""\
c3f9da
@@ -1541,7 +1540,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
c3f9da
                 ONBOOT=yes
c3f9da
                 PHYSDEV=eth0
c3f9da
                 STARTMODE=auto
c3f9da
-                TYPE=Ethernet
c3f9da
                 USERCTL=no
c3f9da
                 VLAN=yes"""),
c3f9da
             'ifcfg-eth1': textwrap.dedent("""\
c3f9da
@@ -2163,7 +2161,6 @@ iface bond0 inet6 static
c3f9da
                 ONBOOT=yes
c3f9da
                 PHYSDEV=en0
c3f9da
                 STARTMODE=auto
c3f9da
-                TYPE=Ethernet
c3f9da
                 USERCTL=no
c3f9da
                 VLAN=yes"""),
c3f9da
         },
c3f9da
@@ -3180,7 +3177,6 @@ USERCTL=no
c3f9da
                 ONBOOT=yes
c3f9da
                 PHYSDEV=eno1
c3f9da
                 STARTMODE=auto
c3f9da
-                TYPE=Ethernet
c3f9da
                 USERCTL=no
c3f9da
                 VLAN=yes
c3f9da
                 """)
c3f9da
-- 
c3f9da
1.8.3.1
c3f9da