Merge lp:~mpontillo/maas/subnet-dns-override-maas-dns-for-default-gw--bug-1576116 into lp:~maas-committers/maas/trunk
- subnet-dns-override-maas-dns-for-default-gw--bug-1576116
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Mike Pontillo |
Approved revision: | no longer in the source branch. |
Merged at revision: | 5178 |
Proposed branch: | lp:~mpontillo/maas/subnet-dns-override-maas-dns-for-default-gw--bug-1576116 |
Merge into: | lp:~maas-committers/maas/trunk |
Diff against target: |
343 lines (+220/-17) 4 files modified
src/maasserver/models/node.py (+60/-5) src/maasserver/models/tests/test_node.py (+155/-0) src/maasserver/preseed_network.py (+3/-6) src/maasserver/tests/test_preseed_network.py (+2/-6) |
To merge this branch: | bzr merge lp:~mpontillo/maas/subnet-dns-override-maas-dns-for-default-gw--bug-1576116 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gavin Panella (community) | Approve | ||
Review via email: mp+299896@code.launchpad.net |
Commit message
When deploying a node, override the MAAS DNS server with the DNS servers specified on the subnet for the default gateway, when specifying DNS servers for the loopback interface.
Description of the change
Mike Pontillo (mpontillo) wrote : | # |
Gavin Panella (allenap) wrote : | # |
Looks good. A few comments but they're all minor.
Mike Pontillo (mpontillo) wrote : | # |
Thanks for the review. Some replies below.
MAAS Lander (maas-lander) wrote : | # |
The attempt to merge lp:~mpontillo/maas/subnet-dns-override-maas-dns-for-default-gw--bug-1576116 into lp:maas failed. Below is the output from the failed tests.
Hit:1 http://
Hit:2 http://
Hit:3 http://
Get:4 http://
Fetched 94.5 kB in 0s (225 kB/s)
Reading package lists...
sudo DEBIAN_
--no-
Reading package lists...
Building dependency tree...
Reading state information...
apache2 is already the newest version (2.4.18-2ubuntu3).
archdetect-deb is already the newest version (1.117ubuntu2).
authbind is already the newest version (2.1.1+nmu1).
build-essential is already the newest version (12.1ubuntu2).
curl is already the newest version (7.47.0-1ubuntu2).
debhelper is already the newest version (9.20160115ubun
distro-info is already the newest version (0.14build1).
freeipmi-tools is already the newest version (1.4.11-1ubuntu1).
git is already the newest version (1:2.7.4-0ubuntu1).
isc-dhcp-common is already the newest version (4.3.3-5ubuntu12).
libjs-angularjs is already the newest version (1.2.28-1ubuntu2).
libjs-jquery is already the newest version (1.11.3+dfsg-4).
libjs-yui3-full is already the newest version (3.5.1-1ubuntu3).
libjs-yui3-min is already the newest version (3.5.1-1ubuntu3).
make is already the newest version (4.1-6).
postgresql is already the newest version (9.5+173).
pxelinux is already the newest version (3:6.03+
python-django is already the newest version (1.8.7-1ubuntu5)...
MAAS Lander (maas-lander) wrote : | # |
The attempt to merge lp:~mpontillo/maas/subnet-dns-override-maas-dns-for-default-gw--bug-1576116 into lp:maas failed. Below is the output from the failed tests.
Get:1 http://
Hit:2 http://
Get:3 http://
Hit:4 http://
Get:5 http://
Get:6 http://
Fetched 799 kB in 0s (1,768 kB/s)
Reading package lists...
sudo DEBIAN_
--no-
Reading package lists...
Building dependency tree...
Reading state information...
apache2 is already the newest version (2.4.18-2ubuntu3).
archdetect-deb is already the newest version (1.117ubuntu2).
authbind is already the newest version (2.1.1+nmu1).
build-essential is already the newest version (12.1ubuntu2).
curl is already the newest version (7.47.0-1ubuntu2).
debhelper is already the newest version (9.20160115ubun
distro-info is already the newest version (0.14build1).
freeipmi-tools is already the newest version (1.4.11-1ubuntu1).
git is already the newest version (1:2.7.4-0ubuntu1).
isc-dhcp-common is already the newest version (4.3.3-5ubuntu12).
libjs-angularjs is already the newest version (1.2.28-1ubuntu2).
libjs-jquery is already the newest version (1.11.3+dfsg-4).
libjs-yui3-full is already the newest version (3.5.1-1ubuntu3).
libjs-yui3-min is already the newest version (3.5.1-1u...
MAAS Lander (maas-lander) wrote : | # |
The attempt to merge lp:~mpontillo/maas/subnet-dns-override-maas-dns-for-default-gw--bug-1576116 into lp:maas failed. Below is the output from the failed tests.
Hit:1 http://
Get:2 http://
Get:3 http://
Hit:4 http://
Fetched 190 kB in 0s (409 kB/s)
Reading package lists...
sudo DEBIAN_
--no-
Reading package lists...
Building dependency tree...
Reading state information...
apache2 is already the newest version (2.4.18-2ubuntu3).
archdetect-deb is already the newest version (1.117ubuntu2).
authbind is already the newest version (2.1.1+nmu1).
build-essential is already the newest version (12.1ubuntu2).
curl is already the newest version (7.47.0-1ubuntu2).
debhelper is already the newest version (9.20160115ubun
distro-info is already the newest version (0.14build1).
freeipmi-tools is already the newest version (1.4.11-1ubuntu1).
git is already the newest version (1:2.7.4-0ubuntu1).
isc-dhcp-common is already the newest version (4.3.3-5ubuntu12).
libjs-angularjs is already the newest version (1.2.28-1ubuntu2).
libjs-jquery is already the newest version (1.11.3+dfsg-4).
libjs-yui3-full is already the newest version (3.5.1-1ubuntu3).
libjs-yui3-min is already the newest version (3.5.1-1ubuntu3).
make is already the newest version (4.1-6).
postgresql is already the newest version (9.5+173).
pxelinux is already the newest version (3:6.03+
python-django is already the newest version (1.8.7-...
Mike Pontillo (mpontillo) wrote : | # |
Strange error. Trying again...
Preview Diff
1 | === modified file 'src/maasserver/models/node.py' |
2 | --- src/maasserver/models/node.py 2016-07-06 17:22:11 +0000 |
3 | +++ src/maasserver/models/node.py 2016-07-15 00:08:33 +0000 |
4 | @@ -215,8 +215,23 @@ |
5 | |
6 | # Return type from `get_effective_power_info`. |
7 | PowerInfo = namedtuple("PowerInfo", ( |
8 | - "can_be_started", "can_be_stopped", "can_be_queried", "power_type", |
9 | - "power_parameters")) |
10 | + "can_be_started", |
11 | + "can_be_stopped", |
12 | + "can_be_queried", |
13 | + "power_type", |
14 | + "power_parameters", |
15 | +)) |
16 | + |
17 | +DefaultGateways = namedtuple("DefaultGateways", ( |
18 | + "ipv4", |
19 | + "ipv6", |
20 | +)) |
21 | + |
22 | +GatewayDefinition = namedtuple("GatewayDefinition", ( |
23 | + "interface_id", |
24 | + "subnet_id", |
25 | + "gateway_ip", |
26 | +)) |
27 | |
28 | |
29 | def generate_node_system_id(): |
30 | @@ -2691,7 +2706,7 @@ |
31 | interface.id |
32 | """, (self.id,)) |
33 | return [ |
34 | - (found[0], found[1], found[2]) |
35 | + GatewayDefinition._make((found[0], found[1], found[2])) |
36 | for found in cursor.fetchall() |
37 | ] |
38 | |
39 | @@ -2743,7 +2758,7 @@ |
40 | |
41 | # Early out if we already have both gateways. |
42 | if gateway_ipv4 and gateway_ipv6: |
43 | - return (gateway_ipv4, gateway_ipv6) |
44 | + return DefaultGateways._make((gateway_ipv4, gateway_ipv6)) |
45 | |
46 | # Get the best guesses for the missing IP families. |
47 | found_gateways = self.get_best_guess_for_default_gateways() |
48 | @@ -2753,7 +2768,47 @@ |
49 | if not gateway_ipv6: |
50 | gateway_ipv6 = self._get_gateway_tuple_by_family( |
51 | found_gateways, IPADDRESS_FAMILY.IPv6) |
52 | - return (gateway_ipv4, gateway_ipv6) |
53 | + return DefaultGateways._make((gateway_ipv4, gateway_ipv6)) |
54 | + |
55 | + def get_default_dns_servers(self): |
56 | + """Return the default DNS servers for this node.""" |
57 | + # Circular imports. |
58 | + from maasserver.dns.zonegenerator import get_dns_server_address |
59 | + |
60 | + gateways = self.get_default_gateways() |
61 | + |
62 | + # Try first to use DNS servers from default gateway subnets. |
63 | + if gateways.ipv4 is not None: |
64 | + subnet = Subnet.objects.get(id=gateways.ipv4.subnet_id) |
65 | + if subnet.dns_servers is not None and len(subnet.dns_servers) > 0: |
66 | + # An IPv4 subnet is hosting the default gateway and has DNS |
67 | + # servers defined. IPv4 DNS servers take first-priority. |
68 | + return subnet.dns_servers |
69 | + if gateways.ipv6 is not None: |
70 | + subnet = Subnet.objects.get(id=gateways.ipv6.subnet_id) |
71 | + if subnet.dns_servers is not None and len(subnet.dns_servers) > 0: |
72 | + # An IPv6 subnet is hosting the default gateway and has DNS |
73 | + # servers defined. IPv6 DNS servers take second-priority. |
74 | + return subnet.dns_servers |
75 | + |
76 | + # No default gateway subnet has specific DNS servers defined, so |
77 | + # use MAAS for the default DNS server. |
78 | + if gateways.ipv4 is None and gateways.ipv6 is None: |
79 | + # If there are no default gateways, the default is the MAAS |
80 | + # region IP address. |
81 | + maas_dns_server = get_dns_server_address( |
82 | + rack_controller=self.get_boot_rack_controller()) |
83 | + else: |
84 | + # Choose an address consistent with the primary address-family |
85 | + # in use, as indicated by the presence (or not) of a gateway. |
86 | + # Note that this path is only taken if the MAAS URL is set to |
87 | + # a hostname, and the hostname resolves to both an IPv4 and an |
88 | + # IPv6 address. |
89 | + maas_dns_server = get_dns_server_address( |
90 | + rack_controller=self.get_boot_rack_controller(), |
91 | + ipv4=(gateways.ipv4 is not None), |
92 | + ipv6=(gateways.ipv6 is not None)) |
93 | + return [maas_dns_server] |
94 | |
95 | def get_boot_purpose(self): |
96 | """ |
97 | |
98 | === modified file 'src/maasserver/models/tests/test_node.py' |
99 | --- src/maasserver/models/tests/test_node.py 2016-06-30 17:03:46 +0000 |
100 | +++ src/maasserver/models/tests/test_node.py 2016-07-15 00:08:33 +0000 |
101 | @@ -36,6 +36,7 @@ |
102 | from maasserver.enum import ( |
103 | FILESYSTEM_GROUP_TYPE, |
104 | FILESYSTEM_TYPE, |
105 | + INTERFACE_LINK_TYPE, |
106 | INTERFACE_TYPE, |
107 | IPADDRESS_TYPE, |
108 | NODE_PERMISSION, |
109 | @@ -93,6 +94,7 @@ |
110 | NODE_TRANSITIONS, |
111 | ) |
112 | from maasserver.rpc.testing.fixtures import MockLiveRegionToClusterRPCFixture |
113 | +import maasserver.server_address as server_address_module |
114 | from maasserver.storage_layouts import ( |
115 | StorageLayoutError, |
116 | StorageLayoutMissingBootDiskError, |
117 | @@ -136,6 +138,7 @@ |
118 | commissioning, |
119 | disk_erasing, |
120 | ) |
121 | +from netaddr import IPAddress |
122 | from provisioningserver.events import ( |
123 | EVENT_DETAILS, |
124 | EVENT_TYPES, |
125 | @@ -4303,6 +4306,158 @@ |
126 | ), node.get_default_gateways()) |
127 | |
128 | |
129 | +class TestGetDefaultDNSServers(MAASServerTestCase): |
130 | + """Tests for `Node.get_default_dns_servers`.""" |
131 | + |
132 | + def make_Node_with_RackController( |
133 | + self, ipv4=True, ipv6=True, ipv4_gateway=True, ipv6_gateway=True, |
134 | + ipv4_subnet_dns=None, ipv6_subnet_dns=None): |
135 | + ipv4_subnet_dns = [] if ipv4_subnet_dns is None else ipv4_subnet_dns |
136 | + ipv6_subnet_dns = [] if ipv6_subnet_dns is None else ipv6_subnet_dns |
137 | + rack_v4 = None |
138 | + rack_v6 = None |
139 | + fabric = factory.make_Fabric() |
140 | + vlan = fabric.get_default_vlan() |
141 | + if ipv4: |
142 | + gateway_ip = None if ipv4_gateway else "" |
143 | + v4_subnet = factory.make_Subnet( |
144 | + version=4, vlan=vlan, dns_servers=ipv4_subnet_dns, |
145 | + gateway_ip=gateway_ip) |
146 | + if ipv6: |
147 | + gateway_ip = None if ipv6_gateway else "" |
148 | + v6_subnet = factory.make_Subnet( |
149 | + version=6, vlan=vlan, dns_servers=ipv6_subnet_dns, |
150 | + gateway_ip=gateway_ip) |
151 | + rack = factory.make_RegionRackController() |
152 | + vlan.primary_rack = rack |
153 | + vlan.dhcp_on = True |
154 | + vlan.save() |
155 | + # In order to determine the correct IP address per-address-family, |
156 | + # a name lookup is performed on the hostname part of the URL. |
157 | + # We need to mock that so we can return whatever IP addresses it |
158 | + # resolves to. |
159 | + rack.url = "http://region:5240/MAAS/" |
160 | + if ipv4: |
161 | + rack_v4 = factory.pick_ip_in_Subnet(v4_subnet) |
162 | + if ipv6: |
163 | + rack_v6 = factory.pick_ip_in_Subnet(v6_subnet) |
164 | + |
165 | + def get_address(hostname, ip_version=4): |
166 | + """Mock function to return the IP address of the rack based on the |
167 | + given address family. |
168 | + """ |
169 | + if ip_version == 4: |
170 | + return {IPAddress(rack_v4)} if rack_v4 else set() |
171 | + elif ip_version == 6: |
172 | + return {IPAddress(rack_v6)} if rack_v6 else set() |
173 | + |
174 | + resolve_hostname = self.patch( |
175 | + server_address_module, 'resolve_hostname') |
176 | + resolve_hostname.side_effect = get_address |
177 | + rack.interface_set.all().delete() |
178 | + rackif = factory.make_Interface(vlan=vlan, node=rack) |
179 | + if ipv4: |
180 | + rackif.link_subnet(INTERFACE_LINK_TYPE.STATIC, v4_subnet, rack_v4) |
181 | + if ipv6: |
182 | + rackif.link_subnet(INTERFACE_LINK_TYPE.STATIC, v6_subnet, rack_v6) |
183 | + rack.boot_interface = rackif |
184 | + rack.save() |
185 | + node = factory.make_Node(status=NODE_STATUS.READY, disable_ipv4=False) |
186 | + nodeif = factory.make_Interface(vlan=vlan, node=node) |
187 | + if ipv4: |
188 | + nodeif.link_subnet(INTERFACE_LINK_TYPE.AUTO, v4_subnet) |
189 | + if ipv6: |
190 | + nodeif.link_subnet(INTERFACE_LINK_TYPE.AUTO, v6_subnet) |
191 | + node.boot_interface = nodeif |
192 | + node.save() |
193 | + return rack_v4, rack_v6, node |
194 | + |
195 | + def test__uses_rack_ipv4_if_ipv4_only_with_no_gateway(self): |
196 | + rack_v4, rack_v6, node = self.make_Node_with_RackController( |
197 | + ipv4=True, ipv4_gateway=False, ipv6=False, ipv6_gateway=False) |
198 | + self.assertThat(node.get_default_dns_servers(), Equals([rack_v4])) |
199 | + |
200 | + def test__uses_rack_ipv4_if_ipv4_only_with_no_gateway_v4_dns(self): |
201 | + ipv4_subnet_dns = factory.make_ip_address(ipv6=False) |
202 | + rack_v4, rack_v6, node = self.make_Node_with_RackController( |
203 | + ipv4=True, ipv4_gateway=False, ipv6=False, ipv6_gateway=False, |
204 | + ipv4_subnet_dns=[ipv4_subnet_dns]) |
205 | + self.assertThat( |
206 | + node.get_default_dns_servers(), Equals([rack_v4])) |
207 | + |
208 | + def test__uses_rack_ipv6_if_ipv6_only_with_no_gateway_v6_dns(self): |
209 | + ipv6_subnet_dns = factory.make_ip_address(ipv6=True) |
210 | + rack_v4, rack_v6, node = self.make_Node_with_RackController( |
211 | + ipv4=False, ipv4_gateway=False, ipv6=True, ipv6_gateway=False, |
212 | + ipv6_subnet_dns=[ipv6_subnet_dns]) |
213 | + self.assertThat(node.get_default_dns_servers(), Equals([rack_v6])) |
214 | + |
215 | + def test__uses_rack_ipv4_if_dual_stack_with_no_gateway(self): |
216 | + rack_v4, rack_v6, node = self.make_Node_with_RackController( |
217 | + ipv4=True, ipv4_gateway=False, ipv6=True, ipv6_gateway=False) |
218 | + self.assertThat(node.get_default_dns_servers(), Equals([rack_v4])) |
219 | + |
220 | + def test__uses_rack_ipv4_if_dual_stack_with_ipv4_gateway(self): |
221 | + rack_v4, rack_v6, node = self.make_Node_with_RackController( |
222 | + ipv4=True, ipv4_gateway=True, ipv6=True, ipv6_gateway=False) |
223 | + self.assertThat(node.get_default_dns_servers(), Equals([rack_v4])) |
224 | + |
225 | + def test__uses_subnet_ipv4_if_dual_stack_with_ipv4_gateway_with_dns(self): |
226 | + ipv4_subnet_dns = factory.make_ip_address(ipv6=False) |
227 | + ipv6_subnet_dns = factory.make_ip_address(ipv6=True) |
228 | + rack_v4, rack_v6, node = self.make_Node_with_RackController( |
229 | + ipv4=True, ipv4_gateway=True, ipv6=True, ipv6_gateway=False, |
230 | + ipv4_subnet_dns=[ipv4_subnet_dns], |
231 | + ipv6_subnet_dns=[ipv6_subnet_dns]) |
232 | + self.assertThat( |
233 | + node.get_default_dns_servers(), Equals([ipv4_subnet_dns])) |
234 | + |
235 | + def test__uses_rack_ipv6_if_dual_stack_with_ipv6_gateway(self): |
236 | + rack_v4, rack_v6, node = self.make_Node_with_RackController( |
237 | + ipv4=True, ipv4_gateway=False, ipv6=True, ipv6_gateway=True) |
238 | + self.assertThat(node.get_default_dns_servers(), Equals([rack_v6])) |
239 | + |
240 | + def test__uses_subnet_ipv6_if_dual_stack_with_ipv6_gateway(self): |
241 | + ipv4_subnet_dns = factory.make_ip_address(ipv6=False) |
242 | + ipv6_subnet_dns = factory.make_ip_address(ipv6=True) |
243 | + rack_v4, rack_v6, node = self.make_Node_with_RackController( |
244 | + ipv4=True, ipv4_gateway=False, ipv6=True, ipv6_gateway=True, |
245 | + ipv4_subnet_dns=[ipv4_subnet_dns], |
246 | + ipv6_subnet_dns=[ipv6_subnet_dns]) |
247 | + self.assertThat( |
248 | + node.get_default_dns_servers(), Equals([ipv6_subnet_dns])) |
249 | + |
250 | + def test__uses_rack_ipv4_if_ipv4_with_ipv4_gateway(self): |
251 | + rack_v4, rack_v6, node = self.make_Node_with_RackController( |
252 | + ipv4=True, ipv4_gateway=True, ipv6=False, ipv6_gateway=False) |
253 | + self.assertThat(node.get_default_dns_servers(), Equals([rack_v4])) |
254 | + |
255 | + def test__uses_subnet_ipv4_if_ipv4_stack_with_ipv4_gateway_and_dns(self): |
256 | + ipv4_subnet_dns = factory.make_ip_address(ipv6=False) |
257 | + ipv6_subnet_dns = factory.make_ip_address(ipv6=True) |
258 | + rack_v4, rack_v6, node = self.make_Node_with_RackController( |
259 | + ipv4=True, ipv4_gateway=True, ipv6=False, ipv6_gateway=False, |
260 | + ipv4_subnet_dns=[ipv4_subnet_dns], |
261 | + ipv6_subnet_dns=[ipv6_subnet_dns]) |
262 | + self.assertThat( |
263 | + node.get_default_dns_servers(), Equals([ipv4_subnet_dns])) |
264 | + |
265 | + def test__uses_rack_ipv6_if_ipv6_with_ipv6_gateway(self): |
266 | + rack_v4, rack_v6, node = self.make_Node_with_RackController( |
267 | + ipv4=False, ipv4_gateway=False, ipv6=True, ipv6_gateway=True) |
268 | + self.assertThat(node.get_default_dns_servers(), Equals([rack_v6])) |
269 | + |
270 | + def test__uses_subnet_ipv6_if_ipv6_with_ipv6_gateway_and_dns(self): |
271 | + ipv4_subnet_dns = factory.make_ip_address(ipv6=False) |
272 | + ipv6_subnet_dns = factory.make_ip_address(ipv6=True) |
273 | + rack_v4, rack_v6, node = self.make_Node_with_RackController( |
274 | + ipv4=False, ipv4_gateway=False, ipv6=True, ipv6_gateway=True, |
275 | + ipv4_subnet_dns=[ipv4_subnet_dns], |
276 | + ipv6_subnet_dns=[ipv6_subnet_dns]) |
277 | + self.assertThat( |
278 | + node.get_default_dns_servers(), Equals([ipv6_subnet_dns])) |
279 | + |
280 | + |
281 | class TestNode_Start(MAASServerTestCase): |
282 | """Tests for Node.start().""" |
283 | |
284 | |
285 | === modified file 'src/maasserver/preseed_network.py' |
286 | --- src/maasserver/preseed_network.py 2016-03-28 13:54:47 +0000 |
287 | +++ src/maasserver/preseed_network.py 2016-07-15 00:08:33 +0000 |
288 | @@ -6,10 +6,7 @@ |
289 | __all__ = [ |
290 | ] |
291 | |
292 | -from maasserver.dns.zonegenerator import ( |
293 | - get_dns_search_paths, |
294 | - get_dns_server_address, |
295 | -) |
296 | +from maasserver.dns.zonegenerator import get_dns_search_paths |
297 | from maasserver.enum import ( |
298 | INTERFACE_TYPE, |
299 | IPADDRESS_FAMILY, |
300 | @@ -24,6 +21,7 @@ |
301 | def __init__(self, node): |
302 | self.node = node |
303 | self.gateways = node.get_default_gateways() |
304 | + self.dns_servers = node.get_default_dns_servers() |
305 | self.gateway_ipv4_set = False |
306 | self.gateway_ipv6_set = False |
307 | self.operations = { |
308 | @@ -51,8 +49,7 @@ |
309 | |
310 | self.network_config.append({ |
311 | "type": "nameserver", |
312 | - "address": get_dns_server_address( |
313 | - rack_controller=self.node.get_boot_rack_controller()), |
314 | + "address": self.dns_servers, |
315 | "search": sorted(get_dns_search_paths()), |
316 | }) |
317 | |
318 | |
319 | === modified file 'src/maasserver/tests/test_preseed_network.py' |
320 | --- src/maasserver/tests/test_preseed_network.py 2016-04-15 23:38:27 +0000 |
321 | +++ src/maasserver/tests/test_preseed_network.py 2016-07-15 00:08:33 +0000 |
322 | @@ -8,10 +8,7 @@ |
323 | import random |
324 | from textwrap import dedent |
325 | |
326 | -from maasserver.dns.zonegenerator import ( |
327 | - get_dns_search_paths, |
328 | - get_dns_server_address, |
329 | -) |
330 | +from maasserver.dns.zonegenerator import get_dns_search_paths |
331 | from maasserver.enum import ( |
332 | INTERFACE_TYPE, |
333 | IPADDRESS_FAMILY, |
334 | @@ -203,8 +200,7 @@ |
335 | |
336 | def collectDNSConfig(self, node): |
337 | config = "- type: nameserver\n address: %s\n search:\n" % ( |
338 | - get_dns_server_address( |
339 | - rack_controller=node.get_boot_primary_rack_controller())) |
340 | + repr(node.get_default_dns_servers())) |
341 | dns_searches = sorted(get_dns_search_paths()) |
342 | for dns_name in dns_searches: |
343 | config += " - %s\n" % dns_name |
I think this is ready for review now. This branch implements the work we discussed the other day: making curtin's default DNS servers (for the loopback interface) consistent with the DNS servers on the default gateway's subnet. Previously, the DNS server was always the rack-facing MAAS IP address.
The code was relatively simple, but it was pretty gnarly to unit test all the different permutations.