Merge lp:~gmb/maas/enlist-uscm-to-RPC into lp:~maas-committers/maas/trunk

Proposed by Graham Binns
Status: Superseded
Proposed branch: lp:~gmb/maas/enlist-uscm-to-RPC
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 354 lines (+234/-30)
6 files modified
src/maasserver/models/nodegroup.py (+30/-8)
src/maasserver/models/tests/test_nodegroup.py (+100/-0)
src/provisioningserver/rpc/cluster.py (+28/-0)
src/provisioningserver/rpc/clusterservice.py (+22/-0)
src/provisioningserver/rpc/tests/test_clusterservice.py (+54/-0)
src/provisioningserver/tasks.py (+0/-22)
To merge this branch: bzr merge lp:~gmb/maas/enlist-uscm-to-RPC
Reviewer Review Type Date Requested Status
MAAS Maintainers Pending
Review via email: mp+234284@code.launchpad.net

This proposal has been superseded by a proposal from 2014-09-11.

Commit message

Convert the enlist_nodes_from_ucsm() celery task to use RPC.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/models/nodegroup.py'
2--- src/maasserver/models/nodegroup.py 2014-09-10 16:01:38 +0000
3+++ src/maasserver/models/nodegroup.py 2014-09-11 10:17:45 +0000
4@@ -41,13 +41,11 @@
5 from provisioningserver.rpc.cluster import (
6 AddSeaMicro15k,
7 AddVirsh,
8+ EnlistNodesFromMSCM,
9+ EnlistNodesFromUCSM,
10 ImportBootImages,
11 )
12 from provisioningserver.rpc.exceptions import NoConnectionsAvailable
13-from provisioningserver.tasks import (
14- enlist_nodes_from_mscm,
15- enlist_nodes_from_ucsm,
16- )
17
18
19 class NodeGroupManager(Manager):
20@@ -304,9 +302,21 @@
21 :param URL: URL of the Cisco UCS Manager HTTP-XML API.
22 :param username: username for UCS Manager.
23 :param password: password for UCS Manager.
24+
25+ :raises NoConnectionsAvailable: If no connections to the cluster
26+ are available.
27 """
28- args = (url, username, password)
29- enlist_nodes_from_ucsm.apply_async(queue=self.uuid, args=args)
30+ try:
31+ client = getClientFor(self.uuid, timeout=1)
32+ except NoConnectionsAvailable:
33+ # No connection to the cluster so we can't do anything. We
34+ # let the caller handle the error, since we don't want to
35+ # just drop it.
36+ raise
37+ else:
38+ return client(
39+ EnlistNodesFromUCSM, url=url, username=username,
40+ password=password)
41
42 def enlist_nodes_from_mscm(self, host, username, password):
43 """ Add the servers from a Moonshot HP iLO Chassis Manager.
44@@ -314,6 +324,18 @@
45 :param host: IP address for the MSCM.
46 :param username: username for MSCM.
47 :param password: password for MSCM.
48+
49+ :raises NoConnectionsAvailable: If no connections to the cluster
50+ are available.
51 """
52- args = (host, username, password)
53- enlist_nodes_from_mscm.apply_async(queue=self.uuid, args=args)
54+ try:
55+ client = getClientFor(self.uuid, timeout=1)
56+ except NoConnectionsAvailable:
57+ # No connection to the cluster so we can't do anything. We
58+ # let the caller handle the error, since we don't want to
59+ # just drop it.
60+ raise
61+ else:
62+ return client(
63+ EnlistNodesFromMSCM, host=host, username=username,
64+ password=password)
65
66=== modified file 'src/maasserver/models/tests/test_nodegroup.py'
67--- src/maasserver/models/tests/test_nodegroup.py 2014-09-10 16:01:38 +0000
68+++ src/maasserver/models/tests/test_nodegroup.py 2014-09-11 10:17:45 +0000
69@@ -49,6 +49,8 @@
70 from provisioningserver.rpc.cluster import (
71 AddSeaMicro15k,
72 AddVirsh,
73+ EnlistNodesFromMSCM,
74+ EnlistNodesFromUCSM,
75 ImportBootImages,
76 )
77 from provisioningserver.rpc.exceptions import NoConnectionsAvailable
78@@ -513,3 +515,101 @@
79 self.assertRaises(
80 NoConnectionsAvailable, nodegroup.add_seamicro15k,
81 mac, username, password, power_control)
82+
83+ def test_enlist_nodes_from_mscm_end_to_end(self):
84+ nodegroup = factory.make_NodeGroup(status=NODEGROUP_STATUS.ACCEPTED)
85+
86+ self.useFixture(RegionEventLoopFixture("rpc"))
87+ self.useFixture(RunningEventLoopFixture())
88+ fixture = self.useFixture(MockLiveRegionToClusterRPCFixture())
89+ protocol = fixture.makeCluster(nodegroup, EnlistNodesFromMSCM)
90+ protocol.EnlistNodesFromMSCM.return_value = defer.succeed({})
91+
92+ host = factory.make_name('host')
93+ username = factory.make_name('user')
94+ password = factory.make_name('password')
95+ nodegroup.enlist_nodes_from_mscm(
96+ host, username, password).wait(10)
97+
98+ self.expectThat(
99+ protocol.EnlistNodesFromMSCM,
100+ MockCalledOnceWith(
101+ ANY, host=host, username=username, password=password))
102+
103+ def test_enlist_nodes_from_mscm_calls_client_with_resource_endpoint(self):
104+ getClientFor = self.patch(nodegroup_module, 'getClientFor')
105+ client = getClientFor.return_value
106+ nodegroup = factory.make_NodeGroup()
107+
108+ host = factory.make_name('host')
109+ username = factory.make_name('user')
110+ password = factory.make_name('password')
111+ nodegroup.enlist_nodes_from_mscm(
112+ host, username, password).wait(10)
113+
114+ self.expectThat(
115+ client,
116+ MockCalledOnceWith(
117+ EnlistNodesFromMSCM, host=host, username=username,
118+ password=password))
119+
120+ def test_enlist_nodes_from_mscm_raises_if_no_connection_to_cluster(self):
121+ getClientFor = self.patch(nodegroup_module, 'getClientFor')
122+ getClientFor.side_effect = NoConnectionsAvailable()
123+ nodegroup = factory.make_NodeGroup()
124+
125+ host = factory.make_name('host')
126+ username = factory.make_name('user')
127+ password = factory.make_name('password')
128+ self.assertRaises(
129+ NoConnectionsAvailable, nodegroup.enlist_nodes_from_mscm,
130+ host, username, password)
131+
132+ def test_enlist_nodes_from_ucsm_end_to_end(self):
133+ nodegroup = factory.make_NodeGroup(status=NODEGROUP_STATUS.ACCEPTED)
134+
135+ self.useFixture(RegionEventLoopFixture("rpc"))
136+ self.useFixture(RunningEventLoopFixture())
137+ fixture = self.useFixture(MockLiveRegionToClusterRPCFixture())
138+ protocol = fixture.makeCluster(nodegroup, EnlistNodesFromUCSM)
139+ protocol.EnlistNodesFromUCSM.return_value = defer.succeed({})
140+
141+ url = factory.make_url()
142+ username = factory.make_name('user')
143+ password = factory.make_name('password')
144+ nodegroup.enlist_nodes_from_ucsm(
145+ url, username, password).wait(10)
146+
147+ self.expectThat(
148+ protocol.EnlistNodesFromUCSM,
149+ MockCalledOnceWith(
150+ ANY, url=url, username=username, password=password))
151+
152+ def test_enlist_nodes_from_ucsm_calls_client_with_resource_endpoint(self):
153+ getClientFor = self.patch(nodegroup_module, 'getClientFor')
154+ client = getClientFor.return_value
155+ nodegroup = factory.make_NodeGroup()
156+
157+ url = factory.make_url()
158+ username = factory.make_name('user')
159+ password = factory.make_name('password')
160+ nodegroup.enlist_nodes_from_ucsm(
161+ url, username, password).wait(10)
162+
163+ self.expectThat(
164+ client,
165+ MockCalledOnceWith(
166+ EnlistNodesFromUCSM, url=url, username=username,
167+ password=password))
168+
169+ def test_enlist_nodes_from_ucsm_raises_if_no_connection_to_cluster(self):
170+ getClientFor = self.patch(nodegroup_module, 'getClientFor')
171+ getClientFor.side_effect = NoConnectionsAvailable()
172+ nodegroup = factory.make_NodeGroup()
173+
174+ url = factory.make_url()
175+ username = factory.make_name('user')
176+ password = factory.make_name('password')
177+ self.assertRaises(
178+ NoConnectionsAvailable, nodegroup.enlist_nodes_from_ucsm,
179+ url, username, password)
180
181=== modified file 'src/provisioningserver/rpc/cluster.py'
182--- src/provisioningserver/rpc/cluster.py 2014-09-10 16:44:28 +0000
183+++ src/provisioningserver/rpc/cluster.py 2014-09-11 10:17:45 +0000
184@@ -377,3 +377,31 @@
185 errors = {
186 exceptions.NoIPFoundForMACAddress: b"NoIPFoundForMACAddress",
187 }
188+
189+
190+class EnlistNodesFromMSCM(amp.Command):
191+ """Probe for and enlist mscm machines attached to the cluster.
192+
193+ :since 1.7:
194+ """
195+ arguments = [
196+ (b"host", amp.Unicode()),
197+ (b"username", amp.Unicode()),
198+ (b"password", amp.Unicode()),
199+ ]
200+ response = []
201+ errors = {}
202+
203+
204+class EnlistNodesFromUCSM(amp.Command):
205+ """Probe for and enlist ucsm machines attached to the cluster.
206+
207+ :since 1.7:
208+ """
209+ arguments = [
210+ (b"url", amp.Unicode()),
211+ (b"username", amp.Unicode()),
212+ (b"password", amp.Unicode()),
213+ ]
214+ response = []
215+ errors = {}
216
217=== modified file 'src/provisioningserver/rpc/clusterservice.py'
218--- src/provisioningserver/rpc/clusterservice.py 2014-09-10 23:00:52 +0000
219+++ src/provisioningserver/rpc/clusterservice.py 2014-09-11 10:17:45 +0000
220@@ -29,6 +29,8 @@
221 ArchitectureRegistry,
222 PowerTypeRegistry,
223 )
224+from provisioningserver.drivers.hardware.mscm import probe_and_enlist_mscm
225+from provisioningserver.drivers.hardware.ucsm import probe_and_enlist_ucsm
226 from provisioningserver.drivers.hardware.seamicro import (
227 probe_seamicro15k_and_enlist,
228 )
229@@ -266,6 +268,26 @@
230 raise exceptions.NoIPFoundForMACAddress(message)
231 return {}
232
233+ @cluster.EnlistNodesFromMSCM.responder
234+ def enlist_nodes_from_mscm(self, host, username, password):
235+ """enlist_nodes_from_mscm()
236+
237+ Implemention of
238+ :py:class:`~provisioningserver.rpc.cluster.EnlistNodesFromMSCM`.
239+ """
240+ probe_and_enlist_mscm(host, username, password)
241+ return {}
242+
243+ @cluster.EnlistNodesFromUCSM.responder
244+ def enlist_nodes_from_ucsm(self, url, username, password):
245+ """enlist_nodes_from_ucsm()
246+
247+ Implemention of
248+ :py:class:`~provisioningserver.rpc.cluster.EnlistNodesFromUCSM`.
249+ """
250+ probe_and_enlist_ucsm(url, username, password)
251+ return {}
252+
253
254 @implementer(IConnection)
255 class ClusterClient(Cluster):
256
257=== modified file 'src/provisioningserver/rpc/tests/test_clusterservice.py'
258--- src/provisioningserver/rpc/tests/test_clusterservice.py 2014-09-10 23:00:52 +0000
259+++ src/provisioningserver/rpc/tests/test_clusterservice.py 2014-09-11 10:17:45 +0000
260@@ -1256,3 +1256,57 @@
261 probe_seamicro15k_and_enlist, MockCalledOnceWith(
262 find_ip_via_arp.return_value, username, password,
263 power_control=power_control))
264+
265+
266+class TestClusterProtocol_EnlistNodesFromMSCM(MAASTestCase):
267+
268+ def test__is_registered(self):
269+ protocol = Cluster()
270+ responder = protocol.locateResponder(
271+ cluster.EnlistNodesFromMSCM.commandName)
272+ self.assertIsNot(responder, None)
273+
274+ def test__calls_probe_and_enlist_mscm(self):
275+ probe_and_enlist_mscm = self.patch_autospec(
276+ clusterservice, 'probe_and_enlist_mscm')
277+
278+ host = factory.make_name('host')
279+ username = factory.make_name('user')
280+ password = factory.make_name('password')
281+
282+ call_responder(Cluster(), cluster.EnlistNodesFromMSCM, {
283+ 'host': host,
284+ 'username': username,
285+ 'password': password,
286+ })
287+
288+ self.assertThat(
289+ probe_and_enlist_mscm, MockCalledOnceWith(
290+ host, username, password))
291+
292+
293+class TestClusterProtocol_EnlistNodesFromUCSM(MAASTestCase):
294+
295+ def test__is_registered(self):
296+ protocol = Cluster()
297+ responder = protocol.locateResponder(
298+ cluster.EnlistNodesFromUCSM.commandName)
299+ self.assertIsNot(responder, None)
300+
301+ def test__calls_probe_and_enlist_ucsm(self):
302+ probe_and_enlist_ucsm = self.patch_autospec(
303+ clusterservice, 'probe_and_enlist_ucsm')
304+
305+ url = factory.make_url()
306+ username = factory.make_name('user')
307+ password = factory.make_name('password')
308+
309+ call_responder(Cluster(), cluster.EnlistNodesFromUCSM, {
310+ 'url': url,
311+ 'username': username,
312+ 'password': password,
313+ })
314+
315+ self.assertThat(
316+ probe_and_enlist_ucsm, MockCalledOnceWith(
317+ url, username, password))
318
319=== modified file 'src/provisioningserver/tasks.py'
320--- src/provisioningserver/tasks.py 2014-09-10 17:00:43 +0000
321+++ src/provisioningserver/tasks.py 2014-09-11 10:17:45 +0000
322@@ -42,8 +42,6 @@
323 set_up_options_conf,
324 setup_rndc,
325 )
326-from provisioningserver.drivers.hardware.mscm import probe_and_enlist_mscm
327-from provisioningserver.drivers.hardware.ucsm import probe_and_enlist_ucsm
328 from provisioningserver.logger import get_maas_logger
329
330 # For each item passed to refresh_secrets, a refresh function to give it to.
331@@ -297,23 +295,3 @@
332 exc=exc, countdown=UPDATE_NODE_TAGS_RETRY_DELAY)
333 else:
334 raise
335-
336-
337-# =====================================================================
338-# Custom hardware tasks
339-# =====================================================================
340-
341-@task
342-@log_task_events()
343-@log_exception_text
344-def enlist_nodes_from_ucsm(url, username, password):
345- """ See `maasserver.api.NodeGroupHandler.enlist_nodes_from_ucsm`. """
346- probe_and_enlist_ucsm(url, username, password)
347-
348-
349-@task
350-@log_task_events()
351-@log_exception_text
352-def enlist_nodes_from_mscm(host, username, password):
353- """ See `maasserver.api.NodeGroupHandler.enlist_nodes_from_mscm`. """
354- probe_and_enlist_mscm(host, username, password)