canonical / cloud-init

Official upstream for the cloud-init: cloud instance initialization
https://cloud-init.io/
Other
2.85k stars 855 forks source link

bionic: DNS search domains lost from cloud-init to netplan #3189

Open ubuntu-server-builder opened 1 year ago

ubuntu-server-builder commented 1 year ago

This bug was originally filed in Launchpad as LP: #1774540

Launchpad details
affected_projects = []
assignee = None
assignee_name = None
date_closed = None
date_created = 2018-06-01T00:30:23.851349+00:00
date_fix_committed = None
date_fix_released = None
id = 1774540
importance = medium
is_complete = False
lp_url = https://bugs.launchpad.net/cloud-init/+bug/1774540
milestone = None
owner = fo0bar
owner_name = Ryan Finnie
private = False
status = confirmed
submitter = fo0bar
submitter_name = Ryan Finnie
tags = []
duplicates = []

Launchpad user Ryan Finnie(fo0bar) wrote on 2018-06-01T00:30:23.851349+00:00

On a deployed node with a MAAS datasource, /etc/cloud/cloud.cfg.d/50-curtin-networking.cfg contains:

network:   config:   - id: enp1s0     mac_address: 52:54:00:9a:b4:64     mtu: 1500     name: enp1s0     subnets:     - address: 10.48.7.48/21       dns_nameservers:       - 10.48.0.5       gateway: 10.48.0.1       type: static     type: physical   - address:     - 10.48.0.5     search:     - bos01.canonistack.internal     type: nameserver   version: 1

But the generated /etc/netplan/50-cloud-init.yaml contains no search domains under nameservers for the interface:

This file is generated from information provided by

the datasource. Changes to it will not persist across an instance.

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:         enp1s0:             addresses:             - 10.48.7.48/21             gateway4: 10.48.0.1             match:                 macaddress: 52:54:00:9a:b4:64             mtu: 1500             nameservers:                 addresses:                 - 10.48.0.5             set-name: enp1s0

Related bugs:

ubuntu-server-builder commented 1 year ago

Launchpad user Scott Moser(smoser) wrote on 2018-07-13T16:34:50.575083+00:00

This is related to bug 1750884. In netplan/systemd-networkd there is no such thing as "global" dns. The decision was made that although users configured dns globally for the vast majority of the last 30 years, we were not going to support that behavior any more in netplan or systemd-networkd.

Under that bug, though, cloud-init worked around by copying the 'nameserver' settings from the global section to each interface.

Curiously, though, we did not copy the search entries.

I am not sure why.

ubuntu-server-builder commented 1 year ago

Launchpad user Ryan Harper(raharper) wrote on 2018-07-16T14:37:29.872561+00:00

The searchpath is copied. In netplan , the config namespace is:

nameservers:

The relevant code in cloudinit/net/netplan.py:

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})

Note the nscfg contains both the nameservers and the searchdomains.

ubuntu-server-builder commented 1 year ago

Launchpad user Scott Moser(smoser) wrote on 2018-07-16T16:09:10.049710+00:00

@Ryan,

I marked this confirmed because the issue reproduces with current master and 'net-convert.py'. I think the issue here is that the subnet had dns_nameservers. but 'search' was only declared at the global level.

The patch http://paste.ubuntu.com/p/k3hjFPv5qD/ will fix this issue.

$ cat my.cfg network: config:

$ PYTHONPATH=$PWD ./tools/net-convert.py --network-data=my.cfg --kind=yaml -d out.d --output-kind=netplan

$ cat out.d/etc/netplan/50-cloud-init.yaml

network: version: 2 ethernets: enp1s0: addresses:

holmanb commented 3 months ago

It looks like the attached patch fixes the issue but was never merged. I've cleaned up the patch, and I see this output which appears to correct the issue:

network:
  config:
  - id: enp1s0
    mac_address: 52:54:00:9a:b4:64
    mtu: 1500
    name: enp1s0
    subnets:
    - address: 10.48.7.48/21
      dns_nameservers:
      - 10.48.0.5
      gateway: 10.48.0.1
      type: static
    type: physical
  - address:
    - 10.48.0.5
    search:
    - bos01.canonistack.internal
    type: nameserver
  version: 1

the patch:

diff --git a/cloudinit/net/netplan.py b/cloudinit/net/netplan.py
index 43dce4477..620cfd77b 100644
--- a/cloudinit/net/netplan.py
+++ b/cloudinit/net/netplan.py
@@ -535,9 +535,14 @@ class Renderer(renderer.Renderer):
             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:
+                    if "addresses" not in cfg:
                         continue
-                    cfg.update({"nameservers": nscfg})
+                    if "nameservers" not in cfg:
+                        cfg["nameservers"] = nscfg.copy()
+                    else:
+                        for k, v in nscfg.items():
+                            if not cfg["nameservers"].get(k):
+                                cfg["nameservers"][k] = v

         # workaround yaml dictionary key sorting when dumping
         def _render_section(name, section):
holmanb commented 3 months ago

Setting this to new to re-triage since we have a bug and an attached fix.