Merge ~bjornt/maas:bug-1992330-3.2 into maas:3.2

Proposed by Björn Tillenius
Status: Merged
Approved by: Björn Tillenius
Approved revision: 6c309c32f2b2e4b68041a8be938b09674b68cab8
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~bjornt/maas:bug-1992330-3.2
Merge into: maas:3.2
Diff against target: 201 lines (+60/-44)
4 files modified
src/maasserver/dhcp.py (+5/-34)
src/maasserver/models/subnet.py (+9/-4)
src/maasserver/models/tests/test_subnet.py (+4/-4)
src/maasserver/tests/test_dhcp.py (+42/-2)
Reviewer Review Type Date Requested Status
Björn Tillenius Approve
Review via email: mp+433102@code.launchpad.net

Commit message

Don't return ipv6 boot addresses for ipv4 subnets.

An ipv4 subnet won't be able to use ipv6 addresses, and it would break the
DHCP config.

(cherry picked from commit 425a78cfd666e05757bf6f72e63c48bdf0f807df)

LP #1992330: Use the rack controller IP as DNS when relaying DHCP

Add relay rack ips as DNS servers
This patch aims to add the rack controll IP addresses of the relay
vlan as DNS servers.

This fixes an issue that when there are no other settings or available
IPs, MAAS adds only the IP address of the region controller, but
sometimes the region controller might not be routed to that vlan, hence
this patch, as the rack controllers should always be reachable by the
machines.

(cherry picked from commit 65a0cacf6aa37704195e0165ee69e2c516fb6936)

To post a comment you must log in.
Revision history for this message
Björn Tillenius (bjornt) wrote :

Self-approve backport

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 be288ea..55f355e 100644
3--- a/src/maasserver/dhcp.py
4+++ b/src/maasserver/dhcp.py
5@@ -23,7 +23,6 @@ from maasserver.enum import (
6 INTERFACE_TYPE,
7 IPADDRESS_TYPE,
8 IPRANGE_TYPE,
9- NODE_TYPE,
10 SERVICE_STATUS,
11 )
12 from maasserver.exceptions import UnresolvableHost
13@@ -37,6 +36,7 @@ from maasserver.models import (
14 Subnet,
15 VLAN,
16 )
17+from maasserver.models.subnet import get_boot_rackcontroller_ips
18 from maasserver.rpc import getAllClients, getClientFor, getRandomClient
19 from maasserver.utils.orm import transactional
20 from maasserver.utils.threads import deferToDatabase
21@@ -545,37 +545,6 @@ def get_ntp_servers(ntp_servers, subnet, peer_rack):
22 return ntp_servers
23
24
25-def get_dns_server_addresses_for_rack(
26- rack_controller: RackController, subnet: Subnet
27-) -> dict:
28- """Return a map of IP addresses suitable for DNS on subnet.
29-
30- This will define a list of IP addresses across all rack controllers that
31- exist on `subnet`. The `rack_controller` will always be the first in the
32- list followed by other rack controllers that are also on the subnet.
33- """
34- addresses = StaticIPAddress.objects.filter(
35- subnet=subnet,
36- alloc_type__in={IPADDRESS_TYPE.STICKY, IPADDRESS_TYPE.USER_RESERVED},
37- interface__enabled=True,
38- interface__node_config__node__node_type__in={
39- NODE_TYPE.RACK_CONTROLLER,
40- NODE_TYPE.REGION_AND_RACK_CONTROLLER,
41- },
42- )
43- addresses = addresses.distinct()
44- addresses = addresses.values_list("ip", "interface__node_config__node_id")
45-
46- def sort_key__rack__ip(record):
47- ip, node_id = record
48- return -int(node_id == rack_controller.id), IPAddress(ip)
49-
50- return [
51- IPAddress(record[0])
52- for record in sorted(addresses, key=sort_key__rack__ip)
53- ]
54-
55-
56 def get_default_dns_servers(rack_controller, subnet, use_rack_proxy=True):
57 """Calculates the DNS servers on a per-subnet basis, to make sure we
58 choose the best possible IP addresses for each subnet.
59@@ -607,7 +576,9 @@ def get_default_dns_servers(rack_controller, subnet, use_rack_proxy=True):
60 if use_rack_proxy:
61 # Add the IP address for the rack controllers on the subnet before the
62 # region DNS servers.
63- rack_ips = get_dns_server_addresses_for_rack(rack_controller, subnet)
64+ rack_ips = [
65+ IPAddress(ip) for ip in get_boot_rackcontroller_ips(subnet)
66+ ]
67 if dns_servers:
68 dns_servers = rack_ips + [
69 server
70@@ -616,7 +587,7 @@ def get_default_dns_servers(rack_controller, subnet, use_rack_proxy=True):
71 ]
72 elif rack_ips:
73 dns_servers = rack_ips
74- elif default_region_ip in dns_servers:
75+ if default_region_ip in dns_servers:
76 # Make sure the region DNS server comes last
77 dns_servers = [
78 server for server in dns_servers if server != default_region_ip
79diff --git a/src/maasserver/models/subnet.py b/src/maasserver/models/subnet.py
80index d0cf030..6d9920c 100644
81--- a/src/maasserver/models/subnet.py
82+++ b/src/maasserver/models/subnet.py
83@@ -1087,9 +1087,6 @@ def get_boot_rackcontroller_ips(subnet):
84 value = 2
85 if ip in network:
86 value = 1
87- # Prefer addresses of the same IP version.
88- if ip.version != network.version:
89- value *= 10
90 return value
91
92 from maasserver.models.staticipaddress import StaticIPAddress
93@@ -1107,5 +1104,13 @@ def get_boot_rackcontroller_ips(subnet):
94 subnet__vlan=dhcp_vlan,
95 interface__node_config__in=node_configs,
96 )
97- ips = sorted((static_ip.ip for static_ip in static_ips), key=rank_ip)
98+ ip_version = IPNetwork(subnet.cidr).version
99+ ips = sorted(
100+ (
101+ static_ip.ip
102+ for static_ip in static_ips
103+ if IPAddress(static_ip.ip).version == ip_version
104+ ),
105+ key=rank_ip,
106+ )
107 return ips
108diff --git a/src/maasserver/models/tests/test_subnet.py b/src/maasserver/models/tests/test_subnet.py
109index b4d158c..a09306c 100644
110--- a/src/maasserver/models/tests/test_subnet.py
111+++ b/src/maasserver/models/tests/test_subnet.py
112@@ -1990,7 +1990,7 @@ class TestGetBootRackcontrollerIPs(MAASServerTestCase):
113 boot_ips = get_boot_rackcontroller_ips(relay_subnet)
114 self.assertCountEqual(["10.10.0.2", "10.10.1.2"], boot_ips)
115
116- def test_with_relay_prefer_ipv4(self):
117+ def test_with_relay_mixed_ipv4_subnet(self):
118 dhcp_vlan = factory.make_VLAN(
119 dhcp_on=False,
120 primary_rack=None,
121@@ -2017,9 +2017,9 @@ class TestGetBootRackcontrollerIPs(MAASServerTestCase):
122 relay_vlan.relay_vlan = dhcp_vlan
123 relay_vlan.save()
124 boot_ips = get_boot_rackcontroller_ips(relay_subnet)
125- self.assertEqual(["10.10.0.2", "fd12:3456:789a::2"], boot_ips)
126+ self.assertEqual(["10.10.0.2"], boot_ips)
127
128- def test_with_relay_prefer_ipv6(self):
129+ def test_with_relay_prefer_mixed_ipv6_subnet(self):
130 dhcp_vlan = factory.make_VLAN(
131 dhcp_on=False,
132 primary_rack=None,
133@@ -2046,4 +2046,4 @@ class TestGetBootRackcontrollerIPs(MAASServerTestCase):
134 relay_vlan.relay_vlan = dhcp_vlan
135 relay_vlan.save()
136 boot_ips = get_boot_rackcontroller_ips(relay_subnet)
137- self.assertEqual(["fd12:3456:789a::2", "10.10.0.2"], boot_ips)
138+ self.assertEqual(["fd12:3456:789a::2"], boot_ips)
139diff --git a/src/maasserver/tests/test_dhcp.py b/src/maasserver/tests/test_dhcp.py
140index fa482a7..5e7f347 100644
141--- a/src/maasserver/tests/test_dhcp.py
142+++ b/src/maasserver/tests/test_dhcp.py
143@@ -1118,9 +1118,9 @@ class TestGetDefaultDNSServers(MAASServerTestCase):
144 # Regression test for LP:1881133
145 mock_get_source_address = self.patch(dhcp, "get_source_address")
146 mock_get_source_address.return_value = "192.168.122.209"
147- vlan = factory.make_VLAN()
148- subnet = factory.make_Subnet(vlan=vlan, cidr="192.168.200.0/24")
149 rack = factory.make_RackController(interface=False)
150+ vlan = factory.make_VLAN(dhcp_on=True, primary_rack=rack)
151+ subnet = factory.make_Subnet(vlan=vlan, cidr="192.168.200.0/24")
152 iface = factory.make_Interface(
153 INTERFACE_TYPE.PHYSICAL, vlan=vlan, node=rack
154 )
155@@ -1134,6 +1134,46 @@ class TestGetDefaultDNSServers(MAASServerTestCase):
156 servers = get_default_dns_servers(rack, subnet)
157 self.assertThat(servers, Equals([IPAddress("192.168.200.1")]))
158
159+ def test_dns_servers_when_relaying(self):
160+ mock_get_source_address = self.patch(dhcp, "get_source_address")
161+ mock_get_source_address.return_value = "10.20.30.1"
162+ rack = factory.make_RackController(interface=False)
163+ vlan1_primary = factory.make_VLAN(dhcp_on=True, primary_rack=rack)
164+ vlan2_secondary = factory.make_VLAN(
165+ primary_rack=rack, dhcp_on=False, relay_vlan=vlan1_primary
166+ )
167+ subnet1 = factory.make_Subnet(
168+ vlan=vlan1_primary, vid=10, cidr="10.20.40.0/24"
169+ )
170+ subnet2 = factory.make_Subnet(
171+ vlan=vlan2_secondary, vid=20, cidr="10.20.50.0/24"
172+ )
173+ rack_interface = factory.make_Interface(
174+ INTERFACE_TYPE.PHYSICAL, node=rack
175+ )
176+ rack_interface_vlan1 = factory.make_Interface(
177+ INTERFACE_TYPE.VLAN,
178+ vlan=vlan1_primary,
179+ parents=[rack_interface],
180+ node=rack,
181+ )
182+ factory.make_Interface(
183+ INTERFACE_TYPE.VLAN,
184+ vlan=vlan2_secondary,
185+ parents=[rack_interface],
186+ node=rack,
187+ )
188+ factory.make_StaticIPAddress(
189+ interface=rack_interface_vlan1,
190+ subnet=subnet1,
191+ alloc_type=IPADDRESS_TYPE.STICKY,
192+ ip="10.20.40.1",
193+ )
194+ dns_servers = dhcp.get_default_dns_servers(
195+ rack, subnet2, use_rack_proxy=True
196+ )
197+ self.assertEqual(dns_servers, [IPAddress("10.20.40.1")])
198+
199 def test_no_default_region_ip(self):
200 self.patch(dhcp, "get_source_address").return_value = None
201 vlan = factory.make_VLAN()

Subscribers

People subscribed via source and target branches