Merge lp:~blake-rouse/maas/fix-1566336-1.9 into lp:maas/1.9

Proposed by Blake Rouse
Status: Merged
Approved by: Blake Rouse
Approved revision: no longer in the source branch.
Merged at revision: 4552
Proposed branch: lp:~blake-rouse/maas/fix-1566336-1.9
Merge into: lp:maas/1.9
Diff against target: 1205 lines (+409/-138)
10 files modified
src/maasserver/api/tests/test_interfaces.py (+21/-13)
src/maasserver/forms_interface.py (+55/-12)
src/maasserver/models/interface.py (+3/-2)
src/maasserver/models/signals/interfaces.py (+58/-18)
src/maasserver/models/signals/tests/test_interfaces.py (+46/-0)
src/maasserver/models/tests/test_interface.py (+55/-23)
src/maasserver/models/tests/test_staticipaddress.py (+3/-0)
src/maasserver/testing/factory.py (+17/-4)
src/maasserver/tests/test_forms_interface.py (+137/-57)
src/maasserver/websockets/handlers/tests/test_node.py (+14/-9)
To merge this branch: bzr merge lp:~blake-rouse/maas/fix-1566336-1.9
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+291009@code.launchpad.net

Commit message

Remove links on parents when added to a bond. Only allow physical interface and bond interface to be attached to the untagged VLAN on a fabric.

To post a comment you must log in.
Revision history for this message
Blake Rouse (blake-rouse) wrote :

Self-approving backport.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/api/tests/test_interfaces.py'
2--- src/maasserver/api/tests/test_interfaces.py 2015-12-04 21:23:28 +0000
3+++ src/maasserver/api/tests/test_interfaces.py 2016-04-05 16:02:24 +0000
4@@ -56,14 +56,14 @@
5 def make_complex_interface(node, name=None):
6 """Makes interface with parents and children."""
7 fabric = factory.make_Fabric()
8- vlan_5 = factory.make_VLAN(vid=5, fabric=fabric)
9+ untagged = fabric.get_default_vlan()
10 nic_0 = factory.make_Interface(
11- INTERFACE_TYPE.PHYSICAL, vlan=vlan_5, node=node)
12+ INTERFACE_TYPE.PHYSICAL, vlan=untagged, node=node)
13 nic_1 = factory.make_Interface(
14- INTERFACE_TYPE.PHYSICAL, vlan=vlan_5, node=node)
15+ INTERFACE_TYPE.PHYSICAL, vlan=untagged, node=node)
16 parents = [nic_0, nic_1]
17 bond_interface = factory.make_Interface(
18- INTERFACE_TYPE.BOND, mac_address=nic_0.mac_address, vlan=vlan_5,
19+ INTERFACE_TYPE.BOND, mac_address=nic_0.mac_address, vlan=untagged,
20 parents=parents, name=name)
21 vlan_10 = factory.make_VLAN(vid=10, fabric=fabric)
22 vlan_nic_10 = factory.make_Interface(
23@@ -117,7 +117,8 @@
24 node = factory.make_Node(status=status)
25 mac = factory.make_mac_address()
26 name = factory.make_name("eth")
27- vlan = factory.make_VLAN()
28+ fabric = factory.make_Fabric()
29+ vlan = fabric.get_default_vlan()
30 tags = [
31 factory.make_name("tag")
32 for _ in range(3)
33@@ -150,7 +151,8 @@
34 owner=self.logged_in_user, installable=False, parent=parent)
35 mac = factory.make_mac_address()
36 name = factory.make_name("eth")
37- vlan = factory.make_VLAN()
38+ fabric = factory.make_Fabric()
39+ vlan = fabric.get_default_vlan()
40 tags = [
41 factory.make_name("tag")
42 for _ in range(3)
43@@ -183,7 +185,8 @@
44 node = factory.make_Node(status=status)
45 mac = factory.make_mac_address()
46 name = factory.make_name("eth")
47- vlan = factory.make_VLAN()
48+ fabric = factory.make_Fabric()
49+ vlan = fabric.get_default_vlan()
50 tags = [
51 factory.make_name("tag")
52 for _ in range(3)
53@@ -279,7 +282,8 @@
54 interface_on_other_node = factory.make_Interface(
55 INTERFACE_TYPE.PHYSICAL)
56 name = factory.make_name("eth")
57- vlan = factory.make_VLAN()
58+ fabric = factory.make_Fabric()
59+ vlan = fabric.get_default_vlan()
60 uri = get_interfaces_uri(node)
61 response = self.client.post(uri, {
62 "op": "create_physical",
63@@ -299,7 +303,8 @@
64 self.become_admin()
65 for status in (NODE_STATUS.READY, NODE_STATUS.BROKEN):
66 node = factory.make_Node(status=status)
67- vlan = factory.make_VLAN()
68+ fabric = factory.make_Fabric()
69+ vlan = fabric.get_default_vlan()
70 parent_1_iface = factory.make_Interface(
71 INTERFACE_TYPE.PHYSICAL, vlan=vlan, node=node)
72 parent_2_iface = factory.make_Interface(
73@@ -402,7 +407,7 @@
74 self.assertEqual(
75 httplib.CONFLICT, response.status_code, response.content)
76
77- def test_create_bond_requires_name_vlan_and_parents(self):
78+ def test_create_bond_requires_name_and_parents(self):
79 self.become_admin()
80 node = factory.make_Node(status=NODE_STATUS.READY)
81 uri = get_interfaces_uri(node)
82@@ -415,7 +420,6 @@
83 self.assertEquals({
84 "mac_address": ["This field cannot be blank."],
85 "name": ["This field is required."],
86- "vlan": ["This field is required."],
87 "parents": ["A Bond interface must have one or more parents."],
88 }, json.loads(response.content))
89
90@@ -634,7 +638,8 @@
91 interface = factory.make_Interface(
92 INTERFACE_TYPE.PHYSICAL, node=node)
93 new_name = factory.make_name("name")
94- new_vlan = factory.make_VLAN()
95+ new_fabric = factory.make_Fabric()
96+ new_vlan = new_fabric.get_default_vlan()
97 uri = get_interface_uri(interface)
98 response = self.client.put(uri, {
99 "name": new_name,
100@@ -653,7 +658,8 @@
101 interface = factory.make_Interface(
102 INTERFACE_TYPE.PHYSICAL, node=device)
103 new_name = factory.make_name("name")
104- new_vlan = factory.make_VLAN()
105+ new_fabric = factory.make_Fabric()
106+ new_vlan = new_fabric.get_default_vlan()
107 uri = get_interface_uri(interface)
108 response = self.client.put(uri, {
109 "name": new_name,
110@@ -688,9 +694,11 @@
111 node)
112 physical_interface = factory.make_Interface(
113 INTERFACE_TYPE.PHYSICAL, node=node)
114+ new_vlan = factory.make_VLAN(fabric=physical_interface.vlan.fabric)
115 uri = get_interface_uri(vlan_10)
116 response = self.client.put(uri, {
117 "parent": physical_interface.id,
118+ "vlan": new_vlan.id,
119 })
120 self.assertEqual(
121 httplib.OK, response.status_code, response.content)
122
123=== modified file 'src/maasserver/forms_interface.py'
124--- src/maasserver/forms_interface.py 2015-10-31 23:55:19 +0000
125+++ src/maasserver/forms_interface.py 2016-04-05 16:02:24 +0000
126@@ -196,6 +196,13 @@
127 msg = "A physical interface cannot have parents."
128 raise ValidationError({'parents': [msg]})
129
130+ def clean_vlan(self):
131+ new_vlan = self.cleaned_data.get('vlan')
132+ if new_vlan and new_vlan.fabric.get_default_vlan() != new_vlan:
133+ raise ValidationError(
134+ "A physical interface can only belong to an untagged VLAN.")
135+ return new_vlan
136+
137 def clean(self):
138 cleaned_data = super(PhysicalInterfaceForm, self).clean()
139 new_name = cleaned_data.get('name')
140@@ -233,11 +240,25 @@
141 "in a bond.")
142 return parents
143
144+ def clean_vlan(self):
145+ new_vlan = self.cleaned_data.get('vlan')
146+ if new_vlan and new_vlan.fabric.get_default_vlan() == new_vlan:
147+ raise ValidationError(
148+ "A VLAN interface can only belong to a tagged VLAN.")
149+ return new_vlan
150+
151 def clean(self):
152 cleaned_data = super(VLANInterfaceForm, self).clean()
153 if self.fields_ok(['vlan', 'parents']):
154 new_vlan = self.cleaned_data.get('vlan')
155 if new_vlan:
156+ # VLAN needs to be the in the same fabric as the parent.
157+ parent = self.cleaned_data.get('parents')[0]
158+ if parent.vlan.fabric_id != new_vlan.fabric_id:
159+ set_form_error(
160+ self, "vlan",
161+ "A VLAN interface can only belong to a tagged VLAN on "
162+ "the same fabric as its parent interface.")
163 name = build_vlan_interface_name(
164 self.cleaned_data.get('parents').first(), new_vlan)
165 self.clean_interface_name_uniqueness(name)
166@@ -281,6 +302,15 @@
167 'name',
168 )
169
170+ def __init__(self, *args, **kwargs):
171+ super(BondInterfaceForm, self).__init__(*args, **kwargs)
172+ # Allow VLAN to be blank when creating.
173+ instance = kwargs.get("instance", None)
174+ if instance is not None and instance.id is not None:
175+ self.fields['vlan'].required = True
176+ else:
177+ self.fields['vlan'].required = False
178+
179 def clean_parents(self):
180 parents = self.get_clean_parents()
181 if parents is None:
182@@ -290,9 +320,16 @@
183 raise ValidationError({'parents': [msg]})
184 return parents
185
186+ def clean_vlan(self):
187+ new_vlan = self.cleaned_data.get('vlan')
188+ if new_vlan and new_vlan.fabric.get_default_vlan() != new_vlan:
189+ raise ValidationError(
190+ "A bond interface can only belong to an untagged VLAN.")
191+ return new_vlan
192+
193 def clean(self):
194 cleaned_data = super(BondInterfaceForm, self).clean()
195- if self.fields_ok(['parents']):
196+ if self.fields_ok(['vlan', 'parents']):
197 parents = self.cleaned_data.get('parents')
198 # Set the mac_address if its missing and the interface is being
199 # created.
200@@ -333,6 +370,23 @@
201 self, 'parents',
202 "%s is already in-use by another interface." % (
203 ', '.join(sorted(parents_with_other_children))))
204+
205+ # When creating the bond set VLAN to the same as the parents
206+ # and check that the parents all belong to the same VLAN.
207+ if self.instance.id is None:
208+ vlan = self.cleaned_data.get('vlan')
209+ if vlan is None:
210+ vlan = parents[0].vlan
211+ self.cleaned_data['vlan'] = vlan
212+ parent_vlans = {
213+ parent.vlan
214+ for parent in parents
215+ }
216+ if parent_vlans != set([vlan]):
217+ set_form_error(
218+ self, 'parents',
219+ "All parents must belong to the same VLAN.")
220+
221 return cleaned_data
222
223 def set_extra_parameters(self, interface, created):
224@@ -356,17 +410,6 @@
225 elif created:
226 interface.params[bond_field] = self.fields[bond_field].initial
227
228- def save(self, *args, **kwargs):
229- """Persist the interface into the database."""
230- created = self.instance.id is None
231- interface = super(BondInterfaceForm, self).save()
232- if created:
233- # Bond was created we remove all the links on the parent interfaces
234- # and ensure that the bond has atleast a LINK_UP.
235- for parent in interface.parents.all():
236- parent.clear_all_links(clearing_config=True)
237- return interface
238-
239
240 INTERFACE_FORM_MAPPING = {
241 INTERFACE_TYPE.PHYSICAL: PhysicalInterfaceForm,
242
243=== modified file 'src/maasserver/models/interface.py'
244--- src/maasserver/models/interface.py 2015-12-11 00:24:18 +0000
245+++ src/maasserver/models/interface.py 2016-04-05 16:02:24 +0000
246@@ -922,11 +922,12 @@
247 # Nothing to do, already has links.
248 return
249 else:
250- # Use an associated subnet if it exists, else it will just be a
251+ # Use an associated subnet if it exists and its on the same VLAN
252+ # the interface is currently connected, else it will just be a
253 # LINK_UP without a subnet.
254 discovered_address = self.ip_addresses.filter(
255 alloc_type=IPADDRESS_TYPE.DISCOVERED,
256- subnet__isnull=False).first()
257+ subnet__vlan=self.vlan).first()
258 if discovered_address is not None:
259 subnet = discovered_address.subnet
260 else:
261
262=== modified file 'src/maasserver/models/signals/interfaces.py'
263--- src/maasserver/models/signals/interfaces.py 2015-11-03 12:38:17 +0000
264+++ src/maasserver/models/signals/interfaces.py 2016-04-05 16:02:24 +0000
265@@ -14,6 +14,7 @@
266 __metaclass__ = type
267 __all__ = []
268
269+from django.db.models.signals import post_save
270 from maasserver.enum import (
271 INTERFACE_TYPE,
272 IPADDRESS_TYPE,
273@@ -27,6 +28,14 @@
274 from maasserver.utils.signals import connect_to_field_change
275
276
277+INTERFACE_CLASSES = [
278+ Interface,
279+ PhysicalInterface,
280+ BondInterface,
281+ VLANInterface,
282+]
283+
284+
285 def interface_enabled_or_disabled(instance, old_values, **kwargs):
286 """When an interface is enabled be sure at minimum a LINK_UP is created.
287 When an interface is disabled make sure that all its links are removed,
288@@ -52,12 +61,10 @@
289 ip_address, clearing_config=True)
290
291
292-connect_to_field_change(
293- interface_enabled_or_disabled,
294- Interface, ['enabled'], delete=False)
295-connect_to_field_change(
296- interface_enabled_or_disabled,
297- PhysicalInterface, ['enabled'], delete=False)
298+for klass in INTERFACE_CLASSES:
299+ connect_to_field_change(
300+ interface_enabled_or_disabled,
301+ klass, ['enabled'], delete=False)
302
303
304 def interface_mtu_params_update(instance, old_values, **kwargs):
305@@ -118,15 +125,48 @@
306 parent.save()
307
308
309-connect_to_field_change(
310- interface_mtu_params_update,
311- Interface, ['params'], delete=False)
312-connect_to_field_change(
313- interface_mtu_params_update,
314- PhysicalInterface, ['params'], delete=False)
315-connect_to_field_change(
316- interface_mtu_params_update,
317- BondInterface, ['params'], delete=False)
318-connect_to_field_change(
319- interface_mtu_params_update,
320- VLANInterface, ['params'], delete=False)
321+for klass in INTERFACE_CLASSES:
322+ connect_to_field_change(
323+ interface_mtu_params_update,
324+ klass, ['params'], delete=False)
325+
326+
327+def update_bond_parents(sender, instance, created, **kwargs):
328+ """Update bond parents when interface created."""
329+ if instance.type == INTERFACE_TYPE.BOND:
330+ for parent in instance.parents.all():
331+ # Make sure the parent has not links as well, just to be sure.
332+ parent.clear_all_links(clearing_config=True)
333+ if parent.vlan != instance.vlan:
334+ parent.vlan = instance.vlan
335+ parent.save()
336+
337+
338+for klass in INTERFACE_CLASSES:
339+ post_save.connect(
340+ update_bond_parents, sender=klass)
341+
342+
343+def interface_vlan_update(instance, old_values, **kwargs):
344+ """When an interfaces VLAN is changed we need to remove all
345+ links if the VLAN is different.
346+ """
347+ new_vlan_id = instance.vlan_id
348+ [old_vlan_id] = old_values
349+ if new_vlan_id == old_vlan_id:
350+ # Nothing changed do nothing.
351+ return
352+ if instance.node is None:
353+ # Not assigned to a node. Nothing to do.
354+ return
355+
356+ # Interface VLAN was changed on a machine or device. Remove all its
357+ # links except the DISCOVERED ones.
358+ instance.ip_addresses.exclude(
359+ alloc_type=IPADDRESS_TYPE.DISCOVERED).delete()
360+
361+
362+for klass in INTERFACE_CLASSES:
363+ connect_to_field_change(
364+ interface_vlan_update,
365+ klass, ['vlan_id'], delete=False)
366
367=== modified file 'src/maasserver/models/signals/tests/test_interfaces.py'
368--- src/maasserver/models/signals/tests/test_interfaces.py 2015-11-03 12:38:17 +0000
369+++ src/maasserver/models/signals/tests/test_interfaces.py 2016-04-05 16:02:24 +0000
370@@ -132,3 +132,49 @@
371 self.assertEquals({
372 'mtu': bond_mtu,
373 }, reload_object(physical3_interface).params)
374+
375+
376+class TestUpdateBondParents(MAASServerTestCase):
377+
378+ def test__updates_bond_parents(self):
379+ parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
380+ parent2 = factory.make_Interface(
381+ INTERFACE_TYPE.PHYSICAL, node=parent1.node)
382+ bond = factory.make_Interface(
383+ INTERFACE_TYPE.BOND, parents=[parent1, parent2])
384+ self.assertEqual(bond.vlan, reload_object(parent1).vlan)
385+ self.assertEqual(bond.vlan, reload_object(parent2).vlan)
386+
387+ def test__update_bond_clears_parent_links(self):
388+ parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
389+ parent2 = factory.make_Interface(
390+ INTERFACE_TYPE.PHYSICAL, node=parent1.node)
391+ static_ip = factory.make_StaticIPAddress(interface=parent1)
392+ factory.make_Interface(
393+ INTERFACE_TYPE.BOND, parents=[parent1, parent2])
394+ self.assertIsNone(reload_object(static_ip))
395+
396+
397+class TestInterfaceVLANUpdate(MAASServerTestCase):
398+
399+ scenarios = (
400+ ("node", {
401+ "maker": factory.make_Node,
402+ }),
403+ ("device", {
404+ "maker": factory.make_Device,
405+ }),
406+ )
407+
408+ def test__removes_links(self):
409+ node = self.maker()
410+ interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)
411+ static_ip = factory.make_StaticIPAddress(interface=interface)
412+ discovered_ip = factory.make_StaticIPAddress(
413+ alloc_type=IPADDRESS_TYPE.DISCOVERED, interface=interface)
414+ new_fabric = factory.make_Fabric()
415+ new_vlan = new_fabric.get_default_vlan()
416+ interface.vlan = new_vlan
417+ interface.save()
418+ self.assertIsNone(reload_object(static_ip))
419+ self.assertIsNotNone(reload_object(discovered_ip))
420
421=== modified file 'src/maasserver/models/tests/test_interface.py'
422--- src/maasserver/models/tests/test_interface.py 2015-12-11 00:24:23 +0000
423+++ src/maasserver/models/tests/test_interface.py 2016-04-05 16:02:24 +0000
424@@ -230,31 +230,51 @@
425 ["id:%s" % iface1.id, "id:%s" % iface2.id]), [iface1, iface2])
426
427 def test__filter_by_specifiers_matches_vid(self):
428- iface1 = factory.make_Interface()
429- iface2 = factory.make_Interface()
430- self.assertItemsEqual(
431- Interface.objects.filter_by_specifiers(
432- "vid:%s" % iface1.vlan.vid), [iface1])
433- self.assertItemsEqual(
434- Interface.objects.filter_by_specifiers(
435- "vid:%s" % iface2.vlan.vid), [iface2])
436- self.assertItemsEqual(
437- Interface.objects.filter_by_specifiers(
438- ["vid:%s" % iface1.vlan.vid, "vid:%s" % iface2.vlan.vid]),
439+ fabric1 = factory.make_Fabric()
440+ parent1 = factory.make_Interface(
441+ INTERFACE_TYPE.PHYSICAL, vlan=fabric1.get_default_vlan())
442+ vlan1 = factory.make_VLAN(fabric=fabric1)
443+ iface1 = factory.make_Interface(
444+ INTERFACE_TYPE.VLAN, vlan=vlan1, parents=[parent1])
445+ fabric2 = factory.make_Fabric()
446+ parent2 = factory.make_Interface(
447+ INTERFACE_TYPE.PHYSICAL, vlan=fabric2.get_default_vlan())
448+ vlan2 = factory.make_VLAN(fabric=fabric2)
449+ iface2 = factory.make_Interface(
450+ INTERFACE_TYPE.VLAN, vlan=vlan2, parents=[parent2])
451+ self.assertItemsEqual(
452+ Interface.objects.filter_by_specifiers(
453+ "vid:%s" % vlan1.vid), [iface1])
454+ self.assertItemsEqual(
455+ Interface.objects.filter_by_specifiers(
456+ "vid:%s" % vlan2.vid), [iface2])
457+ self.assertItemsEqual(
458+ Interface.objects.filter_by_specifiers(
459+ ["vid:%s" % vlan1.vid, "vid:%s" % vlan2.vid]),
460 [iface1, iface2])
461
462 def test__filter_by_specifiers_matches_vlan(self):
463- iface1 = factory.make_Interface()
464- iface2 = factory.make_Interface()
465- self.assertItemsEqual(
466- Interface.objects.filter_by_specifiers(
467- "vlan:%s" % iface1.vlan.vid), [iface1])
468- self.assertItemsEqual(
469- Interface.objects.filter_by_specifiers(
470- "vlan:%s" % iface2.vlan.vid), [iface2])
471- self.assertItemsEqual(
472- Interface.objects.filter_by_specifiers(
473- ["vlan:%s" % iface1.vlan.vid, "vlan:%s" % iface2.vlan.vid]),
474+ fabric1 = factory.make_Fabric()
475+ parent1 = factory.make_Interface(
476+ INTERFACE_TYPE.PHYSICAL, vlan=fabric1.get_default_vlan())
477+ vlan1 = factory.make_VLAN(fabric=fabric1)
478+ iface1 = factory.make_Interface(
479+ INTERFACE_TYPE.VLAN, vlan=vlan1, parents=[parent1])
480+ fabric2 = factory.make_Fabric()
481+ parent2 = factory.make_Interface(
482+ INTERFACE_TYPE.PHYSICAL, vlan=fabric2.get_default_vlan())
483+ vlan2 = factory.make_VLAN(fabric=fabric2)
484+ iface2 = factory.make_Interface(
485+ INTERFACE_TYPE.VLAN, vlan=vlan2, parents=[parent2])
486+ self.assertItemsEqual(
487+ Interface.objects.filter_by_specifiers(
488+ "vlan:%s" % vlan1.vid), [iface1])
489+ self.assertItemsEqual(
490+ Interface.objects.filter_by_specifiers(
491+ "vlan:%s" % vlan2.vid), [iface2])
492+ self.assertItemsEqual(
493+ Interface.objects.filter_by_specifiers(
494+ ["vlan:%s" % vlan1.vid, "vlan:%s" % vlan2.vid]),
495 [iface1, iface2])
496
497 def test__filter_by_specifiers_matches_subnet_specifier(self):
498@@ -1515,7 +1535,7 @@
499 1, interface.ip_addresses.count(),
500 "Should only have one IP address assigned.")
501
502- def test__creates_link_up_to_discovered_subnet(self):
503+ def test__creates_link_up_to_discovered_subnet_on_same_vlan(self):
504 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
505 subnet = factory.make_Subnet(vlan=interface.vlan)
506 factory.make_StaticIPAddress(
507@@ -1527,6 +1547,18 @@
508 self.assertIsNone(link_ip.ip)
509 self.assertEquals(subnet, link_ip.subnet)
510
511+ def test__creates_link_up_to_no_subnet_when_on_different_vlan(self):
512+ interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
513+ subnet = factory.make_Subnet()
514+ factory.make_StaticIPAddress(
515+ alloc_type=IPADDRESS_TYPE.DISCOVERED, ip="",
516+ subnet=subnet, interface=interface)
517+ interface.ensure_link_up()
518+ link_ip = interface.ip_addresses.filter(
519+ alloc_type=IPADDRESS_TYPE.STICKY).first()
520+ self.assertIsNone(link_ip.ip)
521+ self.assertIsNone(link_ip.subnet)
522+
523 def test__creates_link_up_to_no_subnet(self):
524 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
525 interface.ensure_link_up()
526
527=== modified file 'src/maasserver/models/tests/test_staticipaddress.py'
528--- src/maasserver/models/tests/test_staticipaddress.py 2015-11-17 00:33:35 +0000
529+++ src/maasserver/models/tests/test_staticipaddress.py 2016-04-05 16:02:24 +0000
530@@ -805,6 +805,7 @@
531
532 def test_get_hostname_ip_mapping_prefers_bond_with_no_boot_interface(self):
533 self.patch_autospec(interface_module, "update_host_maps")
534+ self.patch_autospec(interface_module, "remove_host_maps")
535 subnet = factory.make_Subnet(
536 cidr=unicode(factory.make_ipv4_network().cidr))
537 node = factory.make_Node_with_Interface_on_Subnet(
538@@ -835,6 +836,7 @@
539
540 def test_get_hostname_ip_mapping_prefers_bond_with_boot_interface(self):
541 self.patch_autospec(interface_module, "update_host_maps")
542+ self.patch_autospec(interface_module, "remove_host_maps")
543 subnet = factory.make_Subnet(
544 cidr=unicode(factory.make_ipv4_network().cidr))
545 node = factory.make_Node_with_Interface_on_Subnet(
546@@ -859,6 +861,7 @@
547
548 def test_get_hostname_ip_mapping_ignores_bond_without_boot_interface(self):
549 self.patch_autospec(interface_module, "update_host_maps")
550+ self.patch_autospec(interface_module, "remove_host_maps")
551 subnet = factory.make_Subnet(
552 cidr=unicode(factory.make_ipv4_network().cidr))
553 node = factory.make_Node_with_Interface_on_Subnet(
554
555=== modified file 'src/maasserver/testing/factory.py'
556--- src/maasserver/testing/factory.py 2015-12-11 00:24:23 +0000
557+++ src/maasserver/testing/factory.py 2016-04-05 16:02:24 +0000
558@@ -335,7 +335,6 @@
559 acquired = node.status in ALLOCATED_NODE_STATUSES
560 self.make_Filesystem(
561 partition=root_partition, mount_point='/', acquired=acquired)
562-
563 # Update the 'updated'/'created' fields with a call to 'update'
564 # preventing a call to save() from overriding the values.
565 if updated is not None:
566@@ -591,7 +590,9 @@
567 node = self.make_Node(
568 nodegroup=nodegroup, fabric=fabric, **kwargs)
569 if vlan is None:
570- vlan = self.make_VLAN(fabric=fabric)
571+ if fabric is None:
572+ fabric = factory.make_Fabric()
573+ vlan = fabric.get_default_vlan()
574 if subnet is None:
575 subnet = self.make_Subnet(vlan=vlan, cidr=cidr)
576 # Check if the subnet already has a managed interface.
577@@ -630,7 +631,7 @@
578 self.make_StaticIPAddress(
579 alloc_type=IPADDRESS_TYPE.STICKY, ip="",
580 subnet=subnet, interface=interface)
581- return node
582+ return reload_object(node)
583
584 UNDEFINED = float('NaN')
585
586@@ -786,7 +787,19 @@
587 if iftype is None:
588 iftype = INTERFACE_TYPE.PHYSICAL
589 if vlan is None:
590- vlan = self.make_VLAN(fabric=fabric)
591+ if fabric is not None:
592+ if iftype == INTERFACE_TYPE.VLAN:
593+ vlan = self.make_VLAN(fabric=fabric)
594+ else:
595+ vlan = fabric.get_default_vlan()
596+ else:
597+ if iftype == INTERFACE_TYPE.VLAN and parents:
598+ vlan = self.make_VLAN(fabric=parents[0].vlan.fabric)
599+ elif iftype == INTERFACE_TYPE.BOND and parents:
600+ vlan = parents[0].vlan
601+ else:
602+ fabric = self.make_Fabric()
603+ vlan = fabric.get_default_vlan()
604 if (mac_address is None and
605 iftype in [
606 INTERFACE_TYPE.PHYSICAL,
607
608=== modified file 'src/maasserver/tests/test_forms_interface.py'
609--- src/maasserver/tests/test_forms_interface.py 2015-10-31 23:55:19 +0000
610+++ src/maasserver/tests/test_forms_interface.py 2016-04-05 16:02:24 +0000
611@@ -32,6 +32,7 @@
612 )
613 from maasserver.models.interface import build_vlan_interface_name
614 from maasserver.testing.factory import factory
615+from maasserver.testing.orm import reload_object
616 from maasserver.testing.testcase import MAASServerTestCase
617 from maasserver.utils.forms import compose_invalid_choice_text
618 from testtools import ExpectedException
619@@ -67,7 +68,8 @@
620 node = factory.make_Node()
621 mac_address = factory.make_mac_address()
622 interface_name = 'eth0'
623- vlan = factory.make_VLAN()
624+ fabric = factory.make_Fabric()
625+ vlan = fabric.get_default_vlan()
626 tags = [
627 factory.make_name("tag")
628 for _ in range(3)
629@@ -93,7 +95,8 @@
630 node = factory.make_Node()
631 mac_address = factory.make_mac_address()
632 interface_name = 'eth0'
633- vlan = factory.make_VLAN()
634+ fabric = factory.make_Fabric()
635+ vlan = fabric.get_default_vlan()
636 tags = [
637 factory.make_name("tag")
638 for _ in range(3)
639@@ -113,7 +116,8 @@
640
641 def test__requires_mac_address(self):
642 interface_name = 'eth0'
643- vlan = factory.make_VLAN()
644+ fabric = factory.make_Fabric()
645+ vlan = fabric.get_default_vlan()
646 form = PhysicalInterfaceForm(
647 node=factory.make_Node(),
648 data={
649@@ -128,7 +132,9 @@
650 form.errors['mac_address'][0])
651
652 def test_rejects_interface_with_duplicate_name(self):
653- interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
654+ fabric = factory.make_Fabric()
655+ vlan = fabric.get_default_vlan()
656+ interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
657 mac_address = factory.make_mac_address()
658 form = PhysicalInterfaceForm(
659 node=interface.node,
660@@ -144,9 +150,30 @@
661 "already has an interface named '%s'." % interface.name,
662 form.errors['name'][0])
663
664+ def test_rejects_interface_on_tagged_vlan(self):
665+ fabric = factory.make_Fabric()
666+ interface = factory.make_Interface(
667+ INTERFACE_TYPE.PHYSICAL, vlan=fabric.get_default_vlan())
668+ vlan = factory.make_VLAN(fabric=fabric)
669+ mac_address = factory.make_mac_address()
670+ form = PhysicalInterfaceForm(
671+ node=interface.node,
672+ data={
673+ 'name': factory.make_name("eth"),
674+ 'mac_address': mac_address,
675+ 'vlan': vlan.id,
676+ })
677+ self.assertFalse(form.is_valid(), form.errors)
678+ self.assertItemsEqual(
679+ ['vlan'], form.errors.keys(), form.errors)
680+ self.assertIn(
681+ "A physical interface can only belong to an untagged VLAN.",
682+ form.errors['vlan'][0])
683+
684 def test__rejects_parents(self):
685 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
686- vlan = factory.make_VLAN()
687+ fabric = factory.make_Fabric()
688+ vlan = fabric.get_default_vlan()
689 form = PhysicalInterfaceForm(
690 node=parent.node,
691 data={
692@@ -166,7 +193,8 @@
693 interface = factory.make_Interface(
694 INTERFACE_TYPE.PHYSICAL, name='eth0')
695 new_name = 'eth1'
696- new_vlan = factory.make_VLAN(vid=33)
697+ new_fabric = factory.make_Fabric()
698+ new_vlan = new_fabric.get_default_vlan()
699 form = PhysicalInterfaceForm(
700 instance=interface,
701 data={
702@@ -187,7 +215,8 @@
703 node = factory.make_Node()
704 mac_address = factory.make_mac_address()
705 interface_name = 'eth0'
706- vlan = factory.make_VLAN()
707+ fabric = factory.make_Fabric()
708+ vlan = fabric.get_default_vlan()
709 tags = [
710 factory.make_name("tag")
711 for _ in range(3)
712@@ -226,7 +255,8 @@
713 "autoconf": autoconf,
714 }
715 new_name = 'eth1'
716- new_vlan = factory.make_VLAN(vid=33)
717+ new_fabric = factory.make_Fabric()
718+ new_vlan = new_fabric.get_default_vlan()
719 form = PhysicalInterfaceForm(
720 instance=interface,
721 data={
722@@ -299,7 +329,7 @@
723
724 def test__creates_vlan_interface(self):
725 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
726- vlan = factory.make_VLAN(vid=10)
727+ vlan = factory.make_VLAN(fabric=parent.vlan.fabric, vid=10)
728 form = VLANInterfaceForm(
729 node=parent.node,
730 data={
731@@ -317,7 +347,7 @@
732
733 def test__create_ensures_link_up(self):
734 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
735- vlan = factory.make_VLAN(vid=10)
736+ vlan = factory.make_VLAN(fabric=parent.vlan.fabric, vid=10)
737 form = VLANInterfaceForm(
738 node=parent.node,
739 data={
740@@ -330,13 +360,10 @@
741 interface.ip_addresses.filter(alloc_type=IPADDRESS_TYPE.STICKY))
742
743 def test_rejects_interface_with_duplicate_name(self):
744- vlan = factory.make_VLAN(vid=10)
745- parent = factory.make_Interface(
746- INTERFACE_TYPE.PHYSICAL,
747- vlan=vlan)
748+ parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
749+ vlan = factory.make_VLAN(fabric=parent.vlan.fabric, vid=10)
750 interface = factory.make_Interface(
751- INTERFACE_TYPE.VLAN,
752- vlan=vlan, parents=[parent])
753+ INTERFACE_TYPE.VLAN, vlan=vlan, parents=[parent])
754 form = VLANInterfaceForm(
755 node=parent.node,
756 data={
757@@ -350,6 +377,22 @@
758 "already has an interface named '%s'." % interface.name,
759 form.errors['name'][0])
760
761+ def test_rejects_interface_on_default_fabric(self):
762+ parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
763+ vlan = parent.vlan.fabric.get_default_vlan()
764+ form = VLANInterfaceForm(
765+ node=parent.node,
766+ data={
767+ 'vlan': vlan.id,
768+ 'parents': [parent.id],
769+ })
770+ self.assertFalse(form.is_valid(), form.errors)
771+ self.assertItemsEqual(
772+ ['vlan'], form.errors.keys(), form.errors)
773+ self.assertIn(
774+ "A VLAN interface can only belong to a tagged VLAN.",
775+ form.errors['vlan'][0])
776+
777 def test__rejects_no_parents(self):
778 vlan = factory.make_VLAN(vid=10)
779 form = VLANInterfaceForm(
780@@ -365,13 +408,14 @@
781
782 def test__rejects_vlan_parent(self):
783 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
784+ vlan = factory.make_VLAN(fabric=parent.vlan.fabric, vid=10)
785 vlan_parent = factory.make_Interface(
786- INTERFACE_TYPE.VLAN, parents=[parent])
787- vlan = factory.make_VLAN(vid=10)
788+ INTERFACE_TYPE.VLAN, vlan=vlan, parents=[parent])
789+ other_vlan = factory.make_VLAN(fabric=parent.vlan.fabric, vid=11)
790 form = VLANInterfaceForm(
791 node=parent.node,
792 data={
793- 'vlan': vlan.id,
794+ 'vlan': other_vlan.id,
795 'parents': [vlan_parent.id],
796 })
797 self.assertFalse(form.is_valid(), form.errors)
798@@ -380,10 +424,27 @@
799 "VLAN interface can't have another VLAN interface as parent.",
800 form.errors['parents'][0])
801
802+ def test__rejects_vlan_not_on_same_fabric(self):
803+ parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
804+ factory.make_VLAN(fabric=parent.vlan.fabric, vid=10)
805+ other_vlan = factory.make_VLAN()
806+ form = VLANInterfaceForm(
807+ node=parent.node,
808+ data={
809+ 'vlan': other_vlan.id,
810+ 'parents': [parent.id],
811+ })
812+ self.assertFalse(form.is_valid(), form.errors)
813+ self.assertItemsEqual(['vlan'], form.errors.keys())
814+ self.assertIn(
815+ "A VLAN interface can only belong to a tagged VLAN on "
816+ "the same fabric as its parent interface.",
817+ form.errors['vlan'][0])
818+
819 def test__rejects_parent_on_bond(self):
820 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
821- factory.make_Interface(INTERFACE_TYPE.BOND, parents=[parent])
822- vlan = factory.make_VLAN(vid=10)
823+ bond = factory.make_Interface(INTERFACE_TYPE.BOND, parents=[parent])
824+ vlan = factory.make_VLAN(fabric=bond.vlan.fabric, vid=10)
825 form = VLANInterfaceForm(
826 node=parent.node,
827 data={
828@@ -417,7 +478,7 @@
829 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
830 interface = factory.make_Interface(
831 INTERFACE_TYPE.VLAN, parents=[parent])
832- new_vlan = factory.make_VLAN(vid=33)
833+ new_vlan = factory.make_VLAN(fabric=interface.vlan.fabric, vid=33)
834 form = VLANInterfaceForm(
835 instance=interface,
836 data={
837@@ -438,15 +499,13 @@
838 def test__error_with_invalid_bond_mode(self):
839 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
840 parent2 = factory.make_Interface(
841- INTERFACE_TYPE.PHYSICAL, node=parent1.node)
842+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
843 interface_name = factory.make_name()
844- vlan = factory.make_VLAN(vid=10)
845 bond_mode = factory.make_name("bond_mode")
846 form = BondInterfaceForm(
847 node=parent1.node,
848 data={
849 'name': interface_name,
850- 'vlan': vlan.id,
851 'parents': [parent1.id, parent2.id],
852 'bond_mode': bond_mode,
853 })
854@@ -460,14 +519,12 @@
855 def test__creates_bond_interface(self):
856 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
857 parent2 = factory.make_Interface(
858- INTERFACE_TYPE.PHYSICAL, node=parent1.node)
859+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
860 interface_name = factory.make_name()
861- vlan = factory.make_VLAN(vid=10)
862 form = BondInterfaceForm(
863 node=parent1.node,
864 data={
865 'name': interface_name,
866- 'vlan': vlan.id,
867 'parents': [parent1.id, parent2.id],
868 })
869 self.assertTrue(form.is_valid(), form.errors)
870@@ -484,15 +541,13 @@
871 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
872 parent1.ensure_link_up()
873 parent2 = factory.make_Interface(
874- INTERFACE_TYPE.PHYSICAL, node=parent1.node)
875+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
876 parent2.ensure_link_up()
877 interface_name = factory.make_name()
878- vlan = factory.make_VLAN(vid=10)
879 form = BondInterfaceForm(
880 node=parent1.node,
881 data={
882 'name': interface_name,
883- 'vlan': vlan.id,
884 'parents': [parent1.id, parent2.id],
885 })
886 self.assertTrue(form.is_valid(), form.errors)
887@@ -511,14 +566,12 @@
888 def test__creates_bond_interface_with_parent_mac_address(self):
889 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
890 parent2 = factory.make_Interface(
891- INTERFACE_TYPE.PHYSICAL, node=parent1.node)
892+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
893 interface_name = factory.make_name()
894- vlan = factory.make_VLAN(vid=10)
895 form = BondInterfaceForm(
896 node=parent1.node,
897 data={
898 'name': interface_name,
899- 'vlan': vlan.id,
900 'parents': [parent1.id, parent2.id],
901 'mac_address': parent1.mac_address,
902 })
903@@ -534,14 +587,12 @@
904 def test__creates_bond_interface_with_default_bond_params(self):
905 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
906 parent2 = factory.make_Interface(
907- INTERFACE_TYPE.PHYSICAL, node=parent1.node)
908+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
909 interface_name = factory.make_name()
910- vlan = factory.make_VLAN(vid=10)
911 form = BondInterfaceForm(
912 node=parent1.node,
913 data={
914 'name': interface_name,
915- 'vlan': vlan.id,
916 'parents': [parent1.id, parent2.id],
917 })
918 self.assertTrue(form.is_valid(), form.errors)
919@@ -558,9 +609,8 @@
920 def test__creates_bond_interface_with_bond_params(self):
921 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
922 parent2 = factory.make_Interface(
923- INTERFACE_TYPE.PHYSICAL, node=parent1.node)
924+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
925 interface_name = factory.make_name()
926- vlan = factory.make_VLAN(vid=10)
927 bond_mode = factory.pick_choice(BOND_MODE_CHOICES)
928 bond_miimon = random.randint(0, 1000)
929 bond_downdelay = random.randint(0, 1000)
930@@ -572,7 +622,6 @@
931 node=parent1.node,
932 data={
933 'name': interface_name,
934- 'vlan': vlan.id,
935 'parents': [parent1.id, parent2.id],
936 'bond_mode': bond_mode,
937 'bond_miimon': bond_miimon,
938@@ -593,13 +642,11 @@
939 }, interface.params)
940
941 def test__rejects_no_parents(self):
942- vlan = factory.make_VLAN(vid=10)
943 interface_name = factory.make_name()
944 form = BondInterfaceForm(
945 node=factory.make_Node(),
946 data={
947 'name': interface_name,
948- 'vlan': vlan.id,
949 })
950 self.assertFalse(form.is_valid(), form.errors)
951 self.assertItemsEqual(['parents', 'mac_address'], form.errors.keys())
952@@ -607,21 +654,37 @@
953 "A Bond interface must have one or more parents.",
954 form.errors['parents'][0])
955
956+ def test__rejects_when_vlan_not_untagged(self):
957+ interface_name = factory.make_name()
958+ parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
959+ vlan = factory.make_VLAN(fabric=parent.vlan.fabric)
960+ form = BondInterfaceForm(
961+ node=parent.node,
962+ data={
963+ 'name': interface_name,
964+ 'parents': [parent.id],
965+ 'mac_address': parent.mac_address,
966+ 'vlan': vlan.id,
967+ })
968+ self.assertFalse(form.is_valid(), form.errors)
969+ self.assertItemsEqual(['vlan'], form.errors.keys())
970+ self.assertIn(
971+ "A bond interface can only belong to an untagged VLAN.",
972+ form.errors['vlan'][0])
973+
974 def test__rejects_when_parents_already_have_children(self):
975 node = factory.make_Node()
976 parent1 = factory.make_Interface(
977 INTERFACE_TYPE.PHYSICAL, node=node, name="eth0")
978 factory.make_Interface(INTERFACE_TYPE.VLAN, parents=[parent1])
979 parent2 = factory.make_Interface(
980- INTERFACE_TYPE.PHYSICAL, node=node, name="eth1")
981+ INTERFACE_TYPE.PHYSICAL, node=node, name="eth1", vlan=parent1.vlan)
982 factory.make_Interface(INTERFACE_TYPE.VLAN, parents=[parent2])
983- vlan = factory.make_VLAN(vid=10)
984 interface_name = factory.make_name()
985 form = BondInterfaceForm(
986 node=node,
987 data={
988 'name': interface_name,
989- 'vlan': vlan.id,
990 'parents': [parent1.id, parent2.id]
991 })
992 self.assertFalse(form.is_valid(), form.errors)
993@@ -629,17 +692,36 @@
994 "eth0, eth1 is already in-use by another interface.",
995 form.errors['parents'][0])
996
997+ def test__rejects_when_parents_not_in_same_vlan(self):
998+ node = factory.make_Node()
999+ parent1 = factory.make_Interface(
1000+ INTERFACE_TYPE.PHYSICAL, node=node, name="eth0")
1001+ parent2 = factory.make_Interface(
1002+ INTERFACE_TYPE.PHYSICAL, node=node, name="eth1")
1003+ interface_name = factory.make_name()
1004+ form = BondInterfaceForm(
1005+ node=node,
1006+ data={
1007+ 'name': interface_name,
1008+ 'parents': [parent1.id, parent2.id]
1009+ })
1010+ self.assertFalse(form.is_valid(), form.errors)
1011+ self.assertEquals(
1012+ "All parents must belong to the same VLAN.",
1013+ form.errors['parents'][0])
1014+
1015 def test__edits_interface(self):
1016 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
1017 parent2 = factory.make_Interface(
1018- INTERFACE_TYPE.PHYSICAL, node=parent1.node)
1019+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
1020 interface = factory.make_Interface(
1021 INTERFACE_TYPE.BOND,
1022 parents=[parent1, parent2])
1023- new_vlan = factory.make_VLAN(vid=33)
1024+ new_fabric = factory.make_Fabric()
1025+ new_vlan = new_fabric.get_default_vlan()
1026 new_name = factory.make_name()
1027 new_parent = factory.make_Interface(
1028- INTERFACE_TYPE.PHYSICAL, node=parent1.node)
1029+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
1030 form = BondInterfaceForm(
1031 instance=interface,
1032 data={
1033@@ -656,6 +738,10 @@
1034 vlan=new_vlan, type=INTERFACE_TYPE.BOND))
1035 self.assertItemsEqual(
1036 [parent1, parent2, new_parent], interface.parents.all())
1037+ self.assertItemsEqual([new_vlan], set(
1038+ reload_object(parent).vlan
1039+ for parent in [parent1, parent2, new_parent]
1040+ ))
1041
1042 def test__edits_interface_removes_parents(self):
1043 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
1044@@ -713,7 +799,7 @@
1045 def test__edit_doesnt_overwrite_params(self):
1046 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
1047 parent2 = factory.make_Interface(
1048- INTERFACE_TYPE.PHYSICAL, node=parent1.node)
1049+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
1050 interface = factory.make_Interface(
1051 INTERFACE_TYPE.BOND,
1052 parents=[parent1, parent2])
1053@@ -733,12 +819,10 @@
1054 "bond_xmit_hash_policy": bond_xmit_hash_policy,
1055 }
1056 interface.save()
1057- new_vlan = factory.make_VLAN(vid=33)
1058 new_name = factory.make_name()
1059 form = BondInterfaceForm(
1060 instance=interface,
1061 data={
1062- 'vlan': new_vlan.id,
1063 'name': new_name,
1064 })
1065 self.assertTrue(form.is_valid(), form.errors)
1066@@ -755,7 +839,7 @@
1067 def test__edit_does_overwrite_params(self):
1068 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
1069 parent2 = factory.make_Interface(
1070- INTERFACE_TYPE.PHYSICAL, node=parent1.node)
1071+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
1072 interface = factory.make_Interface(
1073 INTERFACE_TYPE.BOND,
1074 parents=[parent1, parent2])
1075@@ -775,7 +859,6 @@
1076 "bond_xmit_hash_policy": bond_xmit_hash_policy,
1077 }
1078 interface.save()
1079- new_vlan = factory.make_VLAN(vid=33)
1080 new_name = factory.make_name()
1081 new_bond_mode = factory.pick_choice(BOND_MODE_CHOICES)
1082 new_bond_miimon = random.randint(0, 1000)
1083@@ -787,7 +870,6 @@
1084 form = BondInterfaceForm(
1085 instance=interface,
1086 data={
1087- 'vlan': new_vlan.id,
1088 'name': new_name,
1089 'bond_mode': new_bond_mode,
1090 'bond_miimon': new_bond_miimon,
1091@@ -810,7 +892,7 @@
1092 def test__edit_allows_zero_params(self):
1093 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
1094 parent2 = factory.make_Interface(
1095- INTERFACE_TYPE.PHYSICAL, node=parent1.node)
1096+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
1097 interface = factory.make_Interface(
1098 INTERFACE_TYPE.BOND,
1099 parents=[parent1, parent2])
1100@@ -830,7 +912,6 @@
1101 "bond_xmit_hash_policy": bond_xmit_hash_policy,
1102 }
1103 interface.save()
1104- new_vlan = factory.make_VLAN(vid=33)
1105 new_name = factory.make_name()
1106 new_bond_mode = factory.pick_choice(BOND_MODE_CHOICES)
1107 new_bond_miimon = 0
1108@@ -842,7 +923,6 @@
1109 form = BondInterfaceForm(
1110 instance=interface,
1111 data={
1112- 'vlan': new_vlan.id,
1113 'name': new_name,
1114 'bond_mode': new_bond_mode,
1115 'bond_miimon': new_bond_miimon,
1116
1117=== modified file 'src/maasserver/websockets/handlers/tests/test_node.py'
1118--- src/maasserver/websockets/handlers/tests/test_node.py 2015-11-18 18:14:30 +0000
1119+++ src/maasserver/websockets/handlers/tests/test_node.py 2016-04-05 16:02:24 +0000
1120@@ -1912,7 +1912,8 @@
1121 handler = NodeHandler(user, {})
1122 name = factory.make_name("eth")
1123 mac_address = factory.make_mac_address()
1124- vlan = factory.make_VLAN()
1125+ fabric = factory.make_Fabric()
1126+ vlan = fabric.get_default_vlan()
1127 handler.create_physical({
1128 "system_id": node.system_id,
1129 "name": name,
1130@@ -1929,7 +1930,8 @@
1131 handler = NodeHandler(user, {})
1132 name = factory.make_name("eth")
1133 mac_address = factory.make_mac_address()
1134- vlan = factory.make_VLAN()
1135+ fabric = factory.make_Fabric()
1136+ vlan = fabric.get_default_vlan()
1137 subnet = factory.make_Subnet(vlan=vlan)
1138 handler.create_physical({
1139 "system_id": node.system_id,
1140@@ -1951,7 +1953,8 @@
1141 handler = NodeHandler(user, {})
1142 name = factory.make_name("eth")
1143 mac_address = factory.make_mac_address()
1144- vlan = factory.make_VLAN()
1145+ fabric = factory.make_Fabric()
1146+ vlan = fabric.get_default_vlan()
1147 handler.create_physical({
1148 "system_id": node.system_id,
1149 "name": name,
1150@@ -1971,7 +1974,8 @@
1151 handler = NodeHandler(user, {})
1152 name = factory.make_name("eth")
1153 mac_address = factory.make_mac_address()
1154- vlan = factory.make_VLAN()
1155+ fabric = factory.make_Fabric()
1156+ vlan = fabric.get_default_vlan()
1157 subnet = factory.make_Subnet(vlan=vlan)
1158 handler.create_physical({
1159 "system_id": node.system_id,
1160@@ -1992,7 +1996,7 @@
1161 node = factory.make_Node()
1162 handler = NodeHandler(user, {})
1163 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)
1164- new_vlan = factory.make_VLAN()
1165+ new_vlan = factory.make_VLAN(fabric=interface.vlan.fabric)
1166 handler.create_vlan({
1167 "system_id": node.system_id,
1168 "parent": interface.id,
1169@@ -2008,7 +2012,7 @@
1170 node = factory.make_Node()
1171 handler = NodeHandler(user, {})
1172 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)
1173- new_vlan = factory.make_VLAN()
1174+ new_vlan = factory.make_VLAN(fabric=interface.vlan.fabric)
1175 new_subnet = factory.make_Subnet(vlan=new_vlan)
1176 handler.create_vlan({
1177 "system_id": node.system_id,
1178@@ -2030,7 +2034,7 @@
1179 node = factory.make_Node()
1180 handler = NodeHandler(user, {})
1181 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)
1182- new_vlan = factory.make_VLAN()
1183+ new_vlan = factory.make_VLAN(fabric=interface.vlan.fabric)
1184 handler.create_vlan({
1185 "system_id": node.system_id,
1186 "parent": interface.id,
1187@@ -2050,7 +2054,7 @@
1188 node = factory.make_Node()
1189 handler = NodeHandler(user, {})
1190 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)
1191- new_vlan = factory.make_VLAN()
1192+ new_vlan = factory.make_VLAN(fabric=interface.vlan.fabric)
1193 new_subnet = factory.make_Subnet(vlan=new_vlan)
1194 handler.create_vlan({
1195 "system_id": node.system_id,
1196@@ -2110,7 +2114,8 @@
1197 handler = NodeHandler(user, {})
1198 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)
1199 new_name = factory.make_name("name")
1200- new_vlan = factory.make_VLAN()
1201+ new_fabric = factory.make_Fabric()
1202+ new_vlan = new_fabric.get_default_vlan()
1203 handler.update_interface({
1204 "system_id": node.system_id,
1205 "interface_id": interface.id,

Subscribers

People subscribed via source and target branches