Merge "Add API schema for v2.1/v3 hosts API"
This commit is contained in:
commit
da59d32281
@ -17,8 +17,10 @@
|
||||
|
||||
import webob.exc
|
||||
|
||||
from nova.api.openstack.compute.schemas.v3 import hosts
|
||||
from nova.api.openstack import extensions
|
||||
from nova.api.openstack import wsgi
|
||||
from nova.api import validation
|
||||
from nova import compute
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
@ -92,49 +94,29 @@ class HostController(wsgi.Controller):
|
||||
return {'hosts': hosts}
|
||||
|
||||
@extensions.expected_errors((400, 404, 501))
|
||||
@validation.schema(hosts.update)
|
||||
def update(self, req, id, body):
|
||||
""":param body: example format {'host': {'status': 'enable',
|
||||
'maintenance_mode': 'enable'}}
|
||||
:returns:
|
||||
"""
|
||||
def read_enabled(orig_val, msg):
|
||||
def read_enabled(orig_val):
|
||||
""":param orig_val: A string with either 'enable' or 'disable'. May
|
||||
be surrounded by whitespace, and case doesn't
|
||||
matter
|
||||
:param msg: The message to be passed to HTTPBadRequest. A single
|
||||
%s will be replaced with orig_val.
|
||||
:returns: True for 'enabled' and False for 'disabled'
|
||||
"""
|
||||
val = orig_val.strip().lower()
|
||||
if val == "enable":
|
||||
return True
|
||||
elif val == "disable":
|
||||
return False
|
||||
else:
|
||||
raise webob.exc.HTTPBadRequest(explanation=msg % orig_val)
|
||||
return val == "enable"
|
||||
context = req.environ['nova.context']
|
||||
authorize(context)
|
||||
# See what the user wants to 'update'
|
||||
if not self.is_valid_body(body, 'host'):
|
||||
raise webob.exc.HTTPBadRequest(
|
||||
explanation=_("The request body invalid"))
|
||||
params = dict([(k.strip().lower(), v)
|
||||
for k, v in body['host'].iteritems()])
|
||||
orig_status = status = params.pop('status', None)
|
||||
orig_maint_mode = maint_mode = params.pop('maintenance_mode', None)
|
||||
# Validate the request
|
||||
if len(params) > 0:
|
||||
# Some extra param was passed. Fail.
|
||||
explanation = _("Invalid update setting: '%s'") % params.keys()[0]
|
||||
raise webob.exc.HTTPBadRequest(explanation=explanation)
|
||||
if orig_status is not None:
|
||||
status = read_enabled(orig_status, _("Invalid status: '%s'"))
|
||||
if orig_maint_mode is not None:
|
||||
maint_mode = read_enabled(orig_maint_mode, _("Invalid mode: '%s'"))
|
||||
if status is None and maint_mode is None:
|
||||
explanation = _("'status' or 'maintenance_mode' needed for "
|
||||
"host update")
|
||||
raise webob.exc.HTTPBadRequest(explanation=explanation)
|
||||
status = body['host'].get('status')
|
||||
maint_mode = body['host'].get('maintenance_mode')
|
||||
if status is not None:
|
||||
status = read_enabled(status)
|
||||
if maint_mode is not None:
|
||||
maint_mode = read_enabled(maint_mode)
|
||||
# Make the calls and merge the results
|
||||
result = {'host': id}
|
||||
if status is not None:
|
||||
|
43
nova/api/openstack/compute/schemas/v3/hosts.py
Normal file
43
nova/api/openstack/compute/schemas/v3/hosts.py
Normal file
@ -0,0 +1,43 @@
|
||||
# Copyright 2014 NEC Corporation. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
update = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'host': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'status': {
|
||||
'type': 'string',
|
||||
'enum': ['enable', 'disable',
|
||||
'Enable', 'Disable',
|
||||
'ENABLE', 'DISABLE'],
|
||||
},
|
||||
'maintenance_mode': {
|
||||
'type': 'string',
|
||||
'enum': ['enable', 'disable',
|
||||
'Enable', 'Disable',
|
||||
'ENABLE', 'DISABLE'],
|
||||
},
|
||||
},
|
||||
'anyOf': [
|
||||
{'required': ['status']},
|
||||
{'required': ['maintenance_mode']}
|
||||
],
|
||||
'additionalProperties': False,
|
||||
},
|
||||
},
|
||||
'required': ['host'],
|
||||
'additionalProperties': False,
|
||||
}
|
@ -167,7 +167,7 @@ class HostTestCase(test.TestCase):
|
||||
|
||||
def _test_host_update(self, host, key, val, expected_value):
|
||||
body = {'host': {key: val}}
|
||||
result = self.controller.update(self.req, host, body)
|
||||
result = self.controller.update(self.req, host, body=body)
|
||||
self.assertEqual(result['host'][key], expected_value)
|
||||
|
||||
def test_list_hosts(self):
|
||||
@ -211,7 +211,7 @@ class HostTestCase(test.TestCase):
|
||||
body = {'host': {key: val}}
|
||||
host = "serviceunavailable"
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
self.req, host, body)
|
||||
self.req, host, body=body)
|
||||
|
||||
def test_enable_host_service_unavailable(self):
|
||||
self._test_host_update_service_unavailable('status', 'enable')
|
||||
@ -307,45 +307,55 @@ class HostTestCase(test.TestCase):
|
||||
|
||||
def test_bad_status_value(self):
|
||||
bad_body = {"host": {"status": "bad"}}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
self.req, "host_c1", bad_body)
|
||||
self.assertRaises(exception.ValidationError, self.controller.update,
|
||||
self.req, "host", body=bad_body)
|
||||
bad_body2 = {"host": {"status": "disablabc"}}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
self.req, "host_c1", bad_body2)
|
||||
self.assertRaises(exception.ValidationError, self.controller.update,
|
||||
self.req, "host", body=bad_body2)
|
||||
|
||||
def test_bad_update_key(self):
|
||||
bad_body = {"host": {"crazy": "bad"}}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
self.req, "host_c1", bad_body)
|
||||
self.assertRaises(exception.ValidationError, self.controller.update,
|
||||
self.req, "host", body=bad_body)
|
||||
|
||||
def test_bad_update_key_type(self):
|
||||
bad_body = {"host": "abc"}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
self.req, "host_c1", bad_body)
|
||||
self.assertRaises(exception.ValidationError, self.controller.update,
|
||||
self.req, "host", body=bad_body)
|
||||
bad_body = {"host": None}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
self.req, "host_c1", bad_body)
|
||||
self.assertRaises(exception.ValidationError, self.controller.update,
|
||||
self.req, "host", body=bad_body)
|
||||
|
||||
def test_bad_update_empty(self):
|
||||
bad_body = {}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
self.req, "host_c1", bad_body)
|
||||
self.assertRaises(exception.ValidationError, self.controller.update,
|
||||
self.req, "host", body=bad_body)
|
||||
|
||||
def test_bad_update_key_and_correct_update_key(self):
|
||||
bad_body = {"host": {"status": "disable",
|
||||
"crazy": "bad"}}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
self.req, "host_c1", bad_body)
|
||||
self.assertRaises(exception.ValidationError, self.controller.update,
|
||||
self.req, "host", body=bad_body)
|
||||
|
||||
def test_good_update_keys(self):
|
||||
body = {"host": {"status": "disable",
|
||||
"maintenance_mode": "enable"}}
|
||||
result = self.controller.update(self.req, 'host_c1', body)
|
||||
result = self.controller.update(self.req, 'host_c1', body=body)
|
||||
self.assertEqual(result["host"]["host"], "host_c1")
|
||||
self.assertEqual(result["host"]["status"], "disabled")
|
||||
self.assertEqual(result["host"]["maintenance_mode"],
|
||||
"on_maintenance")
|
||||
|
||||
def test_update_with_status_key_only(self):
|
||||
body = {"host": {"status": "enable"}}
|
||||
result = self.controller.update(self.req, 'host_c1', body=body)
|
||||
self.assertEqual("enabled", result["host"]["status"])
|
||||
|
||||
def test_update_with_maintenance_mode_key_only(self):
|
||||
body = {"host": {"maintenance_mode": "enable"}}
|
||||
result = self.controller.update(self.req, 'host_c1', body=body)
|
||||
self.assertEqual("on_maintenance", result["host"]["maintenance_mode"])
|
||||
|
||||
def test_show_forbidden(self):
|
||||
self.req.environ["nova.context"].is_admin = False
|
||||
dest = 'dummydest'
|
||||
|
Loading…
Reference in New Issue
Block a user