launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #12552
[Merge] lp:~julian-edwards/maas/enlist-power-params into lp:maas
Julian Edwards has proposed merging lp:~julian-edwards/maas/enlist-power-params into lp:maas.
Commit message:
Allow the commissioning "signal" parameter to take optional power parameters.
This means the BMC discovery at commissioning will be able to set the parameters up thereby allowing MAAS to power up the machine later.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~julian-edwards/maas/enlist-power-params/+merge/126619
--
https://code.launchpad.net/~julian-edwards/maas/enlist-power-params/+merge/126619
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~julian-edwards/maas/enlist-power-params into lp:maas.
=== modified file 'src/metadataserver/api.py'
--- src/metadataserver/api.py 2012-09-24 11:44:49 +0000
+++ src/metadataserver/api.py 2012-09-27 07:35:26 +0000
@@ -47,6 +47,7 @@
get_enlist_userdata,
get_preseed,
)
+from maasserver.utils import map_enum
from maasserver.utils.orm import get_one
from metadataserver.models import (
NodeCommissionResult,
@@ -55,6 +56,7 @@
)
from piston.handler import BaseHandler
from piston.utils import rc
+from provisioningserver.enum import POWER_TYPE
class UnknownMetadataVersion(MAASAPINotFound):
@@ -186,6 +188,31 @@
contents = raw_content.decode('utf-8')
NodeCommissionResult.objects.store_data(node, name, contents)
+ def _store_power_parameters(self, node, request):
+ """Store power parameters passed back in commissioning result."""
+ type = request.POST.get("power_type", None)
+ address = request.POST.get("power_address", None)
+ user = request.POST.get("power_user", None)
+ password = request.POST.get("power_pass", None)
+
+ if type is None:
+ return
+
+ type_dict = map_enum(POWER_TYPE)
+ if type.upper() not in type_dict:
+ raise MAASAPIBadRequest("Bad power_type '%s'" % type)
+ if password is None:
+ raise MAASAPIBadRequest("Missing power_pass parameter")
+ if user is None:
+ raise MAASAPIBadRequest("Missing power_user parameter")
+ if address is None:
+ raise MAASAPIBadRequest("Missing power_address parameter")
+
+ node.power_parameters = dict(
+ power_type=type, power_address=address, power_user=user,
+ power_pass=password)
+ node.save()
+
@api_exported('POST')
def signal(self, request, version=None, mac=None):
"""Signal commissioning status.
@@ -222,6 +249,7 @@
return rc.ALL_OK
self._store_commissioning_results(node, request)
+ self._store_power_parameters(node, request)
target_status = self.signaling_statuses.get(status)
if target_status in (None, node.status):
=== modified file 'src/metadataserver/tests/test_api.py'
--- src/metadataserver/tests/test_api.py 2012-09-25 12:15:46 +0000
+++ src/metadataserver/tests/test_api.py 2012-09-27 07:35:26 +0000
@@ -504,6 +504,75 @@
self.assertEqual(xmlbytes, node.hardware_details)
self.assertEqual(0, node.memory)
+ def test_signal_refuses_bad_power_type(self):
+ node = factory.make_node(status=NODE_STATUS.COMMISSIONING)
+ client = self.make_node_client(node=node)
+ response = self.call_signal(client, power_type="foo")
+ self.assertEqual(
+ (httplib.BAD_REQUEST, "Bad power_type 'foo'"),
+ (response.status_code, response.content))
+
+ def test_signal_requires_power_pass(self):
+ node = factory.make_node(status=NODE_STATUS.COMMISSIONING)
+ client = self.make_node_client(node=node)
+ response = self.call_signal(
+ client, power_type="IPMI",
+ power_address=factory.getRandomString(),
+ power_user=factory.getRandomString())
+ self.assertEqual(
+ (httplib.BAD_REQUEST, "Missing power_pass parameter"),
+ (response.status_code, response.content))
+
+ def test_signal_requires_power_user(self):
+ node = factory.make_node(status=NODE_STATUS.COMMISSIONING)
+ client = self.make_node_client(node=node)
+ response = self.call_signal(
+ client, power_type="IPMI",
+ power_address=factory.getRandomString(),
+ power_pass=factory.getRandomString())
+ self.assertEqual(
+ (httplib.BAD_REQUEST, "Missing power_user parameter"),
+ (response.status_code, response.content))
+
+ def test_signal_requires_power_address(self):
+ node = factory.make_node(status=NODE_STATUS.COMMISSIONING)
+ client = self.make_node_client(node=node)
+ response = self.call_signal(
+ client, power_type="IPMI",
+ power_user=factory.getRandomString(),
+ power_pass=factory.getRandomString())
+ self.assertEqual(
+ (httplib.BAD_REQUEST, "Missing power_address parameter"),
+ (response.status_code, response.content))
+
+ def test_signal_power_type_stores_params(self):
+ node = factory.make_node(status=NODE_STATUS.COMMISSIONING)
+ client = self.make_node_client(node=node)
+ params = dict(
+ power_address=factory.getRandomString(),
+ power_user=factory.getRandomString(),
+ power_pass=factory.getRandomString(),
+ power_type="IPMI")
+ response = self.call_signal(client, **params)
+ self.assertEqual(httplib.OK, response.status_code)
+ node = reload_object(node)
+ self.assertEqual(
+ params, node.power_parameters)
+
+ def test_signal_power_type_lower_case_works(self):
+ node = factory.make_node(status=NODE_STATUS.COMMISSIONING)
+ client = self.make_node_client(node=node)
+ params = dict(
+ power_address=factory.getRandomString(),
+ power_user=factory.getRandomString(),
+ power_pass=factory.getRandomString(),
+ power_type="ipmi")
+ response = self.call_signal(client, **params)
+ self.assertEqual(httplib.OK, response.status_code)
+ node = reload_object(node)
+ self.assertEqual(
+ params, node.power_parameters)
+
def test_api_retrieves_node_metadata_by_mac(self):
mac = factory.make_mac_address()
url = reverse(
Follow ups