208 lines
8.2 KiB
Diff
208 lines
8.2 KiB
Diff
From c21351ad9da5aebcb252aa36cbfa92ac16fa9746 Mon Sep 17 00:00:00 2001
|
|
From: Florian Apolloner <florian@apolloner.eu>
|
|
Date: Fri, 5 Jan 2024 19:07:12 +0100
|
|
Subject: [PATCH 2/3] feat: apply global DNS to interfaces in network-manager
|
|
(#4723)
|
|
|
|
RH-Author: Cathy Avery <cavery@redhat.com>
|
|
RH-MergeRequest: 72: Fixes for cloud-init fails to configure DNS/search domains for network-config v1
|
|
RH-Jira: RHEL-20964
|
|
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
RH-Commit: [2/2] 1d2b10133ec2558e9665f21f53e4b1a898e283a8 (cavery/cloud-init-c-9-s)
|
|
|
|
Sometimes DNS settings in cloud configs are specified globally and
|
|
not per interface / subnet. This results in a configuration without
|
|
proper nameservers. This was fixed for netplan in d29eeccd and is
|
|
now also applied to the network-manager renderer.
|
|
|
|
Co-authored-by: James Falcon <james.falcon@canonical.com>
|
|
(cherry picked from commit 0d787d0a262f70ff848b315633742aa8fc45a1de)
|
|
Signed-off-by: Cathy Avery <cavery@redhat.com>
|
|
---
|
|
cloudinit/net/network_manager.py | 52 ++++++++++++++---------
|
|
tests/unittests/net/test_net_rendering.py | 3 ++
|
|
tests/unittests/test_net.py | 11 +++++
|
|
tools/.github-cla-signers | 1 +
|
|
4 files changed, 47 insertions(+), 20 deletions(-)
|
|
|
|
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
|
|
index bd6e6d75..0ba210b7 100644
|
|
--- a/cloudinit/net/network_manager.py
|
|
+++ b/cloudinit/net/network_manager.py
|
|
@@ -246,7 +246,7 @@ class NMConnection:
|
|
"""
|
|
return addr.replace("-", ":").upper()
|
|
|
|
- def render_interface(self, iface, renderer):
|
|
+ def render_interface(self, iface, network_state, renderer):
|
|
"""
|
|
Integrate information from network state interface information
|
|
into the connection. Most of the work is done here.
|
|
@@ -311,7 +311,6 @@ class NMConnection:
|
|
found_dns_search = []
|
|
|
|
# Deal with Layer 3 configuration
|
|
- use_top_level_dns = "dns" in iface
|
|
for subnet in iface["subnets"]:
|
|
family = "ipv6" if subnet_is_ipv6(subnet) else "ipv4"
|
|
|
|
@@ -322,26 +321,39 @@ class NMConnection:
|
|
self.config[family]["gateway"] = subnet["gateway"]
|
|
for route in subnet["routes"]:
|
|
self._add_route(route)
|
|
- if not use_top_level_dns and "dns_nameservers" in subnet:
|
|
- for nameserver in subnet["dns_nameservers"]:
|
|
- found_nameservers.append(nameserver)
|
|
- if not use_top_level_dns and "dns_search" in subnet:
|
|
- found_dns_search.append(subnet["dns_search"])
|
|
+ # 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"])
|
|
if family == "ipv4" and "mtu" in subnet:
|
|
ipv4_mtu = subnet["mtu"]
|
|
|
|
- # Now add our DNS search domains. We add them later because we
|
|
- # only want them if an IP family has already been defined
|
|
- if use_top_level_dns:
|
|
- for nameserver in iface["dns"]["nameservers"]:
|
|
- self._add_nameserver(nameserver)
|
|
- if iface["dns"]["search"]:
|
|
- self._add_dns_search(iface["dns"]["search"])
|
|
- else:
|
|
- for nameserver in found_nameservers:
|
|
- self._add_nameserver(nameserver)
|
|
- for dns_search in found_dns_search:
|
|
- self._add_dns_search(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
|
|
+ ]
|
|
+
|
|
+ # We prefer any interface-specific DNS entries, but if we do not
|
|
+ # have any, add the global DNS to the connection
|
|
+ if not found_nameservers and network_state.dns_nameservers:
|
|
+ found_nameservers = network_state.dns_nameservers
|
|
+ if not found_dns_search and network_state.dns_searchdomains:
|
|
+ found_dns_search = network_state.dns_searchdomains
|
|
+
|
|
+ # Write out all DNS entries to the connection
|
|
+ for nameserver in found_nameservers:
|
|
+ self._add_nameserver(nameserver)
|
|
+ if found_dns_search:
|
|
+ self._add_dns_search(found_dns_search)
|
|
|
|
# we do not want to set may-fail to false for both ipv4 and ipv6 dhcp
|
|
# at the at the same time. This will make the network configuration
|
|
@@ -457,7 +469,7 @@ class Renderer(renderer.Renderer):
|
|
# Now render the actual interface configuration
|
|
for iface in network_state.iter_interfaces():
|
|
conn = self.connections[iface["name"]]
|
|
- conn.render_interface(iface, self)
|
|
+ conn.render_interface(iface, network_state, self)
|
|
|
|
# And finally write the files
|
|
for con_id, conn in self.connections.items():
|
|
diff --git a/tests/unittests/net/test_net_rendering.py b/tests/unittests/net/test_net_rendering.py
|
|
index 06feab89..f340ffc1 100644
|
|
--- a/tests/unittests/net/test_net_rendering.py
|
|
+++ b/tests/unittests/net/test_net_rendering.py
|
|
@@ -88,6 +88,9 @@ def _check_network_manager(network_state: NetworkState, tmp_path: Path):
|
|
"test_name, renderers",
|
|
[("no_matching_mac_v2", Renderer.Netplan | Renderer.NetworkManager)],
|
|
)
|
|
+@pytest.mark.xfail(
|
|
+ reason="v2 interface-specific DNS errantly gets applied globally"
|
|
+)
|
|
def test_convert(test_name, renderers, tmp_path):
|
|
network_config = safeyaml.load(
|
|
Path(ARTIFACT_DIR, f"{test_name}.yaml").read_text()
|
|
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
|
index 2a99f150..d7c9a414 100644
|
|
--- a/tests/unittests/test_net.py
|
|
+++ b/tests/unittests/test_net.py
|
|
@@ -646,6 +646,7 @@ 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;
|
|
|
|
""".lstrip(),
|
|
),
|
|
@@ -2797,6 +2798,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
[ipv4]
|
|
method=auto
|
|
may-fail=false
|
|
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
|
|
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
|
|
"""
|
|
),
|
|
@@ -2822,6 +2825,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
method=manual
|
|
may-fail=false
|
|
address1=192.168.200.7/24
|
|
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
|
|
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
|
|
"""
|
|
),
|
|
@@ -2846,6 +2851,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
[ipv4]
|
|
method=auto
|
|
may-fail=false
|
|
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
|
|
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
|
|
"""
|
|
),
|
|
@@ -2930,12 +2937,15 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
method=manual
|
|
may-fail=false
|
|
address1=192.168.14.2/24
|
|
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
|
|
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
|
|
[ipv6]
|
|
method=manual
|
|
may-fail=false
|
|
address1=2001:1::1/64
|
|
route1=::/0,2001:4800:78ff:1b::1
|
|
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
|
|
"""
|
|
),
|
|
@@ -2990,6 +3000,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
[ipv6]
|
|
method=auto
|
|
may-fail=false
|
|
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
|
|
"""
|
|
),
|
|
diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers
|
|
index dbdb9cfa..f4da0989 100644
|
|
--- a/tools/.github-cla-signers
|
|
+++ b/tools/.github-cla-signers
|
|
@@ -13,6 +13,7 @@ andrewbogott
|
|
andrewlukoshko
|
|
ani-sinha
|
|
antonyc
|
|
+apollo13
|
|
aswinrajamannar
|
|
bdrung
|
|
beantaxi
|
|
--
|
|
2.39.3
|
|
|