← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~raharper/cloud-init:fix/lp-1750884-netplan-global-dns into cloud-init:master

 

Ryan Harper has proposed merging ~raharper/cloud-init:fix/lp-1750884-netplan-global-dns into cloud-init:master.

Requested reviews:
  Server Team CI bot (server-team-bot): continuous-integration
  cloud-init commiters (cloud-init-dev)
Related bugs:
  Bug #1750884 in cloud-init: "[2.4, bionic] /etc/resolv.conf not configured correctly in Bionic, leads to no DNS resolution"
  https://bugs.launchpad.net/cloud-init/+bug/1750884

For more details, see:
https://code.launchpad.net/~raharper/cloud-init/+git/cloud-init/+merge/341662

Handle global dns entries in netplan
    
In network config v1 format, there are dns values which are not bound
to a specific interface and do not map to the per-interface format in
netplan.  To handle this case we render netplan configuration that duplicates
the DNS configuration on any interface that has a static network config.
We avoiding interfaces which have DHCP configuration which may provide
conflicting DNS values.
    
LP: #1750884
-- 
Your team cloud-init commiters is requested to review the proposed merge of ~raharper/cloud-init:fix/lp-1750884-netplan-global-dns into cloud-init:master.
diff --git a/cloudinit/net/netplan.py b/cloudinit/net/netplan.py
index 6bee3d3..6344348 100644
--- a/cloudinit/net/netplan.py
+++ b/cloudinit/net/netplan.py
@@ -336,22 +336,15 @@ class Renderer(renderer.Renderer):
                 _extract_addresses(ifcfg, vlan)
                 vlans.update({ifname: vlan})
 
-        # inject global nameserver values under each physical interface
-        if nameservers:
-            for _eth, cfg in ethernets.items():
-                nscfg = cfg.get('nameservers', {})
-                addresses = nscfg.get('addresses', [])
-                addresses += nameservers
-                nscfg.update({'addresses': addresses})
-                cfg.update({'nameservers': nscfg})
-
-        if searchdomains:
-            for _eth, cfg in ethernets.items():
-                nscfg = cfg.get('nameservers', {})
-                search = nscfg.get('search', [])
-                search += searchdomains
-                nscfg.update({'search': search})
-                cfg.update({'nameservers': nscfg})
+        # inject global nameserver values under each all interface which
+        # has addresses and do not already have a DNS configuration
+        if nameservers or searchdomains:
+            nscfg = {'addresses': nameservers, 'search': searchdomains}
+            for section in [ethernets, wifis, bonds, bridges, vlans]:
+                for _name, cfg in section.items():
+                    if 'nameservers' in cfg or 'addresses' not in cfg:
+                        continue
+                    cfg.update({'nameservers': nscfg})
 
         # workaround yaml dictionary key sorting when dumping
         def _render_section(name, section):
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 84a0eab..c12a487 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -393,12 +393,6 @@ NETWORK_CONFIGS = {
                     eth1:
                         match:
                             macaddress: cf:d6:af:48:e8:80
-                        nameservers:
-                            addresses:
-                            - 1.2.3.4
-                            - 5.6.7.8
-                            search:
-                            - wark.maas
                         set-name: eth1
                     eth99:
                         addresses:
@@ -410,12 +404,9 @@ NETWORK_CONFIGS = {
                             addresses:
                             - 8.8.8.8
                             - 8.8.4.4
-                            - 1.2.3.4
-                            - 5.6.7.8
                             search:
                             - barley.maas
                             - sach.maas
-                            - wark.maas
                         routes:
                         -   to: 0.0.0.0/0
                             via: 65.61.151.37
@@ -654,81 +645,27 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
                     eth0:
                         match:
                             macaddress: c0:d6:9f:2c:e8:80
-                        nameservers:
-                            addresses:
-                            - 8.8.8.8
-                            - 4.4.4.4
-                            - 8.8.4.4
-                            search:
-                            - barley.maas
-                            - wark.maas
-                            - foobar.maas
                         set-name: eth0
                     eth1:
                         match:
                             macaddress: aa:d6:9f:2c:e8:80
-                        nameservers:
-                            addresses:
-                            - 8.8.8.8
-                            - 4.4.4.4
-                            - 8.8.4.4
-                            search:
-                            - barley.maas
-                            - wark.maas
-                            - foobar.maas
                         set-name: eth1
                     eth2:
                         match:
                             macaddress: c0:bb:9f:2c:e8:80
-                        nameservers:
-                            addresses:
-                            - 8.8.8.8
-                            - 4.4.4.4
-                            - 8.8.4.4
-                            search:
-                            - barley.maas
-                            - wark.maas
-                            - foobar.maas
                         set-name: eth2
                     eth3:
                         match:
                             macaddress: 66:bb:9f:2c:e8:80
-                        nameservers:
-                            addresses:
-                            - 8.8.8.8
-                            - 4.4.4.4
-                            - 8.8.4.4
-                            search:
-                            - barley.maas
-                            - wark.maas
-                            - foobar.maas
                         set-name: eth3
                     eth4:
                         match:
                             macaddress: 98:bb:9f:2c:e8:80
-                        nameservers:
-                            addresses:
-                            - 8.8.8.8
-                            - 4.4.4.4
-                            - 8.8.4.4
-                            search:
-                            - barley.maas
-                            - wark.maas
-                            - foobar.maas
                         set-name: eth4
                     eth5:
                         dhcp4: true
                         match:
                             macaddress: 98:bb:9f:2c:e8:8a
-                        nameservers:
-                            addresses:
-                            - 8.8.8.8
-                            - 4.4.4.4
-                            - 8.8.4.4
-                            search:
-                            - barley.maas
-                            - wark.maas
-                            - foobar.maas
                         set-name: eth5
                 bonds:
                     bond0:
@@ -748,6 +685,15 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
                         interfaces:
                         - eth3
                         - eth4
+                        nameservers:
+                            addresses:
+                            - 8.8.8.8
+                            - 4.4.4.4
+                            - 8.8.4.4
+                            search:
+                            - barley.maas
+                            - wark.maas
+                            - foobar.maas
                         parameters:
                             ageing-time: 250
                             forward-delay: 1
@@ -2334,6 +2280,9 @@ class TestNetplanRoundTrip(CiTestCase):
     def testsimple_render_all(self):
         entry = NETWORK_CONFIGS['all']
         files = self._render_and_read(network_config=yaml.load(entry['yaml']))
+        print(entry['expected_netplan'])
+        print('-- expected ^ | v rendered --')
+        print(files['/etc/netplan/50-cloud-init.yaml'])
         self.assertEqual(
             entry['expected_netplan'].splitlines(),
             files['/etc/netplan/50-cloud-init.yaml'].splitlines())