Merge ~petermakowski/maas:backport-fix_allow_dns=false into maas:3.4

Proposed by Peter Makowski
Status: Merged
Approved by: Peter Makowski
Approved revision: 580365817ea2cfb9deb165e7c8fcbbd8e23b7a6d
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~petermakowski/maas:backport-fix_allow_dns=false
Merge into: maas:3.4
Diff against target: 362 lines (+189/-23)
2 files modified
src/maasserver/preseed_network.py (+18/-7)
src/maasserver/tests/test_preseed_network.py (+171/-16)
Reviewer Review Type Date Requested Status
MAAS Lander Approve
Christian Grabowski Approve
Review via email: mp+461447@code.launchpad.net

Commit message

fix: allow_dns=False disables MAAS DNS on an interface

(cherry picked from commit 6dad6b120b31e61f386a574c1776d52d852d33f0)

To post a comment you must log in.
Revision history for this message
Christian Grabowski (cgrabowski) wrote :

+1

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b backport-fix_allow_dns=false lp:~petermakowski/maas/+git/maas into -b 3.4 lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas-tester/4750/console
COMMIT: 2b55ff05b1ace2547052d6170754ed97a82b6ece

review: Needs Fixing
Revision history for this message
Alexsander de Souza (alexsander-souza) wrote :

jenkins: !test

Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b backport-fix_allow_dns=false lp:~petermakowski/maas/+git/maas into -b 3.4 lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 580365817ea2cfb9deb165e7c8fcbbd8e23b7a6d

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/preseed_network.py b/src/maasserver/preseed_network.py
2index c1e516c..1203e6b 100644
3--- a/src/maasserver/preseed_network.py
4+++ b/src/maasserver/preseed_network.py
5@@ -362,18 +362,19 @@ class InterfaceConfiguration:
6
7 if "dns_nameservers" not in v1_subnet_operation:
8 v1_subnet_operation["dns_nameservers"] = []
9+ if "nameservers" not in v2_config:
10+ v2_config["nameservers"] = v2_nameservers
11+ if "addresses" not in v2_nameservers:
12+ v2_nameservers["addresses"] = []
13+
14+ if subnet.allow_dns:
15 v1_subnet_operation[
16 "dns_search"
17 ] = self.node_config.default_search_list
18- if "nameservers" not in v2_config:
19 v2_nameservers[
20 "search"
21 ] = self.node_config.default_search_list
22- v2_config["nameservers"] = v2_nameservers
23- if "addresses" not in v2_nameservers:
24- v2_nameservers["addresses"] = []
25
26- if subnet.allow_dns:
27 for ip in StaticIPAddress.objects.filter(
28 interface__node_config__node__in=[
29 subnet.vlan.primary_rack,
30@@ -416,7 +417,8 @@ class InterfaceConfiguration:
31 # Delete if no DNS servers were added.
32 if len(v1_subnet_operation["dns_nameservers"]) == 0:
33 del v1_subnet_operation["dns_nameservers"]
34- del v1_subnet_operation["dns_search"]
35+ if "dns_search" in v1_subnet_operation:
36+ del v1_subnet_operation["dns_search"]
37 if len(v2_nameservers["addresses"]) == 0:
38 del v2_config["nameservers"]
39 if dhcp_type:
40@@ -751,7 +753,16 @@ class NodeNetworkConfiguration:
41 if "addresses" not in config:
42 # Skip interfaces with no manual addresses.
43 continue
44- config.update({"nameservers": v2_default_nameservers})
45+
46+ v2_nameservers = v2_default_nameservers.copy()
47+ iface = Interface.objects.get(
48+ node_config__node=self.node, name=ifname
49+ )
50+ for address in iface.ip_addresses.all():
51+ if not address.subnet.allow_dns:
52+ return
53+
54+ config.update({"nameservers": v2_nameservers})
55
56
57 def compose_curtin_network_config(node, version=1, source_routing=False):
58diff --git a/src/maasserver/tests/test_preseed_network.py b/src/maasserver/tests/test_preseed_network.py
59index 4c64b12..7e97a05 100644
60--- a/src/maasserver/tests/test_preseed_network.py
61+++ b/src/maasserver/tests/test_preseed_network.py
62@@ -27,7 +27,7 @@ from maasserver.enum import (
63 IPADDRESS_TYPE,
64 NODE_STATUS,
65 )
66-from maasserver.models import Domain
67+from maasserver.models import Domain, Node
68 from maasserver.preseed_network import (
69 compose_curtin_network_config,
70 NodeNetworkConfiguration,
71@@ -1611,8 +1611,8 @@ class TestNetplan(MAASServerTestCase):
72 },
73 {
74 "address": ["127.0.0.2"],
75- "search": expected_search_list,
76 "type": "nameserver",
77+ "search": expected_search_list,
78 },
79 ],
80 }
81@@ -1734,34 +1734,169 @@ class TestNetplan(MAASServerTestCase):
82 "address": [
83 "10.0.1.2"
84 ], # assert default gateway assigns dns server
85- "search": expected_search_list,
86 "type": "nameserver",
87+ "search": expected_search_list,
88 },
89 ],
90 }
91 }
92 self.assertEqual(v1, expected_v1)
93
94+ def test_one_ethernet_interface_without_dns(self):
95+ node = factory.make_Node()
96+ rack = factory.make_RackController()
97+ vlan = factory.make_VLAN(primary_rack=rack)
98+ subnet = factory.make_Subnet(
99+ cidr="10.0.0.0/24",
100+ gateway_ip="10.0.0.1",
101+ dns_servers=[],
102+ vlan=vlan,
103+ )
104+ subnet2 = factory.make_Subnet(
105+ cidr="10.0.1.0/24",
106+ gateway_ip="10.0.1.1",
107+ dns_servers=[],
108+ allow_dns=False,
109+ vlan=vlan,
110+ )
111+ eth0 = factory.make_Interface(
112+ node=node,
113+ name="eth0",
114+ mac_address="00:01:02:03:04:05",
115+ vlan=subnet.vlan,
116+ enabled=True,
117+ )
118+ eth1 = factory.make_Interface(
119+ node=node,
120+ name="eth1",
121+ mac_address="02:01:02:03:04:05",
122+ vlan=subnet2.vlan,
123+ enabled=True,
124+ )
125+ node.boot_interface = eth0
126+ node.save()
127+ factory.make_StaticIPAddress(
128+ interface=eth0,
129+ subnet=subnet,
130+ ip="10.0.0.4",
131+ alloc_type=IPADDRESS_TYPE.AUTO,
132+ )
133+ factory.make_StaticIPAddress(
134+ interface=eth1,
135+ subnet=subnet2,
136+ ip="10.0.1.4",
137+ alloc_type=IPADDRESS_TYPE.AUTO,
138+ )
139+ # Make sure we know when and where the default DNS server will be used.
140+ get_default_dns_servers_mock = self.patch(
141+ node, "get_default_dns_servers"
142+ )
143+ get_default_dns_servers_mock.return_value = ["10.0.0.1"]
144+ netplan = self._render_netplan_dict(node)
145+ expected_netplan = {
146+ "network": OrderedDict(
147+ [
148+ ("version", 2),
149+ (
150+ "ethernets",
151+ {
152+ "eth0": {
153+ "match": {"macaddress": "00:01:02:03:04:05"},
154+ "mtu": 1500,
155+ "set-name": "eth0",
156+ "addresses": ["10.0.0.4/24"],
157+ "gateway4": "10.0.0.1",
158+ "nameservers": {
159+ "addresses": [
160+ ip.ip
161+ for iface in rack.current_config.interface_set.all()
162+ for ip in iface.ip_addresses.all()
163+ ],
164+ "search": [
165+ domain.name
166+ for domain in Domain.objects.filter(
167+ authoritative=True
168+ )
169+ ],
170+ },
171+ },
172+ "eth1": {
173+ "match": {"macaddress": "02:01:02:03:04:05"},
174+ "mtu": 1500,
175+ "set-name": "eth1",
176+ "addresses": ["10.0.1.4/24"],
177+ },
178+ },
179+ ),
180+ ]
181+ )
182+ }
183+ self.assertCountEqual(netplan, expected_netplan)
184+ self.assertCountEqual(
185+ netplan["network"]["ethernets"]["eth0"],
186+ expected_netplan["network"]["ethernets"]["eth0"],
187+ )
188+ self.assertCountEqual(
189+ netplan["network"]["ethernets"]["eth1"],
190+ expected_netplan["network"]["ethernets"]["eth1"],
191+ )
192+ v1 = self._render_v1_dict(node)
193+ expected_v1 = {
194+ "network": {
195+ "version": 1,
196+ "config": [
197+ {
198+ "id": "eth0",
199+ "mac_address": "00:01:02:03:04:05",
200+ "mtu": 1500,
201+ "name": "eth0",
202+ "subnets": [{"type": "dhcp4"}],
203+ "type": "physical",
204+ },
205+ {
206+ "id": "eth1",
207+ "mac_address": "02:01:02:03:04:05",
208+ "mtu": 1500,
209+ "name": "eth1",
210+ "subnets": [{"type": "dhcp4"}],
211+ "type": "physical",
212+ },
213+ ],
214+ }
215+ }
216+ self.assertCountEqual(v1, expected_v1)
217+
218 def test_multiple_ethernet_interfaces_without_dns(self):
219 node = factory.make_Node()
220- vlan = factory.make_VLAN()
221+ rack = factory.make_RackController()
222+ vlan = factory.make_VLAN(primary_rack=rack)
223 subnet = factory.make_Subnet(
224 cidr="10.0.0.0/24",
225 gateway_ip="10.0.0.1",
226- dns_servers=["10.0.0.2"],
227+ dns_servers=[],
228 allow_dns=False,
229+ vlan=vlan,
230 )
231 subnet2 = factory.make_Subnet(
232 cidr="10.0.1.0/24",
233 gateway_ip="10.0.1.1",
234- dns_servers=["10.0.1.2"],
235+ dns_servers=[],
236 allow_dns=False,
237+ vlan=vlan,
238 )
239 eth0 = factory.make_Interface(
240- node=node, name="eth0", mac_address="00:01:02:03:04:05", vlan=vlan
241+ node=node,
242+ name="eth0",
243+ mac_address="00:01:02:03:04:05",
244+ vlan=subnet.vlan,
245+ enabled=True,
246 )
247 eth1 = factory.make_Interface(
248- node=node, name="eth1", mac_address="02:01:02:03:04:05"
249+ node=node,
250+ name="eth1",
251+ mac_address="02:01:02:03:04:05",
252+ vlan=subnet2.vlan,
253+ enabled=True,
254 )
255 node.boot_interface = eth0
256 node.save()
257@@ -1769,19 +1904,19 @@ class TestNetplan(MAASServerTestCase):
258 interface=eth0,
259 subnet=subnet,
260 ip="10.0.0.4",
261- alloc_type=IPADDRESS_TYPE.DHCP,
262+ alloc_type=IPADDRESS_TYPE.AUTO,
263 )
264 factory.make_StaticIPAddress(
265 interface=eth1,
266 subnet=subnet2,
267 ip="10.0.1.4",
268- alloc_type=IPADDRESS_TYPE.DHCP,
269+ alloc_type=IPADDRESS_TYPE.AUTO,
270 )
271 # Make sure we know when and where the default DNS server will be used.
272 get_default_dns_servers_mock = self.patch(
273 node, "get_default_dns_servers"
274 )
275- get_default_dns_servers_mock.return_value = []
276+ get_default_dns_servers_mock.return_value = ["10.0.0.1"]
277 netplan = self._render_netplan_dict(node)
278 expected_netplan = {
279 "network": OrderedDict(
280@@ -1794,20 +1929,29 @@ class TestNetplan(MAASServerTestCase):
281 "match": {"macaddress": "00:01:02:03:04:05"},
282 "mtu": 1500,
283 "set-name": "eth0",
284- "dhcp4": True,
285+ "addresses": ["10.0.0.4/24"],
286+ "gateway4": "10.0.0.1",
287 },
288 "eth1": {
289 "match": {"macaddress": "02:01:02:03:04:05"},
290 "mtu": 1500,
291 "set-name": "eth1",
292- "dhcp4": True,
293+ "addresses": ["10.0.1.4/24"],
294 },
295 },
296 ),
297 ]
298 )
299 }
300- self.expectThat(netplan, Equals(expected_netplan))
301+ self.assertCountEqual(netplan, expected_netplan)
302+ self.assertCountEqual(
303+ netplan["network"]["ethernets"]["eth0"],
304+ expected_netplan["network"]["ethernets"]["eth0"],
305+ )
306+ self.assertCountEqual(
307+ netplan["network"]["ethernets"]["eth1"],
308+ expected_netplan["network"]["ethernets"]["eth1"],
309+ )
310 v1 = self._render_v1_dict(node)
311 expected_v1 = {
312 "network": {
313@@ -1832,7 +1976,7 @@ class TestNetplan(MAASServerTestCase):
314 ],
315 }
316 }
317- self.expectThat(v1, Equals(expected_v1))
318+ self.assertCountEqual(v1, expected_v1)
319
320 def test_ha__default_dns(self):
321 node = factory.make_Node()
322@@ -1904,6 +2048,7 @@ class TestNetplan(MAASServerTestCase):
323
324 def test_dns_includes_rack_controllers(self):
325 # Regression test for LP:1881133
326+
327 vlan = factory.make_VLAN()
328 subnet = factory.make_Subnet(dns_servers=[], vlan=vlan)
329 rack = factory.make_RackController(subnet=subnet)
330@@ -1911,6 +2056,11 @@ class TestNetplan(MAASServerTestCase):
331 rack_ip = factory.make_StaticIPAddress(
332 subnet=subnet, interface=rack_iface
333 )
334+
335+ # this will normally try to resolve localhost against the system,
336+ # this is a problem if the host has IPv6 but no localhost entry for v6
337+ self.patch(Node, "get_default_dns_servers").return_value = [rack_ip.ip]
338+
339 vlan.primary_rack = rack
340 vlan.save()
341 node = factory.make_Node_with_Interface_on_Subnet(
342@@ -1943,7 +2093,7 @@ class TestNetplan(MAASServerTestCase):
343 factory.make_StaticIPAddress(subnet=subnet, interface=iface)
344 v2 = self._render_netplan_dict(node)
345 self.assertDictEqual(
346- {"search": ["maas"], "addresses": [nameserver]},
347+ {"addresses": [nameserver]},
348 v2["network"]["ethernets"][iface.name]["nameservers"],
349 )
350
351@@ -1976,6 +2126,11 @@ class TestNetplan(MAASServerTestCase):
352 def test_commissioning_dhcp_config(self):
353 # Verifies dhcp config is given when commissioning has run
354 # or just run and no AUTOIP has been acquired.
355+
356+ # this will normally try to resolve localhost against the system,
357+ # this is a problem if the host has IPv6 but no localhost entry for v6
358+ self.patch(Node, "get_default_dns_servers").return_value = ["10.0.0.1"]
359+
360 subnet = factory.make_Subnet(dns_servers=[])
361 subnet_ver = subnet.get_ipnetwork().version
362 node = factory.make_Node_with_Interface_on_Subnet(

Subscribers

People subscribed via source and target branches