Convert root controller to plain controller

The RestController._route method[1] contains a lot of logic which
exists to support implementing CRUD APIs, none of which is required to
server / and /v1.

This change converts the RestController based root controller with a
simple object based controller. This results in a shorter code path
for every API request.

The path / is handled by the index method, with the *args length check
returning a 404 to be consistent with the previous behaviour of
returning a 404 for a request like //v1

The _route method is replaced with a _lookup[2] method to handle paths
which are missing the v1 prefix (and to curate the trailing slash from
the path, which was been done by the RestController).

[1] https://github.com/pecan/pecan/blob/master/pecan/rest.py#L103

Change-Id: Ia962f9bf53af12fb308e3d66eff114b302638714
Story: 1651346
Task: 10551
This commit is contained in:
Steve Baker 2020-07-14 09:49:53 +12:00
parent 52160b5bfe
commit bf15520119

View File

@ -15,13 +15,15 @@
# under the License. # under the License.
import pecan import pecan
from pecan import rest
from ironic.api.controllers import v1 from ironic.api.controllers import v1
from ironic.api.controllers import version from ironic.api.controllers import version
from ironic.api import method from ironic.api import method
V1 = v1.Controller()
def root(): def root():
return { return {
'name': "OpenStack Ironic API", 'name': "OpenStack Ironic API",
@ -32,22 +34,32 @@ def root():
} }
class RootController(rest.RestController): class RootController(object):
v1 = v1.Controller()
@method.expose() @method.expose()
def get(self): def index(self, *args):
if args:
pecan.abort(404)
return root() return root()
@pecan.expose() @pecan.expose()
def _route(self, args, request=None): def _lookup(self, primary_key, *remainder):
"""Overrides the default routing behavior. """Overrides the default routing behavior.
It redirects the request to the default version of the ironic API It redirects the request to the default version of the ironic API
if the version number is not specified in the url. if the version number is not specified in the url.
""" """
if args[0] and args[0] != version.ID_VERSION1: # support paths which are missing the first version element
args = [version.ID_VERSION1] + args if primary_key and primary_key != version.ID_VERSION1:
return super(RootController, self)._route(args, request) remainder = [primary_key] + list(remainder)
# remove any trailing /
if remainder and not remainder[-1]:
remainder = remainder[:-1]
# but ensure /v1 goes to /v1/
if not remainder:
remainder = ['']
return V1, remainder