Allow exceptions to propagate through stevedore map
Allow exceptions to propagate up through the stevedore map function used by the V3 API servers core extension. This allows for functionality such as extension specific parsing of client supplied data formerly required to be handled by the core API to be handled by the extension itself instead. This functionality requires stevedore 0.10 or later Partially implements blueprint nova-v3-api Change-Id: Ib848147225707f1c7eda27b1ba796022161ba20f
This commit is contained in:
parent
9e2d4ac460
commit
aad95316d4
@ -509,7 +509,8 @@ class ServersController(wsgi.Controller):
|
||||
namespace=self.EXTENSION_CREATE_NAMESPACE,
|
||||
check_func=_create_check_load_extension('server_create'),
|
||||
invoke_on_load=True,
|
||||
invoke_kwds={"extension_info": self.extension_info})
|
||||
invoke_kwds={"extension_info": self.extension_info},
|
||||
propagate_map_exceptions=True)
|
||||
if not list(self.create_extension_manager):
|
||||
LOG.debug(_("Did not find any server create extensions"))
|
||||
|
||||
@ -521,7 +522,8 @@ class ServersController(wsgi.Controller):
|
||||
check_func=_create_check_load_extension(
|
||||
'server_xml_extract_server_deserialize'),
|
||||
invoke_on_load=True,
|
||||
invoke_kwds={"extension_info": self.extension_info})
|
||||
invoke_kwds={"extension_info": self.extension_info},
|
||||
propagate_map_exceptions=True)
|
||||
if not list(self.create_xml_deserialize_manager):
|
||||
LOG.debug(_("Did not find any server create xml deserializer"
|
||||
" extensions"))
|
||||
|
@ -30,7 +30,9 @@ import webob
|
||||
|
||||
from nova.api.openstack import compute
|
||||
from nova.api.openstack.compute import plugins
|
||||
from nova.api.openstack.compute.plugins.v3 import availability_zone
|
||||
from nova.api.openstack.compute.plugins.v3 import ips
|
||||
from nova.api.openstack.compute.plugins.v3 import keypairs
|
||||
from nova.api.openstack.compute.plugins.v3 import servers
|
||||
from nova.api.openstack.compute import views
|
||||
from nova.api.openstack import xmlutil
|
||||
@ -2836,6 +2838,42 @@ class ServersControllerCreateTest(test.TestCase):
|
||||
self._check_admin_pass_len(server)
|
||||
self.assertEqual(FAKE_UUID, server['id'])
|
||||
|
||||
def test_create_instance_extension_create_exception(self):
|
||||
def fake_keypair_server_create(self, server_dict,
|
||||
create_kwargs):
|
||||
raise KeyError
|
||||
|
||||
self.stubs.Set(keypairs.Keypairs, 'server_create',
|
||||
fake_keypair_server_create)
|
||||
# proper local hrefs must start with 'http://localhost/v3/'
|
||||
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
|
||||
image_href = 'http://localhost/v3/images/%s' % image_uuid
|
||||
flavor_ref = 'http://localhost/123/flavors/3'
|
||||
body = {
|
||||
'server': {
|
||||
'name': 'server_test',
|
||||
'imageRef': image_href,
|
||||
'flavorRef': flavor_ref,
|
||||
'metadata': {
|
||||
'hello': 'world',
|
||||
'open': 'stack',
|
||||
},
|
||||
'personality': [
|
||||
{
|
||||
"path": "/etc/banner.txt",
|
||||
"contents": "MQ==",
|
||||
},
|
||||
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
req = fakes.HTTPRequestV3.blank('/servers')
|
||||
req.method = 'POST'
|
||||
req.body = jsonutils.dumps(body)
|
||||
req.headers["content-type"] = "application/json"
|
||||
self.assertRaises(KeyError, self.controller.create, req, body)
|
||||
|
||||
def test_create_instance_pass_disabled(self):
|
||||
self.flags(enable_instance_password=False)
|
||||
# proper local hrefs must start with 'http://localhost/v3/'
|
||||
@ -3246,7 +3284,9 @@ class TestServerCreateRequestXMLDeserializer(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestServerCreateRequestXMLDeserializer, self).setUp()
|
||||
self.deserializer = servers.CreateDeserializer(None)
|
||||
ext_info = plugins.LoadedExtensionInfo()
|
||||
servers_controller = servers.ServersController(extension_info=ext_info)
|
||||
self.deserializer = servers.CreateDeserializer(servers_controller)
|
||||
|
||||
def test_minimal_request(self):
|
||||
serial_request = """
|
||||
@ -3264,6 +3304,23 @@ class TestServerCreateRequestXMLDeserializer(test.TestCase):
|
||||
}
|
||||
self.assertEquals(request['body'], expected)
|
||||
|
||||
def test_xml_create_exception(self):
|
||||
def fake_availablity_extract_xml_deserialize(self,
|
||||
server_node,
|
||||
server_dict):
|
||||
raise KeyError
|
||||
|
||||
self.stubs.Set(availability_zone.AvailabilityZone,
|
||||
'server_xml_extract_server_deserialize',
|
||||
fake_availablity_extract_xml_deserialize)
|
||||
serial_request = """
|
||||
<server xmlns="http://docs.openstack.org/compute/api/v2"
|
||||
name="new-server-test"
|
||||
imageRef="1"
|
||||
flavorRef="2"/>"""
|
||||
self.assertRaises(KeyError, self.deserializer.deserialize,
|
||||
serial_request)
|
||||
|
||||
def test_request_with_alternate_namespace_prefix(self):
|
||||
serial_request = """
|
||||
<ns2:server xmlns:ns2="http://docs.openstack.org/compute/api/v2"
|
||||
|
@ -27,7 +27,7 @@ python-neutronclient>=2.2.3,<3.0.0
|
||||
python-glanceclient>=0.9.0
|
||||
python-keystoneclient>=0.2.0
|
||||
six
|
||||
stevedore>=0.9
|
||||
stevedore>=0.10
|
||||
websockify<0.4
|
||||
pyparsing>=1.5.7,<2.0 # order-dependent python-quantumclient req, bug 1191866
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user