Merge lp:~mpontillo/maas/allow-physical-interfaces-on-vlans-with-known-tag--bug-1678339 into lp:~maas-committers/maas/trunk

Proposed by Mike Pontillo
Status: Merged
Approved by: Mike Pontillo
Approved revision: no longer in the source branch.
Merged at revision: 6087
Proposed branch: lp:~mpontillo/maas/allow-physical-interfaces-on-vlans-with-known-tag--bug-1678339
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 764 lines (+103/-161)
4 files modified
src/maasserver/api/tests/test_interfaces.py (+13/-22)
src/maasserver/forms/interface.py (+2/-21)
src/maasserver/forms/tests/test_interface.py (+65/-94)
src/maasserver/websockets/handlers/tests/test_machine.py (+23/-24)
To merge this branch: bzr merge lp:~mpontillo/maas/allow-physical-interfaces-on-vlans-with-known-tag--bug-1678339
Reviewer Review Type Date Requested Status
Andres Rodriguez (community) Approve
Review via email: mp+325774@code.launchpad.net

Commit message

Allow physical (and bond) interfaces to be placed on VLANs with a known 802.1q tag.

Description of the change

This was preventing users with moderately complex networks from using the MAAS 2.2 release with DHCP relay, since nodes on the relay VLANs by definition are not "untagged" from the rack controller's point of view.

(The bug also occurs in situations without DHCP relay, as the linked bug description shows.)

To post a comment you must log in.
Revision history for this message
Andres Rodriguez (andreserl) wrote :

lgtm!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/maasserver/api/tests/test_interfaces.py'
--- src/maasserver/api/tests/test_interfaces.py 2017-04-20 22:41:52 +0000
+++ src/maasserver/api/tests/test_interfaces.py 2017-06-15 21:08:15 +0000
@@ -79,14 +79,14 @@
79def make_complex_interface(node, name=None):79def make_complex_interface(node, name=None):
80 """Makes interface with parents and children."""80 """Makes interface with parents and children."""
81 fabric = factory.make_Fabric()81 fabric = factory.make_Fabric()
82 untagged = fabric.get_default_vlan()82 vlan_5 = factory.make_VLAN(vid=5, fabric=fabric)
83 nic_0 = factory.make_Interface(83 nic_0 = factory.make_Interface(
84 INTERFACE_TYPE.PHYSICAL, vlan=untagged, node=node)84 INTERFACE_TYPE.PHYSICAL, vlan=vlan_5, node=node)
85 nic_1 = factory.make_Interface(85 nic_1 = factory.make_Interface(
86 INTERFACE_TYPE.PHYSICAL, vlan=untagged, node=node)86 INTERFACE_TYPE.PHYSICAL, vlan=vlan_5, node=node)
87 parents = [nic_0, nic_1]87 parents = [nic_0, nic_1]
88 bond_interface = factory.make_Interface(88 bond_interface = factory.make_Interface(
89 INTERFACE_TYPE.BOND, mac_address=nic_0.mac_address, vlan=untagged,89 INTERFACE_TYPE.BOND, mac_address=nic_0.mac_address, vlan=vlan_5,
90 parents=parents, name=name)90 parents=parents, name=name)
91 vlan_10 = factory.make_VLAN(vid=10, fabric=fabric)91 vlan_10 = factory.make_VLAN(vid=10, fabric=fabric)
92 vlan_nic_10 = factory.make_Interface(92 vlan_nic_10 = factory.make_Interface(
@@ -179,8 +179,7 @@
179 node = factory.make_Node(status=status)179 node = factory.make_Node(status=status)
180 mac = factory.make_mac_address()180 mac = factory.make_mac_address()
181 name = factory.make_name("eth")181 name = factory.make_name("eth")
182 fabric = factory.make_Fabric()182 vlan = factory.make_VLAN()
183 vlan = fabric.get_default_vlan()
184 tags = [183 tags = [
185 factory.make_name("tag")184 factory.make_name("tag")
186 for _ in range(3)185 for _ in range(3)
@@ -213,8 +212,7 @@
213 owner=self.user, parent=parent)212 owner=self.user, parent=parent)
214 mac = factory.make_mac_address()213 mac = factory.make_mac_address()
215 name = factory.make_name("eth")214 name = factory.make_name("eth")
216 fabric = factory.make_Fabric()215 vlan = factory.make_VLAN()
217 vlan = fabric.get_default_vlan()
218 tags = [216 tags = [
219 factory.make_name("tag")217 factory.make_name("tag")
220 for _ in range(3)218 for _ in range(3)
@@ -247,8 +245,7 @@
247 node = factory.make_Node(status=status)245 node = factory.make_Node(status=status)
248 mac = factory.make_mac_address()246 mac = factory.make_mac_address()
249 name = factory.make_name("eth")247 name = factory.make_name("eth")
250 fabric = factory.make_Fabric()248 vlan = factory.make_VLAN()
251 vlan = fabric.get_default_vlan()
252 tags = [249 tags = [
253 factory.make_name("tag")250 factory.make_name("tag")
254 for _ in range(3)251 for _ in range(3)
@@ -327,8 +324,7 @@
327 interface_on_other_node = factory.make_Interface(324 interface_on_other_node = factory.make_Interface(
328 INTERFACE_TYPE.PHYSICAL)325 INTERFACE_TYPE.PHYSICAL)
329 name = factory.make_name("eth")326 name = factory.make_name("eth")
330 fabric = factory.make_Fabric()327 vlan = factory.make_VLAN()
331 vlan = fabric.get_default_vlan()
332 uri = get_interfaces_uri(node)328 uri = get_interfaces_uri(node)
333 response = self.client.post(uri, {329 response = self.client.post(uri, {
334 "op": "create_physical",330 "op": "create_physical",
@@ -348,8 +344,7 @@
348 self.become_admin()344 self.become_admin()
349 for status in (NODE_STATUS.READY, NODE_STATUS.BROKEN):345 for status in (NODE_STATUS.READY, NODE_STATUS.BROKEN):
350 node = factory.make_Node(status=status)346 node = factory.make_Node(status=status)
351 fabric = factory.make_Fabric()347 vlan = factory.make_VLAN()
352 vlan = fabric.get_default_vlan()
353 parent_1_iface = factory.make_Interface(348 parent_1_iface = factory.make_Interface(
354 INTERFACE_TYPE.PHYSICAL, vlan=vlan, node=node)349 INTERFACE_TYPE.PHYSICAL, vlan=vlan, node=node)
355 parent_2_iface = factory.make_Interface(350 parent_2_iface = factory.make_Interface(
@@ -438,7 +433,7 @@
438 self.assertEqual(433 self.assertEqual(
439 http.client.CONFLICT, response.status_code, response.content)434 http.client.CONFLICT, response.status_code, response.content)
440435
441 def test_create_bond_requires_name_and_parents(self):436 def test_create_bond_requires_name_vlan_and_parents(self):
442 self.become_admin()437 self.become_admin()
443 node = factory.make_Node(status=NODE_STATUS.READY)438 node = factory.make_Node(status=NODE_STATUS.READY)
444 uri = get_interfaces_uri(node)439 uri = get_interfaces_uri(node)
@@ -941,8 +936,7 @@
941 interface = factory.make_Interface(936 interface = factory.make_Interface(
942 INTERFACE_TYPE.PHYSICAL, node=node)937 INTERFACE_TYPE.PHYSICAL, node=node)
943 new_name = factory.make_name("name")938 new_name = factory.make_name("name")
944 new_fabric = factory.make_Fabric()939 new_vlan = factory.make_VLAN()
945 new_vlan = new_fabric.get_default_vlan()
946 uri = get_interface_uri(interface)940 uri = get_interface_uri(interface)
947 response = self.client.put(uri, {941 response = self.client.put(uri, {
948 "name": new_name,942 "name": new_name,
@@ -961,8 +955,7 @@
961 interface = factory.make_Interface(955 interface = factory.make_Interface(
962 INTERFACE_TYPE.PHYSICAL, node=device)956 INTERFACE_TYPE.PHYSICAL, node=device)
963 new_name = factory.make_name("name")957 new_name = factory.make_name("name")
964 new_fabric = factory.make_Fabric()958 new_vlan = factory.make_VLAN()
965 new_vlan = new_fabric.get_default_vlan()
966 uri = get_interface_uri(interface)959 uri = get_interface_uri(interface)
967 response = self.client.put(uri, {960 response = self.client.put(uri, {
968 "name": new_name,961 "name": new_name,
@@ -996,12 +989,10 @@
996 bond, [nic_0, nic_1], [vlan_10, vlan_11] = make_complex_interface(989 bond, [nic_0, nic_1], [vlan_10, vlan_11] = make_complex_interface(
997 node)990 node)
998 physical_interface = factory.make_Interface(991 physical_interface = factory.make_Interface(
999 INTERFACE_TYPE.PHYSICAL, node=node)992 INTERFACE_TYPE.PHYSICAL, node=node, vlan=nic_0.vlan)
1000 new_vlan = factory.make_VLAN(fabric=physical_interface.vlan.fabric)
1001 uri = get_interface_uri(vlan_10)993 uri = get_interface_uri(vlan_10)
1002 response = self.client.put(uri, {994 response = self.client.put(uri, {
1003 "parent": physical_interface.id,995 "parent": physical_interface.id,
1004 "vlan": new_vlan.id,
1005 })996 })
1006 self.assertEqual(997 self.assertEqual(
1007 http.client.OK, response.status_code, response.content)998 http.client.OK, response.status_code, response.content)
1008999
=== modified file 'src/maasserver/forms/interface.py'
--- src/maasserver/forms/interface.py 2017-04-05 22:50:03 +0000
+++ src/maasserver/forms/interface.py 2017-06-15 21:08:15 +0000
@@ -252,18 +252,6 @@
252 if len(parents) > 0:252 if len(parents) > 0:
253 raise ValidationError("A physical interface cannot have parents.")253 raise ValidationError("A physical interface cannot have parents.")
254254
255 def clean_vlan(self):
256 new_vlan = self.cleaned_data.get('vlan')
257 if new_vlan and new_vlan.fabric.get_default_vlan() != new_vlan:
258 # A device's physical interface can be connected to a tagged VLAN.
259 # This is because a container or VM could be bridged on the machine
260 # to a tagged VLAN interface. See lp:1572070 for details.
261 if self.node.node_type != NODE_TYPE.DEVICE:
262 raise ValidationError(
263 "A physical interface can only belong to an "
264 "untagged VLAN.")
265 return new_vlan
266
267 def clean(self):255 def clean(self):
268 cleaned_data = super(PhysicalInterfaceForm, self).clean()256 cleaned_data = super(PhysicalInterfaceForm, self).clean()
269 new_name = cleaned_data.get('name')257 new_name = cleaned_data.get('name')
@@ -313,7 +301,7 @@
313 not created and new_vlan is None and vlan_was_set):301 not created and new_vlan is None and vlan_was_set):
314 raise ValidationError(302 raise ValidationError(
315 "A VLAN interface must be connected to a tagged VLAN.")303 "A VLAN interface must be connected to a tagged VLAN.")
316 if new_vlan and new_vlan.fabric.get_default_vlan() == new_vlan:304 if new_vlan and new_vlan.vid == 0:
317 raise ValidationError(305 raise ValidationError(
318 "A VLAN interface can only belong to a tagged VLAN.")306 "A VLAN interface can only belong to a tagged VLAN.")
319 return new_vlan307 return new_vlan
@@ -455,16 +443,9 @@
455 'name',443 'name',
456 )444 )
457445
458 def clean_vlan(self):
459 new_vlan = self.cleaned_data.get('vlan')
460 if new_vlan and new_vlan.fabric.get_default_vlan() != new_vlan:
461 raise ValidationError(
462 "A bond interface can only belong to an untagged VLAN.")
463 return new_vlan
464
465 def clean(self):446 def clean(self):
466 cleaned_data = super().clean()447 cleaned_data = super().clean()
467 if self.fields_ok(['vlan', 'parents']):448 if self.fields_ok(['parents']):
468 parents = self.cleaned_data.get('parents')449 parents = self.cleaned_data.get('parents')
469 # Set the mac_address if its missing and the interface is being450 # Set the mac_address if its missing and the interface is being
470 # created.451 # created.
471452
=== modified file 'src/maasserver/forms/tests/test_interface.py'
--- src/maasserver/forms/tests/test_interface.py 2017-04-05 23:39:23 +0000
+++ src/maasserver/forms/tests/test_interface.py 2017-06-15 21:08:15 +0000
@@ -30,7 +30,6 @@
30from maasserver.testing.factory import factory30from maasserver.testing.factory import factory
31from maasserver.testing.testcase import MAASServerTestCase31from maasserver.testing.testcase import MAASServerTestCase
32from maasserver.utils.forms import compose_invalid_choice_text32from maasserver.utils.forms import compose_invalid_choice_text
33from maasserver.utils.orm import reload_object
34from testtools import ExpectedException33from testtools import ExpectedException
35from testtools.matchers import MatchesStructure34from testtools.matchers import MatchesStructure
3635
@@ -133,8 +132,7 @@
133 node = factory.make_Node()132 node = factory.make_Node()
134 mac_address = factory.make_mac_address()133 mac_address = factory.make_mac_address()
135 interface_name = 'eth0'134 interface_name = 'eth0'
136 fabric = factory.make_Fabric()135 vlan = factory.make_VLAN()
137 vlan = fabric.get_default_vlan()
138 tags = [136 tags = [
139 factory.make_name("tag")137 factory.make_name("tag")
140 for _ in range(3)138 for _ in range(3)
@@ -211,8 +209,7 @@
211 node = factory.make_Node()209 node = factory.make_Node()
212 mac_address = factory.make_mac_address()210 mac_address = factory.make_mac_address()
213 interface_name = 'eth0'211 interface_name = 'eth0'
214 fabric = factory.make_Fabric()212 vlan = factory.make_VLAN()
215 vlan = fabric.get_default_vlan()
216 tags = [213 tags = [
217 factory.make_name("tag")214 factory.make_name("tag")
218 for _ in range(3)215 for _ in range(3)
@@ -232,8 +229,7 @@
232229
233 def test__requires_mac_address(self):230 def test__requires_mac_address(self):
234 interface_name = 'eth0'231 interface_name = 'eth0'
235 fabric = factory.make_Fabric()232 vlan = factory.make_VLAN()
236 vlan = fabric.get_default_vlan()
237 form = PhysicalInterfaceForm(233 form = PhysicalInterfaceForm(
238 node=factory.make_Node(),234 node=factory.make_Node(),
239 data={235 data={
@@ -248,9 +244,7 @@
248 form.errors['mac_address'][0])244 form.errors['mac_address'][0])
249245
250 def test_rejects_interface_with_duplicate_name(self):246 def test_rejects_interface_with_duplicate_name(self):
251 fabric = factory.make_Fabric()247 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
252 vlan = fabric.get_default_vlan()
253 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
254 mac_address = factory.make_mac_address()248 mac_address = factory.make_mac_address()
255 form = PhysicalInterfaceForm(249 form = PhysicalInterfaceForm(
256 node=interface.node,250 node=interface.node,
@@ -266,26 +260,6 @@
266 "already has an interface named '%s'." % interface.name,260 "already has an interface named '%s'." % interface.name,
267 form.errors['name'][0])261 form.errors['name'][0])
268262
269 def test_rejects_interface_on_tagged_vlan(self):
270 fabric = factory.make_Fabric()
271 interface = factory.make_Interface(
272 INTERFACE_TYPE.PHYSICAL, vlan=fabric.get_default_vlan())
273 vlan = factory.make_VLAN(fabric=fabric)
274 mac_address = factory.make_mac_address()
275 form = PhysicalInterfaceForm(
276 node=interface.node,
277 data={
278 'name': factory.make_name("eth"),
279 'mac_address': mac_address,
280 'vlan': vlan.id,
281 })
282 self.assertFalse(form.is_valid(), dict(form.errors))
283 self.assertItemsEqual(
284 ['vlan'], form.errors.keys(), form.errors)
285 self.assertIn(
286 "A physical interface can only belong to an untagged VLAN.",
287 form.errors['vlan'][0])
288
289 def test_allows_interface_on_tagged_vlan_for_device(self):263 def test_allows_interface_on_tagged_vlan_for_device(self):
290 device = factory.make_Device()264 device = factory.make_Device()
291 fabric = factory.make_Fabric()265 fabric = factory.make_Fabric()
@@ -307,8 +281,7 @@
307281
308 def test__rejects_parents(self):282 def test__rejects_parents(self):
309 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)283 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
310 fabric = factory.make_Fabric()284 vlan = factory.make_VLAN()
311 vlan = fabric.get_default_vlan()
312 form = PhysicalInterfaceForm(285 form = PhysicalInterfaceForm(
313 node=parent.node,286 node=parent.node,
314 data={287 data={
@@ -328,8 +301,7 @@
328 interface = factory.make_Interface(301 interface = factory.make_Interface(
329 INTERFACE_TYPE.PHYSICAL, name='eth0')302 INTERFACE_TYPE.PHYSICAL, name='eth0')
330 new_name = 'eth1'303 new_name = 'eth1'
331 new_fabric = factory.make_Fabric()304 new_vlan = factory.make_VLAN(vid=33)
332 new_vlan = new_fabric.get_default_vlan()
333 form = PhysicalInterfaceForm(305 form = PhysicalInterfaceForm(
334 instance=interface,306 instance=interface,
335 data={307 data={
@@ -390,8 +362,7 @@
390 node = factory.make_Node()362 node = factory.make_Node()
391 mac_address = factory.make_mac_address()363 mac_address = factory.make_mac_address()
392 interface_name = 'eth0'364 interface_name = 'eth0'
393 fabric = factory.make_Fabric()365 vlan = factory.make_VLAN()
394 vlan = fabric.get_default_vlan()
395 tags = [366 tags = [
396 factory.make_name("tag")367 factory.make_name("tag")
397 for _ in range(3)368 for _ in range(3)
@@ -430,8 +401,7 @@
430 "autoconf": autoconf,401 "autoconf": autoconf,
431 }402 }
432 new_name = 'eth1'403 new_name = 'eth1'
433 new_fabric = factory.make_Fabric()404 new_vlan = factory.make_VLAN(vid=33)
434 new_vlan = new_fabric.get_default_vlan()
435 form = PhysicalInterfaceForm(405 form = PhysicalInterfaceForm(
436 instance=interface,406 instance=interface,
437 data={407 data={
@@ -503,8 +473,8 @@
503class VLANInterfaceFormTest(MAASServerTestCase):473class VLANInterfaceFormTest(MAASServerTestCase):
504474
505 def test__creates_vlan_interface(self):475 def test__creates_vlan_interface(self):
506 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)476 vlan = factory.make_VLAN(vid=10)
507 vlan = factory.make_VLAN(fabric=parent.vlan.fabric, vid=10)477 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
508 form = VLANInterfaceForm(478 form = VLANInterfaceForm(
509 node=parent.node,479 node=parent.node,
510 data={480 data={
@@ -521,8 +491,8 @@
521 self.assertItemsEqual([parent], interface.parents.all())491 self.assertItemsEqual([parent], interface.parents.all())
522492
523 def test__create_ensures_link_up(self):493 def test__create_ensures_link_up(self):
524 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)494 vlan = factory.make_VLAN(vid=10)
525 vlan = factory.make_VLAN(fabric=parent.vlan.fabric, vid=10)495 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
526 form = VLANInterfaceForm(496 form = VLANInterfaceForm(
527 node=parent.node,497 node=parent.node,
528 data={498 data={
@@ -549,10 +519,13 @@
549 form.errors['vlan'][0])519 form.errors['vlan'][0])
550520
551 def test_rejects_interface_with_duplicate_name(self):521 def test_rejects_interface_with_duplicate_name(self):
552 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)522 vlan = factory.make_VLAN(vid=10)
553 vlan = factory.make_VLAN(fabric=parent.vlan.fabric, vid=10)523 parent = factory.make_Interface(
524 INTERFACE_TYPE.PHYSICAL,
525 vlan=vlan)
554 interface = factory.make_Interface(526 interface = factory.make_Interface(
555 INTERFACE_TYPE.VLAN, vlan=vlan, parents=[parent])527 INTERFACE_TYPE.VLAN,
528 vlan=vlan, parents=[parent])
556 form = VLANInterfaceForm(529 form = VLANInterfaceForm(
557 node=parent.node,530 node=parent.node,
558 data={531 data={
@@ -597,14 +570,13 @@
597570
598 def test__rejects_vlan_parent(self):571 def test__rejects_vlan_parent(self):
599 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)572 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
600 vlan = factory.make_VLAN(fabric=parent.vlan.fabric, vid=10)
601 vlan_parent = factory.make_Interface(573 vlan_parent = factory.make_Interface(
602 INTERFACE_TYPE.VLAN, vlan=vlan, parents=[parent])574 INTERFACE_TYPE.VLAN, parents=[parent])
603 other_vlan = factory.make_VLAN(fabric=parent.vlan.fabric, vid=11)575 vlan = factory.make_VLAN(vid=10)
604 form = VLANInterfaceForm(576 form = VLANInterfaceForm(
605 node=parent.node,577 node=parent.node,
606 data={578 data={
607 'vlan': other_vlan.id,579 'vlan': vlan.id,
608 'parents': [vlan_parent.id],580 'parents': [vlan_parent.id],
609 })581 })
610 self.assertFalse(form.is_valid(), dict(form.errors))582 self.assertFalse(form.is_valid(), dict(form.errors))
@@ -646,8 +618,8 @@
646618
647 def test__rejects_parent_on_bond(self):619 def test__rejects_parent_on_bond(self):
648 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)620 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
649 bond = factory.make_Interface(INTERFACE_TYPE.BOND, parents=[parent])621 factory.make_Interface(INTERFACE_TYPE.BOND, parents=[parent])
650 vlan = factory.make_VLAN(fabric=bond.vlan.fabric, vid=10)622 vlan = factory.make_VLAN(vid=10)
651 form = VLANInterfaceForm(623 form = VLANInterfaceForm(
652 node=parent.node,624 node=parent.node,
653 data={625 data={
@@ -682,7 +654,7 @@
682 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)654 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
683 interface = factory.make_Interface(655 interface = factory.make_Interface(
684 INTERFACE_TYPE.VLAN, parents=[parent])656 INTERFACE_TYPE.VLAN, parents=[parent])
685 new_vlan = factory.make_VLAN(fabric=interface.vlan.fabric, vid=33)657 new_vlan = factory.make_VLAN(vid=33)
686 form = VLANInterfaceForm(658 form = VLANInterfaceForm(
687 instance=interface,659 instance=interface,
688 data={660 data={
@@ -701,15 +673,17 @@
701class BondInterfaceFormTest(MAASServerTestCase):673class BondInterfaceFormTest(MAASServerTestCase):
702674
703 def test__error_with_invalid_bond_mode(self):675 def test__error_with_invalid_bond_mode(self):
704 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)676 vlan = factory.make_VLAN(vid=10)
677 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
705 parent2 = factory.make_Interface(678 parent2 = factory.make_Interface(
706 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)679 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=vlan)
707 interface_name = factory.make_name()680 interface_name = factory.make_name()
708 bond_mode = factory.make_name("bond_mode")681 bond_mode = factory.make_name("bond_mode")
709 form = BondInterfaceForm(682 form = BondInterfaceForm(
710 node=parent1.node,683 node=parent1.node,
711 data={684 data={
712 'name': interface_name,685 'name': interface_name,
686 'vlan': vlan.id,
713 'parents': [parent1.id, parent2.id],687 'parents': [parent1.id, parent2.id],
714 'bond_mode': bond_mode,688 'bond_mode': bond_mode,
715 })689 })
@@ -721,14 +695,16 @@
721 }, form.errors)695 }, form.errors)
722696
723 def test__creates_bond_interface(self):697 def test__creates_bond_interface(self):
724 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)698 vlan = factory.make_VLAN(vid=10)
699 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
725 parent2 = factory.make_Interface(700 parent2 = factory.make_Interface(
726 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)701 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=vlan)
727 interface_name = factory.make_name()702 interface_name = factory.make_name()
728 form = BondInterfaceForm(703 form = BondInterfaceForm(
729 node=parent1.node,704 node=parent1.node,
730 data={705 data={
731 'name': interface_name,706 'name': interface_name,
707 'vlan': vlan.id,
732 'parents': [parent1.id, parent2.id],708 'parents': [parent1.id, parent2.id],
733 })709 })
734 self.assertTrue(form.is_valid(), dict(form.errors))710 self.assertTrue(form.is_valid(), dict(form.errors))
@@ -743,16 +719,18 @@
743 self.assertItemsEqual([parent1, parent2], interface.parents.all())719 self.assertItemsEqual([parent1, parent2], interface.parents.all())
744720
745 def test__create_removes_parent_links_and_sets_link_up_on_bond(self):721 def test__create_removes_parent_links_and_sets_link_up_on_bond(self):
746 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)722 vlan = factory.make_VLAN(vid=10)
723 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
747 parent1.ensure_link_up()724 parent1.ensure_link_up()
748 parent2 = factory.make_Interface(725 parent2 = factory.make_Interface(
749 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)726 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=vlan)
750 parent2.ensure_link_up()727 parent2.ensure_link_up()
751 interface_name = factory.make_name()728 interface_name = factory.make_name()
752 form = BondInterfaceForm(729 form = BondInterfaceForm(
753 node=parent1.node,730 node=parent1.node,
754 data={731 data={
755 'name': interface_name,732 'name': interface_name,
733 'vlan': vlan.id,
756 'parents': [parent1.id, parent2.id],734 'parents': [parent1.id, parent2.id],
757 })735 })
758 self.assertTrue(form.is_valid(), dict(form.errors))736 self.assertTrue(form.is_valid(), dict(form.errors))
@@ -769,14 +747,16 @@
769 interface.ip_addresses.filter(alloc_type=IPADDRESS_TYPE.STICKY))747 interface.ip_addresses.filter(alloc_type=IPADDRESS_TYPE.STICKY))
770748
771 def test__creates_bond_interface_with_parent_mac_address(self):749 def test__creates_bond_interface_with_parent_mac_address(self):
772 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)750 vlan = factory.make_VLAN(vid=10)
751 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
773 parent2 = factory.make_Interface(752 parent2 = factory.make_Interface(
774 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)753 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=vlan)
775 interface_name = factory.make_name()754 interface_name = factory.make_name()
776 form = BondInterfaceForm(755 form = BondInterfaceForm(
777 node=parent1.node,756 node=parent1.node,
778 data={757 data={
779 'name': interface_name,758 'name': interface_name,
759 'vlan': vlan.id,
780 'parents': [parent1.id, parent2.id],760 'parents': [parent1.id, parent2.id],
781 'mac_address': parent1.mac_address,761 'mac_address': parent1.mac_address,
782 })762 })
@@ -790,14 +770,16 @@
790 self.assertItemsEqual([parent1, parent2], interface.parents.all())770 self.assertItemsEqual([parent1, parent2], interface.parents.all())
791771
792 def test__creates_bond_interface_with_default_bond_params(self):772 def test__creates_bond_interface_with_default_bond_params(self):
793 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)773 vlan = factory.make_VLAN(vid=10)
774 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
794 parent2 = factory.make_Interface(775 parent2 = factory.make_Interface(
795 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)776 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=vlan)
796 interface_name = factory.make_name()777 interface_name = factory.make_name()
797 form = BondInterfaceForm(778 form = BondInterfaceForm(
798 node=parent1.node,779 node=parent1.node,
799 data={780 data={
800 'name': interface_name,781 'name': interface_name,
782 'vlan': vlan.id,
801 'parents': [parent1.id, parent2.id],783 'parents': [parent1.id, parent2.id],
802 })784 })
803 self.assertTrue(form.is_valid(), dict(form.errors))785 self.assertTrue(form.is_valid(), dict(form.errors))
@@ -812,9 +794,10 @@
812 }, interface.params)794 }, interface.params)
813795
814 def test__creates_bond_interface_with_bond_params(self):796 def test__creates_bond_interface_with_bond_params(self):
815 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)797 vlan = factory.make_VLAN(vid=10)
798 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
816 parent2 = factory.make_Interface(799 parent2 = factory.make_Interface(
817 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)800 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=vlan)
818 interface_name = factory.make_name()801 interface_name = factory.make_name()
819 bond_mode = factory.pick_choice(BOND_MODE_CHOICES)802 bond_mode = factory.pick_choice(BOND_MODE_CHOICES)
820 bond_miimon = random.randint(0, 1000)803 bond_miimon = random.randint(0, 1000)
@@ -827,6 +810,7 @@
827 node=parent1.node,810 node=parent1.node,
828 data={811 data={
829 'name': interface_name,812 'name': interface_name,
813 'vlan': vlan.id,
830 'parents': [parent1.id, parent2.id],814 'parents': [parent1.id, parent2.id],
831 'bond_mode': bond_mode,815 'bond_mode': bond_mode,
832 'bond_miimon': bond_miimon,816 'bond_miimon': bond_miimon,
@@ -847,11 +831,13 @@
847 }, interface.params)831 }, interface.params)
848832
849 def test__rejects_no_parents(self):833 def test__rejects_no_parents(self):
834 vlan = factory.make_VLAN(vid=10)
850 interface_name = factory.make_name()835 interface_name = factory.make_name()
851 form = BondInterfaceForm(836 form = BondInterfaceForm(
852 node=factory.make_Node(),837 node=factory.make_Node(),
853 data={838 data={
854 'name': interface_name,839 'name': interface_name,
840 'vlan': vlan.id,
855 })841 })
856 self.assertFalse(form.is_valid(), dict(form.errors))842 self.assertFalse(form.is_valid(), dict(form.errors))
857 self.assertItemsEqual(['parents', 'mac_address'], form.errors.keys())843 self.assertItemsEqual(['parents', 'mac_address'], form.errors.keys())
@@ -859,37 +845,21 @@
859 "A bond interface must have one or more parents.",845 "A bond interface must have one or more parents.",
860 form.errors['parents'][0])846 form.errors['parents'][0])
861847
862 def test__rejects_when_vlan_not_untagged(self):
863 interface_name = factory.make_name()
864 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
865 vlan = factory.make_VLAN(fabric=parent.vlan.fabric)
866 form = BondInterfaceForm(
867 node=parent.node,
868 data={
869 'name': interface_name,
870 'parents': [parent.id],
871 'mac_address': parent.mac_address,
872 'vlan': vlan.id,
873 })
874 self.assertFalse(form.is_valid(), dict(form.errors))
875 self.assertItemsEqual(['vlan'], form.errors.keys())
876 self.assertIn(
877 "A bond interface can only belong to an untagged VLAN.",
878 form.errors['vlan'][0])
879
880 def test__rejects_when_parents_already_have_children(self):848 def test__rejects_when_parents_already_have_children(self):
881 node = factory.make_Node()849 node = factory.make_Node()
882 parent1 = factory.make_Interface(850 parent1 = factory.make_Interface(
883 INTERFACE_TYPE.PHYSICAL, node=node, name="eth0")851 INTERFACE_TYPE.PHYSICAL, node=node, name="eth0")
884 factory.make_Interface(INTERFACE_TYPE.VLAN, parents=[parent1])852 factory.make_Interface(INTERFACE_TYPE.VLAN, parents=[parent1])
885 parent2 = factory.make_Interface(853 parent2 = factory.make_Interface(
886 INTERFACE_TYPE.PHYSICAL, node=node, name="eth1", vlan=parent1.vlan)854 INTERFACE_TYPE.PHYSICAL, node=node, name="eth1")
887 factory.make_Interface(INTERFACE_TYPE.VLAN, parents=[parent2])855 factory.make_Interface(INTERFACE_TYPE.VLAN, parents=[parent2])
856 vlan = factory.make_VLAN(vid=10)
888 interface_name = factory.make_name()857 interface_name = factory.make_name()
889 form = BondInterfaceForm(858 form = BondInterfaceForm(
890 node=node,859 node=node,
891 data={860 data={
892 'name': interface_name,861 'name': interface_name,
862 'vlan': vlan.id,
893 'parents': [parent1.id, parent2.id]863 'parents': [parent1.id, parent2.id]
894 })864 })
895 self.assertFalse(form.is_valid(), dict(form.errors))865 self.assertFalse(form.is_valid(), dict(form.errors))
@@ -918,15 +888,14 @@
918 def test__edits_interface(self):888 def test__edits_interface(self):
919 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)889 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
920 parent2 = factory.make_Interface(890 parent2 = factory.make_Interface(
921 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)891 INTERFACE_TYPE.PHYSICAL, node=parent1.node)
922 interface = factory.make_Interface(892 interface = factory.make_Interface(
923 INTERFACE_TYPE.BOND,893 INTERFACE_TYPE.BOND,
924 parents=[parent1, parent2])894 parents=[parent1, parent2])
925 new_fabric = factory.make_Fabric()895 new_vlan = factory.make_VLAN(vid=33)
926 new_vlan = new_fabric.get_default_vlan()
927 new_name = factory.make_name()896 new_name = factory.make_name()
928 new_parent = factory.make_Interface(897 new_parent = factory.make_Interface(
929 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)898 INTERFACE_TYPE.PHYSICAL, node=parent1.node)
930 form = BondInterfaceForm(899 form = BondInterfaceForm(
931 instance=interface,900 instance=interface,
932 data={901 data={
@@ -943,10 +912,6 @@
943 vlan=new_vlan, type=INTERFACE_TYPE.BOND))912 vlan=new_vlan, type=INTERFACE_TYPE.BOND))
944 self.assertItemsEqual(913 self.assertItemsEqual(
945 [parent1, parent2, new_parent], interface.parents.all())914 [parent1, parent2, new_parent], interface.parents.all())
946 self.assertItemsEqual([new_vlan], set(
947 reload_object(parent).vlan
948 for parent in [parent1, parent2, new_parent]
949 ))
950915
951 def test__edits_interface_allows_disconnected(self):916 def test__edits_interface_allows_disconnected(self):
952 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)917 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
@@ -1023,7 +988,7 @@
1023 def test__edit_doesnt_overwrite_params(self):988 def test__edit_doesnt_overwrite_params(self):
1024 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)989 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
1025 parent2 = factory.make_Interface(990 parent2 = factory.make_Interface(
1026 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)991 INTERFACE_TYPE.PHYSICAL, node=parent1.node)
1027 interface = factory.make_Interface(992 interface = factory.make_Interface(
1028 INTERFACE_TYPE.BOND,993 INTERFACE_TYPE.BOND,
1029 parents=[parent1, parent2])994 parents=[parent1, parent2])
@@ -1043,10 +1008,12 @@
1043 "bond_xmit_hash_policy": bond_xmit_hash_policy,1008 "bond_xmit_hash_policy": bond_xmit_hash_policy,
1044 }1009 }
1045 interface.save()1010 interface.save()
1011 new_vlan = factory.make_VLAN(vid=33)
1046 new_name = factory.make_name()1012 new_name = factory.make_name()
1047 form = BondInterfaceForm(1013 form = BondInterfaceForm(
1048 instance=interface,1014 instance=interface,
1049 data={1015 data={
1016 'vlan': new_vlan.id,
1050 'name': new_name,1017 'name': new_name,
1051 })1018 })
1052 self.assertTrue(form.is_valid(), dict(form.errors))1019 self.assertTrue(form.is_valid(), dict(form.errors))
@@ -1063,7 +1030,7 @@
1063 def test__edit_does_overwrite_params(self):1030 def test__edit_does_overwrite_params(self):
1064 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)1031 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
1065 parent2 = factory.make_Interface(1032 parent2 = factory.make_Interface(
1066 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)1033 INTERFACE_TYPE.PHYSICAL, node=parent1.node)
1067 interface = factory.make_Interface(1034 interface = factory.make_Interface(
1068 INTERFACE_TYPE.BOND,1035 INTERFACE_TYPE.BOND,
1069 parents=[parent1, parent2])1036 parents=[parent1, parent2])
@@ -1083,6 +1050,7 @@
1083 "bond_xmit_hash_policy": bond_xmit_hash_policy,1050 "bond_xmit_hash_policy": bond_xmit_hash_policy,
1084 }1051 }
1085 interface.save()1052 interface.save()
1053 new_vlan = factory.make_VLAN(vid=33)
1086 new_name = factory.make_name()1054 new_name = factory.make_name()
1087 new_bond_mode = factory.pick_choice(BOND_MODE_CHOICES)1055 new_bond_mode = factory.pick_choice(BOND_MODE_CHOICES)
1088 new_bond_miimon = random.randint(0, 1000)1056 new_bond_miimon = random.randint(0, 1000)
@@ -1094,6 +1062,7 @@
1094 form = BondInterfaceForm(1062 form = BondInterfaceForm(
1095 instance=interface,1063 instance=interface,
1096 data={1064 data={
1065 'vlan': new_vlan.id,
1097 'name': new_name,1066 'name': new_name,
1098 'bond_mode': new_bond_mode,1067 'bond_mode': new_bond_mode,
1099 'bond_miimon': new_bond_miimon,1068 'bond_miimon': new_bond_miimon,
@@ -1116,7 +1085,7 @@
1116 def test__edit_allows_zero_params(self):1085 def test__edit_allows_zero_params(self):
1117 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)1086 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
1118 parent2 = factory.make_Interface(1087 parent2 = factory.make_Interface(
1119 INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)1088 INTERFACE_TYPE.PHYSICAL, node=parent1.node)
1120 interface = factory.make_Interface(1089 interface = factory.make_Interface(
1121 INTERFACE_TYPE.BOND,1090 INTERFACE_TYPE.BOND,
1122 parents=[parent1, parent2])1091 parents=[parent1, parent2])
@@ -1136,6 +1105,7 @@
1136 "bond_xmit_hash_policy": bond_xmit_hash_policy,1105 "bond_xmit_hash_policy": bond_xmit_hash_policy,
1137 }1106 }
1138 interface.save()1107 interface.save()
1108 new_vlan = factory.make_VLAN(vid=33)
1139 new_name = factory.make_name()1109 new_name = factory.make_name()
1140 new_bond_mode = factory.pick_choice(BOND_MODE_CHOICES)1110 new_bond_mode = factory.pick_choice(BOND_MODE_CHOICES)
1141 new_bond_miimon = 01111 new_bond_miimon = 0
@@ -1147,6 +1117,7 @@
1147 form = BondInterfaceForm(1117 form = BondInterfaceForm(
1148 instance=interface,1118 instance=interface,
1149 data={1119 data={
1120 'vlan': new_vlan.id,
1150 'name': new_name,1121 'name': new_name,
1151 'bond_mode': new_bond_mode,1122 'bond_mode': new_bond_mode,
1152 'bond_miimon': new_bond_miimon,1123 'bond_miimon': new_bond_miimon,
11531124
=== modified file 'src/maasserver/websockets/handlers/tests/test_machine.py'
--- src/maasserver/websockets/handlers/tests/test_machine.py 2017-04-20 08:58:42 +0000
+++ src/maasserver/websockets/handlers/tests/test_machine.py 2017-06-15 21:08:15 +0000
@@ -2079,8 +2079,7 @@
2079 handler = MachineHandler(user, {})2079 handler = MachineHandler(user, {})
2080 name = factory.make_name("eth")2080 name = factory.make_name("eth")
2081 mac_address = factory.make_mac_address()2081 mac_address = factory.make_mac_address()
2082 fabric = factory.make_Fabric()2082 vlan = factory.make_VLAN()
2083 vlan = fabric.get_default_vlan()
2084 handler.create_physical({2083 handler.create_physical({
2085 "system_id": node.system_id,2084 "system_id": node.system_id,
2086 "name": name,2085 "name": name,
@@ -2097,8 +2096,7 @@
2097 handler = MachineHandler(user, {})2096 handler = MachineHandler(user, {})
2098 name = factory.make_name("eth")2097 name = factory.make_name("eth")
2099 mac_address = factory.make_mac_address()2098 mac_address = factory.make_mac_address()
2100 fabric = factory.make_Fabric()2099 vlan = factory.make_VLAN()
2101 vlan = fabric.get_default_vlan()
2102 subnet = factory.make_Subnet(vlan=vlan)2100 subnet = factory.make_Subnet(vlan=vlan)
2103 handler.create_physical({2101 handler.create_physical({
2104 "system_id": node.system_id,2102 "system_id": node.system_id,
@@ -2120,8 +2118,7 @@
2120 handler = MachineHandler(user, {})2118 handler = MachineHandler(user, {})
2121 name = factory.make_name("eth")2119 name = factory.make_name("eth")
2122 mac_address = factory.make_mac_address()2120 mac_address = factory.make_mac_address()
2123 fabric = factory.make_Fabric()2121 vlan = factory.make_VLAN()
2124 vlan = fabric.get_default_vlan()
2125 handler.create_physical({2122 handler.create_physical({
2126 "system_id": node.system_id,2123 "system_id": node.system_id,
2127 "name": name,2124 "name": name,
@@ -2141,8 +2138,7 @@
2141 handler = MachineHandler(user, {})2138 handler = MachineHandler(user, {})
2142 name = factory.make_name("eth")2139 name = factory.make_name("eth")
2143 mac_address = factory.make_mac_address()2140 mac_address = factory.make_mac_address()
2144 fabric = factory.make_Fabric()2141 vlan = factory.make_VLAN()
2145 vlan = fabric.get_default_vlan()
2146 subnet = factory.make_Subnet(vlan=vlan)2142 subnet = factory.make_Subnet(vlan=vlan)
2147 handler.create_physical({2143 handler.create_physical({
2148 "system_id": node.system_id,2144 "system_id": node.system_id,
@@ -2162,12 +2158,13 @@
2162 user = factory.make_admin()2158 user = factory.make_admin()
2163 node = factory.make_Node()2159 node = factory.make_Node()
2164 handler = MachineHandler(user, {})2160 handler = MachineHandler(user, {})
2165 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)2161 vlan = factory.make_VLAN()
2166 new_vlan = factory.make_VLAN(fabric=interface.vlan.fabric)2162 interface = factory.make_Interface(
2163 INTERFACE_TYPE.PHYSICAL, node=node, vlan=vlan)
2167 handler.create_vlan({2164 handler.create_vlan({
2168 "system_id": node.system_id,2165 "system_id": node.system_id,
2169 "parent": interface.id,2166 "parent": interface.id,
2170 "vlan": new_vlan.id,2167 "vlan": vlan.id,
2171 })2168 })
2172 vlan_interface = get_one(2169 vlan_interface = get_one(
2173 Interface.objects.filter(2170 Interface.objects.filter(
@@ -2178,13 +2175,14 @@
2178 user = factory.make_admin()2175 user = factory.make_admin()
2179 node = factory.make_Node()2176 node = factory.make_Node()
2180 handler = MachineHandler(user, {})2177 handler = MachineHandler(user, {})
2181 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)2178 vlan = factory.make_VLAN()
2182 new_vlan = factory.make_VLAN(fabric=interface.vlan.fabric)2179 interface = factory.make_Interface(
2183 new_subnet = factory.make_Subnet(vlan=new_vlan)2180 INTERFACE_TYPE.PHYSICAL, node=node, vlan=vlan)
2181 new_subnet = factory.make_Subnet(vlan=vlan)
2184 handler.create_vlan({2182 handler.create_vlan({
2185 "system_id": node.system_id,2183 "system_id": node.system_id,
2186 "parent": interface.id,2184 "parent": interface.id,
2187 "vlan": new_vlan.id,2185 "vlan": vlan.id,
2188 "mode": INTERFACE_LINK_TYPE.AUTO,2186 "mode": INTERFACE_LINK_TYPE.AUTO,
2189 "subnet": new_subnet.id,2187 "subnet": new_subnet.id,
2190 })2188 })
@@ -2200,12 +2198,13 @@
2200 user = factory.make_admin()2198 user = factory.make_admin()
2201 node = factory.make_Node()2199 node = factory.make_Node()
2202 handler = MachineHandler(user, {})2200 handler = MachineHandler(user, {})
2203 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)2201 vlan = factory.make_VLAN()
2204 new_vlan = factory.make_VLAN(fabric=interface.vlan.fabric)2202 interface = factory.make_Interface(
2203 INTERFACE_TYPE.PHYSICAL, node=node, vlan=vlan)
2205 handler.create_vlan({2204 handler.create_vlan({
2206 "system_id": node.system_id,2205 "system_id": node.system_id,
2207 "parent": interface.id,2206 "parent": interface.id,
2208 "vlan": new_vlan.id,2207 "vlan": vlan.id,
2209 "mode": INTERFACE_LINK_TYPE.LINK_UP,2208 "mode": INTERFACE_LINK_TYPE.LINK_UP,
2210 })2209 })
2211 vlan_interface = get_one(2210 vlan_interface = get_one(
@@ -2220,13 +2219,14 @@
2220 user = factory.make_admin()2219 user = factory.make_admin()
2221 node = factory.make_Node()2220 node = factory.make_Node()
2222 handler = MachineHandler(user, {})2221 handler = MachineHandler(user, {})
2223 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)2222 vlan = factory.make_VLAN()
2224 new_vlan = factory.make_VLAN(fabric=interface.vlan.fabric)2223 interface = factory.make_Interface(
2225 new_subnet = factory.make_Subnet(vlan=new_vlan)2224 INTERFACE_TYPE.PHYSICAL, node=node, vlan=vlan)
2225 new_subnet = factory.make_Subnet(vlan=vlan)
2226 handler.create_vlan({2226 handler.create_vlan({
2227 "system_id": node.system_id,2227 "system_id": node.system_id,
2228 "parent": interface.id,2228 "parent": interface.id,
2229 "vlan": new_vlan.id,2229 "vlan": vlan.id,
2230 "mode": INTERFACE_LINK_TYPE.LINK_UP,2230 "mode": INTERFACE_LINK_TYPE.LINK_UP,
2231 "subnet": new_subnet.id,2231 "subnet": new_subnet.id,
2232 })2232 })
@@ -2317,8 +2317,7 @@
2317 handler = MachineHandler(user, {})2317 handler = MachineHandler(user, {})
2318 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)2318 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)
2319 new_name = factory.make_name("name")2319 new_name = factory.make_name("name")
2320 new_fabric = factory.make_Fabric()2320 new_vlan = factory.make_VLAN()
2321 new_vlan = new_fabric.get_default_vlan()
2322 handler.update_interface({2321 handler.update_interface({
2323 "system_id": node.system_id,2322 "system_id": node.system_id,
2324 "interface_id": interface.id,2323 "interface_id": interface.id,