Skip to content

Commit

Permalink
Merge pull request #23229 from rjfd/wip-dashboard-query-params-bug
Browse files Browse the repository at this point in the history
mgr/dashboard: fix query parameters in task annotated endpoints

Reviewed-by: Tiago Melo <tmelo@suse.com>
  • Loading branch information
tchaikov committed Jul 30, 2018
2 parents c13aa38 + dcbae67 commit 53951a8
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 39 deletions.
77 changes: 38 additions & 39 deletions src/pybind/mgr/dashboard/controllers/__init__.py
Expand Up @@ -257,6 +257,32 @@ def json_error_page(status, message, traceback, version):
version=version))


def _get_function_params(func):
"""
Retrieves the list of parameters declared in function.
Each parameter is represented as dict with keys:
* name (str): the name of the parameter
* required (bool): whether the parameter is required or not
* default (obj): the parameter's default value
"""
fspec = getargspec(func)

func_params = []
nd = len(fspec.args) if not fspec.defaults else -len(fspec.defaults)
for param in fspec.args[1:nd]:
func_params.append({'name': param, 'required': True})

if fspec.defaults:
for param, val in zip(fspec.args[nd:], fspec.defaults):
func_params.append({
'name': param,
'required': False,
'default': val
})

return func_params


class Task(object):
def __init__(self, name, metadata, wait_for=5.0, exception_handler=None):
self.name = name
Expand All @@ -268,24 +294,23 @@ def __init__(self, name, metadata, wait_for=5.0, exception_handler=None):
self.exception_handler = exception_handler

def _gen_arg_map(self, func, args, kwargs):
# pylint: disable=deprecated-method
arg_map = {}
if sys.version_info > (3, 0): # pylint: disable=no-else-return
sig = inspect.signature(func)
arg_list = [a for a in sig.parameters]
else:
sig = getargspec(func)
arg_list = [a for a in sig.args]
params = _get_function_params(func)

for idx, arg in enumerate(arg_list):
args = args[1:] # exclude self
for idx, param in enumerate(params):
if idx < len(args):
arg_map[arg] = args[idx]
arg_map[param['name']] = args[idx]
else:
if arg in kwargs:
arg_map[arg] = kwargs[arg]
if arg in arg_map:
if param['name'] in kwargs:
arg_map[param['name']] = kwargs[param['name']]
else:
assert not param['required']
arg_map[param['name']] = param['default']

if param['name'] in arg_map:
# This is not a type error. We are using the index here.
arg_map[idx] = arg_map[arg]
arg_map[idx+1] = arg_map[param['name']]

return arg_map

Expand Down Expand Up @@ -325,32 +350,6 @@ def wrapper(*args, **kwargs):
return wrapper


def _get_function_params(func):
"""
Retrieves the list of parameters declared in function.
Each parameter is represented as dict with keys:
* name (str): the name of the parameter
* required (bool): whether the parameter is required or not
* default (obj): the parameter's default value
"""
fspec = getargspec(func)

func_params = []
nd = len(fspec.args) if not fspec.defaults else -len(fspec.defaults)
for param in fspec.args[1:nd]:
func_params.append({'name': param, 'required': True})

if fspec.defaults:
for param, val in zip(fspec.args[nd:], fspec.defaults):
func_params.append({
'name': param,
'required': False,
'default': val
})

return func_params


class BaseController(object):
"""
Base class for all controllers providing API endpoints.
Expand Down
9 changes: 9 additions & 0 deletions src/pybind/mgr/dashboard/tests/test_rest_tasks.py
Expand Up @@ -38,6 +38,11 @@ def foo(self, param):
def bar(self, key, param=None):
return {'my_param': param, 'key': key}

@Task('task/query', ['{param}'])
@RESTController.Collection('POST', query_params=['param'])
def query(self, param=None):
return {'my_param': param}


class TaskControllerTest(ControllerTestCase):
@classmethod
Expand Down Expand Up @@ -75,3 +80,7 @@ def test_foo_task(self):
def test_bar_task(self):
self._task_put('/test/task/3/bar', {'param': 'hello'})
self.assertJsonBody({'my_param': 'hello', 'key': '3'})

def test_query_param(self):
self._task_post('/test/task/query')
self.assertJsonBody({'my_param': None})

0 comments on commit 53951a8

Please sign in to comment.