Skip to content

Commit

Permalink
Prevent NM from handling DNS when only network interfaces have DNS co…
Browse files Browse the repository at this point in the history
…nfig

In the change under PR #5401, if no global DNS configuration is present and only
network interfaces have DNS and search domain configuration, we add DNS and
search domain information from interface config and use it to populate
/etc/resolv.conf. Therefore, in the absence of global DNS/search domain config
and presence of only per-interface DNS/search domain information, we should add
a network manager configuration to prevent network manager from manipulating
/etc/resolv.conf.
This is in addition to what we already do when a global DNS data is configured.

Fixes: 1b8030e ("feat(sysconfig): Add DNS from interface config to resolv.conf (#5401))
Signed-off-by: Ani Sinha <[email protected]>
  • Loading branch information
ani-sinha committed Oct 28, 2024
1 parent 4b56c5c commit a76cf20
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 5 deletions.
28 changes: 23 additions & 5 deletions cloudinit/net/sysconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -906,17 +906,35 @@ def _render_dns(network_state, existing_dns_path=None):

@staticmethod
def _render_networkmanager_conf(network_state, templates=None):
iface_dns = False
content = networkmanager_conf.NetworkManagerConf("")

# If DNS server information is provided, configure
# NetworkManager to not manage dns, so that /etc/resolv.conf
# does not get clobbered.
# check if there is interface specific DNS information configured
for iface in network_state.iter_interfaces():
for subnet in iface["subnets"]:
if "dns_nameservers" in subnet or "dns_search" in subnet:
iface_dns = True
break
if (
not iface_dns
and "dns" in iface
and (iface["dns"]["nameservers"] or iface["dns"]["search"])
):
iface_dns = True
break

# If DNS server and/or dns search information is provided either
# globally or per interface basis, configure NetworkManager to
# not manage dns, so that /etc/resolv.conf does not get clobbered.
# This is not required for NetworkManager renderer as it
# does not write /etc/resolv.conf directly. DNS information is
# written to the interface keyfile and NetworkManager is then
# responsible for using the DNS information from the keyfile,
# including managing /etc/resolv.conf.
if network_state.dns_nameservers:
if (
network_state.dns_nameservers
or network_state.dns_searchdomains
or iface_dns
):
content.set_section_keypair("main", "dns", "none")

if len(content) == 0:
Expand Down
157 changes: 157 additions & 0 deletions tests/unittests/test_net.py
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,163 @@
),
],
},
{
"in_data": {
"networks": [
{
"network_id": "dacd568d-5be6-4786-91fe-750c374b78b4",
"type": "ipv4",
"netmask": "255.255.252.0",
"link": "eth0",
"routes": [
{
"netmask": "0.0.0.0",
"network": "0.0.0.0",
"gateway": "172.19.3.254",
}
],
"ip_address": "172.19.1.34",
"dns_search": ["example3.com"],
"dns_nameservers": ["172.19.0.12"],
"id": "network0",
}
],
"links": [
{
"ethernet_mac_address": "fa:16:3e:ed:9a:59",
"mtu": None,
"type": "physical",
"id": "eth0",
},
],
},
"in_macs": {
"fa:16:3e:ed:9a:59": "eth0",
},
"out_sysconfig_opensuse": [
(
"etc/sysconfig/network/ifcfg-eth0",
"""
# Created by cloud-init automatically, do not edit.
#
BOOTPROTO=static
IPADDR=172.19.1.34
LLADDR=fa:16:3e:ed:9a:59
NETMASK=255.255.252.0
STARTMODE=auto
""".lstrip(),
),
(
"etc/resolv.conf",
"""
; Created by cloud-init automatically, do not edit.
;
nameserver 172.19.0.12
search example3.com
""".lstrip(),
),
(
"etc/NetworkManager/conf.d/99-cloud-init.conf",
"""
# Created by cloud-init automatically, do not edit.
#
[main]
dns = none
""".lstrip(),
),
(
"etc/udev/rules.d/85-persistent-net-cloud-init.rules",
"".join(
[
'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
]
),
),
],
"out_sysconfig_rhel": [
(
"etc/sysconfig/network-scripts/ifcfg-eth0",
"""
# Created by cloud-init automatically, do not edit.
#
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
DNS1=172.19.0.12
DOMAIN=example3.com
GATEWAY=172.19.3.254
HWADDR=fa:16:3e:ed:9a:59
IPADDR=172.19.1.34
NETMASK=255.255.252.0
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
""".lstrip(),
),
(
"etc/resolv.conf",
"""
; Created by cloud-init automatically, do not edit.
;
nameserver 172.19.0.12
search example3.com
""".lstrip(),
),
(
"etc/NetworkManager/conf.d/99-cloud-init.conf",
"""
# Created by cloud-init automatically, do not edit.
#
[main]
dns = none
""".lstrip(),
),
(
"etc/udev/rules.d/70-persistent-net.rules",
"".join(
[
'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
]
),
),
],
"expected_network_manager": [
(
"".join(
[
"etc/NetworkManager/system-connections",
"/cloud-init-eth0.nmconnection",
]
),
"""
# Generated by cloud-init. Changes will be lost.
[connection]
id=cloud-init eth0
uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
autoconnect-priority=120
type=ethernet
[user]
org.freedesktop.NetworkManager.origin=cloud-init
[ethernet]
mac-address=FA:16:3E:ED:9A:59
[ipv4]
method=manual
may-fail=false
address1=172.19.1.34/22
route1=0.0.0.0/0,172.19.3.254
dns=172.19.0.12;
dns-search=example3.com;
""".lstrip(),
),
],
},
{
"in_data": {
"services": [{"type": "dns", "address": "172.19.0.12"}],
Expand Down

0 comments on commit a76cf20

Please sign in to comment.