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

Proposed by Graham Binns
Status: Merged
Approved by: Graham Binns
Approved revision: no longer in the source branch.
Merged at revision: 2957
Proposed branch: lp:~gmb/maas/enlist-uscm-to-RPC
Merge into: lp:~maas-committers/maas/trunk
Prerequisite: lp:~gmb/maas/enlist-mscm-to-RPC
Diff against target: 291 lines (+126/-33)
8 files modified
src/maasserver/api/tests/test_nodegroup.py (+9/-4)
src/maasserver/models/nodegroup.py (+15/-3)
src/maasserver/models/tests/test_nodegroup.py (+50/-0)
src/provisioningserver/rpc/cluster.py (+14/-0)
src/provisioningserver/rpc/clusterservice.py (+11/-0)
src/provisioningserver/rpc/tests/test_clusterservice.py (+27/-0)
src/provisioningserver/tasks.py (+0/-13)
src/provisioningserver/tests/test_tasks.py (+0/-13)
To merge this branch: bzr merge lp:~gmb/maas/enlist-uscm-to-RPC
Reviewer Review Type Date Requested Status
Raphaël Badin (community) Approve
Review via email: mp+234285@code.launchpad.net

This proposal supersedes a proposal from 2014-09-11.

Commit message

Convert the enlist_nodes_from_ucsm() task to use RPC.

To post a comment you must log in.
Revision history for this message
Raphaël Badin (rvb) wrote :

Looks good. (These branches are a bit boring aren't they?)

review: Approve
Revision history for this message
Graham Binns (gmb) wrote :

On 11 September 2014 11:35, Raphaël Badin <email address hidden> wrote:
>
>
> When the method is called from the API it will be transformed into a 500 error. This is probably what we want but could you check that the error message in that case is meaningful? (I mean, I'd like to be sure it mentions at least the UUID problematic cluster.)

Yes, I'll check. I'll fix that in a followup branch if necessary;
there are several sites that follow this pattern and they could all do
with the same love :)

Revision history for this message
MAAS Lander (maas-lander) wrote :
Download full text (19.0 KiB)

The attempt to merge lp:~gmb/maas/enlist-uscm-to-RPC into lp:maas failed. Below is the output from the failed tests.

Ign http://security.ubuntu.com trusty-security InRelease
Hit http://security.ubuntu.com trusty-security Release.gpg
Hit http://security.ubuntu.com trusty-security Release
Ign http://nova.clouds.archive.ubuntu.com trusty InRelease
Ign http://nova.clouds.archive.ubuntu.com trusty-updates InRelease
Hit http://nova.clouds.archive.ubuntu.com trusty Release.gpg
Hit http://nova.clouds.archive.ubuntu.com trusty-updates Release.gpg
Hit http://nova.clouds.archive.ubuntu.com trusty Release
Hit http://nova.clouds.archive.ubuntu.com trusty-updates Release
Hit http://security.ubuntu.com trusty-security/main Sources
Hit http://security.ubuntu.com trusty-security/universe Sources
Hit http://security.ubuntu.com trusty-security/main amd64 Packages
Hit http://security.ubuntu.com trusty-security/universe amd64 Packages
Hit http://security.ubuntu.com trusty-security/main Translation-en
Hit http://security.ubuntu.com trusty-security/universe Translation-en
Hit http://nova.clouds.archive.ubuntu.com trusty/main Sources
Hit http://nova.clouds.archive.ubuntu.com trusty/universe Sources
Hit http://nova.clouds.archive.ubuntu.com trusty/main amd64 Packages
Hit http://nova.clouds.archive.ubuntu.com trusty/universe amd64 Packages
Hit http://nova.clouds.archive.ubuntu.com trusty/main Translation-en
Hit http://nova.clouds.archive.ubuntu.com trusty/universe Translation-en
Hit http://nova.clouds.archive.ubuntu.com trusty-updates/main Sources
Hit http://nova.clouds.archive.ubuntu.com trusty-updates/universe Sources
Hit http://nova.clouds.archive.ubuntu.com trusty-updates/main amd64 Packages
Hit http://nova.clouds.archive.ubuntu.com trusty-updates/universe amd64 Packages
Hit http://nova.clouds.archive.ubuntu.com trusty-updates/main Translation-en
Hit http://nova.clouds.archive.ubuntu.com trusty-updates/universe Translation-en
Ign http://nova.clouds.archive.ubuntu.com trusty/main Translation-en_US
Ign http://nova.clouds.archive.ubuntu.com trusty/universe Translation-en_US
Reading package lists...
sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
     --no-install-recommends install apache2 authbind bind9 bind9utils build-essential bzr-builddeb curl daemontools debhelper dh-apport distro-info dnsutils firefox freeipmi-tools ipython isc-dhcp-common libjs-raphael libjs-yui3-full libjs-yui3-min libpq-dev make pep8 postgresql pyflakes python-amqplib python-bzrlib python-celery python-convoy python-crochet python-cssselect python-curtin python-dev python-distro-info python-django python-django-piston python-django-south python-djorm-ext-pgarray python-docutils python-extras python-fixtures python-flake8 python-formencode python-hivex python-httplib2 python-jinja2 python-jsonschema python-lockfile python-lxml python-mimeparse python-mock python-netaddr python-netifaces python-nose python-oauth python-oops python-oops-amqp python-oops-datedir-repo python-oops-twisted python-oops-wsgi python-openssl python-paramiko python-pexpect python-pip python-pocket-lint python-psycopg2 python-pyinotify python-seamicroclient python-simplejson python-simplestreams python-sphinx python-s...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/maasserver/api/tests/test_nodegroup.py'
--- src/maasserver/api/tests/test_nodegroup.py 2014-09-11 11:21:49 +0000
+++ src/maasserver/api/tests/test_nodegroup.py 2014-09-11 12:18:08 +0000
@@ -57,6 +57,7 @@
57from provisioningserver.auth import get_recorded_nodegroup_uuid57from provisioningserver.auth import get_recorded_nodegroup_uuid
58from provisioningserver.rpc.cluster import (58from provisioningserver.rpc.cluster import (
59 EnlistNodesFromMSCM,59 EnlistNodesFromMSCM,
60 EnlistNodesFromUCSM,
60 ImportBootImages,61 ImportBootImages,
61 )62 )
62from testresources import FixtureResource63from testresources import FixtureResource
@@ -347,7 +348,9 @@
347 password = factory.make_name('password')348 password = factory.make_name('password')
348 self.become_admin()349 self.become_admin()
349350
350 mock = self.patch(nodegroup_module, 'enlist_nodes_from_ucsm')351 getClientFor = self.patch(nodegroup_module, 'getClientFor')
352 client = getClientFor.return_value
353 nodegroup = factory.make_NodeGroup()
351354
352 response = self.client.post(355 response = self.client.post(
353 reverse('nodegroup_handler', args=[nodegroup.uuid]),356 reverse('nodegroup_handler', args=[nodegroup.uuid]),
@@ -362,9 +365,11 @@
362 httplib.OK, response.status_code,365 httplib.OK, response.status_code,
363 explain_unexpected_response(httplib.OK, response))366 explain_unexpected_response(httplib.OK, response))
364367
365 args = (url, username, password)368 self.expectThat(
366 matcher = MockCalledOnceWith(queue=nodegroup.uuid, args=args)369 client,
367 self.assertThat(mock.apply_async, matcher)370 MockCalledOnceWith(
371 EnlistNodesFromUCSM, url=url, username=username,
372 password=password))
368373
369 def test_probe_and_enlist_mscm_adds_mscm(self):374 def test_probe_and_enlist_mscm_adds_mscm(self):
370 nodegroup = factory.make_NodeGroup()375 nodegroup = factory.make_NodeGroup()
371376
=== modified file 'src/maasserver/models/nodegroup.py'
--- src/maasserver/models/nodegroup.py 2014-09-11 09:58:18 +0000
+++ src/maasserver/models/nodegroup.py 2014-09-11 12:18:08 +0000
@@ -42,10 +42,10 @@
42 AddSeaMicro15k,42 AddSeaMicro15k,
43 AddVirsh,43 AddVirsh,
44 EnlistNodesFromMSCM,44 EnlistNodesFromMSCM,
45 EnlistNodesFromUCSM,
45 ImportBootImages,46 ImportBootImages,
46 )47 )
47from provisioningserver.rpc.exceptions import NoConnectionsAvailable48from provisioningserver.rpc.exceptions import NoConnectionsAvailable
48from provisioningserver.tasks import enlist_nodes_from_ucsm
4949
5050
51class NodeGroupManager(Manager):51class NodeGroupManager(Manager):
@@ -302,9 +302,21 @@
302 :param URL: URL of the Cisco UCS Manager HTTP-XML API.302 :param URL: URL of the Cisco UCS Manager HTTP-XML API.
303 :param username: username for UCS Manager.303 :param username: username for UCS Manager.
304 :param password: password for UCS Manager.304 :param password: password for UCS Manager.
305
306 :raises NoConnectionsAvailable: If no connections to the cluster
307 are available.
305 """308 """
306 args = (url, username, password)309 try:
307 enlist_nodes_from_ucsm.apply_async(queue=self.uuid, args=args)310 client = getClientFor(self.uuid, timeout=1)
311 except NoConnectionsAvailable:
312 # No connection to the cluster so we can't do anything. We
313 # let the caller handle the error, since we don't want to
314 # just drop it.
315 raise
316 else:
317 return client(
318 EnlistNodesFromUCSM, url=url, username=username,
319 password=password)
308320
309 def enlist_nodes_from_mscm(self, host, username, password):321 def enlist_nodes_from_mscm(self, host, username, password):
310 """ Add the servers from a Moonshot HP iLO Chassis Manager.322 """ Add the servers from a Moonshot HP iLO Chassis Manager.
311323
=== modified file 'src/maasserver/models/tests/test_nodegroup.py'
--- src/maasserver/models/tests/test_nodegroup.py 2014-09-11 09:53:46 +0000
+++ src/maasserver/models/tests/test_nodegroup.py 2014-09-11 12:18:08 +0000
@@ -50,6 +50,7 @@
50 AddSeaMicro15k,50 AddSeaMicro15k,
51 AddVirsh,51 AddVirsh,
52 EnlistNodesFromMSCM,52 EnlistNodesFromMSCM,
53 EnlistNodesFromUCSM,
53 ImportBootImages,54 ImportBootImages,
54 )55 )
55from provisioningserver.rpc.exceptions import NoConnectionsAvailable56from provisioningserver.rpc.exceptions import NoConnectionsAvailable
@@ -563,3 +564,52 @@
563 self.assertRaises(564 self.assertRaises(
564 NoConnectionsAvailable, nodegroup.enlist_nodes_from_mscm,565 NoConnectionsAvailable, nodegroup.enlist_nodes_from_mscm,
565 host, username, password)566 host, username, password)
567
568 def test_enlist_nodes_from_ucsm_end_to_end(self):
569 nodegroup = factory.make_NodeGroup(status=NODEGROUP_STATUS.ACCEPTED)
570
571 self.useFixture(RegionEventLoopFixture("rpc"))
572 self.useFixture(RunningEventLoopFixture())
573 fixture = self.useFixture(MockLiveRegionToClusterRPCFixture())
574 protocol = fixture.makeCluster(nodegroup, EnlistNodesFromUCSM)
575 protocol.EnlistNodesFromUCSM.return_value = defer.succeed({})
576
577 url = factory.make_url()
578 username = factory.make_name('user')
579 password = factory.make_name('password')
580 nodegroup.enlist_nodes_from_ucsm(
581 url, username, password).wait(10)
582
583 self.expectThat(
584 protocol.EnlistNodesFromUCSM,
585 MockCalledOnceWith(
586 ANY, url=url, username=username, password=password))
587
588 def test_enlist_nodes_from_ucsm_calls_client_with_resource_endpoint(self):
589 getClientFor = self.patch(nodegroup_module, 'getClientFor')
590 client = getClientFor.return_value
591 nodegroup = factory.make_NodeGroup()
592
593 url = factory.make_url()
594 username = factory.make_name('user')
595 password = factory.make_name('password')
596 nodegroup.enlist_nodes_from_ucsm(
597 url, username, password).wait(10)
598
599 self.expectThat(
600 client,
601 MockCalledOnceWith(
602 EnlistNodesFromUCSM, url=url, username=username,
603 password=password))
604
605 def test_enlist_nodes_from_ucsm_raises_if_no_connection_to_cluster(self):
606 getClientFor = self.patch(nodegroup_module, 'getClientFor')
607 getClientFor.side_effect = NoConnectionsAvailable()
608 nodegroup = factory.make_NodeGroup()
609
610 url = factory.make_url()
611 username = factory.make_name('user')
612 password = factory.make_name('password')
613 self.assertRaises(
614 NoConnectionsAvailable, nodegroup.enlist_nodes_from_ucsm,
615 url, username, password)
566616
=== modified file 'src/provisioningserver/rpc/cluster.py'
--- src/provisioningserver/rpc/cluster.py 2014-09-11 11:16:53 +0000
+++ src/provisioningserver/rpc/cluster.py 2014-09-11 12:18:08 +0000
@@ -391,3 +391,17 @@
391 ]391 ]
392 response = []392 response = []
393 errors = {}393 errors = {}
394
395
396class EnlistNodesFromUCSM(amp.Command):
397 """Probe for and enlist ucsm machines attached to the cluster.
398
399 :since: 1.7
400 """
401 arguments = [
402 (b"url", amp.Unicode()),
403 (b"username", amp.Unicode()),
404 (b"password", amp.Unicode()),
405 ]
406 response = []
407 errors = {}
394408
=== modified file 'src/provisioningserver/rpc/clusterservice.py'
--- src/provisioningserver/rpc/clusterservice.py 2014-09-11 09:58:18 +0000
+++ src/provisioningserver/rpc/clusterservice.py 2014-09-11 12:18:08 +0000
@@ -33,6 +33,7 @@
33from provisioningserver.drivers.hardware.seamicro import (33from provisioningserver.drivers.hardware.seamicro import (
34 probe_seamicro15k_and_enlist,34 probe_seamicro15k_and_enlist,
35 )35 )
36from provisioningserver.drivers.hardware.ucsm import probe_and_enlist_ucsm
36from provisioningserver.drivers.hardware.virsh import probe_virsh_and_enlist37from provisioningserver.drivers.hardware.virsh import probe_virsh_and_enlist
37from provisioningserver.logger.log import get_maas_logger38from provisioningserver.logger.log import get_maas_logger
38from provisioningserver.rpc import (39from provisioningserver.rpc import (
@@ -277,6 +278,16 @@
277 probe_and_enlist_mscm(host, username, password)278 probe_and_enlist_mscm(host, username, password)
278 return {}279 return {}
279280
281 @cluster.EnlistNodesFromUCSM.responder
282 def enlist_nodes_from_ucsm(self, url, username, password):
283 """enlist_nodes_from_ucsm()
284
285 Implemention of
286 :py:class:`~provisioningserver.rpc.cluster.EnlistNodesFromUCSM`.
287 """
288 probe_and_enlist_ucsm(url, username, password)
289 return {}
290
280291
281@implementer(IConnection)292@implementer(IConnection)
282class ClusterClient(Cluster):293class ClusterClient(Cluster):
283294
=== modified file 'src/provisioningserver/rpc/tests/test_clusterservice.py'
--- src/provisioningserver/rpc/tests/test_clusterservice.py 2014-09-11 09:53:18 +0000
+++ src/provisioningserver/rpc/tests/test_clusterservice.py 2014-09-11 12:18:08 +0000
@@ -1283,3 +1283,30 @@
1283 self.assertThat(1283 self.assertThat(
1284 probe_and_enlist_mscm, MockCalledOnceWith(1284 probe_and_enlist_mscm, MockCalledOnceWith(
1285 host, username, password))1285 host, username, password))
1286
1287
1288class TestClusterProtocol_EnlistNodesFromUCSM(MAASTestCase):
1289
1290 def test__is_registered(self):
1291 protocol = Cluster()
1292 responder = protocol.locateResponder(
1293 cluster.EnlistNodesFromUCSM.commandName)
1294 self.assertIsNot(responder, None)
1295
1296 def test__calls_probe_and_enlist_ucsm(self):
1297 probe_and_enlist_ucsm = self.patch_autospec(
1298 clusterservice, 'probe_and_enlist_ucsm')
1299
1300 url = factory.make_url()
1301 username = factory.make_name('user')
1302 password = factory.make_name('password')
1303
1304 call_responder(Cluster(), cluster.EnlistNodesFromUCSM, {
1305 'url': url,
1306 'username': username,
1307 'password': password,
1308 })
1309
1310 self.assertThat(
1311 probe_and_enlist_ucsm, MockCalledOnceWith(
1312 url, username, password))
12861313
=== modified file 'src/provisioningserver/tasks.py'
--- src/provisioningserver/tasks.py 2014-09-11 09:54:13 +0000
+++ src/provisioningserver/tasks.py 2014-09-11 12:18:08 +0000
@@ -42,7 +42,6 @@
42 set_up_options_conf,42 set_up_options_conf,
43 setup_rndc,43 setup_rndc,
44 )44 )
45from provisioningserver.drivers.hardware.ucsm import probe_and_enlist_ucsm
46from provisioningserver.logger import get_maas_logger45from provisioningserver.logger import get_maas_logger
4746
48# For each item passed to refresh_secrets, a refresh function to give it to.47# For each item passed to refresh_secrets, a refresh function to give it to.
@@ -296,15 +295,3 @@
296 exc=exc, countdown=UPDATE_NODE_TAGS_RETRY_DELAY)295 exc=exc, countdown=UPDATE_NODE_TAGS_RETRY_DELAY)
297 else:296 else:
298 raise297 raise
299
300
301# =====================================================================
302# Custom hardware tasks
303# =====================================================================
304
305@task
306@log_task_events()
307@log_exception_text
308def enlist_nodes_from_ucsm(url, username, password):
309 """ See `maasserver.api.NodeGroupHandler.enlist_nodes_from_ucsm`. """
310 probe_and_enlist_ucsm(url, username, password)
311298
=== modified file 'src/provisioningserver/tests/test_tasks.py'
--- src/provisioningserver/tests/test_tasks.py 2014-09-11 10:56:06 +0000
+++ src/provisioningserver/tests/test_tasks.py 2014-09-11 12:18:08 +0000
@@ -31,7 +31,6 @@
31 FakeMethod,31 FakeMethod,
32 MultiFakeMethod,32 MultiFakeMethod,
33 )33 )
34from maastesting.matchers import MockCalledOnceWith
35from mock import Mock34from mock import Mock
36from netaddr import IPNetwork35from netaddr import IPNetwork
37from provisioningserver import (36from provisioningserver import (
@@ -55,7 +54,6 @@
55 )54 )
56from provisioningserver.tags import MissingCredentials55from provisioningserver.tags import MissingCredentials
57from provisioningserver.tasks import (56from provisioningserver.tasks import (
58 enlist_nodes_from_ucsm,
59 refresh_secrets,57 refresh_secrets,
60 report_boot_images,58 report_boot_images,
61 rndc_command,59 rndc_command,
@@ -391,14 +389,3 @@
391 self.assertRaises(389 self.assertRaises(
392 MissingCredentials, update_node_tags.delay, tag,390 MissingCredentials, update_node_tags.delay, tag,
393 '//node', tag_nsmap=None, retry=True)391 '//node', tag_nsmap=None, retry=True)
394
395
396class TestAddUCSM(PservTestCase):
397
398 def test_enlist_nodes_from_ucsm(self):
399 url = 'url'
400 username = 'username'
401 password = 'password'
402 mock = self.patch(tasks, 'probe_and_enlist_ucsm')
403 enlist_nodes_from_ucsm(url, username, password)
404 self.assertThat(mock, MockCalledOnceWith(url, username, password))