Merge ~ltrager/maas:lp1881133 into maas:master

Proposed by Lee Trager
Status: Merged
Approved by: Lee Trager
Approved revision: 1c15e2019ad33436a7db30495ea7608c11b6668a
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~ltrager/maas:lp1881133
Merge into: maas:master
Diff against target: 261 lines (+105/-49)
4 files modified
src/maasserver/dhcp.py (+17/-3)
src/maasserver/preseed_network.py (+40/-34)
src/maasserver/tests/test_dhcp.py (+26/-12)
src/maasserver/tests/test_preseed_network.py (+22/-0)
Reviewer Review Type Date Requested Status
Adam Collard (community) Approve
MAAS Lander Approve
Review via email: mp+388092@code.launchpad.net

Commit message

LP: #1881133 - Always include rack controller IPs for DNS servers.

MAAS was only including the configured URL for controllers which did not
always include all rack controllers the VLAN is configured to use. This
would also sometimes include the region controller's IP even when the
machine is unable to directly access the rack controller.

To post a comment you must log in.
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b lp1881133 lp:~ltrager/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: e73e635eb3fd03943cd400d6d36542b627168395

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

UNIT TESTS
-b lp1881133 lp:~ltrager/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/8029/console
COMMIT: e58fb6df87b8f2244b95803a58a9211c62c5fa9b

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

UNIT TESTS
-b lp1881133 lp:~ltrager/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/8041/console
COMMIT: 2a52feecdcc91988b569f65d0fdb90833449d6dd

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

UNIT TESTS
-b lp1881133 lp:~ltrager/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/8042/console
COMMIT: 154abccbb8f6031c057580f0707bdc4629cde19c

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

UNIT TESTS
-b lp1881133 lp:~ltrager/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 913b9489646c07b8122355ed01343202c31b700b

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

UNIT TESTS
-b lp1881133 lp:~ltrager/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/8077/console
COMMIT: 274991f9d990fbd081dd5504884ff3ccb9dae427

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

UNIT TESTS
-b lp1881133 lp:~ltrager/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/8097/console
COMMIT: efd4d4470bfd3fadee6ce7be6c7978779d4fe185

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

UNIT TESTS
-b lp1881133 lp:~ltrager/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/8122/console
COMMIT: 6942f03547c2f25e4a0477d50adc7a8bab08923a

review: Needs Fixing
Revision history for this message
Adam Collard (adam-collard) :
~ltrager/maas:lp1881133 updated
1c15e20... by Lee Trager

adam-collard fixes

Revision history for this message
Lee Trager (ltrager) wrote :

Thanks for the review! Made changes as suggested, let me know if there is anything else.

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

UNIT TESTS
-b lp1881133 lp:~ltrager/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/8139/console
COMMIT: 1c15e2019ad33436a7db30495ea7608c11b6668a

review: Needs Fixing
Revision history for this message
Adam Collard (adam-collard) wrote :

jenkins: !test

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

UNIT TESTS
-b lp1881133 lp:~ltrager/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 1c15e2019ad33436a7db30495ea7608c11b6668a

review: Approve
Revision history for this message
Adam Collard (adam-collard) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/dhcp.py b/src/maasserver/dhcp.py
2index d9b9299..848ff1b 100644
3--- a/src/maasserver/dhcp.py
4+++ b/src/maasserver/dhcp.py
5@@ -1,4 +1,4 @@
6-# Copyright 2012-2019 Canonical Ltd. This software is licensed under the
7+# Copyright 2012-2020 Canonical Ltd. This software is licensed under the
8 # GNU Affero General Public License version 3 (see the file LICENSE).
9
10 """DHCP management module."""
11@@ -558,8 +558,8 @@ def get_default_dns_servers(rack_controller, subnet, use_rack_proxy=True):
12 or not.
13 """
14 ip_version = subnet.get_ip_version()
15+ default_region_ip = get_source_address(subnet.get_ipnetwork())
16 try:
17- default_region_ip = get_source_address(subnet.get_ipnetwork())
18 dns_servers = get_dns_server_addresses(
19 rack_controller,
20 ipv4=(ip_version == 4),
21@@ -570,16 +570,30 @@ def get_default_dns_servers(rack_controller, subnet, use_rack_proxy=True):
22 except UnresolvableHost:
23 dns_servers = None
24
25+ if default_region_ip:
26+ default_region_ip = IPAddress(default_region_ip)
27 if use_rack_proxy:
28 # Add the IP address for the rack controllers on the subnet before the
29 # region DNS servers.
30 rack_ips = get_dns_server_addresses_for_rack(rack_controller, subnet)
31 if dns_servers:
32 dns_servers = rack_ips + [
33- server for server in dns_servers if server not in rack_ips
34+ server
35+ for server in dns_servers
36+ if server not in rack_ips and server != default_region_ip
37 ]
38 elif rack_ips:
39 dns_servers = rack_ips
40+ elif default_region_ip in dns_servers:
41+ # Make sure the region DNS server comes last
42+ dns_servers = [
43+ server for server in dns_servers if server != default_region_ip
44+ ] + [default_region_ip]
45+ # If no DNS servers were found give the region IP. This won't go through
46+ # the rack but its better than nothing.
47+ if not dns_servers:
48+ log.warn("No DNS servers found, DHCP defaulting to region IP.")
49+ dns_servers = [default_region_ip]
50
51 return dns_servers
52
53diff --git a/src/maasserver/preseed_network.py b/src/maasserver/preseed_network.py
54index f8a782f..11dc858 100644
55--- a/src/maasserver/preseed_network.py
56+++ b/src/maasserver/preseed_network.py
57@@ -8,13 +8,10 @@ __all__ = []
58 from collections import defaultdict, OrderedDict
59 from operator import attrgetter
60
61-from netaddr import IPNetwork
62+from netaddr import IPAddress, IPNetwork
63 import yaml
64
65-from maasserver.dns.zonegenerator import (
66- get_dns_search_paths,
67- get_dns_server_addresses,
68-)
69+from maasserver.dns.zonegenerator import get_dns_search_paths
70 from maasserver.enum import (
71 BRIDGE_TYPE,
72 INTERFACE_TYPE,
73@@ -22,7 +19,7 @@ from maasserver.enum import (
74 IPADDRESS_TYPE,
75 NODE_STATUS,
76 )
77-from maasserver.models import Interface
78+from maasserver.models import Interface, StaticIPAddress
79 from maasserver.models.staticroute import StaticRoute
80 from provisioningserver.utils.netplan import (
81 get_netplan_bond_parameters,
82@@ -362,40 +359,42 @@ class InterfaceConfiguration:
83 v1_subnet_operation if version == 1 else v2_config,
84 version,
85 )
86- if (
87- subnet.dns_servers is not None
88- and len(subnet.dns_servers) > 0
89- ):
90+
91+ if "dns_nameservers" not in v1_subnet_operation:
92 v1_subnet_operation["dns_nameservers"] = []
93 v1_subnet_operation[
94 "dns_search"
95 ] = self.node_config.default_search_list
96- if "nameservers" not in v2_config:
97- v2_config["nameservers"] = v2_nameservers
98- v2_config["nameservers"][
99- "search"
100- ] = self.node_config.default_search_list
101- if "addresses" not in v2_nameservers:
102- v2_nameservers["addresses"] = []
103- for rack in {
104+ if "nameservers" not in v2_config:
105+ v2_nameservers[
106+ "search"
107+ ] = self.node_config.default_search_list
108+ v2_config["nameservers"] = v2_nameservers
109+ if "addresses" not in v2_nameservers:
110+ v2_nameservers["addresses"] = []
111+
112+ for ip in StaticIPAddress.objects.filter(
113+ interface__node__in=[
114 subnet.vlan.primary_rack,
115 subnet.vlan.secondary_rack,
116- }:
117- if rack is None:
118- continue
119- for ip in get_dns_server_addresses(
120- rack_controller=rack,
121- ipv4=(subnet.get_ip_version() == 4),
122- ipv6=(subnet.get_ip_version() == 6),
123- include_alternates=True,
124- ):
125- if ip.is_loopback():
126- continue
127- ip_str = str(ip)
128- v1_subnet_operation["dns_nameservers"].append(
129- ip_str
130- )
131- v2_nameservers["addresses"].append(ip_str)
132+ ],
133+ subnet__vlan=subnet.vlan,
134+ alloc_type__in=[
135+ IPADDRESS_TYPE.AUTO,
136+ IPADDRESS_TYPE.STICKY,
137+ ],
138+ ).exclude(ip=None):
139+ if (
140+ IPAddress(ip.get_ip()).version
141+ == subnet.get_ip_version()
142+ and ip.get_ip() not in v2_nameservers["addresses"]
143+ ):
144+ v1_subnet_operation["dns_nameservers"].append(
145+ ip.ip
146+ )
147+ v2_nameservers["addresses"].append(ip.ip)
148+
149+ if subnet.dns_servers:
150 v1_subnet_operation[
151 "dns_nameservers"
152 ] += subnet.dns_servers
153@@ -408,6 +407,13 @@ class InterfaceConfiguration:
154 matching_subnet_routes, version=version
155 )
156 v1_subnet_operation["routes"] = routes
157+
158+ # Delete if no DNS servers were added.
159+ if len(v1_subnet_operation["dns_nameservers"]) == 0:
160+ del v1_subnet_operation["dns_nameservers"]
161+ del v1_subnet_operation["dns_search"]
162+ if len(v2_nameservers["addresses"]) == 0:
163+ del v2_config["nameservers"]
164 if dhcp_type:
165 v1_config.append({"type": dhcp_type})
166 if dhcp_type == "dhcp":
167diff --git a/src/maasserver/tests/test_dhcp.py b/src/maasserver/tests/test_dhcp.py
168index 6894dd3..d53f8bb 100644
169--- a/src/maasserver/tests/test_dhcp.py
170+++ b/src/maasserver/tests/test_dhcp.py
171@@ -1,4 +1,4 @@
172-# Copyright 2012-2019 Canonical Ltd. This software is licensed under the
173+# Copyright 2012-2020 Canonical Ltd. This software is licensed under the
174 # GNU Affero General Public License version 3 (see the file LICENSE).
175
176 """Tests for DHCP management."""
177@@ -1089,7 +1089,7 @@ class TestGetDefaultDNSServers(MAASServerTestCase):
178 )
179 servers = get_default_dns_servers(r1, subnet, False)
180 self.assertThat(
181- servers, Equals([IPAddress("10.0.0.1"), IPAddress(address.ip)])
182+ servers, Equals([IPAddress(address.ip), IPAddress("10.0.0.1")])
183 )
184
185 def test_racks_on_subnet_comes_before_region(self):
186@@ -1117,18 +1117,32 @@ class TestGetDefaultDNSServers(MAASServerTestCase):
187 subnet=subnet,
188 alloc_type=IPADDRESS_TYPE.STICKY,
189 )
190- servers = get_default_dns_servers(r1, subnet)
191- self.assertThat(
192- servers,
193- Equals(
194- [
195- IPAddress(r1_address.ip),
196- IPAddress(r2_address.ip),
197- IPAddress("10.0.0.1"),
198- ]
199- ),
200+ servers = get_default_dns_servers(r1, subnet, False)
201+ self.assertItemsEqual(
202+ servers[0:-1], [IPAddress(r1_address.ip), IPAddress(r2_address.ip)]
203+ )
204+ self.assertEquals(IPAddress("10.0.0.1"), servers[-1])
205+
206+ def test_doesnt_include_remote_region_ip(self):
207+ # Regression test for LP:1881133
208+ mock_get_source_address = self.patch(dhcp, "get_source_address")
209+ mock_get_source_address.return_value = "192.168.122.209"
210+ vlan = factory.make_VLAN()
211+ subnet = factory.make_Subnet(vlan=vlan, cidr="192.168.200.0/24")
212+ rack = factory.make_RackController(interface=False)
213+ iface = factory.make_Interface(
214+ INTERFACE_TYPE.PHYSICAL, vlan=vlan, node=rack
215+ )
216+ factory.make_StaticIPAddress(
217+ interface=iface,
218+ subnet=subnet,
219+ alloc_type=IPADDRESS_TYPE.STICKY,
220+ ip="192.168.200.1",
221 )
222
223+ servers = get_default_dns_servers(rack, subnet)
224+ self.assertThat(servers, Equals([IPAddress("192.168.200.1")]))
225+
226
227 class TestMakeSubnetConfig(MAASServerTestCase):
228 """Tests for `make_subnet_config`."""
229diff --git a/src/maasserver/tests/test_preseed_network.py b/src/maasserver/tests/test_preseed_network.py
230index bc49c79..c19283a 100644
231--- a/src/maasserver/tests/test_preseed_network.py
232+++ b/src/maasserver/tests/test_preseed_network.py
233@@ -1739,6 +1739,28 @@ class TestNetplan(MAASServerTestCase):
234 }
235 self.expectThat(v1, Equals(expected_v1))
236
237+ def test_dns_includes_rack_controllers(self):
238+ # Regression test for LP:1881133
239+ vlan = factory.make_VLAN()
240+ subnet = factory.make_Subnet(dns_servers=[], vlan=vlan)
241+ rack = factory.make_RackController(subnet=subnet)
242+ rack_iface = rack.interface_set.first()
243+ rack_ip = factory.make_StaticIPAddress(
244+ subnet=subnet, interface=rack_iface
245+ )
246+ vlan.primary_rack = rack
247+ vlan.save()
248+ node = factory.make_Node_with_Interface_on_Subnet(
249+ status=NODE_STATUS.DEPLOYING, subnet=subnet
250+ )
251+ iface = node.interface_set.first()
252+ factory.make_StaticIPAddress(subnet=subnet, interface=iface)
253+ v2 = self._render_netplan_dict(node)
254+ self.assertDictEqual(
255+ {"search": ["maas"], "addresses": [rack_ip.ip]},
256+ v2["network"]["ethernets"][iface.name]["nameservers"],
257+ )
258+
259 def test_commissioning_dhcp_config(self):
260 # Verifies dhcp config is given when commissioning has run
261 # or just run and no AUTOIP has been acquired.

Subscribers

People subscribed via source and target branches