Merge lp:~julian-edwards/maas/pxeconfig-updates-cluster-interface-bug-1387859 into lp:~maas-committers/maas/trunk
- pxeconfig-updates-cluster-interface-bug-1387859
- Merge into trunk
Proposed by
Julian Edwards
Status: | Merged |
---|---|
Approved by: | Julian Edwards |
Approved revision: | no longer in the source branch. |
Merged at revision: | 3407 |
Proposed branch: | lp:~julian-edwards/maas/pxeconfig-updates-cluster-interface-bug-1387859 |
Merge into: | lp:~maas-committers/maas/trunk |
Diff against target: |
352 lines (+96/-109) 7 files modified
src/maasserver/api/pxeconfig.py (+5/-1) src/maasserver/api/tests/test_pxeconfig.py (+14/-0) src/maasserver/models/macaddress.py (+33/-32) src/maasserver/models/node.py (+9/-5) src/maasserver/models/tests/test_macaddress.py (+35/-44) src/maasserver/rpc/leases.py (+0/-2) src/maasserver/rpc/tests/test_regionservice.py (+0/-25) |
To merge this branch: | bzr merge lp:~julian-edwards/maas/pxeconfig-updates-cluster-interface-bug-1387859 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Graham Binns (community) | Approve | ||
Review via email: mp+243937@code.launchpad.net |
Commit message
Set the mac.cluster_
Description of the change
Thanks to whomever wrote the Node.add_mac tests which don't use patching, and instead test the desired behaviour — it meant that I could just change the underlying code and watch it pass.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/maasserver/api/pxeconfig.py' | |||
2 | --- src/maasserver/api/pxeconfig.py 2014-12-05 16:13:38 +0000 | |||
3 | +++ src/maasserver/api/pxeconfig.py 2014-12-08 02:56:05 +0000 | |||
4 | @@ -34,6 +34,7 @@ | |||
5 | 34 | MACAddress, | 34 | MACAddress, |
6 | 35 | NodeGroup, | 35 | NodeGroup, |
7 | 36 | ) | 36 | ) |
8 | 37 | from maasserver.models.macaddress import update_mac_cluster_interfaces | ||
9 | 37 | from maasserver.preseed import ( | 38 | from maasserver.preseed import ( |
10 | 38 | compose_enlistment_preseed_url, | 39 | compose_enlistment_preseed_url, |
11 | 39 | compose_preseed_url, | 40 | compose_preseed_url, |
12 | @@ -163,12 +164,15 @@ | |||
13 | 163 | is preferred. | 164 | is preferred. |
14 | 164 | """ | 165 | """ |
15 | 165 | request_mac = request.GET.get('mac', None) | 166 | request_mac = request.GET.get('mac', None) |
16 | 167 | request_ip = request.GET.get('remote', None) | ||
17 | 166 | node = get_node_from_mac_string(request_mac) | 168 | node = get_node_from_mac_string(request_mac) |
18 | 167 | 169 | ||
19 | 168 | if node is not None: | 170 | if node is not None: |
21 | 169 | # Update the record of which MAC address this node uses to PXE boot. | 171 | # Update the record of which MAC address and cluster interface |
22 | 172 | # this node uses to PXE boot. | ||
23 | 170 | node.pxe_mac = MACAddress.objects.get(mac_address=request_mac) | 173 | node.pxe_mac = MACAddress.objects.get(mac_address=request_mac) |
24 | 171 | node.save() | 174 | node.save() |
25 | 175 | update_mac_cluster_interfaces(request_ip, request_mac, node.nodegroup) | ||
26 | 172 | 176 | ||
27 | 173 | if node is None or node.get_boot_purpose() == "commissioning": | 177 | if node is None or node.get_boot_purpose() == "commissioning": |
28 | 174 | osystem = Config.objects.get_config('commissioning_osystem') | 178 | osystem = Config.objects.get_config('commissioning_osystem') |
29 | 175 | 179 | ||
30 | === modified file 'src/maasserver/api/tests/test_pxeconfig.py' | |||
31 | --- src/maasserver/api/tests/test_pxeconfig.py 2014-12-05 16:13:38 +0000 | |||
32 | +++ src/maasserver/api/tests/test_pxeconfig.py 2014-12-08 02:56:05 +0000 | |||
33 | @@ -576,3 +576,17 @@ | |||
34 | 576 | params_out = self.get_pxeconfig(params) | 576 | params_out = self.get_pxeconfig(params) |
35 | 577 | self.assertEqual(commissioning_osystem, params_out['osystem']) | 577 | self.assertEqual(commissioning_osystem, params_out['osystem']) |
36 | 578 | self.assertEqual(commissioning_series, params_out['release']) | 578 | self.assertEqual(commissioning_series, params_out['release']) |
37 | 579 | |||
38 | 580 | def test_pxeconfig_updates_cluster_interface_for_request_mac(self): | ||
39 | 581 | params = self.get_mac_params() | ||
40 | 582 | node = factory.make_Node(mac=True) | ||
41 | 583 | params['cluster_uuid'] = node.nodegroup.uuid | ||
42 | 584 | params['mac'] = node.get_primary_mac() | ||
43 | 585 | update_mac_cluster_interfaces = self.patch( | ||
44 | 586 | pxeconfig_module, 'update_mac_cluster_interfaces') | ||
45 | 587 | response = self.client.get(reverse('pxeconfig'), params) | ||
46 | 588 | self.assertEqual(httplib.OK, response.status_code, response.content) | ||
47 | 589 | self.assertThat( | ||
48 | 590 | update_mac_cluster_interfaces, | ||
49 | 591 | MockCalledOnceWith( | ||
50 | 592 | params['remote'], unicode(params['mac']), node.nodegroup)) | ||
51 | 579 | 593 | ||
52 | === modified file 'src/maasserver/models/macaddress.py' | |||
53 | --- src/maasserver/models/macaddress.py 2014-11-27 11:06:23 +0000 | |||
54 | +++ src/maasserver/models/macaddress.py 2014-12-08 02:56:05 +0000 | |||
55 | @@ -65,8 +65,14 @@ | |||
56 | 65 | return None | 65 | return None |
57 | 66 | 66 | ||
58 | 67 | 67 | ||
60 | 68 | def update_mac_cluster_interfaces(leases, cluster): | 68 | def update_mac_cluster_interfaces(ip, mac, cluster): |
61 | 69 | """Calculate and store which interface a MAC is attached to.""" | 69 | """Calculate and store which interface a MAC is attached to.""" |
62 | 70 | try: | ||
63 | 71 | mac_address = MACAddress.objects.get(mac_address=mac) | ||
64 | 72 | except MACAddress.DoesNotExist: | ||
65 | 73 | # Silently ignore MAC addresses that we don't know about. | ||
66 | 74 | return | ||
67 | 75 | |||
68 | 70 | interface_ranges = {} | 76 | interface_ranges = {} |
69 | 71 | # Only consider configured interfaces. | 77 | # Only consider configured interfaces. |
70 | 72 | interfaces = ( | 78 | interfaces = ( |
71 | @@ -74,6 +80,8 @@ | |||
72 | 74 | .exclude(ip_range_low__isnull=True) | 80 | .exclude(ip_range_low__isnull=True) |
73 | 75 | .exclude(ip_range_high__isnull=True) | 81 | .exclude(ip_range_high__isnull=True) |
74 | 76 | ) | 82 | ) |
75 | 83 | # Pre-calculate a dict of interface ranges, keyed by cluster | ||
76 | 84 | # interface. | ||
77 | 77 | for interface in interfaces: | 85 | for interface in interfaces: |
78 | 78 | ip_range = IPRange( | 86 | ip_range = IPRange( |
79 | 79 | interface.ip_range_low, interface.ip_range_high) | 87 | interface.ip_range_low, interface.ip_range_high) |
80 | @@ -83,37 +91,30 @@ | |||
81 | 83 | else: | 91 | else: |
82 | 84 | static_range = [] | 92 | static_range = [] |
83 | 85 | interface_ranges[interface] = (ip_range, static_range) | 93 | interface_ranges[interface] = (ip_range, static_range) |
115 | 86 | for ip, mac in leases.items(): | 94 | |
116 | 87 | try: | 95 | # Look through the interface ranges to see if any match the passed |
117 | 88 | mac_address = MACAddress.objects.get(mac_address=mac) | 96 | # IP address. |
118 | 89 | except MACAddress.DoesNotExist: | 97 | for interface, (ip_range, static_range) in interface_ranges.items(): |
119 | 90 | # Silently ignore MAC addresses that we don't know about. | 98 | ipaddress = IPAddress(ip) |
120 | 91 | continue | 99 | # Set the cluster interface only if it's new/changed. |
121 | 92 | for interface, (ip_range, static_range) in interface_ranges.items(): | 100 | # This is only an optimisation to prevent repeated logging. |
122 | 93 | ipaddress = IPAddress(ip) | 101 | changed = mac_address.cluster_interface != interface |
123 | 94 | # Set the cluster interface only if it's new/changed. | 102 | in_range = ipaddress in ip_range or ipaddress in static_range |
124 | 95 | # This is only an optimisation to prevent repeated logging. | 103 | if in_range and changed: |
125 | 96 | changed = mac_address.cluster_interface != interface | 104 | mac_address.cluster_interface = interface |
126 | 97 | in_range = ipaddress in ip_range or ipaddress in static_range | 105 | mac_address.save() |
127 | 98 | if in_range and changed: | 106 | maaslog.info( |
128 | 99 | mac_address.cluster_interface = interface | 107 | "%s %s linked to cluster interface %s", |
129 | 100 | mac_address.save() | 108 | mac_address.node.hostname, mac_address, interface.name) |
130 | 101 | maaslog.info( | 109 | |
131 | 102 | "%s %s linked to cluster interface %s", | 110 | # Locate the Network to which this MAC belongs and link it. |
132 | 103 | mac_address.node.hostname, mac_address, interface.name) | 111 | ipnetwork = interface.network |
133 | 104 | 112 | if ipnetwork is not None: | |
134 | 105 | # Locate the Network to which this MAC belongs. | 113 | try: |
135 | 106 | ipnetwork = interface.network | 114 | network = Network.objects.get(ip=ipnetwork.ip.format()) |
136 | 107 | if ipnetwork is not None: | 115 | network.macaddress_set.add(mac_address) |
137 | 108 | try: | 116 | except Network.DoesNotExist: |
138 | 109 | network = Network.objects.get(ip=ipnetwork.ip.format()) | 117 | pass |
108 | 110 | network.macaddress_set.add(mac_address) | ||
109 | 111 | except Network.DoesNotExist: | ||
110 | 112 | pass | ||
111 | 113 | |||
112 | 114 | # Cheap optimisation. No other interfaces will match, so | ||
113 | 115 | # break out of the loop. | ||
114 | 116 | break | ||
139 | 117 | 118 | ||
140 | 118 | 119 | ||
141 | 119 | class MACAddress(CleanSave, TimestampedModel): | 120 | class MACAddress(CleanSave, TimestampedModel): |
142 | 120 | 121 | ||
143 | === modified file 'src/maasserver/models/node.py' | |||
144 | --- src/maasserver/models/node.py 2014-12-05 21:32:33 +0000 | |||
145 | +++ src/maasserver/models/node.py 2014-12-08 02:56:05 +0000 | |||
146 | @@ -105,7 +105,10 @@ | |||
147 | 105 | get_db_state, | 105 | get_db_state, |
148 | 106 | strip_domain, | 106 | strip_domain, |
149 | 107 | ) | 107 | ) |
151 | 108 | from maasserver.utils.orm import commit_within_atomic_block | 108 | from maasserver.utils.orm import ( |
152 | 109 | commit_within_atomic_block, | ||
153 | 110 | get_one, | ||
154 | 111 | ) | ||
155 | 109 | from metadataserver.enum import RESULT_TYPE | 112 | from metadataserver.enum import RESULT_TYPE |
156 | 110 | from metadataserver.models import NodeResult | 113 | from metadataserver.models import NodeResult |
157 | 111 | from netaddr import IPAddress | 114 | from netaddr import IPAddress |
158 | @@ -783,10 +786,11 @@ | |||
159 | 783 | 786 | ||
160 | 784 | # See if there's a lease for this MAC and set its | 787 | # See if there's a lease for this MAC and set its |
161 | 785 | # cluster_interface if so. | 788 | # cluster_interface if so. |
166 | 786 | nodegroup_leases = { | 789 | leases = DHCPLease.objects.filter( |
167 | 787 | lease.ip: lease.mac | 790 | nodegroup=self.nodegroup, mac=mac.mac_address) |
168 | 788 | for lease in DHCPLease.objects.filter(nodegroup=self.nodegroup)} | 791 | lease = get_one(leases) |
169 | 789 | update_mac_cluster_interfaces(nodegroup_leases, self.nodegroup) | 792 | if lease is not None: |
170 | 793 | update_mac_cluster_interfaces(lease.ip, lease.mac, self.nodegroup) | ||
171 | 790 | 794 | ||
172 | 791 | return mac | 795 | return mac |
173 | 792 | 796 | ||
174 | 793 | 797 | ||
175 | === modified file 'src/maasserver/models/tests/test_macaddress.py' | |||
176 | --- src/maasserver/models/tests/test_macaddress.py 2014-11-27 11:06:23 +0000 | |||
177 | +++ src/maasserver/models/tests/test_macaddress.py 2014-12-08 02:56:05 +0000 | |||
178 | @@ -736,49 +736,45 @@ | |||
179 | 736 | } | 736 | } |
180 | 737 | return cluster, mac_addresses, leases | 737 | return cluster, mac_addresses, leases |
181 | 738 | 738 | ||
182 | 739 | def make_cluster_with_mac_and_node_and_ip(self, use_static_range=False): | ||
183 | 740 | cluster = factory.make_NodeGroup() | ||
184 | 741 | mac_address = factory.make_MACAddress_with_Node() | ||
185 | 742 | interface = factory.make_NodeGroupInterface(nodegroup=cluster) | ||
186 | 743 | ip = get_random_ip_from_interface_range(interface, use_static_range) | ||
187 | 744 | return cluster, interface, mac_address, ip | ||
188 | 745 | |||
189 | 739 | def test_updates_mac_cluster_interfaces(self): | 746 | def test_updates_mac_cluster_interfaces(self): |
199 | 740 | cluster, mac_addresses, leases = ( | 747 | cluster, interface, mac_address, ip = ( |
200 | 741 | self.make_cluster_with_macs_and_leases()) | 748 | self.make_cluster_with_mac_and_node_and_ip()) |
201 | 742 | update_mac_cluster_interfaces(leases, cluster) | 749 | update_mac_cluster_interfaces(ip, mac_address.mac_address, cluster) |
202 | 743 | results = { | 750 | mac_address = reload_object(mac_address) |
203 | 744 | mac_address: mac_address.cluster_interface | 751 | self.assertEqual(interface, mac_address.cluster_interface) |
195 | 745 | for mac_address in MACAddress.objects.filter( | ||
196 | 746 | mac_address__in=leases.values()) | ||
197 | 747 | } | ||
198 | 748 | self.assertEqual(mac_addresses, results) | ||
204 | 749 | 752 | ||
205 | 750 | def test_considers_static_range_when_updating_interfaces(self): | 753 | def test_considers_static_range_when_updating_interfaces(self): |
206 | 751 | cluster, mac_addresses, leases = ( | 754 | cluster, mac_addresses, leases = ( |
207 | 752 | self.make_cluster_with_macs_and_leases(use_static_range=True)) | 755 | self.make_cluster_with_macs_and_leases(use_static_range=True)) |
215 | 753 | update_mac_cluster_interfaces(leases, cluster) | 756 | cluster, interface, mac_address, ip = ( |
216 | 754 | results = { | 757 | self.make_cluster_with_mac_and_node_and_ip(use_static_range=True)) |
217 | 755 | mac_address: mac_address.cluster_interface | 758 | update_mac_cluster_interfaces(ip, mac_address.mac_address, cluster) |
218 | 756 | for mac_address in MACAddress.objects.filter( | 759 | mac_address = reload_object(mac_address) |
219 | 757 | mac_address__in=leases.values()) | 760 | self.assertEqual(interface, mac_address.cluster_interface) |
213 | 758 | } | ||
214 | 759 | self.assertEqual(mac_addresses, results) | ||
220 | 760 | 761 | ||
221 | 761 | def test_updates_network_relations(self): | 762 | def test_updates_network_relations(self): |
222 | 762 | # update_mac_cluster_interfaces should also associate the mac | 763 | # update_mac_cluster_interfaces should also associate the mac |
223 | 763 | # with the network on which it resides. | 764 | # with the network on which it resides. |
224 | 764 | cluster, mac_addresses, leases = ( | 765 | cluster, mac_addresses, leases = ( |
225 | 765 | self.make_cluster_with_macs_and_leases()) | 766 | self.make_cluster_with_macs_and_leases()) |
242 | 766 | expected_relations = [] | 767 | cluster, interface, mac_address, ip = ( |
243 | 767 | for mac, interface in mac_addresses.viewitems(): | 768 | self.make_cluster_with_mac_and_node_and_ip()) |
244 | 768 | net = create_Network_from_NodeGroupInterface(interface) | 769 | net = create_Network_from_NodeGroupInterface(interface) |
245 | 769 | expected_relations.append((net, mac)) | 770 | update_mac_cluster_interfaces(ip, mac_address.mac_address, cluster) |
246 | 770 | update_mac_cluster_interfaces(leases, cluster) | 771 | [observed_macddress] = net.macaddress_set.all() |
247 | 771 | # Doing a single giant comparison here would be unintuitive and | 772 | self.expectThat(mac_address, Equals(observed_macddress)) |
248 | 772 | # fugly, so I'm iterating. | 773 | self.expectThat( |
249 | 773 | for net, mac in expected_relations: | 774 | net, MatchesStructure.byEquality( |
250 | 774 | [observed_macddress] = net.macaddress_set.all() | 775 | default_gateway=interface.router_ip, |
251 | 775 | self.expectThat(mac, Equals(observed_macddress)) | 776 | netmask=interface.subnet_mask, |
252 | 776 | interface = mac_addresses[mac] | 777 | )) |
237 | 777 | self.expectThat( | ||
238 | 778 | net, MatchesStructure.byEquality( | ||
239 | 779 | default_gateway=interface.router_ip, | ||
240 | 780 | netmask=interface.subnet_mask, | ||
241 | 781 | )) | ||
253 | 782 | 778 | ||
254 | 783 | def test_does_not_overwrite_network_with_same_name(self): | 779 | def test_does_not_overwrite_network_with_same_name(self): |
255 | 784 | cluster = factory.make_NodeGroup() | 780 | cluster = factory.make_NodeGroup() |
256 | @@ -794,10 +790,8 @@ | |||
257 | 794 | def test_ignores_mac_not_attached_to_cluster(self): | 790 | def test_ignores_mac_not_attached_to_cluster(self): |
258 | 795 | cluster = factory.make_NodeGroup() | 791 | cluster = factory.make_NodeGroup() |
259 | 796 | mac_address = factory.make_MACAddress_with_Node() | 792 | mac_address = factory.make_MACAddress_with_Node() |
264 | 797 | leases = { | 793 | ip = factory.make_ipv4_address() |
265 | 798 | factory.make_ipv4_address(): mac_address.mac_address | 794 | update_mac_cluster_interfaces(ip, mac_address.mac_address, cluster) |
262 | 799 | } | ||
263 | 800 | update_mac_cluster_interfaces(leases, cluster) | ||
266 | 801 | mac_address = MACAddress.objects.get( | 795 | mac_address = MACAddress.objects.get( |
267 | 802 | id=mac_address.id) | 796 | id=mac_address.id) |
268 | 803 | self.assertIsNone(mac_address.cluster_interface) | 797 | self.assertIsNone(mac_address.cluster_interface) |
269 | @@ -805,13 +799,11 @@ | |||
270 | 805 | def test_ignores_unknown_macs(self): | 799 | def test_ignores_unknown_macs(self): |
271 | 806 | cluster = factory.make_NodeGroup() | 800 | cluster = factory.make_NodeGroup() |
272 | 807 | mac_address = factory.make_mac_address() | 801 | mac_address = factory.make_mac_address() |
276 | 808 | leases = { | 802 | ip = factory.make_ipv4_address() |
274 | 809 | factory.make_ipv4_address(): mac_address | ||
275 | 810 | } | ||
277 | 811 | # This is a test to show that update_mac_cluster_interfaces() | 803 | # This is a test to show that update_mac_cluster_interfaces() |
278 | 812 | # doesn't raise an Http404 when it comes across something it | 804 | # doesn't raise an Http404 when it comes across something it |
279 | 813 | # doesn't know, hence the lack of meaningful assertions. | 805 | # doesn't know, hence the lack of meaningful assertions. |
281 | 814 | update_mac_cluster_interfaces(leases, cluster) | 806 | update_mac_cluster_interfaces(ip, mac_address, cluster) |
282 | 815 | self.assertFalse( | 807 | self.assertFalse( |
283 | 816 | MACAddress.objects.filter(mac_address=mac_address).exists()) | 808 | MACAddress.objects.filter(mac_address=mac_address).exists()) |
284 | 817 | 809 | ||
285 | @@ -824,10 +816,9 @@ | |||
286 | 824 | ip=factory.make_ipv4_address(), | 816 | ip=factory.make_ipv4_address(), |
287 | 825 | management=NODEGROUPINTERFACE_MANAGEMENT.UNMANAGED) | 817 | management=NODEGROUPINTERFACE_MANAGEMENT.UNMANAGED) |
288 | 826 | mac_address = factory.make_mac_address() | 818 | mac_address = factory.make_mac_address() |
293 | 827 | leases = { | 819 | ip = factory.make_ipv4_address() |
294 | 828 | factory.make_ipv4_address(): mac_address | 820 | self.assertIsNone( |
295 | 829 | } | 821 | update_mac_cluster_interfaces(ip, mac_address, cluster)) |
292 | 830 | self.assertIsNone(update_mac_cluster_interfaces(leases, cluster)) | ||
296 | 831 | # The real test is that update_mac_cluster_interfaces() doesn't | 822 | # The real test is that update_mac_cluster_interfaces() doesn't |
297 | 832 | # stacktrace because of the unconfigured interface (see bug | 823 | # stacktrace because of the unconfigured interface (see bug |
298 | 833 | # 1332596). | 824 | # 1332596). |
299 | 834 | 825 | ||
300 | === modified file 'src/maasserver/rpc/leases.py' | |||
301 | --- src/maasserver/rpc/leases.py 2014-10-01 23:07:50 +0000 | |||
302 | +++ src/maasserver/rpc/leases.py 2014-12-08 02:56:05 +0000 | |||
303 | @@ -17,7 +17,6 @@ | |||
304 | 17 | ] | 17 | ] |
305 | 18 | 18 | ||
306 | 19 | from maasserver.models.dhcplease import DHCPLease | 19 | from maasserver.models.dhcplease import DHCPLease |
307 | 20 | from maasserver.models.macaddress import update_mac_cluster_interfaces | ||
308 | 21 | from maasserver.models.nodegroup import NodeGroup | 20 | from maasserver.models.nodegroup import NodeGroup |
309 | 22 | from maasserver.utils.async import transactional | 21 | from maasserver.utils.async import transactional |
310 | 23 | from provisioningserver.pserv_services.lease_upload_service import ( | 22 | from provisioningserver.pserv_services.lease_upload_service import ( |
311 | @@ -50,5 +49,4 @@ | |||
312 | 50 | else: | 49 | else: |
313 | 51 | leases = convert_mappings_to_leases(mappings) | 50 | leases = convert_mappings_to_leases(mappings) |
314 | 52 | DHCPLease.objects.update_leases(nodegroup, leases) | 51 | DHCPLease.objects.update_leases(nodegroup, leases) |
315 | 53 | update_mac_cluster_interfaces(leases, nodegroup) | ||
316 | 54 | return {} | 52 | return {} |
317 | 55 | 53 | ||
318 | === modified file 'src/maasserver/rpc/tests/test_regionservice.py' | |||
319 | --- src/maasserver/rpc/tests/test_regionservice.py 2014-11-25 13:06:34 +0000 | |||
320 | +++ src/maasserver/rpc/tests/test_regionservice.py 2014-12-08 02:56:05 +0000 | |||
321 | @@ -420,31 +420,6 @@ | |||
322 | 420 | self.expectThat(mac, Equals(mapping["mac"])) | 420 | self.expectThat(mac, Equals(mapping["mac"])) |
323 | 421 | 421 | ||
324 | 422 | @wait_for_reactor | 422 | @wait_for_reactor |
325 | 423 | @inlineCallbacks | ||
326 | 424 | def test__updates_mac_to_cluster_links(self): | ||
327 | 425 | uuid = factory.make_name("uuid") | ||
328 | 426 | nodegroup = yield deferToThread(self.make_node_group, uuid) | ||
329 | 427 | cluster_interface = yield deferToThread( | ||
330 | 428 | self.make_node_group_interface, nodegroup) | ||
331 | 429 | mac_address = yield deferToThread(self.make_mac_address) | ||
332 | 430 | |||
333 | 431 | mapping = { | ||
334 | 432 | "ip": cluster_interface.ip_range_low, | ||
335 | 433 | "mac": mac_address.mac_address.get_raw(), | ||
336 | 434 | } | ||
337 | 435 | |||
338 | 436 | response = yield call_responder(Region(), UpdateLeases, { | ||
339 | 437 | b"uuid": uuid, b"mappings": [mapping]}) | ||
340 | 438 | self.assertThat(response, Equals({})) | ||
341 | 439 | |||
342 | 440 | @transactional | ||
343 | 441 | def get_cluster_interface(): | ||
344 | 442 | return reload_object(mac_address).cluster_interface | ||
345 | 443 | |||
346 | 444 | observed = yield deferToThread(get_cluster_interface) | ||
347 | 445 | self.assertThat(observed, Equals(cluster_interface)) | ||
348 | 446 | |||
349 | 447 | @wait_for_reactor | ||
350 | 448 | def test__raises_NoSuchCluster_if_cluster_not_found(self): | 423 | def test__raises_NoSuchCluster_if_cluster_not_found(self): |
351 | 449 | uuid = factory.make_name("uuid") | 424 | uuid = factory.make_name("uuid") |
352 | 450 | d = call_responder( | 425 | d = call_responder( |
LGTM. Nice work!