sailesh1993 / rpms / cloud-init

Forked from rpms/cloud-init a year ago
Clone
20a859
From 2d29c7af0c45186d3031c0ecd9ae0b8881a33c0b Mon Sep 17 00:00:00 2001
20a859
From: Lars Kellogg-Stedman <lars@redhat.com>
20a859
Date: Thu, 2 Mar 2017 11:08:26 -0500
20a859
Subject: [PATCH] net: support both ipv4 and ipv6 gateways in sysconfig.
20a859
20a859
Previously, cloud-init would throw an exception if an interface had
20a859
both ipv4 and ipv6 addresses and a default gateway for each address
20a859
family.  This change allows cloud-init to correctly configure
20a859
interfaces in this situation.
20a859
20a859
LP: #1669504
20a859
(cherry picked from commit 1d751a6f46f044e3c3827f3cef0e4a2e71d50fe7)
20a859
---
20a859
 cloudinit/net/sysconfig.py | 33 ++++++++++++++++++++++++---------
20a859
 1 file changed, 24 insertions(+), 9 deletions(-)
20a859
20a859
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
20a859
index 0b5f13c..29c906f 100644
20a859
--- a/cloudinit/net/sysconfig.py
20a859
+++ b/cloudinit/net/sysconfig.py
20a859
@@ -87,7 +87,8 @@ class Route(ConfigMap):
20a859
     def __init__(self, route_name, base_sysconf_dir):
20a859
         super(Route, self).__init__()
20a859
         self.last_idx = 1
20a859
-        self.has_set_default = False
20a859
+        self.has_set_default_ipv4 = False
20a859
+        self.has_set_default_ipv6 = False
20a859
         self._route_name = route_name
20a859
         self._base_sysconf_dir = base_sysconf_dir
20a859
 
20a859
@@ -95,7 +96,8 @@ class Route(ConfigMap):
20a859
         r = Route(self._route_name, self._base_sysconf_dir)
20a859
         r._conf = self._conf.copy()
20a859
         r.last_idx = self.last_idx
20a859
-        r.has_set_default = self.has_set_default
20a859
+        r.has_set_default_ipv4 = self.has_set_default_ipv4
20a859
+        r.has_set_default_ipv6 = self.has_set_default_ipv6
20a859
         return r
20a859
 
20a859
     @property
20a859
@@ -119,10 +121,10 @@ class NetInterface(ConfigMap):
20a859
         super(NetInterface, self).__init__()
20a859
         self.children = []
20a859
         self.routes = Route(iface_name, base_sysconf_dir)
20a859
-        self._kind = kind
20a859
+        self.kind = kind
20a859
+
20a859
         self._iface_name = iface_name
20a859
         self._conf['DEVICE'] = iface_name
20a859
-        self._conf['TYPE'] = self.iface_types[kind]
20a859
         self._base_sysconf_dir = base_sysconf_dir
20a859
 
20a859
     @property
20a859
@@ -140,6 +142,8 @@ class NetInterface(ConfigMap):
20a859
 
20a859
     @kind.setter
20a859
     def kind(self, kind):
20a859
+        if kind not in self.iface_types:
20a859
+            raise ValueError(kind)
20a859
         self._kind = kind
20a859
         self._conf['TYPE'] = self.iface_types[kind]
20a859
 
20a859
@@ -172,7 +176,7 @@ class Renderer(renderer.Renderer):
20a859
         ('BOOTPROTO', 'none'),
20a859
     ])
20a859
 
20a859
-    # If these keys exist, then there values will be used to form
20a859
+    # If these keys exist, then their values will be used to form
20a859
     # a BONDING_OPTS grouping; otherwise no grouping will be set.
20a859
     bond_tpl_opts = tuple([
20a859
         ('bond_mode', "mode=%s"),
20a859
@@ -198,6 +202,7 @@ class Renderer(renderer.Renderer):
20a859
     def _render_iface_shared(cls, iface, iface_cfg):
20a859
         for k, v in cls.iface_defaults:
20a859
             iface_cfg[k] = v
20a859
+
20a859
         for (old_key, new_key) in [('mac_address', 'HWADDR'), ('mtu', 'MTU')]:
20a859
             old_value = iface.get(old_key)
20a859
             if old_value is not None:
20a859
@@ -226,10 +231,20 @@ class Renderer(renderer.Renderer):
20a859
         if 'netmask' in subnet:
20a859
             iface_cfg['NETMASK'] = subnet['netmask']
20a859
         for route in subnet.get('routes', []):
20a859
+            if subnet.get('ipv6'):
20a859
+                gw_cfg = 'IPV6_DEFAULTGW'
20a859
+            else:
20a859
+                gw_cfg = 'GATEWAY'
20a859
+
20a859
             if _is_default_route(route):
20a859
-                if route_cfg.has_set_default:
20a859
-                    raise ValueError("Duplicate declaration of default"
20a859
-                                     " route found for interface '%s'"
20a859
+                if (
20a859
+                        (subnet.get('ipv4') and
20a859
+                         route_cfg.has_set_default_ipv4) or
20a859
+                        (subnet.get('ipv6') and
20a859
+                         route_cfg.has_set_default_ipv6)
20a859
+                ):
20a859
+                    raise ValueError("Duplicate declaration of default "
20a859
+                                     "route found for interface '%s'"
20a859
                                      % (iface_cfg.name))
20a859
                 # NOTE(harlowja): ipv6 and ipv4 default gateways
20a859
                 gw_key = 'GATEWAY0'
20a859
@@ -241,7 +256,7 @@ class Renderer(renderer.Renderer):
20a859
                 # also provided the default route?
20a859
                 iface_cfg['DEFROUTE'] = True
20a859
                 if 'gateway' in route:
20a859
-                    iface_cfg['GATEWAY'] = route['gateway']
20a859
+                    iface_cfg[gw_cfg] = route['gateway']
20a859
                 route_cfg.has_set_default = True
20a859
             else:
20a859
                 gw_key = 'GATEWAY%s' % route_cfg.last_idx