Change v3 hosts to v2.1
This patch changes v3 hosts API to v2.1 and makes v2 unit tests share between v2 and v2.1. The differences between v2 and v3 are described on the wiki page https://wiki.openstack.org/wiki/NovaAPIv2tov3. Partially implements blueprint v2-on-v3-api Change-Id: I8ce66570edb06bde0bdea677e6e784539aaab763
This commit is contained in:
parent
8304536569
commit
382e85bbf9
@ -1,6 +1,4 @@
|
||||
{
|
||||
"host": {
|
||||
"host": "9557750dbc464741a89c907921c1cb31",
|
||||
"power_action": "reboot"
|
||||
}
|
||||
}
|
||||
"host": "9557750dbc464741a89c907921c1cb31",
|
||||
"power_action": "reboot"
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
{
|
||||
"host": {
|
||||
"host": "77cfa0002e4d45fe97f185968111b27b",
|
||||
"power_action": "shutdown"
|
||||
}
|
||||
}
|
||||
"host": "77cfa0002e4d45fe97f185968111b27b",
|
||||
"power_action": "shutdown"
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
{
|
||||
"host": {
|
||||
"host": "4b392b27930343bbaa27fd5d8328a564",
|
||||
"power_action": "startup"
|
||||
}
|
||||
}
|
||||
"host": "4b392b27930343bbaa27fd5d8328a564",
|
||||
"power_action": "startup"
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
{
|
||||
"host": {
|
||||
"status": "enable",
|
||||
"maintenance_mode": "disable"
|
||||
}
|
||||
}
|
||||
"status": "enable",
|
||||
"maintenance_mode": "disable"
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
{
|
||||
"host": {
|
||||
"host": "65c5d5b7e3bd44308e67fc50f362aee6",
|
||||
"maintenance_mode": "off_maintenance",
|
||||
"status": "enabled"
|
||||
}
|
||||
}
|
||||
"host": "65c5d5b7e3bd44308e67fc50f362aee6",
|
||||
"maintenance_mode": "off_maintenance",
|
||||
"status": "enabled"
|
||||
}
|
||||
|
@ -97,8 +97,8 @@ class HostController(wsgi.Controller):
|
||||
@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'}}
|
||||
""":param body: example format {'status': 'enable',
|
||||
'maintenance_mode': 'enable'}
|
||||
:returns:
|
||||
"""
|
||||
def read_enabled(orig_val):
|
||||
@ -112,8 +112,8 @@ class HostController(wsgi.Controller):
|
||||
context = req.environ['nova.context']
|
||||
authorize(context)
|
||||
# See what the user wants to 'update'
|
||||
status = body['host'].get('status')
|
||||
maint_mode = body['host'].get('maintenance_mode')
|
||||
status = body.get('status')
|
||||
maint_mode = body.get('maintenance_mode')
|
||||
if status is not None:
|
||||
status = read_enabled(status)
|
||||
if maint_mode is not None:
|
||||
@ -126,7 +126,7 @@ class HostController(wsgi.Controller):
|
||||
result['maintenance_mode'] = self._set_host_maintenance(context,
|
||||
id,
|
||||
maint_mode)
|
||||
return {'host': result}
|
||||
return result
|
||||
|
||||
def _set_host_maintenance(self, context, host_name, mode=True):
|
||||
"""Start/Stop host maintenance window. On start, it triggers
|
||||
@ -185,8 +185,7 @@ class HostController(wsgi.Controller):
|
||||
raise webob.exc.HTTPNotFound(explanation=e.format_message())
|
||||
except exception.ComputeServiceUnavailable as e:
|
||||
raise webob.exc.HTTPBadRequest(explanation=e.format_message())
|
||||
return {"host": {"host": host_name,
|
||||
"power_action": result}}
|
||||
return {"host": host_name, "power_action": result}
|
||||
|
||||
@extensions.expected_errors((400, 404, 501))
|
||||
def startup(self, req, id):
|
||||
|
@ -15,29 +15,22 @@
|
||||
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,
|
||||
'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']}
|
||||
],
|
||||
},
|
||||
'required': ['host'],
|
||||
'additionalProperties': False,
|
||||
'additionalProperties': False
|
||||
}
|
||||
|
@ -17,7 +17,8 @@ from lxml import etree
|
||||
import testtools
|
||||
import webob.exc
|
||||
|
||||
from nova.api.openstack.compute.contrib import hosts as os_hosts
|
||||
from nova.api.openstack.compute.contrib import hosts as os_hosts_v2
|
||||
from nova.api.openstack.compute.plugins.v3 import hosts as os_hosts_v3
|
||||
from nova.compute import power_state
|
||||
from nova.compute import vm_states
|
||||
from nova import context as context_maker
|
||||
@ -127,15 +128,23 @@ class FakeRequestWithNovaZone(object):
|
||||
GET = {"zone": "nova"}
|
||||
|
||||
|
||||
class HostTestCase(test.TestCase):
|
||||
class FakeRequestWithNovaService(object):
|
||||
environ = {"nova.context": context_maker.get_admin_context()}
|
||||
GET = {"service": "compute"}
|
||||
|
||||
|
||||
class FakeRequestWithInvalidNovaService(object):
|
||||
environ = {"nova.context": context_maker.get_admin_context()}
|
||||
GET = {"service": "invalid"}
|
||||
|
||||
|
||||
class HostTestCaseV21(test.TestCase):
|
||||
"""Test Case for hosts."""
|
||||
validation_ex = exception.ValidationError
|
||||
Controller = os_hosts_v3.HostController
|
||||
policy_ex = exception.PolicyNotAuthorized
|
||||
|
||||
def setUp(self):
|
||||
super(HostTestCase, self).setUp()
|
||||
self.controller = os_hosts.HostController()
|
||||
self.hosts_api = self.controller.api
|
||||
self.req = FakeRequest()
|
||||
|
||||
def _setup_stubs(self):
|
||||
# Pretend we have fake_hosts.HOST_LIST in the DB
|
||||
self.stubs.Set(db, 'service_get_all',
|
||||
stub_service_get_all)
|
||||
@ -151,9 +160,17 @@ class HostTestCase(test.TestCase):
|
||||
self.stubs.Set(self.hosts_api, 'host_power_action',
|
||||
stub_host_power_action)
|
||||
|
||||
def setUp(self):
|
||||
super(HostTestCaseV21, self).setUp()
|
||||
self.controller = self.Controller()
|
||||
self.hosts_api = self.controller.api
|
||||
self.req = FakeRequest()
|
||||
|
||||
self._setup_stubs()
|
||||
|
||||
def _test_host_update(self, host, key, val, expected_value):
|
||||
body = {key: val}
|
||||
result = self.controller.update(self.req, host, body)
|
||||
result = self.controller.update(self.req, host, body=body)
|
||||
self.assertEqual(result[key], expected_value)
|
||||
|
||||
def test_list_hosts(self):
|
||||
@ -163,12 +180,6 @@ class HostTestCase(test.TestCase):
|
||||
hosts = result['hosts']
|
||||
self.assertEqual(fake_hosts.HOST_LIST, hosts)
|
||||
|
||||
def test_list_hosts_with_zone(self):
|
||||
result = self.controller.index(FakeRequestWithNovaZone())
|
||||
self.assertIn('hosts', result)
|
||||
hosts = result['hosts']
|
||||
self.assertEqual(fake_hosts.HOST_LIST_NOVA_ZONE, hosts)
|
||||
|
||||
def test_disable_host(self):
|
||||
self._test_host_update('host_c1', 'status', 'disable', 'disabled')
|
||||
self._test_host_update('host_c2', 'status', 'disable', 'enabled')
|
||||
@ -254,25 +265,25 @@ class HostTestCase(test.TestCase):
|
||||
|
||||
def test_bad_status_value(self):
|
||||
bad_body = {"status": "bad"}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
self.req, "host_c1", bad_body)
|
||||
self.assertRaises(self.validation_ex, self.controller.update,
|
||||
self.req, "host_c1", body=bad_body)
|
||||
bad_body2 = {"status": "disablabc"}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
self.req, "host_c1", bad_body2)
|
||||
self.assertRaises(self.validation_ex, self.controller.update,
|
||||
self.req, "host_c1", body=bad_body2)
|
||||
|
||||
def test_bad_update_key(self):
|
||||
bad_body = {"crazy": "bad"}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
self.req, "host_c1", bad_body)
|
||||
self.assertRaises(self.validation_ex, self.controller.update,
|
||||
self.req, "host_c1", body=bad_body)
|
||||
|
||||
def test_bad_update_key_and_correct_update_key(self):
|
||||
bad_body = {"status": "disable", "crazy": "bad"}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
self.req, "host_c1", bad_body)
|
||||
self.assertRaises(self.validation_ex, self.controller.update,
|
||||
self.req, "host_c1", body=bad_body)
|
||||
|
||||
def test_good_update_keys(self):
|
||||
body = {"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_c1")
|
||||
self.assertEqual(result["status"], "disabled")
|
||||
self.assertEqual(result["maintenance_mode"], "on_maintenance")
|
||||
@ -280,7 +291,7 @@ class HostTestCase(test.TestCase):
|
||||
def test_show_forbidden(self):
|
||||
self.req.environ["nova.context"].is_admin = False
|
||||
dest = 'dummydest'
|
||||
self.assertRaises(webob.exc.HTTPForbidden,
|
||||
self.assertRaises(self.policy_ex,
|
||||
self.controller.show,
|
||||
self.req, dest)
|
||||
self.req.environ["nova.context"].is_admin = True
|
||||
@ -346,14 +357,41 @@ class HostTestCase(test.TestCase):
|
||||
db.instance_destroy(ctxt, i_ref1['uuid'])
|
||||
db.instance_destroy(ctxt, i_ref2['uuid'])
|
||||
|
||||
def test_list_hosts_with_zone(self):
|
||||
result = self.controller.index(FakeRequestWithNovaZone())
|
||||
self.assertIn('hosts', result)
|
||||
hosts = result['hosts']
|
||||
self.assertEqual(fake_hosts.HOST_LIST_NOVA_ZONE, hosts)
|
||||
|
||||
def test_list_hosts_with_service(self):
|
||||
result = self.controller.index(FakeRequestWithNovaService())
|
||||
self.assertEqual(fake_hosts.HOST_LIST_NOVA_ZONE, result['hosts'])
|
||||
|
||||
def test_list_hosts_with_invalid_service(self):
|
||||
result = self.controller.index(FakeRequestWithInvalidNovaService())
|
||||
self.assertEqual([], result['hosts'])
|
||||
|
||||
|
||||
class HostTestCaseV20(HostTestCaseV21):
|
||||
validation_ex = webob.exc.HTTPBadRequest
|
||||
policy_ex = webob.exc.HTTPForbidden
|
||||
Controller = os_hosts_v2.HostController
|
||||
|
||||
# Note: V2 api don't support list with services
|
||||
def test_list_hosts_with_service(self):
|
||||
pass
|
||||
|
||||
def test_list_hosts_with_invalid_service(self):
|
||||
pass
|
||||
|
||||
|
||||
class HostSerializerTest(test.TestCase):
|
||||
def setUp(self):
|
||||
super(HostSerializerTest, self).setUp()
|
||||
self.deserializer = os_hosts.HostUpdateDeserializer()
|
||||
self.deserializer = os_hosts_v2.HostUpdateDeserializer()
|
||||
|
||||
def test_index_serializer(self):
|
||||
serializer = os_hosts.HostIndexTemplate()
|
||||
serializer = os_hosts_v2.HostIndexTemplate()
|
||||
text = serializer.serialize(fake_hosts.OS_API_HOST_LIST)
|
||||
|
||||
tree = etree.fromstring(text)
|
||||
@ -371,7 +409,7 @@ class HostSerializerTest(test.TestCase):
|
||||
|
||||
def test_update_serializer_with_status(self):
|
||||
exemplar = dict(host='host_c1', status='enabled')
|
||||
serializer = os_hosts.HostUpdateTemplate()
|
||||
serializer = os_hosts_v2.HostUpdateTemplate()
|
||||
text = serializer.serialize(exemplar)
|
||||
|
||||
tree = etree.fromstring(text)
|
||||
@ -382,7 +420,7 @@ class HostSerializerTest(test.TestCase):
|
||||
|
||||
def test_update_serializer_with_maintenance_mode(self):
|
||||
exemplar = dict(host='host_c1', maintenance_mode='enabled')
|
||||
serializer = os_hosts.HostUpdateTemplate()
|
||||
serializer = os_hosts_v2.HostUpdateTemplate()
|
||||
text = serializer.serialize(exemplar)
|
||||
|
||||
tree = etree.fromstring(text)
|
||||
@ -395,7 +433,7 @@ class HostSerializerTest(test.TestCase):
|
||||
exemplar = dict(host='host_c1',
|
||||
maintenance_mode='enabled',
|
||||
status='enabled')
|
||||
serializer = os_hosts.HostUpdateTemplate()
|
||||
serializer = os_hosts_v2.HostUpdateTemplate()
|
||||
text = serializer.serialize(exemplar)
|
||||
|
||||
tree = etree.fromstring(text)
|
||||
@ -406,7 +444,7 @@ class HostSerializerTest(test.TestCase):
|
||||
|
||||
def test_action_serializer(self):
|
||||
exemplar = dict(host='host_c1', power_action='reboot')
|
||||
serializer = os_hosts.HostActionTemplate()
|
||||
serializer = os_hosts_v2.HostActionTemplate()
|
||||
text = serializer.serialize(exemplar)
|
||||
|
||||
tree = etree.fromstring(text)
|
||||
|
@ -1,426 +0,0 @@
|
||||
# Copyright (c) 2011 OpenStack Foundation
|
||||
# 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.
|
||||
|
||||
import testtools
|
||||
import webob.exc
|
||||
|
||||
from nova.api.openstack.compute.plugins.v3 import hosts as os_hosts
|
||||
from nova.compute import power_state
|
||||
from nova.compute import vm_states
|
||||
from nova import context as context_maker
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova import test
|
||||
from nova.tests import fake_hosts
|
||||
|
||||
|
||||
def stub_service_get_all(context, disabled=None):
|
||||
return fake_hosts.SERVICES_LIST
|
||||
|
||||
|
||||
def stub_service_get_by_host_and_topic(context, host_name, topic):
|
||||
for service in stub_service_get_all(context):
|
||||
if service['host'] == host_name and service['topic'] == topic:
|
||||
return service
|
||||
|
||||
|
||||
def stub_set_host_enabled(context, host_name, enabled):
|
||||
"""Simulates three possible behaviours for VM drivers or compute
|
||||
drivers when enabling or disabling a host.
|
||||
|
||||
'enabled' means new instances can go to this host
|
||||
'disabled' means they can't
|
||||
"""
|
||||
results = {True: "enabled", False: "disabled"}
|
||||
if host_name == "notimplemented":
|
||||
# The vm driver for this host doesn't support this feature
|
||||
raise NotImplementedError()
|
||||
elif host_name == "dummydest":
|
||||
# The host does not exist
|
||||
raise exception.ComputeHostNotFound(host=host_name)
|
||||
elif host_name == "host_c2":
|
||||
# Simulate a failure
|
||||
return results[not enabled]
|
||||
elif host_name == "serviceunavailable":
|
||||
raise exception.ComputeServiceUnavailable(host=host_name)
|
||||
else:
|
||||
# Do the right thing
|
||||
return results[enabled]
|
||||
|
||||
|
||||
def stub_set_host_maintenance(context, host_name, mode):
|
||||
# We'll simulate success and failure by assuming
|
||||
# that 'host_c1' always succeeds, and 'host_c2'
|
||||
# always fails
|
||||
results = {True: "on_maintenance", False: "off_maintenance"}
|
||||
if host_name == "notimplemented":
|
||||
# The vm driver for this host doesn't support this feature
|
||||
raise NotImplementedError()
|
||||
elif host_name == "dummydest":
|
||||
# The host does not exist
|
||||
raise exception.ComputeHostNotFound(host=host_name)
|
||||
elif host_name == "host_c2":
|
||||
# Simulate a failure
|
||||
return results[not mode]
|
||||
elif host_name == "serviceunavailable":
|
||||
raise exception.ComputeServiceUnavailable(host=host_name)
|
||||
else:
|
||||
# Do the right thing
|
||||
return results[mode]
|
||||
|
||||
|
||||
def stub_host_power_action(context, host_name, action):
|
||||
if host_name == "notimplemented":
|
||||
raise NotImplementedError()
|
||||
elif host_name == "dummydest":
|
||||
# The host does not exist
|
||||
raise exception.ComputeHostNotFound(host=host_name)
|
||||
elif host_name == "serviceunavailable":
|
||||
raise exception.ComputeServiceUnavailable(host=host_name)
|
||||
return action
|
||||
|
||||
|
||||
def _create_instance(**kwargs):
|
||||
"""Create a test instance."""
|
||||
ctxt = context_maker.get_admin_context()
|
||||
return db.instance_create(ctxt, _create_instance_dict(**kwargs))
|
||||
|
||||
|
||||
def _create_instance_dict(**kwargs):
|
||||
"""Create a dictionary for a test instance."""
|
||||
inst = {}
|
||||
inst['image_ref'] = 'cedef40a-ed67-4d10-800e-17455edce175'
|
||||
inst['reservation_id'] = 'r-fakeres'
|
||||
inst['user_id'] = kwargs.get('user_id', 'admin')
|
||||
inst['project_id'] = kwargs.get('project_id', 'fake')
|
||||
inst['instance_type_id'] = '1'
|
||||
if 'host' in kwargs:
|
||||
inst['host'] = kwargs.get('host')
|
||||
inst['vcpus'] = kwargs.get('vcpus', 1)
|
||||
inst['memory_mb'] = kwargs.get('memory_mb', 20)
|
||||
inst['root_gb'] = kwargs.get('root_gb', 30)
|
||||
inst['ephemeral_gb'] = kwargs.get('ephemeral_gb', 30)
|
||||
inst['vm_state'] = kwargs.get('vm_state', vm_states.ACTIVE)
|
||||
inst['power_state'] = kwargs.get('power_state', power_state.RUNNING)
|
||||
inst['task_state'] = kwargs.get('task_state', None)
|
||||
inst['availability_zone'] = kwargs.get('availability_zone', None)
|
||||
inst['ami_launch_index'] = 0
|
||||
inst['launched_on'] = kwargs.get('launched_on', 'dummy')
|
||||
return inst
|
||||
|
||||
|
||||
class FakeRequest(object):
|
||||
environ = {"nova.context": context_maker.get_admin_context()}
|
||||
GET = {}
|
||||
|
||||
|
||||
class FakeRequestWithNovaZone(object):
|
||||
environ = {"nova.context": context_maker.get_admin_context()}
|
||||
GET = {"zone": "nova"}
|
||||
|
||||
|
||||
class FakeRequestWithNovaService(object):
|
||||
environ = {"nova.context": context_maker.get_admin_context()}
|
||||
GET = {"service": "compute"}
|
||||
|
||||
|
||||
class FakeRequestWithInvalidNovaService(object):
|
||||
environ = {"nova.context": context_maker.get_admin_context()}
|
||||
GET = {"service": "invalid"}
|
||||
|
||||
|
||||
class HostTestCase(test.TestCase):
|
||||
"""Test Case for hosts."""
|
||||
|
||||
def setUp(self):
|
||||
super(HostTestCase, self).setUp()
|
||||
self.controller = os_hosts.HostController()
|
||||
self.hosts_api = self.controller.api
|
||||
self.req = FakeRequest()
|
||||
|
||||
# Pretend we have fake_hosts.HOST_LIST in the DB
|
||||
self.stubs.Set(db, 'service_get_all',
|
||||
stub_service_get_all)
|
||||
# Only hosts in our fake DB exist
|
||||
self.stubs.Set(db, 'service_get_by_host_and_topic',
|
||||
stub_service_get_by_host_and_topic)
|
||||
# 'host_c1' always succeeds, and 'host_c2'
|
||||
self.stubs.Set(self.hosts_api, 'set_host_enabled',
|
||||
stub_set_host_enabled)
|
||||
# 'host_c1' always succeeds, and 'host_c2'
|
||||
self.stubs.Set(self.hosts_api, 'set_host_maintenance',
|
||||
stub_set_host_maintenance)
|
||||
self.stubs.Set(self.hosts_api, 'host_power_action',
|
||||
stub_host_power_action)
|
||||
|
||||
def _test_host_update(self, host, key, val, expected_value):
|
||||
body = {'host': {key: val}}
|
||||
result = self.controller.update(self.req, host, body=body)
|
||||
self.assertEqual(result['host'][key], expected_value)
|
||||
|
||||
def test_list_hosts(self):
|
||||
"""Verify that the compute hosts are returned."""
|
||||
result = self.controller.index(self.req)
|
||||
self.assertIn('hosts', result)
|
||||
hosts = result['hosts']
|
||||
self.assertEqual(fake_hosts.HOST_LIST, hosts)
|
||||
|
||||
def test_list_hosts_with_zone(self):
|
||||
result = self.controller.index(FakeRequestWithNovaZone())
|
||||
self.assertIn('hosts', result)
|
||||
hosts = result['hosts']
|
||||
self.assertEqual(fake_hosts.HOST_LIST_NOVA_ZONE, hosts)
|
||||
|
||||
def test_list_hosts_with_service(self):
|
||||
result = self.controller.index(FakeRequestWithNovaService())
|
||||
self.assertEqual(fake_hosts.HOST_LIST_NOVA_ZONE, result['hosts'])
|
||||
|
||||
def test_list_hosts_with_invalid_service(self):
|
||||
result = self.controller.index(FakeRequestWithInvalidNovaService())
|
||||
self.assertEqual([], result['hosts'])
|
||||
|
||||
def test_disable_host(self):
|
||||
self._test_host_update('host_c1', 'status', 'disable', 'disabled')
|
||||
self._test_host_update('host_c2', 'status', 'disable', 'enabled')
|
||||
|
||||
def test_enable_host(self):
|
||||
self._test_host_update('host_c1', 'status', 'enable', 'enabled')
|
||||
self._test_host_update('host_c2', 'status', 'enable', 'disabled')
|
||||
|
||||
def test_enable_maintenance(self):
|
||||
self._test_host_update('host_c1', 'maintenance_mode',
|
||||
'enable', 'on_maintenance')
|
||||
|
||||
def test_disable_maintenance(self):
|
||||
self._test_host_update('host_c1', 'maintenance_mode',
|
||||
'disable', 'off_maintenance')
|
||||
|
||||
def _test_host_update_service_unavailable(self, key, val):
|
||||
body = {'host': {key: val}}
|
||||
host = "serviceunavailable"
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
||||
self.req, host, body=body)
|
||||
|
||||
def test_enable_host_service_unavailable(self):
|
||||
self._test_host_update_service_unavailable('status', 'enable')
|
||||
|
||||
def test_enable_maintenance_service_unavaliable(self):
|
||||
self._test_host_update_service_unavailable('maintenance_mode',
|
||||
'enable')
|
||||
|
||||
def _test_host_update_notimpl(self, key, val):
|
||||
def stub_service_get_all_notimpl(self, req):
|
||||
return [{'host': 'notimplemented', 'topic': None,
|
||||
'availability_zone': None}]
|
||||
self.stubs.Set(db, 'service_get_all',
|
||||
stub_service_get_all_notimpl)
|
||||
body = {"host": {key: val}}
|
||||
self.assertRaises(webob.exc.HTTPNotImplemented,
|
||||
self.controller.update,
|
||||
self.req, 'notimplemented', body=body)
|
||||
|
||||
def test_disable_host_notimpl(self):
|
||||
self._test_host_update_notimpl('status', 'disable')
|
||||
|
||||
def test_enable_maintenance_notimpl(self):
|
||||
self._test_host_update_notimpl('maintenance_mode', 'enable')
|
||||
|
||||
def test_host_startup(self):
|
||||
result = self.controller.startup(self.req, "host_c1")
|
||||
self.assertEqual(result['host']["power_action"], "startup")
|
||||
|
||||
def test_host_shutdown(self):
|
||||
result = self.controller.shutdown(self.req, "host_c1")
|
||||
self.assertEqual(result['host']["power_action"], "shutdown")
|
||||
|
||||
def test_host_reboot(self):
|
||||
result = self.controller.reboot(self.req, "host_c1")
|
||||
self.assertEqual(result['host']["power_action"], "reboot")
|
||||
|
||||
def _test_host_power_action_service_unavailable(self, method):
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
method, self.req, "serviceunavailable")
|
||||
|
||||
def test_host_startup_service_unavailable(self):
|
||||
self._test_host_power_action_service_unavailable(
|
||||
self.controller.startup)
|
||||
|
||||
def test_host_shutdown_service_unavailable(self):
|
||||
self._test_host_power_action_service_unavailable(
|
||||
self.controller.shutdown)
|
||||
|
||||
def test_host_reboot_service_unavailable(self):
|
||||
self._test_host_power_action_service_unavailable(
|
||||
self.controller.reboot)
|
||||
|
||||
def _test_host_power_action_notimpl(self, method):
|
||||
self.assertRaises(webob.exc.HTTPNotImplemented,
|
||||
method, self.req, "notimplemented")
|
||||
|
||||
def test_host_startup_notimpl(self):
|
||||
self._test_host_power_action_notimpl(self.controller.startup)
|
||||
|
||||
def test_host_shutdown_notimpl(self):
|
||||
self._test_host_power_action_notimpl(self.controller.shutdown)
|
||||
|
||||
def test_host_reboot_notimpl(self):
|
||||
self._test_host_power_action_notimpl(self.controller.reboot)
|
||||
|
||||
def test_host_status_bad_host(self):
|
||||
# A host given as an argument does not exist.
|
||||
self.req.environ["nova.context"].is_admin = True
|
||||
dest = 'dummydest'
|
||||
with testtools.ExpectedException(webob.exc.HTTPNotFound,
|
||||
".*%s.*" % dest):
|
||||
self.controller.update(self.req, dest,
|
||||
body={"host": {'status': 'enable'}})
|
||||
|
||||
def test_host_maintenance_bad_host(self):
|
||||
# A host given as an argument does not exist.
|
||||
self.req.environ["nova.context"].is_admin = True
|
||||
dest = 'dummydest'
|
||||
with testtools.ExpectedException(webob.exc.HTTPNotFound,
|
||||
".*%s.*" % dest):
|
||||
self.controller.update(self.req, dest,
|
||||
body={"host": {
|
||||
'maintenance_mode': 'enable'}})
|
||||
|
||||
def test_host_power_action_bad_host(self):
|
||||
# A host given as an argument does not exist.
|
||||
self.req.environ["nova.context"].is_admin = True
|
||||
dest = 'dummydest'
|
||||
with testtools.ExpectedException(webob.exc.HTTPNotFound,
|
||||
".*%s.*" % dest):
|
||||
self.controller.reboot(self.req, dest)
|
||||
|
||||
def test_bad_status_value(self):
|
||||
bad_body = {"host": {"status": "bad"}}
|
||||
self.assertRaises(exception.ValidationError, self.controller.update,
|
||||
self.req, "host", body=bad_body)
|
||||
bad_body2 = {"host": {"status": "disablabc"}}
|
||||
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(exception.ValidationError, self.controller.update,
|
||||
self.req, "host", body=bad_body)
|
||||
|
||||
def test_bad_update_key_type(self):
|
||||
bad_body = {"host": "abc"}
|
||||
self.assertRaises(exception.ValidationError, self.controller.update,
|
||||
self.req, "host", body=bad_body)
|
||||
bad_body = {"host": None}
|
||||
self.assertRaises(exception.ValidationError, self.controller.update,
|
||||
self.req, "host", body=bad_body)
|
||||
|
||||
def test_bad_update_empty(self):
|
||||
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(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=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'
|
||||
self.assertRaises(exception.PolicyNotAuthorized,
|
||||
self.controller.show,
|
||||
self.req, dest)
|
||||
self.req.environ["nova.context"].is_admin = True
|
||||
|
||||
def test_show_host_not_exist(self):
|
||||
# A host given as an argument does not exist.
|
||||
self.req.environ["nova.context"].is_admin = True
|
||||
dest = 'dummydest'
|
||||
with testtools.ExpectedException(webob.exc.HTTPNotFound,
|
||||
".*%s.*" % dest):
|
||||
self.controller.show(self.req, dest)
|
||||
|
||||
def _create_compute_service(self):
|
||||
"""Create compute-manager(ComputeNode and Service record)."""
|
||||
ctxt = self.req.environ["nova.context"]
|
||||
dic = {'host': 'dummy', 'binary': 'nova-compute', 'topic': 'compute',
|
||||
'report_count': 0}
|
||||
s_ref = db.service_create(ctxt, dic)
|
||||
|
||||
dic = {'service_id': s_ref['id'],
|
||||
'vcpus': 16, 'memory_mb': 32, 'local_gb': 100,
|
||||
'vcpus_used': 16, 'memory_mb_used': 32, 'local_gb_used': 10,
|
||||
'hypervisor_type': 'qemu', 'hypervisor_version': 12003,
|
||||
'cpu_info': '', 'stats': ''}
|
||||
db.compute_node_create(ctxt, dic)
|
||||
|
||||
return db.service_get(ctxt, s_ref['id'])
|
||||
|
||||
def test_show_no_project(self):
|
||||
"""No instances are running on the given host."""
|
||||
ctxt = context_maker.get_admin_context()
|
||||
s_ref = self._create_compute_service()
|
||||
|
||||
result = self.controller.show(self.req, s_ref['host'])
|
||||
|
||||
proj = ['(total)', '(used_now)', '(used_max)']
|
||||
column = ['host', 'project', 'cpu', 'memory_mb', 'disk_gb']
|
||||
self.assertEqual(len(result['host']), 3)
|
||||
for resource in result['host']:
|
||||
self.assertIn(resource['resource']['project'], proj)
|
||||
self.assertEqual(len(resource['resource']), 5)
|
||||
self.assertEqual(set(column), set(resource['resource'].keys()))
|
||||
db.service_destroy(ctxt, s_ref['id'])
|
||||
|
||||
def test_show_works_correctly(self):
|
||||
"""show() works correctly as expected."""
|
||||
ctxt = context_maker.get_admin_context()
|
||||
s_ref = self._create_compute_service()
|
||||
i_ref1 = _create_instance(project_id='p-01', host=s_ref['host'])
|
||||
i_ref2 = _create_instance(project_id='p-02', vcpus=3,
|
||||
host=s_ref['host'])
|
||||
|
||||
result = self.controller.show(self.req, s_ref['host'])
|
||||
|
||||
proj = ['(total)', '(used_now)', '(used_max)', 'p-01', 'p-02']
|
||||
column = ['host', 'project', 'cpu', 'memory_mb', 'disk_gb']
|
||||
self.assertEqual(len(result['host']), 5)
|
||||
for resource in result['host']:
|
||||
self.assertIn(resource['resource']['project'], proj)
|
||||
self.assertEqual(len(resource['resource']), 5)
|
||||
self.assertEqual(set(column), set(resource['resource'].keys()))
|
||||
db.service_destroy(ctxt, s_ref['id'])
|
||||
db.instance_destroy(ctxt, i_ref1['uuid'])
|
||||
db.instance_destroy(ctxt, i_ref2['uuid'])
|
@ -216,7 +216,7 @@ policy_data = """
|
||||
"compute_extension:fping:all_tenants": "is_admin:True",
|
||||
"compute_extension:hide_server_addresses": "",
|
||||
"compute_extension:v3:os-hide-server-addresses": "",
|
||||
"compute_extension:hosts": "",
|
||||
"compute_extension:hosts": "rule:admin_api",
|
||||
"compute_extension:v3:os-hosts": "rule:admin_api",
|
||||
"compute_extension:hypervisors": "",
|
||||
"compute_extension:v3:os-hypervisors": "rule:admin_api",
|
||||
|
@ -1,6 +1,4 @@
|
||||
{
|
||||
"host": {
|
||||
"host": "%(host_name)s",
|
||||
"power_action": "reboot"
|
||||
}
|
||||
"host": "%(host_name)s",
|
||||
"power_action": "reboot"
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
{
|
||||
"host": {
|
||||
"host": "%(host_name)s",
|
||||
"power_action": "shutdown"
|
||||
}
|
||||
"host": "%(host_name)s",
|
||||
"power_action": "shutdown"
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
{
|
||||
"host": {
|
||||
"host": "%(host_name)s",
|
||||
"power_action": "startup"
|
||||
}
|
||||
"host": "%(host_name)s",
|
||||
"power_action": "startup"
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
{
|
||||
"host": {
|
||||
"status": "enable",
|
||||
"maintenance_mode": "disable"
|
||||
}
|
||||
"status": "enable",
|
||||
"maintenance_mode": "disable"
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
{
|
||||
"host": {
|
||||
"host": "%(host_name)s",
|
||||
"maintenance_mode": "off_maintenance",
|
||||
"status": "enabled"
|
||||
}
|
||||
"host": "%(host_name)s",
|
||||
"maintenance_mode": "off_maintenance",
|
||||
"status": "enabled"
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user