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

Proposed by Mike Pontillo on 2017-06-16
Status: Merged
Approved by: Mike Pontillo on 2017-06-16
Approved revision: 6061
Merged at revision: 6064
Proposed branch: lp:~mpontillo/maas/allow-physical-interfaces-on-vlans-with-known-tag--bug-1678339--2.2
Merge into: lp:maas/2.2
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--2.2
Reviewer Review Type Date Requested Status
Mike Pontillo (community) Approve on 2017-06-16
Review via email: mp+325792@code.launchpad.net

Commit message

Backport revision 6087 to MAAS 2.2 to allow physical (and bond) interfaces to be placed on VLANs with a known 802.1q tag.

To post a comment you must log in.
Mike Pontillo (mpontillo) wrote :

Self-approve backport.

review: Approve
MAAS Lander (maas-lander) wrote :
Download full text (2.0 MiB)

The attempt to merge lp:~mpontillo/maas/allow-physical-interfaces-on-vlans-with-known-tag--bug-1678339--2.2 into lp:maas/2.2 failed. Below is the output from the failed tests.

Get:1 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB]
Hit:2 http://archive.ubuntu.com/ubuntu xenial InRelease
Get:3 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB]
Get:4 http://archive.ubuntu.com/ubuntu xenial-backports InRelease [102 kB]
Get:5 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages [558 kB]
Get:6 http://archive.ubuntu.com/ubuntu xenial-updates/universe amd64 Packages [486 kB]
Fetched 1,350 kB in 2s (615 kB/s)
Reading package lists...
sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
    --no-install-recommends install apache2 archdetect-deb authbind avahi-utils bash bind9 bind9utils build-essential bzr bzr-builddeb chromium-browser chromium-chromedriver curl daemontools debhelper dh-apport dh-systemd distro-info dnsutils firefox freeipmi-tools git gjs ipython isc-dhcp-common isc-dhcp-server libjs-angularjs libjs-jquery libjs-jquery-hotkeys libjs-yui3-full libjs-yui3-min libnss-wrapper libpq-dev make nodejs-legacy npm postgresql psmisc pxelinux python3-all python3-apt python3-attr python3-bson python3-convoy python3-crochet python3-cssselect python3-curtin python3-dev python3-distro-info python3-django python3-django-nose python3-django-piston3 python3-dnspython python3-docutils python3-formencode python3-hivex python3-httplib2 python3-jinja2 python3-jsonschema python3-lxml python3-netaddr python3-netifaces python3-novaclient python3-oauth python3-oauthlib python3-openssl python3-paramiko python3-petname python3-pexpect python3-psycopg2 python3-pyinotify python3-pyparsing python3-pyvmomi python3-requests python3-seamicroclient python3-setuptools python3-simplestreams python3-sphinx python3-tempita python3-twisted python3-txtftp python3-tz python3-yaml python3-zope.interface python-bson python-crochet python-django python-django-piston python-djorm-ext-pgarray python-formencode python-lxml python-netaddr python-netifaces python-pocket-lint python-psycopg2 python-simplejson python-tempita python-twisted python-yaml socat syslinux-common tgt ubuntu-cloudimage-keyring wget xvfb
Reading package lists...
Building dependency tree...
Reading state information...
authbind is already the newest version (2.1.1+nmu1).
avahi-utils is already the newest version (0.6.32~rc+dfsg-1ubuntu2).
build-essential is already the newest version (12.1ubuntu2).
debhelper is already the newest version (9.20160115ubuntu3).
distro-info is already the newest version (0.14build1).
libjs-angularjs is already the newest version (1.2.28-1ubuntu2).
libjs-jquery is already the newest version (1.11.3+dfsg-4).
libjs-yui3-full is already the newest version (3.5.1-1ubuntu3).
libjs-yui3-min is already the newest version (3.5.1-1ubuntu3).
make is already the newest version (4.1-6).
postgresql is already the newest version (9.5+173).
psmisc is already the newest version (22.21-2.1build1).
pxelinux is already the newest version (3:6.03+dfsg-11ubuntu1).
python-formencode is already the newest version (1.3.0-0ubuntu5).
python-lxml is already the new...

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 2017-04-20 22:41:52 +0000
3+++ src/maasserver/api/tests/test_interfaces.py 2017-06-16 00:53:57 +0000
4@@ -79,14 +79,14 @@
5 def make_complex_interface(node, name=None):
6 """Makes interface with parents and children."""
7 fabric = factory.make_Fabric()
8- untagged = fabric.get_default_vlan()
9+ vlan_5 = factory.make_VLAN(vid=5, fabric=fabric)
10 nic_0 = factory.make_Interface(
11- INTERFACE_TYPE.PHYSICAL, vlan=untagged, node=node)
12+ INTERFACE_TYPE.PHYSICAL, vlan=vlan_5, node=node)
13 nic_1 = factory.make_Interface(
14- INTERFACE_TYPE.PHYSICAL, vlan=untagged, node=node)
15+ INTERFACE_TYPE.PHYSICAL, vlan=vlan_5, 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=untagged,
19+ INTERFACE_TYPE.BOND, mac_address=nic_0.mac_address, vlan=vlan_5,
20 parents=parents, name=name)
21 vlan_10 = factory.make_VLAN(vid=10, fabric=fabric)
22 vlan_nic_10 = factory.make_Interface(
23@@ -179,8 +179,7 @@
24 node = factory.make_Node(status=status)
25 mac = factory.make_mac_address()
26 name = factory.make_name("eth")
27- fabric = factory.make_Fabric()
28- vlan = fabric.get_default_vlan()
29+ vlan = factory.make_VLAN()
30 tags = [
31 factory.make_name("tag")
32 for _ in range(3)
33@@ -213,8 +212,7 @@
34 owner=self.user, parent=parent)
35 mac = factory.make_mac_address()
36 name = factory.make_name("eth")
37- fabric = factory.make_Fabric()
38- vlan = fabric.get_default_vlan()
39+ vlan = factory.make_VLAN()
40 tags = [
41 factory.make_name("tag")
42 for _ in range(3)
43@@ -247,8 +245,7 @@
44 node = factory.make_Node(status=status)
45 mac = factory.make_mac_address()
46 name = factory.make_name("eth")
47- fabric = factory.make_Fabric()
48- vlan = fabric.get_default_vlan()
49+ vlan = factory.make_VLAN()
50 tags = [
51 factory.make_name("tag")
52 for _ in range(3)
53@@ -327,8 +324,7 @@
54 interface_on_other_node = factory.make_Interface(
55 INTERFACE_TYPE.PHYSICAL)
56 name = factory.make_name("eth")
57- fabric = factory.make_Fabric()
58- vlan = fabric.get_default_vlan()
59+ vlan = factory.make_VLAN()
60 uri = get_interfaces_uri(node)
61 response = self.client.post(uri, {
62 "op": "create_physical",
63@@ -348,8 +344,7 @@
64 self.become_admin()
65 for status in (NODE_STATUS.READY, NODE_STATUS.BROKEN):
66 node = factory.make_Node(status=status)
67- fabric = factory.make_Fabric()
68- vlan = fabric.get_default_vlan()
69+ vlan = factory.make_VLAN()
70 parent_1_iface = factory.make_Interface(
71 INTERFACE_TYPE.PHYSICAL, vlan=vlan, node=node)
72 parent_2_iface = factory.make_Interface(
73@@ -438,7 +433,7 @@
74 self.assertEqual(
75 http.client.CONFLICT, response.status_code, response.content)
76
77- def test_create_bond_requires_name_and_parents(self):
78+ def test_create_bond_requires_name_vlan_and_parents(self):
79 self.become_admin()
80 node = factory.make_Node(status=NODE_STATUS.READY)
81 uri = get_interfaces_uri(node)
82@@ -941,8 +936,7 @@
83 interface = factory.make_Interface(
84 INTERFACE_TYPE.PHYSICAL, node=node)
85 new_name = factory.make_name("name")
86- new_fabric = factory.make_Fabric()
87- new_vlan = new_fabric.get_default_vlan()
88+ new_vlan = factory.make_VLAN()
89 uri = get_interface_uri(interface)
90 response = self.client.put(uri, {
91 "name": new_name,
92@@ -961,8 +955,7 @@
93 interface = factory.make_Interface(
94 INTERFACE_TYPE.PHYSICAL, node=device)
95 new_name = factory.make_name("name")
96- new_fabric = factory.make_Fabric()
97- new_vlan = new_fabric.get_default_vlan()
98+ new_vlan = factory.make_VLAN()
99 uri = get_interface_uri(interface)
100 response = self.client.put(uri, {
101 "name": new_name,
102@@ -996,12 +989,10 @@
103 bond, [nic_0, nic_1], [vlan_10, vlan_11] = make_complex_interface(
104 node)
105 physical_interface = factory.make_Interface(
106- INTERFACE_TYPE.PHYSICAL, node=node)
107- new_vlan = factory.make_VLAN(fabric=physical_interface.vlan.fabric)
108+ INTERFACE_TYPE.PHYSICAL, node=node, vlan=nic_0.vlan)
109 uri = get_interface_uri(vlan_10)
110 response = self.client.put(uri, {
111 "parent": physical_interface.id,
112- "vlan": new_vlan.id,
113 })
114 self.assertEqual(
115 http.client.OK, response.status_code, response.content)
116
117=== modified file 'src/maasserver/forms/interface.py'
118--- src/maasserver/forms/interface.py 2017-04-05 22:50:03 +0000
119+++ src/maasserver/forms/interface.py 2017-06-16 00:53:57 +0000
120@@ -252,18 +252,6 @@
121 if len(parents) > 0:
122 raise ValidationError("A physical interface cannot have parents.")
123
124- def clean_vlan(self):
125- new_vlan = self.cleaned_data.get('vlan')
126- if new_vlan and new_vlan.fabric.get_default_vlan() != new_vlan:
127- # A device's physical interface can be connected to a tagged VLAN.
128- # This is because a container or VM could be bridged on the machine
129- # to a tagged VLAN interface. See lp:1572070 for details.
130- if self.node.node_type != NODE_TYPE.DEVICE:
131- raise ValidationError(
132- "A physical interface can only belong to an "
133- "untagged VLAN.")
134- return new_vlan
135-
136 def clean(self):
137 cleaned_data = super(PhysicalInterfaceForm, self).clean()
138 new_name = cleaned_data.get('name')
139@@ -313,7 +301,7 @@
140 not created and new_vlan is None and vlan_was_set):
141 raise ValidationError(
142 "A VLAN interface must be connected to a tagged VLAN.")
143- if new_vlan and new_vlan.fabric.get_default_vlan() == new_vlan:
144+ if new_vlan and new_vlan.vid == 0:
145 raise ValidationError(
146 "A VLAN interface can only belong to a tagged VLAN.")
147 return new_vlan
148@@ -455,16 +443,9 @@
149 'name',
150 )
151
152- def clean_vlan(self):
153- new_vlan = self.cleaned_data.get('vlan')
154- if new_vlan and new_vlan.fabric.get_default_vlan() != new_vlan:
155- raise ValidationError(
156- "A bond interface can only belong to an untagged VLAN.")
157- return new_vlan
158-
159 def clean(self):
160 cleaned_data = super().clean()
161- if self.fields_ok(['vlan', 'parents']):
162+ if self.fields_ok(['parents']):
163 parents = self.cleaned_data.get('parents')
164 # Set the mac_address if its missing and the interface is being
165 # created.
166
167=== modified file 'src/maasserver/forms/tests/test_interface.py'
168--- src/maasserver/forms/tests/test_interface.py 2017-04-05 23:39:23 +0000
169+++ src/maasserver/forms/tests/test_interface.py 2017-06-16 00:53:57 +0000
170@@ -30,7 +30,6 @@
171 from maasserver.testing.factory import factory
172 from maasserver.testing.testcase import MAASServerTestCase
173 from maasserver.utils.forms import compose_invalid_choice_text
174-from maasserver.utils.orm import reload_object
175 from testtools import ExpectedException
176 from testtools.matchers import MatchesStructure
177
178@@ -133,8 +132,7 @@
179 node = factory.make_Node()
180 mac_address = factory.make_mac_address()
181 interface_name = 'eth0'
182- fabric = factory.make_Fabric()
183- vlan = fabric.get_default_vlan()
184+ vlan = factory.make_VLAN()
185 tags = [
186 factory.make_name("tag")
187 for _ in range(3)
188@@ -211,8 +209,7 @@
189 node = factory.make_Node()
190 mac_address = factory.make_mac_address()
191 interface_name = 'eth0'
192- fabric = factory.make_Fabric()
193- vlan = fabric.get_default_vlan()
194+ vlan = factory.make_VLAN()
195 tags = [
196 factory.make_name("tag")
197 for _ in range(3)
198@@ -232,8 +229,7 @@
199
200 def test__requires_mac_address(self):
201 interface_name = 'eth0'
202- fabric = factory.make_Fabric()
203- vlan = fabric.get_default_vlan()
204+ vlan = factory.make_VLAN()
205 form = PhysicalInterfaceForm(
206 node=factory.make_Node(),
207 data={
208@@ -248,9 +244,7 @@
209 form.errors['mac_address'][0])
210
211 def test_rejects_interface_with_duplicate_name(self):
212- fabric = factory.make_Fabric()
213- vlan = fabric.get_default_vlan()
214- interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
215+ interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
216 mac_address = factory.make_mac_address()
217 form = PhysicalInterfaceForm(
218 node=interface.node,
219@@ -266,26 +260,6 @@
220 "already has an interface named '%s'." % interface.name,
221 form.errors['name'][0])
222
223- def test_rejects_interface_on_tagged_vlan(self):
224- fabric = factory.make_Fabric()
225- interface = factory.make_Interface(
226- INTERFACE_TYPE.PHYSICAL, vlan=fabric.get_default_vlan())
227- vlan = factory.make_VLAN(fabric=fabric)
228- mac_address = factory.make_mac_address()
229- form = PhysicalInterfaceForm(
230- node=interface.node,
231- data={
232- 'name': factory.make_name("eth"),
233- 'mac_address': mac_address,
234- 'vlan': vlan.id,
235- })
236- self.assertFalse(form.is_valid(), dict(form.errors))
237- self.assertItemsEqual(
238- ['vlan'], form.errors.keys(), form.errors)
239- self.assertIn(
240- "A physical interface can only belong to an untagged VLAN.",
241- form.errors['vlan'][0])
242-
243 def test_allows_interface_on_tagged_vlan_for_device(self):
244 device = factory.make_Device()
245 fabric = factory.make_Fabric()
246@@ -307,8 +281,7 @@
247
248 def test__rejects_parents(self):
249 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
250- fabric = factory.make_Fabric()
251- vlan = fabric.get_default_vlan()
252+ vlan = factory.make_VLAN()
253 form = PhysicalInterfaceForm(
254 node=parent.node,
255 data={
256@@ -328,8 +301,7 @@
257 interface = factory.make_Interface(
258 INTERFACE_TYPE.PHYSICAL, name='eth0')
259 new_name = 'eth1'
260- new_fabric = factory.make_Fabric()
261- new_vlan = new_fabric.get_default_vlan()
262+ new_vlan = factory.make_VLAN(vid=33)
263 form = PhysicalInterfaceForm(
264 instance=interface,
265 data={
266@@ -390,8 +362,7 @@
267 node = factory.make_Node()
268 mac_address = factory.make_mac_address()
269 interface_name = 'eth0'
270- fabric = factory.make_Fabric()
271- vlan = fabric.get_default_vlan()
272+ vlan = factory.make_VLAN()
273 tags = [
274 factory.make_name("tag")
275 for _ in range(3)
276@@ -430,8 +401,7 @@
277 "autoconf": autoconf,
278 }
279 new_name = 'eth1'
280- new_fabric = factory.make_Fabric()
281- new_vlan = new_fabric.get_default_vlan()
282+ new_vlan = factory.make_VLAN(vid=33)
283 form = PhysicalInterfaceForm(
284 instance=interface,
285 data={
286@@ -503,8 +473,8 @@
287 class VLANInterfaceFormTest(MAASServerTestCase):
288
289 def test__creates_vlan_interface(self):
290- parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
291- vlan = factory.make_VLAN(fabric=parent.vlan.fabric, vid=10)
292+ vlan = factory.make_VLAN(vid=10)
293+ parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
294 form = VLANInterfaceForm(
295 node=parent.node,
296 data={
297@@ -521,8 +491,8 @@
298 self.assertItemsEqual([parent], interface.parents.all())
299
300 def test__create_ensures_link_up(self):
301- parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
302- vlan = factory.make_VLAN(fabric=parent.vlan.fabric, vid=10)
303+ vlan = factory.make_VLAN(vid=10)
304+ parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
305 form = VLANInterfaceForm(
306 node=parent.node,
307 data={
308@@ -549,10 +519,13 @@
309 form.errors['vlan'][0])
310
311 def test_rejects_interface_with_duplicate_name(self):
312- parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
313- vlan = factory.make_VLAN(fabric=parent.vlan.fabric, vid=10)
314+ vlan = factory.make_VLAN(vid=10)
315+ parent = factory.make_Interface(
316+ INTERFACE_TYPE.PHYSICAL,
317+ vlan=vlan)
318 interface = factory.make_Interface(
319- INTERFACE_TYPE.VLAN, vlan=vlan, parents=[parent])
320+ INTERFACE_TYPE.VLAN,
321+ vlan=vlan, parents=[parent])
322 form = VLANInterfaceForm(
323 node=parent.node,
324 data={
325@@ -597,14 +570,13 @@
326
327 def test__rejects_vlan_parent(self):
328 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
329- vlan = factory.make_VLAN(fabric=parent.vlan.fabric, vid=10)
330 vlan_parent = factory.make_Interface(
331- INTERFACE_TYPE.VLAN, vlan=vlan, parents=[parent])
332- other_vlan = factory.make_VLAN(fabric=parent.vlan.fabric, vid=11)
333+ INTERFACE_TYPE.VLAN, parents=[parent])
334+ vlan = factory.make_VLAN(vid=10)
335 form = VLANInterfaceForm(
336 node=parent.node,
337 data={
338- 'vlan': other_vlan.id,
339+ 'vlan': vlan.id,
340 'parents': [vlan_parent.id],
341 })
342 self.assertFalse(form.is_valid(), dict(form.errors))
343@@ -646,8 +618,8 @@
344
345 def test__rejects_parent_on_bond(self):
346 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
347- bond = factory.make_Interface(INTERFACE_TYPE.BOND, parents=[parent])
348- vlan = factory.make_VLAN(fabric=bond.vlan.fabric, vid=10)
349+ factory.make_Interface(INTERFACE_TYPE.BOND, parents=[parent])
350+ vlan = factory.make_VLAN(vid=10)
351 form = VLANInterfaceForm(
352 node=parent.node,
353 data={
354@@ -682,7 +654,7 @@
355 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
356 interface = factory.make_Interface(
357 INTERFACE_TYPE.VLAN, parents=[parent])
358- new_vlan = factory.make_VLAN(fabric=interface.vlan.fabric, vid=33)
359+ new_vlan = factory.make_VLAN(vid=33)
360 form = VLANInterfaceForm(
361 instance=interface,
362 data={
363@@ -701,15 +673,17 @@
364 class BondInterfaceFormTest(MAASServerTestCase):
365
366 def test__error_with_invalid_bond_mode(self):
367- parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
368+ vlan = factory.make_VLAN(vid=10)
369+ parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
370 parent2 = factory.make_Interface(
371- INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
372+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=vlan)
373 interface_name = factory.make_name()
374 bond_mode = factory.make_name("bond_mode")
375 form = BondInterfaceForm(
376 node=parent1.node,
377 data={
378 'name': interface_name,
379+ 'vlan': vlan.id,
380 'parents': [parent1.id, parent2.id],
381 'bond_mode': bond_mode,
382 })
383@@ -721,14 +695,16 @@
384 }, form.errors)
385
386 def test__creates_bond_interface(self):
387- parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
388+ vlan = factory.make_VLAN(vid=10)
389+ parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
390 parent2 = factory.make_Interface(
391- INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
392+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=vlan)
393 interface_name = factory.make_name()
394 form = BondInterfaceForm(
395 node=parent1.node,
396 data={
397 'name': interface_name,
398+ 'vlan': vlan.id,
399 'parents': [parent1.id, parent2.id],
400 })
401 self.assertTrue(form.is_valid(), dict(form.errors))
402@@ -743,16 +719,18 @@
403 self.assertItemsEqual([parent1, parent2], interface.parents.all())
404
405 def test__create_removes_parent_links_and_sets_link_up_on_bond(self):
406- parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
407+ vlan = factory.make_VLAN(vid=10)
408+ parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
409 parent1.ensure_link_up()
410 parent2 = factory.make_Interface(
411- INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
412+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=vlan)
413 parent2.ensure_link_up()
414 interface_name = factory.make_name()
415 form = BondInterfaceForm(
416 node=parent1.node,
417 data={
418 'name': interface_name,
419+ 'vlan': vlan.id,
420 'parents': [parent1.id, parent2.id],
421 })
422 self.assertTrue(form.is_valid(), dict(form.errors))
423@@ -769,14 +747,16 @@
424 interface.ip_addresses.filter(alloc_type=IPADDRESS_TYPE.STICKY))
425
426 def test__creates_bond_interface_with_parent_mac_address(self):
427- parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
428+ vlan = factory.make_VLAN(vid=10)
429+ parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
430 parent2 = factory.make_Interface(
431- INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
432+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=vlan)
433 interface_name = factory.make_name()
434 form = BondInterfaceForm(
435 node=parent1.node,
436 data={
437 'name': interface_name,
438+ 'vlan': vlan.id,
439 'parents': [parent1.id, parent2.id],
440 'mac_address': parent1.mac_address,
441 })
442@@ -790,14 +770,16 @@
443 self.assertItemsEqual([parent1, parent2], interface.parents.all())
444
445 def test__creates_bond_interface_with_default_bond_params(self):
446- parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
447+ vlan = factory.make_VLAN(vid=10)
448+ parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
449 parent2 = factory.make_Interface(
450- INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
451+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=vlan)
452 interface_name = factory.make_name()
453 form = BondInterfaceForm(
454 node=parent1.node,
455 data={
456 'name': interface_name,
457+ 'vlan': vlan.id,
458 'parents': [parent1.id, parent2.id],
459 })
460 self.assertTrue(form.is_valid(), dict(form.errors))
461@@ -812,9 +794,10 @@
462 }, interface.params)
463
464 def test__creates_bond_interface_with_bond_params(self):
465- parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
466+ vlan = factory.make_VLAN(vid=10)
467+ parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan)
468 parent2 = factory.make_Interface(
469- INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
470+ INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=vlan)
471 interface_name = factory.make_name()
472 bond_mode = factory.pick_choice(BOND_MODE_CHOICES)
473 bond_miimon = random.randint(0, 1000)
474@@ -827,6 +810,7 @@
475 node=parent1.node,
476 data={
477 'name': interface_name,
478+ 'vlan': vlan.id,
479 'parents': [parent1.id, parent2.id],
480 'bond_mode': bond_mode,
481 'bond_miimon': bond_miimon,
482@@ -847,11 +831,13 @@
483 }, interface.params)
484
485 def test__rejects_no_parents(self):
486+ vlan = factory.make_VLAN(vid=10)
487 interface_name = factory.make_name()
488 form = BondInterfaceForm(
489 node=factory.make_Node(),
490 data={
491 'name': interface_name,
492+ 'vlan': vlan.id,
493 })
494 self.assertFalse(form.is_valid(), dict(form.errors))
495 self.assertItemsEqual(['parents', 'mac_address'], form.errors.keys())
496@@ -859,37 +845,21 @@
497 "A bond interface must have one or more parents.",
498 form.errors['parents'][0])
499
500- def test__rejects_when_vlan_not_untagged(self):
501- interface_name = factory.make_name()
502- parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
503- vlan = factory.make_VLAN(fabric=parent.vlan.fabric)
504- form = BondInterfaceForm(
505- node=parent.node,
506- data={
507- 'name': interface_name,
508- 'parents': [parent.id],
509- 'mac_address': parent.mac_address,
510- 'vlan': vlan.id,
511- })
512- self.assertFalse(form.is_valid(), dict(form.errors))
513- self.assertItemsEqual(['vlan'], form.errors.keys())
514- self.assertIn(
515- "A bond interface can only belong to an untagged VLAN.",
516- form.errors['vlan'][0])
517-
518 def test__rejects_when_parents_already_have_children(self):
519 node = factory.make_Node()
520 parent1 = factory.make_Interface(
521 INTERFACE_TYPE.PHYSICAL, node=node, name="eth0")
522 factory.make_Interface(INTERFACE_TYPE.VLAN, parents=[parent1])
523 parent2 = factory.make_Interface(
524- INTERFACE_TYPE.PHYSICAL, node=node, name="eth1", vlan=parent1.vlan)
525+ INTERFACE_TYPE.PHYSICAL, node=node, name="eth1")
526 factory.make_Interface(INTERFACE_TYPE.VLAN, parents=[parent2])
527+ vlan = factory.make_VLAN(vid=10)
528 interface_name = factory.make_name()
529 form = BondInterfaceForm(
530 node=node,
531 data={
532 'name': interface_name,
533+ 'vlan': vlan.id,
534 'parents': [parent1.id, parent2.id]
535 })
536 self.assertFalse(form.is_valid(), dict(form.errors))
537@@ -918,15 +888,14 @@
538 def test__edits_interface(self):
539 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
540 parent2 = factory.make_Interface(
541- INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
542+ INTERFACE_TYPE.PHYSICAL, node=parent1.node)
543 interface = factory.make_Interface(
544 INTERFACE_TYPE.BOND,
545 parents=[parent1, parent2])
546- new_fabric = factory.make_Fabric()
547- new_vlan = new_fabric.get_default_vlan()
548+ new_vlan = factory.make_VLAN(vid=33)
549 new_name = factory.make_name()
550 new_parent = factory.make_Interface(
551- INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
552+ INTERFACE_TYPE.PHYSICAL, node=parent1.node)
553 form = BondInterfaceForm(
554 instance=interface,
555 data={
556@@ -943,10 +912,6 @@
557 vlan=new_vlan, type=INTERFACE_TYPE.BOND))
558 self.assertItemsEqual(
559 [parent1, parent2, new_parent], interface.parents.all())
560- self.assertItemsEqual([new_vlan], set(
561- reload_object(parent).vlan
562- for parent in [parent1, parent2, new_parent]
563- ))
564
565 def test__edits_interface_allows_disconnected(self):
566 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
567@@ -1023,7 +988,7 @@
568 def test__edit_doesnt_overwrite_params(self):
569 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
570 parent2 = factory.make_Interface(
571- INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
572+ INTERFACE_TYPE.PHYSICAL, node=parent1.node)
573 interface = factory.make_Interface(
574 INTERFACE_TYPE.BOND,
575 parents=[parent1, parent2])
576@@ -1043,10 +1008,12 @@
577 "bond_xmit_hash_policy": bond_xmit_hash_policy,
578 }
579 interface.save()
580+ new_vlan = factory.make_VLAN(vid=33)
581 new_name = factory.make_name()
582 form = BondInterfaceForm(
583 instance=interface,
584 data={
585+ 'vlan': new_vlan.id,
586 'name': new_name,
587 })
588 self.assertTrue(form.is_valid(), dict(form.errors))
589@@ -1063,7 +1030,7 @@
590 def test__edit_does_overwrite_params(self):
591 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
592 parent2 = factory.make_Interface(
593- INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
594+ INTERFACE_TYPE.PHYSICAL, node=parent1.node)
595 interface = factory.make_Interface(
596 INTERFACE_TYPE.BOND,
597 parents=[parent1, parent2])
598@@ -1083,6 +1050,7 @@
599 "bond_xmit_hash_policy": bond_xmit_hash_policy,
600 }
601 interface.save()
602+ new_vlan = factory.make_VLAN(vid=33)
603 new_name = factory.make_name()
604 new_bond_mode = factory.pick_choice(BOND_MODE_CHOICES)
605 new_bond_miimon = random.randint(0, 1000)
606@@ -1094,6 +1062,7 @@
607 form = BondInterfaceForm(
608 instance=interface,
609 data={
610+ 'vlan': new_vlan.id,
611 'name': new_name,
612 'bond_mode': new_bond_mode,
613 'bond_miimon': new_bond_miimon,
614@@ -1116,7 +1085,7 @@
615 def test__edit_allows_zero_params(self):
616 parent1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
617 parent2 = factory.make_Interface(
618- INTERFACE_TYPE.PHYSICAL, node=parent1.node, vlan=parent1.vlan)
619+ INTERFACE_TYPE.PHYSICAL, node=parent1.node)
620 interface = factory.make_Interface(
621 INTERFACE_TYPE.BOND,
622 parents=[parent1, parent2])
623@@ -1136,6 +1105,7 @@
624 "bond_xmit_hash_policy": bond_xmit_hash_policy,
625 }
626 interface.save()
627+ new_vlan = factory.make_VLAN(vid=33)
628 new_name = factory.make_name()
629 new_bond_mode = factory.pick_choice(BOND_MODE_CHOICES)
630 new_bond_miimon = 0
631@@ -1147,6 +1117,7 @@
632 form = BondInterfaceForm(
633 instance=interface,
634 data={
635+ 'vlan': new_vlan.id,
636 'name': new_name,
637 'bond_mode': new_bond_mode,
638 'bond_miimon': new_bond_miimon,
639
640=== modified file 'src/maasserver/websockets/handlers/tests/test_machine.py'
641--- src/maasserver/websockets/handlers/tests/test_machine.py 2017-04-20 08:58:42 +0000
642+++ src/maasserver/websockets/handlers/tests/test_machine.py 2017-06-16 00:53:57 +0000
643@@ -2079,8 +2079,7 @@
644 handler = MachineHandler(user, {})
645 name = factory.make_name("eth")
646 mac_address = factory.make_mac_address()
647- fabric = factory.make_Fabric()
648- vlan = fabric.get_default_vlan()
649+ vlan = factory.make_VLAN()
650 handler.create_physical({
651 "system_id": node.system_id,
652 "name": name,
653@@ -2097,8 +2096,7 @@
654 handler = MachineHandler(user, {})
655 name = factory.make_name("eth")
656 mac_address = factory.make_mac_address()
657- fabric = factory.make_Fabric()
658- vlan = fabric.get_default_vlan()
659+ vlan = factory.make_VLAN()
660 subnet = factory.make_Subnet(vlan=vlan)
661 handler.create_physical({
662 "system_id": node.system_id,
663@@ -2120,8 +2118,7 @@
664 handler = MachineHandler(user, {})
665 name = factory.make_name("eth")
666 mac_address = factory.make_mac_address()
667- fabric = factory.make_Fabric()
668- vlan = fabric.get_default_vlan()
669+ vlan = factory.make_VLAN()
670 handler.create_physical({
671 "system_id": node.system_id,
672 "name": name,
673@@ -2141,8 +2138,7 @@
674 handler = MachineHandler(user, {})
675 name = factory.make_name("eth")
676 mac_address = factory.make_mac_address()
677- fabric = factory.make_Fabric()
678- vlan = fabric.get_default_vlan()
679+ vlan = factory.make_VLAN()
680 subnet = factory.make_Subnet(vlan=vlan)
681 handler.create_physical({
682 "system_id": node.system_id,
683@@ -2162,12 +2158,13 @@
684 user = factory.make_admin()
685 node = factory.make_Node()
686 handler = MachineHandler(user, {})
687- interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)
688- new_vlan = factory.make_VLAN(fabric=interface.vlan.fabric)
689+ vlan = factory.make_VLAN()
690+ interface = factory.make_Interface(
691+ INTERFACE_TYPE.PHYSICAL, node=node, vlan=vlan)
692 handler.create_vlan({
693 "system_id": node.system_id,
694 "parent": interface.id,
695- "vlan": new_vlan.id,
696+ "vlan": vlan.id,
697 })
698 vlan_interface = get_one(
699 Interface.objects.filter(
700@@ -2178,13 +2175,14 @@
701 user = factory.make_admin()
702 node = factory.make_Node()
703 handler = MachineHandler(user, {})
704- interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)
705- new_vlan = factory.make_VLAN(fabric=interface.vlan.fabric)
706- new_subnet = factory.make_Subnet(vlan=new_vlan)
707+ vlan = factory.make_VLAN()
708+ interface = factory.make_Interface(
709+ INTERFACE_TYPE.PHYSICAL, node=node, vlan=vlan)
710+ new_subnet = factory.make_Subnet(vlan=vlan)
711 handler.create_vlan({
712 "system_id": node.system_id,
713 "parent": interface.id,
714- "vlan": new_vlan.id,
715+ "vlan": vlan.id,
716 "mode": INTERFACE_LINK_TYPE.AUTO,
717 "subnet": new_subnet.id,
718 })
719@@ -2200,12 +2198,13 @@
720 user = factory.make_admin()
721 node = factory.make_Node()
722 handler = MachineHandler(user, {})
723- interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)
724- new_vlan = factory.make_VLAN(fabric=interface.vlan.fabric)
725+ vlan = factory.make_VLAN()
726+ interface = factory.make_Interface(
727+ INTERFACE_TYPE.PHYSICAL, node=node, vlan=vlan)
728 handler.create_vlan({
729 "system_id": node.system_id,
730 "parent": interface.id,
731- "vlan": new_vlan.id,
732+ "vlan": vlan.id,
733 "mode": INTERFACE_LINK_TYPE.LINK_UP,
734 })
735 vlan_interface = get_one(
736@@ -2220,13 +2219,14 @@
737 user = factory.make_admin()
738 node = factory.make_Node()
739 handler = MachineHandler(user, {})
740- interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)
741- new_vlan = factory.make_VLAN(fabric=interface.vlan.fabric)
742- new_subnet = factory.make_Subnet(vlan=new_vlan)
743+ vlan = factory.make_VLAN()
744+ interface = factory.make_Interface(
745+ INTERFACE_TYPE.PHYSICAL, node=node, vlan=vlan)
746+ new_subnet = factory.make_Subnet(vlan=vlan)
747 handler.create_vlan({
748 "system_id": node.system_id,
749 "parent": interface.id,
750- "vlan": new_vlan.id,
751+ "vlan": vlan.id,
752 "mode": INTERFACE_LINK_TYPE.LINK_UP,
753 "subnet": new_subnet.id,
754 })
755@@ -2317,8 +2317,7 @@
756 handler = MachineHandler(user, {})
757 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)
758 new_name = factory.make_name("name")
759- new_fabric = factory.make_Fabric()
760- new_vlan = new_fabric.get_default_vlan()
761+ new_vlan = factory.make_VLAN()
762 handler.update_interface({
763 "system_id": node.system_id,
764 "interface_id": interface.id,

Subscribers

People subscribed via source and target branches

to all changes: