Merge ~petermakowski/maas:backport-fix_allow_dns=false into maas:3.4
- Git
- lp:~petermakowski/maas
- backport-fix_allow_dns=false
- Merge into 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) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
MAAS Lander | Approve | ||
Christian Grabowski | Approve | ||
Review via email:
|
Commit message
fix: allow_dns=False disables MAAS DNS on an interface
(cherry picked from commit 6dad6b120b31e61
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b backport-
STATUS: FAILED
LOG: http://
COMMIT: 2b55ff05b1ace25
review:
Needs Fixing
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Alexsander de Souza (alexsander-souza) wrote : | # |
jenkins: !test
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b backport-
STATUS: SUCCESS
COMMIT: 580365817ea2cfb
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/src/maasserver/preseed_network.py b/src/maasserver/preseed_network.py |
2 | index 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): |
58 | diff --git a/src/maasserver/tests/test_preseed_network.py b/src/maasserver/tests/test_preseed_network.py |
59 | index 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( |
+1