From 8fb798fb938bab66a11377c89b0363c115359e13 Mon Sep 17 00:00:00 2001 From: Ricardo Dias Date: Fri, 27 Apr 2018 22:15:04 +0100 Subject: [PATCH] mgr/dashboard: removed browsable api Signed-off-by: Ricardo Dias --- qa/tasks/mgr/dashboard/test_auth.py | 2 - .../mgr/dashboard/controllers/__init__.py | 178 ------------------ .../mgr/dashboard/tests/test_exceptions.py | 5 - src/pybind/mgr/dashboard/tests/test_tools.py | 18 -- 4 files changed, 203 deletions(-) diff --git a/qa/tasks/mgr/dashboard/test_auth.py b/qa/tasks/mgr/dashboard/test_auth.py index 1c71687a4d1f8..29350e2dc92c2 100644 --- a/qa/tasks/mgr/dashboard/test_auth.py +++ b/qa/tasks/mgr/dashboard/test_auth.py @@ -72,5 +72,3 @@ class AuthTest(DashboardTestCase): def test_unauthorized(self): self._get("/api/host") self.assertStatus(401) - self._get("/api") - self.assertStatus(401) diff --git a/src/pybind/mgr/dashboard/controllers/__init__.py b/src/pybind/mgr/dashboard/controllers/__init__.py index 019bff55722d8..db6b52defb1ba 100644 --- a/src/pybind/mgr/dashboard/controllers/__init__.py +++ b/src/pybind/mgr/dashboard/controllers/__init__.py @@ -116,9 +116,6 @@ def generate_routes(url_prefix): for ctrl in ctrls: generate_controller_routes(ctrl, mapper, "{}/api".format(url_prefix)) - mapper.connect(ApiRoot.__name__, "{}/api".format(url_prefix), - controller=ApiRoot("{}/api".format(url_prefix), - ctrls)) return mapper @@ -128,170 +125,6 @@ def json_error_page(status, message, traceback, version): version=version)) -class ApiRoot(object): - - _cp_config = { - 'tools.sessions.on': True, - 'tools.authenticate.on': True - } - - def __init__(self, base_url, ctrls): - self.base_url = base_url - self.ctrls = ctrls - - def __call__(self): - tpl = """API Endpoints:
- - """ - endpoints = ['
  • {}
  • ' - .format(self.base_url, ctrl._cp_path_, ctrl.__name__) for - ctrl in self.ctrls] - return tpl.format(lis='\n'.join(endpoints)) - - -def browsable_api_view(meth): - @wraps(meth) - def wrapper(self, *vpath, **kwargs): - assert isinstance(self, BaseController) - if not Settings.ENABLE_BROWSABLE_API: - return meth(self, *vpath, **kwargs) - if 'text/html' not in cherrypy.request.headers.get('Accept', ''): - return meth(self, *vpath, **kwargs) - - if '_method' in kwargs: - cherrypy.request.method = kwargs.pop('_method').upper() - - # Form typically use None as default, but HTML defaults to empty-string. - for k in kwargs: - if not kwargs[k]: - del kwargs[k] - - if '_raw' in kwargs: - kwargs.pop('_raw') - return meth(self, *vpath, **kwargs) - - sub_path = cherrypy.request.path_info.split(self._cp_path_, 1)[-1].strip('/').split('/') - - template = """ - -

    Browsable API

    - {docstring} -

    Request

    -

    {method} {breadcrump}

    - {params} -

    Response

    -

    Status: {status_code}

    -

    {reponse_headers}
    -
    - - -
    -

    Data

    -
    {data}
    - {exception} - {create_form} - {delete_form} -

    Note

    -

    Please note that this API is not an official Ceph REST API to be - used by third-party applications. It's primary purpose is to serve - the requirements of the Ceph Dashboard and is subject to change at - any time. Use at your own risk.

    - """ - - create_form_template = """ -

    Create Form

    -
    - {fields}
    - - -
    - """ - - delete_form_template = """ -

    Create Form

    -
    - - -
    - """ - - def mk_exception(e): - except_template = """ -

    Exception: {etype}: {tostr}

    -
    {trace}
    - """ - import traceback - tb = sys.exc_info()[2] - cherrypy.response.headers['Content-Type'] = 'text/html' - return except_template.format( - etype=e.__class__.__name__, - tostr=str(e), - trace='\n'.join(traceback.format_tb(tb)), - kwargs=kwargs - ) - - try: - data = meth(self, *vpath, **kwargs) - exception = '' - if cherrypy.response.headers['Content-Type'] == 'application/json': - try: - data = json.dumps(json.loads(data), indent=2, sort_keys=True) - except Exception: # pylint: disable=broad-except - pass - except (ViewCacheNoDataException, DashboardException) as e: - cherrypy.response.status = getattr(e, 'status', 400) - data = str(serialize_dashboard_exception(e)) - exception = mk_exception(e) - except Exception as e: # pylint: disable=broad-except - data = '' - exception = mk_exception(e) - - try: - create = getattr(self, 'create') - f_args = RESTController._function_args(create) - input_fields = ['{name}:'.format(name=name) for name in - f_args] - create_form = create_form_template.format( - fields='
    '.join(input_fields), - path=self._cp_path_, - sub_path='/'.join(sub_path) - ) - except AttributeError: - create_form = '' - - def mk_breadcrump(elems): - return '/'.join([ - '{}'.format('/'.join(elems[0:i+1]), e) - for i, e in enumerate(elems) - ]) - - cherrypy.response.headers['Content-Type'] = 'text/html' - return template.format( - docstring='
    {}
    '.format(self.__doc__) if self.__doc__ else '', - method=cherrypy.request.method, - path=self._cp_path_, - sub_path='/'.join(sub_path), - breadcrump=mk_breadcrump(['api', self._cp_path_] + list(sub_path)), - status_code=cherrypy.response.status, - reponse_headers='\n'.join( - '{}: {}'.format(k, v) for k, v in cherrypy.response.headers.items()), - data=data, - exception=exception, - create_form=create_form, - delete_form=delete_form_template.format(path=self._cp_path_, sub_path='/'.join( - sub_path)) if sub_path else '', - params='

    Rrequest Params

    {}
    '.format( - json.dumps(kwargs, indent=2)) if kwargs else '', - ) - - wrapper.exposed = True - if hasattr(meth, '_cp_config'): - wrapper._cp_config = meth._cp_config - return wrapper - - class Task(object): def __init__(self, name, metadata, wait_for=5.0, exception_handler=None): self.name = name @@ -360,17 +193,6 @@ class Task(object): return wrapper -class BaseControllerMeta(type): - def __new__(mcs, name, bases, dct): - new_cls = type.__new__(mcs, name, bases, dct) - - for a_name, thing in new_cls.__dict__.items(): - if callable(thing) and getattr(thing, 'exposed', False): - setattr(new_cls, a_name, browsable_api_view(thing)) - return new_cls - - -@add_metaclass(BaseControllerMeta) class BaseController(object): """ Base class for all controllers providing API endpoints. diff --git a/src/pybind/mgr/dashboard/tests/test_exceptions.py b/src/pybind/mgr/dashboard/tests/test_exceptions.py index 5443cbfb2433a..4fc9ef7f8fcb6 100644 --- a/src/pybind/mgr/dashboard/tests/test_exceptions.py +++ b/src/pybind/mgr/dashboard/tests/test_exceptions.py @@ -126,11 +126,6 @@ class RESTControllerTest(ControllerTestCase): {'detail': '[errno -42] list', 'code': "42", 'component': 'foo'} ) - def test_error_send_command_bowsable_api(self): - self.getPage('/foo/error_send_command', headers=[('Accept', 'text/html')]) - for err in ["'detail': '[errno -42] hi'", "'component': 'foo'"]: - self.assertIn(err.replace("'", "\'").encode('utf-8'), self.body) - def test_error_foo_generic(self): self._get('/foo/error_generic') self.assertJsonBody({'detail': 'hi', 'code': 'Error', 'component': None}) diff --git a/src/pybind/mgr/dashboard/tests/test_tools.py b/src/pybind/mgr/dashboard/tests/test_tools.py index 72e6dc0bbb750..0972c51008cf4 100644 --- a/src/pybind/mgr/dashboard/tests/test_tools.py +++ b/src/pybind/mgr/dashboard/tests/test_tools.py @@ -137,24 +137,6 @@ class RESTControllerTest(ControllerTestCase): self._post('/foo/1/detail', 'post-data') self.assertStatus(404) - # def test_developer_page(self): - # self.getPage('/foo', headers=[('Accept', 'text/html')]) - # self.assertIn('

    GET', self.body.decode('utf-8')) - # self.assertIn('Content-Type: text/html', self.body.decode('utf-8')) - # self.assertIn('

    ', self.body.decode('utf-8')) - # self.assertIn('', - # self.body.decode('utf-8')) - - # def test_developer_exception_page(self): - # self.getPage('/foo', - # headers=[('Accept', 'text/html'), ('Content-Length', '0')], - # method='put') - # self.assertStatus(404) - - def test_create_form(self): - self.getPage('/fooargs', headers=[('Accept', 'text/html')]) - self.assertIn('my_arg_name', self.body.decode('utf-8')) - def test_generate_controller_routes(self): # We just need to add this controller in setup_server(): # noinspection PyStatementEffect -- 2.39.5