352 lines
11 KiB
Diff
352 lines
11 KiB
Diff
|
From 6b32b371bfd37759ddce3d7f29d15546500698e6 Mon Sep 17 00:00:00 2001
|
||
|
From: Ani Sinha <anisinha@redhat.com>
|
||
|
Date: Thu, 20 Jun 2024 22:27:03 +0530
|
||
|
Subject: [PATCH 1/6] feat(sysconfig): Add DNS from interface config to
|
||
|
resolv.conf (#5401)
|
||
|
|
||
|
RH-Author: Ani Sinha <anisinha@redhat.com>
|
||
|
RH-MergeRequest: 88: feat(sysconfig): Add DNS from interface config to resolv.conf (#5401)
|
||
|
RH-Jira: RHEL-17961
|
||
|
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||
|
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||
|
RH-Commit: [1/1] f353b73cc0f4bb9e1aee037708a1d3cb23b83cc3 (anisinha/cloud-init)
|
||
|
|
||
|
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>
|
||
|
(cherry picked from commit 1b8030e0c7fd6fbff7e38ad1e3e6266ae50c83a5)
|
||
|
---
|
||
|
cloudinit/net/sysconfig.py | 52 +++++++++-
|
||
|
tests/unittests/test_net.py | 184 +++++++++++++++++++++++++++++++++++-
|
||
|
2 files changed, 230 insertions(+), 6 deletions(-)
|
||
|
|
||
|
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||
|
index d39f4fe3..7eb430ed 100644
|
||
|
--- a/cloudinit/net/sysconfig.py
|
||
|
+++ b/cloudinit/net/sysconfig.py
|
||
|
@@ -825,20 +825,62 @@ class Renderer(renderer.Renderer):
|
||
|
|
||
|
@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
|
||
|
content = resolv_conf.ResolvConf("")
|
||
|
if existing_dns_path and os.path.isfile(existing_dns_path):
|
||
|
content = resolv_conf.ResolvConf(util.load_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)
|
||
|
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
||
|
index d7c9a414..2d716f4b 100644
|
||
|
--- a/tests/unittests/test_net.py
|
||
|
+++ b/tests/unittests/test_net.py
|
||
|
@@ -516,6 +516,8 @@ OS_SAMPLES = [
|
||
|
}
|
||
|
],
|
||
|
"ip_address": "172.19.1.34",
|
||
|
+ "dns_search": ["testweb.com"],
|
||
|
+ "dns_nameservers": ["172.19.0.13"],
|
||
|
"id": "network0",
|
||
|
}
|
||
|
],
|
||
|
@@ -550,7 +552,9 @@ STARTMODE=auto
|
||
|
"""
|
||
|
; Created by cloud-init automatically, do not edit.
|
||
|
;
|
||
|
+nameserver 172.19.0.13
|
||
|
nameserver 172.19.0.12
|
||
|
+search testweb.com
|
||
|
""".lstrip(),
|
||
|
),
|
||
|
(
|
||
|
@@ -582,6 +586,8 @@ AUTOCONNECT_PRIORITY=120
|
||
|
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
|
||
|
@@ -596,7 +602,174 @@ USERCTL=no
|
||
|
"""
|
||
|
; 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.
|
||
|
+#
|
||
|
+AUTOCONNECT_PRIORITY=120
|
||
|
+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(),
|
||
|
),
|
||
|
(
|
||
|
@@ -647,6 +820,7 @@ 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(),
|
||
|
),
|
||
|
@@ -654,7 +828,13 @@ dns=172.19.0.12;
|
||
|
},
|
||
|
{
|
||
|
"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",
|
||
|
@@ -715,6 +895,7 @@ STARTMODE=auto
|
||
|
; Created by cloud-init automatically, do not edit.
|
||
|
;
|
||
|
nameserver 172.19.0.12
|
||
|
+search example.com
|
||
|
""".lstrip(),
|
||
|
),
|
||
|
(
|
||
|
@@ -763,6 +944,7 @@ USERCTL=no
|
||
|
; Created by cloud-init automatically, do not edit.
|
||
|
;
|
||
|
nameserver 172.19.0.12
|
||
|
+search example.com
|
||
|
""".lstrip(),
|
||
|
),
|
||
|
(
|
||
|
--
|
||
|
2.39.3
|
||
|
|