launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #12967
[Merge] lp:~allenap/maas/anon-power-setting into lp:maas
Gavin Panella has proposed merging lp:~allenap/maas/anon-power-setting into lp:maas.
Commit message:
Allows power parameters to be supplied at enlistment.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #1055662 in MAAS: "Anonymous API access to update power_type, power_settings"
https://bugs.launchpad.net/maas/+bug/1055662
For more details, see:
https://code.launchpad.net/~allenap/maas/anon-power-setting/+merge/128127
--
https://code.launchpad.net/~allenap/maas/anon-power-setting/+merge/128127
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~allenap/maas/anon-power-setting into lp:maas.
=== modified file 'src/maasserver/api.py'
--- src/maasserver/api.py 2012-10-04 10:08:26 +0000
+++ src/maasserver/api.py 2012-10-04 22:25:25 +0000
@@ -158,6 +158,7 @@
compose_preseed_url,
)
from maasserver.server_address import get_maas_facing_server_address
+from maasserver.utils import map_enum
from maasserver.utils.orm import get_one
from piston.handler import (
AnonymousBaseHandler,
@@ -167,6 +168,7 @@
from piston.models import Token
from piston.resource import Resource
from piston.utils import rc
+from provisioningserver.enum import POWER_TYPE
from provisioningserver.kernel_opts import KernelParameters
@@ -418,6 +420,29 @@
)
+def store_node_power_parameters(node, request):
+ """Store power parameters in request.
+
+ The parameters should be JSON, passed with key `power_parameters`.
+ """
+ type = request.POST.get("power_type", None)
+ if type is None:
+ return
+
+ params = request.POST.get("power_parameters", None)
+
+ type_dict = map_enum(POWER_TYPE)
+ if type.upper() not in type_dict:
+ raise MAASAPIBadRequest("Bad power_type '%s'" % type)
+ node.power_type = type_dict[type.upper()]
+
+ try:
+ node.power_parameters = json.loads(params)
+ except ValueError:
+ raise MAASAPIBadRequest("Failed to parse json power_parameters")
+ node.save()
+
+
class NodeHandler(OperationsHandler):
"""Manage individual Nodes."""
create = None # Disable create.
@@ -586,7 +611,10 @@
Form = get_node_create_form(request.user)
form = Form(altered_query_data)
if form.is_valid():
- return form.save()
+ node = form.save()
+ # Hack in the power parameters here.
+ store_node_power_parameters(node, request)
+ return node
else:
raise ValidationError(form.errors)
=== modified file 'src/maasserver/tests/test_api.py'
--- src/maasserver/tests/test_api.py 2012-10-04 12:08:36 +0000
+++ src/maasserver/tests/test_api.py 2012-10-04 22:25:25 +0000
@@ -289,6 +289,32 @@
[diane] = Node.objects.filter(hostname='diane')
self.assertEqual(architecture, diane.architecture)
+ def test_POST_new_creates_node_with_power_parameters(self):
+ # We're setting power parameters so we disable start_commissioning to
+ # prevent anything from attempting to issue power instructions.
+ self.patch(Node, "start_commissioning")
+ hostname = factory.make_name("hostname")
+ architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
+ power_type = POWER_TYPE.IPMI
+ power_parameters = {
+ "power_user": factory.make_name("power-user"),
+ "power_pass": factory.make_name("power-pass"),
+ }
+ response = self.client.post(
+ self.get_uri('nodes/'),
+ {
+ 'op': 'new',
+ 'hostname': hostname,
+ 'architecture': architecture,
+ 'mac_addresses': factory.getRandomMACAddress(),
+ 'power_parameters': json.dumps(power_parameters),
+ 'power_type': power_type,
+ })
+ self.assertEqual(httplib.OK, response.status_code)
+ [node] = Node.objects.filter(hostname=hostname)
+ self.assertEqual(power_parameters, node.power_parameters)
+ self.assertEqual(power_type, node.power_type)
+
def test_POST_new_creates_node_with_arch_only(self):
architecture = factory.getRandomChoice(
[choice for choice in ARCHITECTURE_CHOICES
=== modified file 'src/metadataserver/api.py'
--- src/metadataserver/api.py 2012-10-04 09:53:04 +0000
+++ src/metadataserver/api.py 2012-10-04 22:25:25 +0000
@@ -18,8 +18,6 @@
'VersionIndexHandler',
]
-import json
-
from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
@@ -29,6 +27,7 @@
get_mandatory_param,
operation,
OperationsHandler,
+ store_node_power_parameters,
)
from maasserver.enum import (
NODE_STATUS,
@@ -49,7 +48,6 @@
get_enlist_userdata,
get_preseed,
)
-from maasserver.utils import map_enum
from maasserver.utils.orm import get_one
from metadataserver.models import (
NodeCommissionResult,
@@ -57,7 +55,6 @@
NodeUserData,
)
from piston.utils import rc
-from provisioningserver.enum import POWER_TYPE
class UnknownMetadataVersion(MAASAPINotFound):
@@ -188,25 +185,6 @@
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)
- if type is None:
- return
-
- params = request.POST.get("power_parameters", None)
-
- type_dict = map_enum(POWER_TYPE)
- if type.upper() not in type_dict:
- raise MAASAPIBadRequest("Bad power_type '%s'" % type)
- node.power_type = type_dict[type.upper()]
-
- try:
- node.power_parameters = json.loads(params)
- except ValueError:
- raise MAASAPIBadRequest("Failed to parse json power_parameters")
- node.save()
-
@operation(idempotent=False)
def signal(self, request, version=None, mac=None):
"""Signal commissioning status.
@@ -243,7 +221,7 @@
return rc.ALL_OK
self._store_commissioning_results(node, request)
- self._store_power_parameters(node, request)
+ store_node_power_parameters(node, request)
target_status = self.signaling_statuses.get(status)
if target_status in (None, node.status):