Skip to content

Commit

Permalink
net/renderer/sysconfig: also use dns information from interface config
Browse files Browse the repository at this point in the history
sysconfig renderer currently only uses global dns and search domain
configuration in order to populate /etc/resolv.conf. This means it ignores
interface specific dns configuration completely. This means, when global dns
information is absent and only interface specific dns configuration is present,
/etc/resolv.conf will not have complete dns information. Fix this so that
per interface dns information is also taken into account along with global dns
configuration in order to populate /etc/resolv.conf.

Fixes: GH-5400
Signed-off-by: Ani Sinha <anisinha@redhat.com>
  • Loading branch information
ani-sinha committed Jun 14, 2024
1 parent a01b8d3 commit 7987b85
Show file tree
Hide file tree
Showing 2 changed files with 229 additions and 6 deletions.
52 changes: 47 additions & 5 deletions cloudinit/net/sysconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -824,11 +824,53 @@ def _render_vlan_interfaces(cls, network_state, iface_contents, flavor):

@staticmethod
def _render_dns(network_state, existing_dns_path=None):
# skip writing resolv.conf if network_state doesn't include any input.

found_nameservers = []
found_dns_search = []

for iface in network_state.iter_interfaces():
for subnet in iface["subnets"]:
# Add subnet-level DNS
if "dns_nameservers" in subnet:
found_nameservers.extend(subnet["dns_nameservers"])
if "dns_search" in subnet:
found_dns_search.extend(subnet["dns_search"])

# Add interface-level DNS
if "dns" in iface:
found_nameservers += [
dns
for dns in iface["dns"]["nameservers"]
if dns not in found_nameservers
]
found_dns_search += [
search
for search in iface["dns"]["search"]
if search not in found_dns_search
]

# When both global and interface specific entries are present,
# use them both to generate /etc/resolv.conf eliminating duplicate
# entries. Otherwise use global or interface specific entries whichever
# is provided.
if network_state.dns_nameservers:
found_nameservers += [
nameserver
for nameserver in network_state.dns_nameservers
if nameserver not in found_nameservers
]
if network_state.dns_searchdomains:
found_dns_search += [
search
for search in network_state.dns_searchdomains
if search not in found_dns_search
]

# skip writing resolv.conf if no dns information is provided in conf.
if not any(
[
len(network_state.dns_nameservers),
len(network_state.dns_searchdomains),
len(found_nameservers),
len(found_dns_search),
]
):
return None
Expand All @@ -837,9 +879,9 @@ def _render_dns(network_state, existing_dns_path=None):
content = resolv_conf.ResolvConf(
util.load_text_file(existing_dns_path)
)
for nameserver in network_state.dns_nameservers:
for nameserver in found_nameservers:
content.add_nameserver(nameserver)
for searchdomain in network_state.dns_searchdomains:
for searchdomain in found_dns_search:
content.add_search_domain(searchdomain)
header = _make_header(";")
content_str = str(content)
Expand Down
183 changes: 182 additions & 1 deletion tests/unittests/test_net.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,8 @@
}
],
"ip_address": "172.19.1.34",
"dns_search": ["testweb.com"],
"dns_nameservers": ["172.19.0.13"],
"id": "network0",
}
],
Expand Down Expand Up @@ -549,7 +551,9 @@
"""
; Created by cloud-init automatically, do not edit.
;
nameserver 172.19.0.13
nameserver 172.19.0.12
search testweb.com
""".lstrip(),
),
(
Expand Down Expand Up @@ -580,6 +584,8 @@
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
DNS1=172.19.0.13
DOMAIN=testweb.com
GATEWAY=172.19.3.254
HWADDR=fa:16:3e:ed:9a:59
IPADDR=172.19.1.34
Expand All @@ -594,7 +600,173 @@
"""
; Created by cloud-init automatically, do not edit.
;
nameserver 172.19.0.13
nameserver 172.19.0.12
search testweb.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.13;
dns-search=testweb.com;
""".lstrip(),
),
],
},
{
"in_data": {
"services": [
{
"type": "dns",
"address": "172.19.0.12",
"search": ["example1.com", "example2.com"],
}
],
"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 example1.com example2.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 example1.com example2.com
""".lstrip(),
),
(
Expand Down Expand Up @@ -645,14 +817,21 @@
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"}],
"services": [
{
"type": "dns",
"address": "172.19.0.12",
"search": "example.com",
}
],
"networks": [
{
"network_id": "public-ipv4",
Expand Down Expand Up @@ -713,6 +892,7 @@
; Created by cloud-init automatically, do not edit.
;
nameserver 172.19.0.12
search example.com
""".lstrip(),
),
(
Expand Down Expand Up @@ -760,6 +940,7 @@
; Created by cloud-init automatically, do not edit.
;
nameserver 172.19.0.12
search example.com
""".lstrip(),
),
(
Expand Down

0 comments on commit 7987b85

Please sign in to comment.