Merge ~cgrabowski/maas:add_update_interface_back_to_controller_ws_handler into maas:master

Proposed by Christian Grabowski
Status: Merged
Approved by: Christian Grabowski
Approved revision: 624798b11123c4696d80371ff66ab1b3487e76e8
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~cgrabowski/maas:add_update_interface_back_to_controller_ws_handler
Merge into: maas:master
Diff against target: 288 lines (+115/-79)
4 files modified
src/maasserver/websockets/handlers/controller.py (+7/-5)
src/maasserver/websockets/handlers/machine.py (+0/-74)
src/maasserver/websockets/handlers/node.py (+81/-0)
src/maasserver/websockets/handlers/tests/test_controller.py (+27/-0)
Reviewer Review Type Date Requested Status
MAAS Lander Approve
Alexsander de Souza Approve
Review via email: mp+427457@code.launchpad.net

Commit message

ensure node is up to date before dehydrating

include controller interface form

use boot interface in test

move _update_obj_tags to the Node handler for both Controller and Machine handlers

move form import to correct file

move _get_node_or_permission_error to Node handler for use with Controller and Machine handlers

move update_interface into Node handler for controller to inherit

To post a comment you must log in.
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b add_update_interface_back_to_controller_ws_handler lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas-tester/176/consoleText
COMMIT: c04185ec71067a6e098994170d848d5506a57fe1

review: Needs Fixing
Revision history for this message
Alexsander de Souza (alexsander-souza) wrote :

+1

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b add_update_interface_back_to_controller_ws_handler lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas-tester/178/consoleText
COMMIT: 624798b11123c4696d80371ff66ab1b3487e76e8

review: Needs Fixing
Revision history for this message
Christian Grabowski (cgrabowski) wrote :

jenkins: !test

Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b add_update_interface_back_to_controller_ws_handler lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 624798b11123c4696d80371ff66ab1b3487e76e8

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/websockets/handlers/controller.py b/src/maasserver/websockets/handlers/controller.py
2index dad5976..609526a 100644
3--- a/src/maasserver/websockets/handlers/controller.py
4+++ b/src/maasserver/websockets/handlers/controller.py
5@@ -90,6 +90,7 @@ class ControllerHandler(NodeHandler):
6 "set_script_result_suppressed",
7 "set_script_result_unsuppressed",
8 "get_latest_failed_testing_script_results",
9+ "update_interface",
10 ]
11 form = ControllerForm
12 exclude = [
13@@ -168,7 +169,11 @@ class ControllerHandler(NodeHandler):
14 data = super().dehydrate(obj, data, for_list=for_list)
15
16 vlan_counts = Counter()
17- for vlan_id in obj.vlan_ids:
18+ vlan_ids = [
19+ interface.vlan_id
20+ for interface in obj.current_config.interface_set.all()
21+ ]
22+ for vlan_id in vlan_ids:
23 vlan_counts[self._vlans_ha[vlan_id]] += 1
24
25 data.update(
26@@ -184,10 +189,7 @@ class ControllerHandler(NodeHandler):
27 }
28 )
29 if not for_list:
30- data["vlan_ids"] = [
31- interface.vlan_id
32- for interface in obj.current_config.interface_set.all()
33- ]
34+ data["vlan_ids"] = vlan_ids
35
36 # include certificate info if present
37 certificate = obj.power_parameters.get("certificate")
38diff --git a/src/maasserver/websockets/handlers/machine.py b/src/maasserver/websockets/handlers/machine.py
39index 5a67786..a64d51d 100644
40--- a/src/maasserver/websockets/handlers/machine.py
41+++ b/src/maasserver/websockets/handlers/machine.py
42@@ -45,8 +45,6 @@ from maasserver.forms.interface import (
43 AcquiredBridgeInterfaceForm,
44 BondInterfaceForm,
45 BridgeInterfaceForm,
46- DeployedInterfaceForm,
47- InterfaceForm,
48 PhysicalInterfaceForm,
49 VLANInterfaceForm,
50 )
51@@ -655,11 +653,6 @@ class MachineHandler(NodeHandler):
52 else:
53 form.save()
54
55- def _update_obj_tags(self, obj, params):
56- if "tags" in params:
57- obj.tags = params["tags"]
58- obj.save(update_fields=["tags"])
59-
60 def update_disk(self, params):
61 """Update disk information."""
62 node = self._get_node_or_permission_error(
63@@ -1079,28 +1072,6 @@ class MachineHandler(NodeHandler):
64 else:
65 raise ValidationError(form.errors)
66
67- def update_interface(self, params):
68- """Update the interface."""
69- node = self._get_node_or_permission_error(
70- params, permission=self._meta.edit_permission
71- )
72- interface = Interface.objects.get(
73- node_config__node=node, id=params["interface_id"]
74- )
75- if node.status == NODE_STATUS.DEPLOYED:
76- interface_form = DeployedInterfaceForm
77- else:
78- interface_form = InterfaceForm.get_interface_form(interface.type)
79- form = interface_form(instance=interface, data=params)
80- if form.is_valid():
81- interface = form.save()
82- self._update_obj_tags(interface, params)
83- else:
84- raise ValidationError(form.errors)
85- if "mode" in params:
86- self.link_subnet(params)
87- return self.full_dehydrate(node)
88-
89 def delete_interface(self, params):
90 """Delete the interface."""
91 node = self._get_node_or_permission_error(
92@@ -1111,45 +1082,6 @@ class MachineHandler(NodeHandler):
93 )
94 interface.delete()
95
96- def link_subnet(self, params):
97- """Create or update the link."""
98- node = self._get_node_or_permission_error(
99- params, permission=self._meta.edit_permission
100- )
101- interface = Interface.objects.get(
102- node_config__node=node, id=params["interface_id"]
103- )
104- subnet = None
105- if "subnet" in params:
106- subnet = Subnet.objects.get(id=params["subnet"])
107- if "link_id" in params:
108- if interface.ip_addresses.filter(id=params["link_id"]).exists():
109- # We are updating an already existing link. Which may have
110- # been deleted.
111- interface.update_link_by_id(
112- params["link_id"],
113- params["mode"],
114- subnet,
115- ip_address=params.get("ip_address", None),
116- )
117- else:
118- # We are creating a new link.
119- interface.link_subnet(
120- params["mode"],
121- subnet,
122- ip_address=params.get("ip_address", None),
123- )
124-
125- def unlink_subnet(self, params):
126- """Delete the link."""
127- node = self._get_node_or_permission_error(
128- params, permission=self._meta.edit_permission
129- )
130- interface = Interface.objects.get(
131- node_config__node=node, id=params["interface_id"]
132- )
133- interface.unlink_subnet_by_id(params["link_id"])
134-
135 @asynchronous(timeout=45)
136 def check_power(self, params):
137 """Check the power state of the node."""
138@@ -1178,12 +1110,6 @@ class MachineHandler(NodeHandler):
139 d.addCallback(partial(deferToDatabase, update_state))
140 return d
141
142- def _get_node_or_permission_error(self, params, permission=None):
143- node = self.get_object(params, permission=permission)
144- if node.locked:
145- raise HandlerPermissionError()
146- return node
147-
148 def get_workload_annotations(self, params):
149 """Get the owner data for a machine, known as workload annotations."""
150 machine = self._get_node_or_permission_error(
151diff --git a/src/maasserver/websockets/handlers/node.py b/src/maasserver/websockets/handlers/node.py
152index d6ce3f9..77b6dfc 100644
153--- a/src/maasserver/websockets/handlers/node.py
154+++ b/src/maasserver/websockets/handlers/node.py
155@@ -10,6 +10,7 @@ from itertools import chain
156 import logging
157 from operator import attrgetter, itemgetter
158
159+from django.core.exceptions import ValidationError
160 from django.db.models import Model, Prefetch
161 from lxml import etree
162
163@@ -26,6 +27,11 @@ from maasserver.enum import (
164 POWER_STATE_CHOICES,
165 )
166 from maasserver.forms import list_all_usable_architectures
167+from maasserver.forms.interface import (
168+ ControllerInterfaceForm,
169+ DeployedInterfaceForm,
170+ InterfaceForm,
171+)
172 from maasserver.models import (
173 BlockDevice,
174 BMC,
175@@ -1433,3 +1439,78 @@ class NodeHandler(TimestampedModelHandler):
176 if key == "mem":
177 return self._get_dynamic_filter_options("memory")
178 return self._get_dynamic_filter_options(key)
179+
180+ def update_interface(self, params):
181+ """Update the interface."""
182+ node = self._get_node_or_permission_error(
183+ params, permission=self._meta.edit_permission
184+ )
185+ interface = Interface.objects.get(
186+ node_config__node=node, id=params["interface_id"]
187+ )
188+ if node.is_controller:
189+ interface_form = ControllerInterfaceForm
190+ elif node.status == NODE_STATUS.DEPLOYED:
191+ interface_form = DeployedInterfaceForm
192+ else:
193+ interface_form = InterfaceForm.get_interface_form(interface.type)
194+ form = interface_form(instance=interface, data=params)
195+ if form.is_valid():
196+ interface = form.save()
197+ self._update_obj_tags(interface, params)
198+ else:
199+ raise ValidationError(form.errors)
200+ if "mode" in params:
201+ self.link_subnet(params)
202+ node.refresh_from_db()
203+ return self.full_dehydrate(node)
204+
205+ def _get_node_or_permission_error(self, params, permission=None):
206+ node = self.get_object(params, permission=permission)
207+ if node.locked:
208+ raise HandlerPermissionError()
209+ return node
210+
211+ def _update_obj_tags(self, obj, params):
212+ if "tags" in params:
213+ obj.tags = params["tags"]
214+ obj.save(update_fields=["tags"])
215+
216+ def link_subnet(self, params):
217+ """Create or update the link."""
218+ node = self._get_node_or_permission_error(
219+ params, permission=self._meta.edit_permission
220+ )
221+ interface = Interface.objects.get(
222+ node_config__node=node, id=params["interface_id"]
223+ )
224+ subnet = None
225+ if "subnet" in params:
226+ subnet = Subnet.objects.get(id=params["subnet"])
227+ if "link_id" in params:
228+ if interface.ip_addresses.filter(id=params["link_id"]).exists():
229+ # We are updating an already existing link. Which may have
230+ # been deleted.
231+ interface.update_link_by_id(
232+ params["link_id"],
233+ params["mode"],
234+ subnet,
235+ ip_address=params.get("ip_address", None),
236+ )
237+ else:
238+ # We are creating a new link.
239+ interface.link_subnet(
240+ params["mode"],
241+ subnet,
242+ ip_address=params.get("ip_address", None),
243+ )
244+
245+ def unlink_subnet(self, params):
246+ """Delete the link."""
247+ node = self._get_node_or_permission_error(
248+ params, permission=self._meta.edit_permission
249+ )
250+ interface = Interface.objects.get(
251+ node_config__node=node, id=params["interface_id"]
252+ )
253+ interface.unlink_subnet_by_id(params["link_id"])
254diff --git a/src/maasserver/websockets/handlers/tests/test_controller.py b/src/maasserver/websockets/handlers/tests/test_controller.py
255index 59a3278..f961ede 100644
256--- a/src/maasserver/websockets/handlers/tests/test_controller.py
257+++ b/src/maasserver/websockets/handlers/tests/test_controller.py
258@@ -490,3 +490,30 @@ class TestControllerHandler(MAASServerTestCase):
259 controller.refresh_from_db()
260 # deleting a region+rack controller changes it to just a region controller
261 self.assertEqual(controller.node_type, NODE_TYPE.REGION_CONTROLLER)
262+
263+ def test_update_interface(self):
264+ admin = factory.make_admin()
265+ vlan = factory.make_VLAN()
266+ handler = ControllerHandler(admin, {}, None)
267+ controller = factory.make_RegionRackController()
268+ request = {
269+ "name": controller.boot_interface.name,
270+ "mac_address": controller.boot_interface.mac_address,
271+ "tags": [],
272+ "fabric": vlan.fabric.id,
273+ "vlan": vlan.id,
274+ "mode": "link_up",
275+ "link_connected": True,
276+ "link_speed": 0,
277+ "interface_speed": 0,
278+ "formatted_link_speed": 0,
279+ "formatted_interface_speed": 0,
280+ "type": controller.boot_interface.type,
281+ "parents": controller.boot_interface.parents,
282+ "primary": None,
283+ "system_id": controller.system_id,
284+ "interface_id": controller.boot_interface.id,
285+ }
286+ handler.update_interface(request)
287+ controller.refresh_from_db()
288+ self.assertEqual(controller.boot_interface.vlan, vlan)

Subscribers

People subscribed via source and target branches