summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/api/openstack/__init__.py6
-rw-r--r--nova/api/openstack/extensions.py29
-rw-r--r--nova/tests/api/openstack/extensions/widgets.py15
-rw-r--r--nova/tests/api/openstack/test_extensions.py66
4 files changed, 59 insertions, 57 deletions
diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py
index 8a458eea1..ff91c77cf 100644
--- a/nova/api/openstack/__init__.py
+++ b/nova/api/openstack/__init__.py
@@ -31,7 +31,6 @@ from nova.api.openstack import accounts
from nova.api.openstack import faults
from nova.api.openstack import backup_schedules
from nova.api.openstack import consoles
-from nova.api.openstack import extensions
from nova.api.openstack import flavors
from nova.api.openstack import images
from nova.api.openstack import servers
@@ -121,11 +120,6 @@ class APIRouter(wsgi.Router):
collection={'detail': 'GET'},
controller=shared_ip_groups.Controller())
- if ext_mgr is None:
- ext_mgr = extensions.ExtensionManager(FLAGS.osapi_extensions_path)
- for resource in ext_mgr.get_resources():
- resource.add_routes(mapper)
-
super(APIRouter, self).__init__(mapper)
diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py
index e41de3120..f32471051 100644
--- a/nova/api/openstack/extensions.py
+++ b/nova/api/openstack/extensions.py
@@ -68,7 +68,15 @@ class ExtensionMiddleware(wsgi.Middleware):
if ext_mgr is None:
ext_mgr = ExtensionManager(FLAGS.osapi_extensions_path)
- # create custom mapper connections for extended actions
+ # extended resources
+ for resource in ext_mgr.get_resources():
+ mapper.resource(resource.member, resource.collection,
+ controller=resource.controller,
+ collection=resource.collection_actions,
+ member=resource.member_actions,
+ parent_resource=resource.parent)
+
+ # extended actions
for action in ext_mgr.get_actions():
controller = ExtensionActionController(application, action.name,
action.handler)
@@ -124,10 +132,13 @@ class ExtensionManager(object):
"""
resources = []
for ext in self.extensions:
- resources.append(ext.get_resources())
+ resources.extend(ext.get_resources())
return resources
def get_actions(self):
+ """
+ returns a list of ExtensionAction objects
+ """
actions = []
for ext in self.extensions:
actions.extend(ext.get_actions())
@@ -163,10 +174,12 @@ class ExtensionAction(object):
class ExtensionResource(object):
- """
- Example ExtensionResource object. All ExtensionResource objects should
- adhere to this interface.
- """
- def add_routes(self, mapper):
- pass
+ def __init__(self, member, collection, controller,
+ parent=None, collection_actions={}, member_actions={}):
+ self.member = member
+ self.collection = collection
+ self.controller = controller
+ self.parent = parent
+ self.collection_actions = collection_actions
+ self.member_actions = member_actions
diff --git a/nova/tests/api/openstack/extensions/widgets.py b/nova/tests/api/openstack/extensions/widgets.py
index 6839d2bb2..d5a2d95d9 100644
--- a/nova/tests/api/openstack/extensions/widgets.py
+++ b/nova/tests/api/openstack/extensions/widgets.py
@@ -9,22 +9,17 @@ class WidgetsController(wsgi.Controller):
return "Buy more widgets!"
-class WidgetsExtensionResource(object):
-
- def __init__(self):
- pass
-
- def add_routes(self, mapper):
- mapper.resource('widget', 'widgets', controller=WidgetsController())
-
-
class WidgetsExtension(object):
def __init__(self):
pass
def get_resources(self):
- return WidgetsExtensionResource()
+ resources = []
+ widgets = extensions.ExtensionResource('widget', 'widgets',
+ WidgetsController())
+ resources.append(widgets)
+ return resources
def get_actions(self):
actions = []
diff --git a/nova/tests/api/openstack/test_extensions.py b/nova/tests/api/openstack/test_extensions.py
index f8d217e9c..080760c14 100644
--- a/nova/tests/api/openstack/test_extensions.py
+++ b/nova/tests/api/openstack/test_extensions.py
@@ -22,6 +22,7 @@ import os.path
from nova import flags
from nova.api import openstack
+from nova.api.openstack import extensions
import nova.wsgi
FLAGS = flags.FLAGS
@@ -38,53 +39,51 @@ class StubController(nova.wsgi.Controller):
class StubExtensionManager(object):
- def __init__(self, resources):
- self.resources = resources
+ def __init__(self, resource):
+ self.resource = resource
def get_resources(self):
- return self.resources
+ resources = []
+ if self.resource:
+ resources.append(self.resource)
+ return resources
+ def get_actions(self):
+ actions = []
+ return actions
-class WidgetExtensionResource(object):
- def __init__(self, name, collection, wsgi_app):
- self.name = name
- self.collection = collection
- self.wsgi_app = wsgi_app
-
- def add_routes(self, mapper):
- mapper.resource(self.name, self.collection, controller=self.wsgi_app)
-
-
-class ExtensionTest(unittest.TestCase):
+class ExtensionResourceTest(unittest.TestCase):
def test_no_extension_present(self):
- manager = StubExtensionManager([])
- router = openstack.APIRouter(manager)
+ manager = StubExtensionManager(None)
+ app = openstack.APIRouter()
+ ext_midware = extensions.ExtensionMiddleware(app, manager)
request = webob.Request.blank("/widgets")
- response = request.get_response(router)
+ response = request.get_response(ext_midware)
self.assertEqual(404, response.status_int)
def test_get_resources(self):
response_body = "Buy more widgets!"
- response = webob.Response()
- response.body = response_body
- resource1 = WidgetExtensionResource("widget", "widgets", response)
- manager = StubExtensionManager([resource1])
- router = openstack.APIRouter(manager)
+ widgets = extensions.ExtensionResource('widget', 'widgets',
+ StubController(response_body))
+ manager = StubExtensionManager(widgets)
+ app = openstack.APIRouter()
+ ext_midware = extensions.ExtensionMiddleware(app, manager)
request = webob.Request.blank("/widgets")
- response = request.get_response(router)
+ response = request.get_response(ext_midware)
self.assertEqual(200, response.status_int)
self.assertEqual(response_body, response.body)
def test_get_resources_with_controller(self):
response_body = "Buy more widgets!"
- controller = StubController(response_body)
- resource1 = WidgetExtensionResource("widget", "widgets", controller)
- manager = StubExtensionManager([resource1])
- router = openstack.APIRouter(manager)
+ widgets = extensions.ExtensionResource('widget', 'widgets',
+ StubController(response_body))
+ manager = StubExtensionManager(widgets)
+ app = openstack.APIRouter()
+ ext_midware = extensions.ExtensionMiddleware(app, manager)
request = webob.Request.blank("/widgets")
- response = request.get_response(router)
+ response = request.get_response(ext_midware)
self.assertEqual(200, response.status_int)
self.assertEqual(response_body, response.body)
@@ -96,9 +95,10 @@ class ExtensionManagerTest(unittest.TestCase):
"extensions")
def test_get_resources(self):
- router = openstack.APIRouter()
+ app = openstack.APIRouter()
+ ext_midware = extensions.ExtensionMiddleware(app)
request = webob.Request.blank("/widgets")
- response = request.get_response(router)
+ response = request.get_response(ext_midware)
self.assertEqual(200, response.status_int)
self.assertEqual("Buy more widgets!", response.body)
@@ -111,7 +111,7 @@ class ExtendedActionTest(unittest.TestCase):
def test_extended_action(self):
app = openstack.APIRouter()
- ext_midware = openstack.extensions.ExtensionMiddleware(app)
+ ext_midware = extensions.ExtensionMiddleware(app)
body = dict(add_widget=dict(name="test"))
request = webob.Request.blank("/servers/1/action")
request.method = 'POST'
@@ -123,7 +123,7 @@ class ExtendedActionTest(unittest.TestCase):
def test_invalid_action_body(self):
app = openstack.APIRouter()
- ext_midware = openstack.extensions.ExtensionMiddleware(app)
+ ext_midware = extensions.ExtensionMiddleware(app)
body = dict(blah=dict(name="test")) # Doesn't exist
request = webob.Request.blank("/servers/1/action")
request.method = 'POST'
@@ -134,7 +134,7 @@ class ExtendedActionTest(unittest.TestCase):
def test_invalid_action(self):
app = openstack.APIRouter()
- ext_midware = openstack.extensions.ExtensionMiddleware(app)
+ ext_midware = extensions.ExtensionMiddleware(app)
request = webob.Request.blank("/asdf/1/action")
request.method = 'POST'
request.content_type = 'application/json'