Merge ~blake-rouse/maas:fix-1836276 into maas:master
- Git
- lp:~blake-rouse/maas
- fix-1836276
- Merge into master
Proposed by
Blake Rouse
Status: | Merged |
---|---|
Approved by: | Blake Rouse |
Approved revision: | 21213e9f59ad439d7548d1289d44e8b438631fe3 |
Merge reported by: | MAAS Lander |
Merged at revision: | not available |
Proposed branch: | ~blake-rouse/maas:fix-1836276 |
Merge into: | maas:master |
Diff against target: |
475 lines (+135/-54) 8 files modified
src/maasserver/dhcp.py (+22/-11) src/maasserver/tests/test_dhcp.py (+37/-1) src/provisioningserver/dhcp/config.py (+38/-30) src/provisioningserver/dhcp/testing/config.py (+6/-2) src/provisioningserver/dhcp/tests/test_config.py (+24/-9) src/provisioningserver/rpc/cluster.py (+1/-0) src/provisioningserver/rpc/dhcp.py (+1/-0) src/provisioningserver/rpc/tests/test_clusterservice.py (+6/-1) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Newell Jensen (community) | Approve | ||
MAAS Lander | Approve | ||
Review via email: mp+371302@code.launchpad.net |
Commit message
Fixes LP: #1836276 - Select IP address from interface for shared network defined from the region controller, allowing relayed VLAN's to point to the correct IP address on the rack controller.
Description of the change
To post a comment you must log in.
Revision history for this message
Adam Collard (adam-collard) : | # |
~blake-rouse/maas:fix-1836276
updated
- 21213e9... by Blake Rouse
-
Extract if statement.
Revision history for this message
Blake Rouse (blake-rouse) wrote : | # |
Thanks for the review. I extracted the if statement into a helper function, much cleaner, thanks for the suggestion.
Revision history for this message
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b fix-1836276 lp:~blake-rouse/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: SUCCESS
COMMIT: 21213e9f59ad439
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/dhcp.py b/src/maasserver/dhcp.py |
2 | index 21faa35..ab47384 100644 |
3 | --- a/src/maasserver/dhcp.py |
4 | +++ b/src/maasserver/dhcp.py |
5 | @@ -151,6 +151,17 @@ def _key_interface_subnet_dynamic_range_count(interface): |
6 | return count |
7 | |
8 | |
9 | +def _ip_version_on_vlan(ip_address, ip_version, vlan): |
10 | + """Return True when the `ip_address` is the same `ip_version` and is on |
11 | + the same `vlan` or relay VLAN's for the `vlan.""" |
12 | + return ( |
13 | + ip_is_version(ip_address, ip_version) and |
14 | + ip_address.subnet is not None and |
15 | + ip_address.subnet.vlan is not None and ( |
16 | + ip_address.subnet.vlan == vlan or |
17 | + vlan in list(ip_address.subnet.vlan.relay_vlans.all()))) |
18 | + |
19 | + |
20 | def get_interfaces_with_ip_on_vlan(rack_controller, vlan, ip_version): |
21 | """Return a list of interfaces that have an assigned IP address on `vlan`. |
22 | |
23 | @@ -164,20 +175,16 @@ def get_interfaces_with_ip_on_vlan(rack_controller, vlan, ip_version): |
24 | interfaces_with_static = [] |
25 | interfaces_with_discovered = [] |
26 | for interface in rack_controller.interface_set.all().prefetch_related( |
27 | - "ip_addresses__subnet__vlan", |
28 | + "ip_addresses__subnet__vlan__relay_vlans", |
29 | "ip_addresses__subnet__iprange_set"): |
30 | for ip_address in interface.ip_addresses.all(): |
31 | if ip_address.alloc_type in [ |
32 | IPADDRESS_TYPE.AUTO, IPADDRESS_TYPE.STICKY]: |
33 | - if (ip_is_version(ip_address, ip_version) and |
34 | - ip_address.subnet is not None and |
35 | - ip_address.subnet.vlan == vlan): |
36 | + if _ip_version_on_vlan(ip_address, ip_version, vlan): |
37 | interfaces_with_static.append(interface) |
38 | break |
39 | elif ip_address.alloc_type == IPADDRESS_TYPE.DISCOVERED: |
40 | - if (ip_is_version(ip_address, ip_version) and |
41 | - ip_address.subnet is not None and |
42 | - ip_address.subnet.vlan == vlan): |
43 | + if _ip_version_on_vlan(ip_address, ip_version, vlan): |
44 | interfaces_with_discovered.append(interface) |
45 | break |
46 | if len(interfaces_with_static) == 1: |
47 | @@ -689,14 +696,16 @@ def get_dhcp_configuration(rack_controller, test_dhcp_snippet=None): |
48 | failover_peer, subnets, hosts, interface = config |
49 | if failover_peer is not None: |
50 | failover_peers_v4.append(failover_peer) |
51 | - shared_networks_v4.append({ |
52 | + shared_network = { |
53 | "name": "vlan-%d" % vlan.id, |
54 | "mtu": vlan.mtu, |
55 | "subnets": subnets, |
56 | - }) |
57 | + } |
58 | + shared_networks_v4.append(shared_network) |
59 | hosts_v4.extend(hosts) |
60 | if interface is not None: |
61 | interfaces_v4.add(interface) |
62 | + shared_network["interface"] = interface |
63 | # IPv6 |
64 | if len(subnets_v6) > 0: |
65 | config = get_dhcp_configure_for( |
66 | @@ -706,14 +715,16 @@ def get_dhcp_configuration(rack_controller, test_dhcp_snippet=None): |
67 | failover_peer, subnets, hosts, interface = config |
68 | if failover_peer is not None: |
69 | failover_peers_v6.append(failover_peer) |
70 | - shared_networks_v6.append({ |
71 | + shared_network = { |
72 | "name": "vlan-%d" % vlan.id, |
73 | "mtu": vlan.mtu, |
74 | "subnets": subnets, |
75 | - }) |
76 | + } |
77 | + shared_networks_v6.append(shared_network) |
78 | hosts_v6.extend(hosts) |
79 | if interface is not None: |
80 | interfaces_v6.add(interface) |
81 | + shared_network["interface"] = interface |
82 | # When no interfaces exist for each IP version clear the shared networks |
83 | # as DHCP server cannot be started and needs to be stopped. |
84 | if len(interfaces_v4) == 0: |
85 | diff --git a/src/maasserver/tests/test_dhcp.py b/src/maasserver/tests/test_dhcp.py |
86 | index 8601d84..2c25bcc 100644 |
87 | --- a/src/maasserver/tests/test_dhcp.py |
88 | +++ b/src/maasserver/tests/test_dhcp.py |
89 | @@ -266,7 +266,7 @@ class TestGetInterfacesWithIPOnVLAN(MAASServerTestCase): |
90 | # affects the number of queries performed when performing this |
91 | # operation. It is important to keep this number as low as possible. |
92 | self.assertEqual( |
93 | - query_10_count, 5, |
94 | + query_10_count, 6, |
95 | "Number of queries has changed; make sure this is expected.") |
96 | self.assertEqual( |
97 | query_10_count, query_20_count, |
98 | @@ -426,6 +426,42 @@ class TestGetInterfacesWithIPOnVLAN(MAASServerTestCase): |
99 | dhcp.get_interfaces_with_ip_on_vlan( |
100 | rack_controller, vlan, subnet.get_ipnetwork().version)) |
101 | |
102 | + def test__returns_interface_with_static_ip_on_vlan_from_relay(self): |
103 | + rack_controller = factory.make_RackController() |
104 | + vlan = factory.make_VLAN() |
105 | + relayed_to_another = factory.make_VLAN(relay_vlan=vlan) |
106 | + subnet = factory.make_Subnet(vlan=vlan) |
107 | + interface = factory.make_Interface( |
108 | + INTERFACE_TYPE.PHYSICAL, node=rack_controller, vlan=vlan) |
109 | + factory.make_StaticIPAddress( |
110 | + alloc_type=IPADDRESS_TYPE.AUTO, subnet=subnet, interface=interface) |
111 | + self.assertEquals( |
112 | + [interface], |
113 | + dhcp.get_interfaces_with_ip_on_vlan( |
114 | + rack_controller, relayed_to_another, |
115 | + subnet.get_ipnetwork().version)) |
116 | + |
117 | + def test__returns_interfaces_with_discovered_ips_on_vlan_from_relay(self): |
118 | + rack_controller = factory.make_RackController() |
119 | + vlan = factory.make_VLAN() |
120 | + relayed_to_another = factory.make_VLAN(relay_vlan=vlan) |
121 | + subnet = factory.make_Subnet(vlan=vlan) |
122 | + interface_one = factory.make_Interface( |
123 | + INTERFACE_TYPE.PHYSICAL, node=rack_controller, vlan=vlan) |
124 | + factory.make_StaticIPAddress( |
125 | + alloc_type=IPADDRESS_TYPE.DISCOVERED, |
126 | + subnet=subnet, interface=interface_one) |
127 | + interface_two = factory.make_Interface( |
128 | + INTERFACE_TYPE.PHYSICAL, node=rack_controller, vlan=vlan) |
129 | + factory.make_StaticIPAddress( |
130 | + alloc_type=IPADDRESS_TYPE.DISCOVERED, |
131 | + subnet=subnet, interface=interface_two) |
132 | + self.assertItemsEqual( |
133 | + [interface_one, interface_two], |
134 | + dhcp.get_interfaces_with_ip_on_vlan( |
135 | + rack_controller, relayed_to_another, |
136 | + subnet.get_ipnetwork().version)) |
137 | + |
138 | |
139 | class TestGenManagedVLANsFor(MAASServerTestCase): |
140 | """Tests for `gen_managed_vlans_for`.""" |
141 | diff --git a/src/provisioningserver/dhcp/config.py b/src/provisioningserver/dhcp/config.py |
142 | index 7199e83..63bd67f 100644 |
143 | --- a/src/provisioningserver/dhcp/config.py |
144 | +++ b/src/provisioningserver/dhcp/config.py |
145 | @@ -350,6 +350,32 @@ def normalise_any_iterable_to_quoted_comma_list(iterable): |
146 | return ", ".join(map(quote, iterable)) |
147 | |
148 | |
149 | +def get_rack_ip_for_subnet(version, cidr, interface): |
150 | + """ |
151 | + Return the IP address on this rack controller. |
152 | + |
153 | + First the code will try to find an IP address that is in the cidr, but if |
154 | + not it will use the first IP address on the interface (to support |
155 | + VLAN relay). |
156 | + """ |
157 | + cidr = IPNetwork(cidr) |
158 | + if interface: |
159 | + ip_addresses = [ |
160 | + IPAddress(addr) |
161 | + for addr in net_utils.get_all_addresses_for_interface(interface)] |
162 | + else: |
163 | + ip_addresses = [ |
164 | + IPAddress(addr) |
165 | + for addr in net_utils.get_all_interface_addresses()] |
166 | + for ip_addr in ip_addresses: |
167 | + if ip_addr in cidr: |
168 | + return ip_addr |
169 | + for ip_addr in ip_addresses: |
170 | + if ip_addr.version == version: |
171 | + return ip_addr |
172 | + return None |
173 | + |
174 | + |
175 | @typed |
176 | def get_config_v4( |
177 | template_name: str, global_dhcp_snippets: Sequence[dict], |
178 | @@ -373,22 +399,15 @@ def get_config_v4( |
179 | "running_in_snap": snappy.running_in_snap(), |
180 | } |
181 | |
182 | - rack_addrs = [ |
183 | - IPAddress(addr) |
184 | - for addr in net_utils.get_all_interface_addresses()] |
185 | - |
186 | for shared_network in shared_networks: |
187 | + interface = shared_network.get("interface", None) |
188 | for subnet in shared_network["subnets"]: |
189 | - cidr = IPNetwork(subnet['subnet_cidr']) |
190 | - rack_ips = [ |
191 | - str(rack_addr) |
192 | - for rack_addr in rack_addrs |
193 | - if rack_addr in cidr |
194 | - ] |
195 | - if len(rack_ips) > 0: |
196 | - subnet["next_server"] = rack_ips[0] |
197 | + rack_ip = get_rack_ip_for_subnet( |
198 | + 4, subnet['subnet_cidr'], interface) |
199 | + if rack_ip is not None: |
200 | + subnet["next_server"] = rack_ip |
201 | subnet["bootloader"] = compose_conditional_bootloader( |
202 | - False, rack_ips[0]) |
203 | + False, rack_ip) |
204 | ntp_servers = subnet["ntp_servers"] # Is a list. |
205 | ntp_servers_ipv4, ntp_servers_ipv6 = _get_addresses(*ntp_servers) |
206 | subnet["ntp_servers_ipv4"] = ", ".join(ntp_servers_ipv4) |
207 | @@ -428,12 +447,8 @@ def get_config_v6( |
208 | "running_in_snap": snappy.running_in_snap(), |
209 | } |
210 | |
211 | - rack_addrs = [ |
212 | - IPAddress(addr) |
213 | - for addr in net_utils.get_all_interface_addresses()] |
214 | - |
215 | shared_networks = _process_network_parameters_v6( |
216 | - rack_addrs, failover_peers, shared_networks) |
217 | + failover_peers, shared_networks) |
218 | |
219 | try: |
220 | return template.substitute( |
221 | @@ -446,15 +461,12 @@ def get_config_v6( |
222 | "Failed to render DHCP configuration.") from error |
223 | |
224 | |
225 | -def _process_network_parameters_v6( |
226 | - rack_addrs, failover_peers, shared_networks): |
227 | +def _process_network_parameters_v6(failover_peers, shared_networks): |
228 | """Preprocess shared_networks prior to rendering the template. |
229 | |
230 | This is a separate function, partly for readability, and partly for ease |
231 | of testing. |
232 | |
233 | - :param rack_addrs: a list of IPAddress values for the interfaces on this |
234 | - rack controller. |
235 | :param failover_peers: failover_peers from get_config_v6. |
236 | :param shared_networks: shared_networks from get_config_v6. |
237 | :return: an updated shared_networks, suitable for rendering the template. |
238 | @@ -462,15 +474,11 @@ def _process_network_parameters_v6( |
239 | peers = {x["name"]: x for x in failover_peers} |
240 | |
241 | for shared_network in shared_networks: |
242 | + interface = shared_network.get("interface", None) |
243 | for subnet in shared_network["subnets"]: |
244 | - cidr = IPNetwork(subnet['subnet_cidr']) |
245 | - rack_ip_found = False |
246 | - for rack_addr in rack_addrs: |
247 | - if rack_addr in cidr: |
248 | - rack_ip = str(rack_addr) |
249 | - rack_ip_found = True |
250 | - break |
251 | - if rack_ip_found: |
252 | + rack_ip = get_rack_ip_for_subnet( |
253 | + 6, subnet['subnet_cidr'], interface) |
254 | + if rack_ip is not None: |
255 | subnet["bootloader"] = compose_conditional_bootloader( |
256 | True, rack_ip) |
257 | ntp_servers = subnet["ntp_servers"] # Is a list. |
258 | diff --git a/src/provisioningserver/dhcp/testing/config.py b/src/provisioningserver/dhcp/testing/config.py |
259 | index c2640d4..068f82f 100644 |
260 | --- a/src/provisioningserver/dhcp/testing/config.py |
261 | +++ b/src/provisioningserver/dhcp/testing/config.py |
262 | @@ -133,7 +133,8 @@ def make_subnet_config(network=None, pools=None, ipv6=False, |
263 | } |
264 | |
265 | |
266 | -def make_shared_network(name=None, subnets=None, ipv6=False): |
267 | +def make_shared_network( |
268 | + name=None, subnets=None, ipv6=False, with_interface=False): |
269 | """Return complete DHCP configuration dict for a shared network.""" |
270 | if name is None: |
271 | name = factory.make_name("vlan") |
272 | @@ -142,11 +143,14 @@ def make_shared_network(name=None, subnets=None, ipv6=False): |
273 | make_subnet_config(ipv6=ipv6) |
274 | for _ in range(3) |
275 | ] |
276 | - return { |
277 | + data = { |
278 | "name": name, |
279 | "mtu": 1500, |
280 | "subnets": subnets, |
281 | } |
282 | + if with_interface: |
283 | + data["interface"] = factory.make_name("eth") |
284 | + return data |
285 | |
286 | |
287 | def make_shared_network_v1(name=None, subnets=None, ipv6=False): |
288 | diff --git a/src/provisioningserver/dhcp/tests/test_config.py b/src/provisioningserver/dhcp/tests/test_config.py |
289 | index 13d6a18..69deb0e 100644 |
290 | --- a/src/provisioningserver/dhcp/tests/test_config.py |
291 | +++ b/src/provisioningserver/dhcp/tests/test_config.py |
292 | @@ -61,7 +61,7 @@ def is_ip_address(string): |
293 | return True |
294 | |
295 | |
296 | -def make_sample_params_only(ipv6=False): |
297 | +def make_sample_params_only(ipv6=False, with_interface=False): |
298 | """Return a dict of arbitrary DHCP configuration parameters. |
299 | |
300 | :param ipv6: When true, prepare configuration for a DHCPv6 server, |
301 | @@ -73,7 +73,7 @@ def make_sample_params_only(ipv6=False): |
302 | for _ in range(3) |
303 | ] |
304 | shared_networks = [ |
305 | - make_shared_network(ipv6=ipv6) |
306 | + make_shared_network(ipv6=ipv6, with_interface=with_interface) |
307 | for _ in range(3) |
308 | ] |
309 | |
310 | @@ -114,7 +114,7 @@ def read_aliases_from_etc_hosts(): |
311 | aliases_from_etc_hosts = tuple(read_aliases_from_etc_hosts()) |
312 | |
313 | |
314 | -def make_sample_params(test, ipv6=False): |
315 | +def make_sample_params(test, ipv6=False, with_interface=False): |
316 | """Return a dict of arbitrary DHCP configuration parameters. |
317 | |
318 | This differs from `make_sample_params_only` in that it arranges it such |
319 | @@ -126,7 +126,8 @@ def make_sample_params(test, ipv6=False): |
320 | otherwise prepare configuration for a DHCPv4 server. |
321 | :return: A dictionary of sample configuration. |
322 | """ |
323 | - sample_params = make_sample_params_only(ipv6=ipv6) |
324 | + sample_params = make_sample_params_only( |
325 | + ipv6=ipv6, with_interface=with_interface) |
326 | |
327 | # So that get_config can resolve the configuration, collect hostnames from |
328 | # the sample params that need to resolve then replace them with names that |
329 | @@ -433,7 +434,7 @@ class TestGetConfig(MAASTestCase): |
330 | class TestGetConfigIPv4(MAASTestCase): |
331 | """Tests for `get_config`.""" |
332 | |
333 | - def test__includes_next_server_in_config(self): |
334 | + def test__includes_next_server_in_config_from_all_addresses(self): |
335 | params = make_sample_params(self, ipv6=False) |
336 | subnet = params['shared_networks'][0]['subnets'][0] |
337 | next_server_ip = factory.pick_ip_in_network( |
338 | @@ -446,6 +447,20 @@ class TestGetConfigIPv4(MAASTestCase): |
339 | self.assertThat( |
340 | config_output, Contains('next-server %s;' % next_server_ip)) |
341 | |
342 | + def test__includes_next_server_in_config_from_interface_addresses(self): |
343 | + params = make_sample_params(self, ipv6=False, with_interface=True) |
344 | + subnet = params['shared_networks'][0]['subnets'][0] |
345 | + next_server_ip = factory.pick_ip_in_network( |
346 | + netaddr.IPNetwork(subnet['subnet_cidr'])) |
347 | + self.patch( |
348 | + net_utils, 'get_all_addresses_for_interface').return_value = [ |
349 | + next_server_ip |
350 | + ] |
351 | + config_output = config.get_config('dhcpd.conf.template', **params) |
352 | + validate_dhcpd_configuration(self, config_output, False) |
353 | + self.assertThat( |
354 | + config_output, Contains('next-server %s;' % next_server_ip)) |
355 | + |
356 | |
357 | class Test_process_shared_network_v6(MAASTestCase): |
358 | """Tests for `_process_network_parameters_v6`.""" |
359 | @@ -456,14 +471,12 @@ class Test_process_shared_network_v6(MAASTestCase): |
360 | 'ip_range_high': '2001:db8:3:1::ffff', |
361 | 'ip_range_low': '2001:db8:3:1::', |
362 | 'failover_peer': None}, |
363 | - rack_addrs=[netaddr.IPAddress('2001:db8:3:280::2')], |
364 | failover_peers=[])), |
365 | ('primary', dict( |
366 | expected={ |
367 | 'ip_range_high': '2001:db8:3:1::7fff', |
368 | 'ip_range_low': '2001:db8:3:1::', |
369 | 'failover_peer': 'failover-vlan-5020'}, |
370 | - rack_addrs=[netaddr.IPAddress('2001:db8:3:280::2')], |
371 | failover_peers=[{ |
372 | 'mode': 'primary', |
373 | 'peer_address': '2001:db8:3:0:1::', |
374 | @@ -474,7 +487,6 @@ class Test_process_shared_network_v6(MAASTestCase): |
375 | 'ip_range_high': '2001:db8:3:1::ffff', |
376 | 'ip_range_low': '2001:db8:3:1::8000', |
377 | 'failover_peer': 'failover-vlan-5020'}, |
378 | - rack_addrs=[netaddr.IPAddress('2001:db8:3:0:1::')], |
379 | failover_peers=[{ |
380 | 'mode': 'secondary', |
381 | 'address': '2001:db8:3:0:1::', |
382 | @@ -485,6 +497,7 @@ class Test_process_shared_network_v6(MAASTestCase): |
383 | shared_networks = [ |
384 | { |
385 | 'name': 'vlan-5020', |
386 | + 'interface': 'eth0', |
387 | 'subnets': [ |
388 | { |
389 | 'domain_name': 'maas.example.com', |
390 | @@ -503,12 +516,14 @@ class Test_process_shared_network_v6(MAASTestCase): |
391 | }], |
392 | }] |
393 | self.patch( |
394 | + config, 'get_rack_ip_for_subnet').return_value = None |
395 | + self.patch( |
396 | config, 'compose_conditional_bootloader').return_value = "" |
397 | self.patch( |
398 | config, '_get_addresses').return_value = ( |
399 | [''], ['2001:db8:280::2']) |
400 | actual = config._process_network_parameters_v6( |
401 | - self.rack_addrs, self.failover_peers, shared_networks) |
402 | + self.failover_peers, shared_networks) |
403 | self.assertDictEqual( |
404 | actual[0]['subnets'][0]['pools'][0], self.expected) |
405 | |
406 | diff --git a/src/provisioningserver/rpc/cluster.py b/src/provisioningserver/rpc/cluster.py |
407 | index 5469cf1..40988e2 100644 |
408 | --- a/src/provisioningserver/rpc/cluster.py |
409 | +++ b/src/provisioningserver/rpc/cluster.py |
410 | @@ -416,6 +416,7 @@ class _ConfigureDHCP_V2(amp.Command): |
411 | ], optional=True)), |
412 | ])), |
413 | (b"mtu", amp.Integer(optional=True)), |
414 | + (b"interface", amp.Unicode(optional=True)), |
415 | ])), |
416 | (b"hosts", CompressedAmpList([ |
417 | (b"host", amp.Unicode()), |
418 | diff --git a/src/provisioningserver/rpc/dhcp.py b/src/provisioningserver/rpc/dhcp.py |
419 | index dc42518..babf9ed 100644 |
420 | --- a/src/provisioningserver/rpc/dhcp.py |
421 | +++ b/src/provisioningserver/rpc/dhcp.py |
422 | @@ -529,6 +529,7 @@ def downgrade_shared_networks(shared_networks): |
423 | Mutates `shared_networks` in place. |
424 | """ |
425 | for shared_network in shared_networks: |
426 | + shared_network.pop("interface", None) |
427 | for subnet in shared_network["subnets"]: |
428 | dns_servers = subnet["dns_servers"] |
429 | if not isinstance(dns_servers, str): |
430 | diff --git a/src/provisioningserver/rpc/tests/test_clusterservice.py b/src/provisioningserver/rpc/tests/test_clusterservice.py |
431 | index 07e1645..0b19738 100644 |
432 | --- a/src/provisioningserver/rpc/tests/test_clusterservice.py |
433 | +++ b/src/provisioningserver/rpc/tests/test_clusterservice.py |
434 | @@ -2323,6 +2323,7 @@ class TestClusterProtocol_ConfigureDHCP(MAASTestCase): |
435 | "command": cluster.ConfigureDHCPv4, |
436 | "make_network": factory.make_ipv4_network, |
437 | "make_shared_network": make_shared_network_v1, |
438 | + "make_shared_network_kwargs": {}, |
439 | "concurrency_lock": concurrency.dhcpv4, |
440 | }), |
441 | ("DHCPv4,V2", { |
442 | @@ -2330,6 +2331,7 @@ class TestClusterProtocol_ConfigureDHCP(MAASTestCase): |
443 | "command": cluster.ConfigureDHCPv4_V2, |
444 | "make_network": factory.make_ipv4_network, |
445 | "make_shared_network": make_shared_network, |
446 | + "make_shared_network_kwargs": {"with_interface": True}, |
447 | "concurrency_lock": concurrency.dhcpv4, |
448 | }), |
449 | ("DHCPv6", { |
450 | @@ -2337,6 +2339,7 @@ class TestClusterProtocol_ConfigureDHCP(MAASTestCase): |
451 | "command": cluster.ConfigureDHCPv6, |
452 | "make_network": factory.make_ipv6_network, |
453 | "make_shared_network": make_shared_network_v1, |
454 | + "make_shared_network_kwargs": {}, |
455 | "concurrency_lock": concurrency.dhcpv6, |
456 | }), |
457 | ("DHCPv6,V2", { |
458 | @@ -2344,6 +2347,7 @@ class TestClusterProtocol_ConfigureDHCP(MAASTestCase): |
459 | "command": cluster.ConfigureDHCPv6_V2, |
460 | "make_network": factory.make_ipv6_network, |
461 | "make_shared_network": make_shared_network, |
462 | + "make_shared_network_kwargs": {"with_interface": True}, |
463 | "concurrency_lock": concurrency.dhcpv6, |
464 | }), |
465 | ) |
466 | @@ -2361,7 +2365,8 @@ class TestClusterProtocol_ConfigureDHCP(MAASTestCase): |
467 | |
468 | omapi_key = factory.make_name('key') |
469 | failover_peers = [make_failover_peer_config()] |
470 | - shared_networks = [self.make_shared_network()] |
471 | + shared_networks = [self.make_shared_network( |
472 | + **self.make_shared_network_kwargs)] |
473 | shared_networks = fix_shared_networks_failover( |
474 | shared_networks, failover_peers) |
475 | hosts = [make_host()] |
UNIT TESTS
-b fix-1836276 lp:~blake-rouse/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: SUCCESS b8cbb526178a09a 5ae41b94a8
COMMIT: 6bd4762051b3ec6