Pecan: Fix tags handling for pecan
Tags controller was not being picked up from the extension. This also allows the usage of collection_methods that tags uses. Also, the tags extension made use of action_status on a resource, which allowed overriding the default status codes, so this patch handles action_status as well. Change-Id: Ic7f5cfddd30f26737469516235053656f1ba6a24
This commit is contained in:
parent
028a150db3
commit
96a45cadcc
|
@ -108,4 +108,5 @@ def Resource(controller, faults=None, deserializers=None, serializers=None,
|
|||
# for an extension so it can reuse the code instead of forcing every
|
||||
# extension to rewrite the code for use with pecan.
|
||||
setattr(resource, 'controller', controller)
|
||||
setattr(resource, 'action_status', action_status)
|
||||
return resource
|
||||
|
|
|
@ -127,7 +127,7 @@ class NeutronPecanController(object):
|
|||
def __init__(self, collection, resource, plugin=None, resource_info=None,
|
||||
allow_pagination=None, allow_sorting=None,
|
||||
parent_resource=None, member_actions=None,
|
||||
collection_actions=None, item=None):
|
||||
collection_actions=None, item=None, action_status=None):
|
||||
# Ensure dashes are always replaced with underscores
|
||||
self.collection = collection and collection.replace('-', '_')
|
||||
self.resource = resource and resource.replace('-', '_')
|
||||
|
@ -167,6 +167,13 @@ class NeutronPecanController(object):
|
|||
self._plugin_handlers[action] = '%s%s_%s' % (
|
||||
action, parent_resource, self.resource)
|
||||
self.item = item
|
||||
self.action_status = action_status or {}
|
||||
|
||||
def _set_response_code(self, result, method_name):
|
||||
if method_name in self.action_status:
|
||||
pecan.response.status = self.action_status[method_name]
|
||||
else:
|
||||
pecan.response.status = 200 if result else 204
|
||||
|
||||
def build_field_list(self, request_fields):
|
||||
added_fields = []
|
||||
|
@ -245,10 +252,12 @@ def invert_dict(dictionary):
|
|||
class ShimItemController(NeutronPecanController):
|
||||
|
||||
def __init__(self, collection, resource, item, controller,
|
||||
collection_actions=None, member_actions=None):
|
||||
collection_actions=None, member_actions=None,
|
||||
action_status=None):
|
||||
super(ShimItemController, self).__init__(
|
||||
collection, resource, collection_actions=collection_actions,
|
||||
member_actions=member_actions, item=item)
|
||||
member_actions=member_actions, item=item,
|
||||
action_status=action_status)
|
||||
self.controller = controller
|
||||
self.controller_delete = getattr(controller, 'delete', None)
|
||||
self.controller_update = getattr(controller, 'update', None)
|
||||
|
@ -259,15 +268,20 @@ class ShimItemController(NeutronPecanController):
|
|||
@expose(generic=True)
|
||||
def index(self):
|
||||
shim_request = ShimRequest(request.context['neutron_context'])
|
||||
kwargs = request.context['uri_identifiers']
|
||||
if self.item in self.inverted_collection_actions['GET']:
|
||||
method = getattr(self.controller, self.item, None)
|
||||
# collection actions should not take an self.item because they are
|
||||
# essentially static items.
|
||||
return method(shim_request)
|
||||
result = method(shim_request, **kwargs)
|
||||
self._set_response_code(result, self.item)
|
||||
return result
|
||||
elif not self.controller_show:
|
||||
pecan.abort(405)
|
||||
else:
|
||||
return self.controller_show(shim_request, self.item)
|
||||
result = self.controller_show(shim_request, self.item, **kwargs)
|
||||
self._set_response_code(result, 'show')
|
||||
return result
|
||||
|
||||
@when_delete(index)
|
||||
def delete(self):
|
||||
|
@ -275,19 +289,26 @@ class ShimItemController(NeutronPecanController):
|
|||
pecan.abort(405)
|
||||
shim_request = ShimRequest(request.context['neutron_context'])
|
||||
uri_identifiers = request.context['uri_identifiers']
|
||||
return self.controller_delete(shim_request, self.item,
|
||||
**uri_identifiers)
|
||||
result = self.controller_delete(shim_request, self.item,
|
||||
**uri_identifiers)
|
||||
self._set_response_code(result, 'delete')
|
||||
return result
|
||||
|
||||
@when(index, method='PUT')
|
||||
def update(self):
|
||||
if not self.controller_update:
|
||||
pecan.abort(405)
|
||||
pecan.response.status = 200
|
||||
pecan.response.status = self.action_status.get('update', 201)
|
||||
shim_request = ShimRequest(request.context['neutron_context'])
|
||||
uri_identifiers = request.context['uri_identifiers']
|
||||
return self.controller_update(shim_request, self.item,
|
||||
body=request.json,
|
||||
**uri_identifiers)
|
||||
kwargs = request.context['uri_identifiers']
|
||||
try:
|
||||
kwargs['body'] = request.json
|
||||
except ValueError:
|
||||
pass
|
||||
result = self.controller_update(shim_request, self.item,
|
||||
**kwargs)
|
||||
self._set_response_code(result, 'update')
|
||||
return result
|
||||
|
||||
@expose()
|
||||
def _lookup(self, resource, *remainder):
|
||||
|
@ -300,31 +321,57 @@ class ShimItemController(NeutronPecanController):
|
|||
class ShimCollectionsController(NeutronPecanController):
|
||||
|
||||
def __init__(self, collection, resource, controller,
|
||||
collection_actions=None, member_actions=None):
|
||||
collection_actions=None, member_actions=None,
|
||||
collection_methods=None, action_status=None):
|
||||
collection_methods = collection_methods or {}
|
||||
super(ShimCollectionsController, self).__init__(
|
||||
collection, resource, member_actions=member_actions,
|
||||
collection_actions=collection_actions)
|
||||
collection_actions=collection_actions,
|
||||
action_status=action_status)
|
||||
self.controller = controller
|
||||
self.controller_index = getattr(controller, 'index', None)
|
||||
self.controller_create = getattr(controller, 'create', None)
|
||||
self.controller_update = getattr(controller, 'update', None)
|
||||
self.collection_methods = {}
|
||||
for action, method in collection_methods.items():
|
||||
controller_method = getattr(controller, action, None)
|
||||
self.collection_methods[method] = (
|
||||
controller_method, self.action_status.get(action, 200))
|
||||
|
||||
@expose(generic=True)
|
||||
def index(self):
|
||||
if not self.controller_index:
|
||||
if (not self.controller_index and
|
||||
request.method not in self.collection_methods):
|
||||
pecan.abort(405)
|
||||
controller_method_status = self.collection_methods.get(request.method)
|
||||
status = None
|
||||
if controller_method_status:
|
||||
controller_method = controller_method_status[0]
|
||||
status = controller_method_status[1]
|
||||
else:
|
||||
controller_method = self.controller_index
|
||||
shim_request = ShimRequest(request.context['neutron_context'])
|
||||
uri_identifiers = request.context['uri_identifiers']
|
||||
return self.controller_index(shim_request, **uri_identifiers)
|
||||
args = [shim_request]
|
||||
if request.method == 'PUT':
|
||||
args.append(request.json)
|
||||
result = controller_method(*args, **uri_identifiers)
|
||||
if not status:
|
||||
self._set_response_code(result, 'index')
|
||||
else:
|
||||
pecan.response.status = status
|
||||
return result
|
||||
|
||||
@when(index, method='POST')
|
||||
def create(self):
|
||||
if not self.controller_create:
|
||||
pecan.abort(405)
|
||||
pecan.response.status = 201
|
||||
shim_request = ShimRequest(request.context['neutron_context'])
|
||||
uri_identifiers = request.context['uri_identifiers']
|
||||
return self.controller_create(shim_request, request.json,
|
||||
**uri_identifiers)
|
||||
result = self.controller_create(shim_request, request.json,
|
||||
**uri_identifiers)
|
||||
self._set_response_code(result, 'create')
|
||||
return result
|
||||
|
||||
@expose()
|
||||
def _lookup(self, item, *remainder):
|
||||
|
@ -334,7 +381,8 @@ class ShimCollectionsController(NeutronPecanController):
|
|||
ShimItemController(self.collection, self.resource, item,
|
||||
self.controller,
|
||||
member_actions=self._member_actions,
|
||||
collection_actions=self._collection_actions),
|
||||
collection_actions=self._collection_actions,
|
||||
action_status=self.action_status),
|
||||
remainder
|
||||
)
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
from neutron_lib.plugins import directory
|
||||
from oslo_log import log
|
||||
|
||||
from neutron._i18n import _LW
|
||||
from neutron.api import extensions
|
||||
from neutron.api.v2 import attributes
|
||||
from neutron.api.v2 import base
|
||||
|
@ -26,7 +25,6 @@ from neutron.pecan_wsgi.controllers import resource as res_ctrl
|
|||
from neutron.pecan_wsgi.controllers import utils
|
||||
from neutron import policy
|
||||
from neutron.quota import resource_registry
|
||||
from neutron import wsgi
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
@ -104,14 +102,14 @@ def initialize_all():
|
|||
if path_prefix:
|
||||
manager.NeutronManager.add_resource_for_path_prefix(
|
||||
collection, path_prefix)
|
||||
elif isinstance(legacy_controller, wsgi.Controller):
|
||||
else:
|
||||
new_controller = utils.ShimCollectionsController(
|
||||
collection, None, legacy_controller,
|
||||
collection_actions=collection_actions,
|
||||
member_actions=member_actions)
|
||||
else:
|
||||
LOG.warning(_LW("Unknown controller type encountered %s. It will"
|
||||
"be ignored."), legacy_controller)
|
||||
member_actions=member_actions,
|
||||
action_status=ext_res.controller.action_status,
|
||||
collection_methods=ext_res.collection_methods)
|
||||
|
||||
manager.NeutronManager.set_controller_for_resource(
|
||||
collection_key, new_controller)
|
||||
|
||||
|
|
Loading…
Reference in New Issue