From 569958628881cb6f1b521510b473ab092e3d87ec Mon Sep 17 00:00:00 2001 From: Patrick Nawracay Date: Wed, 7 Feb 2018 15:56:51 +0100 Subject: [PATCH] mgr/dashboard_v2: Add support for nested controllers The `ApiController` decorator is used to define a API endpoints. This change will enable to use `/` in paths, so that nested controllers can be used. Signed-off-by: Patrick Nawracay --- .../mgr/dashboard_v2/controllers/rgw.py | 9 +++---- src/pybind/mgr/dashboard_v2/module.py | 25 ++++++++++++++++--- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/pybind/mgr/dashboard_v2/controllers/rgw.py b/src/pybind/mgr/dashboard_v2/controllers/rgw.py index 3ee8fcb9085..900d5b66a5b 100644 --- a/src/pybind/mgr/dashboard_v2/controllers/rgw.py +++ b/src/pybind/mgr/dashboard_v2/controllers/rgw.py @@ -10,16 +10,13 @@ from .. import logger @ApiController('rgw') @AuthRequired() class Rgw(RESTController): - - def __init__(self): - self.daemon = RgwDaemon(self.mgr) + pass +@ApiController('rgw/daemon') +@AuthRequired() class RgwDaemon(RESTController): - def __init__(self, mgr): - RgwDaemon.mgr = mgr - def list(self): daemons = [] for server in self.mgr.list_servers(): diff --git a/src/pybind/mgr/dashboard_v2/module.py b/src/pybind/mgr/dashboard_v2/module.py index a9034bd6094..dfe11bf6067 100644 --- a/src/pybind/mgr/dashboard_v2/module.py +++ b/src/pybind/mgr/dashboard_v2/module.py @@ -154,11 +154,30 @@ class Module(MgrModule): def __init__(self, mgrmod): self.ctrls = load_controllers(mgrmod) logger.debug('Loaded controllers: %s', self.ctrls) - for ctrl in self.ctrls: + + first_level_ctrls = [ctrl for ctrl in self.ctrls + if '/' not in ctrl._cp_path_] + multi_level_ctrls = set(self.ctrls).difference(first_level_ctrls) + + for ctrl in first_level_ctrls: logger.info('Adding controller: %s -> /api/%s', ctrl.__name__, ctrl._cp_path_) - ins = ctrl() - setattr(Module.ApiRoot, ctrl._cp_path_, ins) + inst = ctrl() + setattr(Module.ApiRoot, ctrl._cp_path_, inst) + + for ctrl in multi_level_ctrls: + path_parts = ctrl._cp_path_.split('/') + path = '/'.join(path_parts[:-1]) + key = path_parts[-1] + parent_ctrl_classes = [c for c in self.ctrls + if c._cp_path_ == path] + if len(parent_ctrl_classes) != 1: + logger.error('No parent controller found for {}! ' + 'Please check your path in the ApiController ' + 'decorator!'.format(ctrl)) + else: + inst = ctrl() + setattr(parent_ctrl_classes[0], key, inst) @cherrypy.expose def index(self): -- 2.39.5