From bf15520119f482a96730337367cf7f7ed192d979 Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Tue, 14 Jul 2020 09:49:53 +1200 Subject: [PATCH] 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 --- ironic/api/controllers/root.py | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/ironic/api/controllers/root.py b/ironic/api/controllers/root.py index 440e10000f..88681874e2 100644 --- a/ironic/api/controllers/root.py +++ b/ironic/api/controllers/root.py @@ -15,13 +15,15 @@ # under the License. import pecan -from pecan import rest from ironic.api.controllers import v1 from ironic.api.controllers import version from ironic.api import method +V1 = v1.Controller() + + def root(): return { 'name': "OpenStack Ironic API", @@ -32,22 +34,32 @@ def root(): } -class RootController(rest.RestController): - - v1 = v1.Controller() +class RootController(object): @method.expose() - def get(self): + def index(self, *args): + if args: + pecan.abort(404) return root() @pecan.expose() - def _route(self, args, request=None): + def _lookup(self, primary_key, *remainder): """Overrides the default routing behavior. It redirects the request to the default version of the ironic API if the version number is not specified in the url. """ - if args[0] and args[0] != version.ID_VERSION1: - args = [version.ID_VERSION1] + args - return super(RootController, self)._route(args, request) + # support paths which are missing the first version element + if primary_key and primary_key != version.ID_VERSION1: + 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