Pass query parameters in GET request to list handler

To support query parameters in list APIs this patch enables the Flask
Blueprint to pass the parameters to its handler method.

Partially Implements: blueprint resource-allocation-api
Change-Id: I47cbded4eb8531dab2aa8cbb8e43a68caa535fc2
This commit is contained in:
Masahito Muroi 2018-07-06 17:08:20 +09:00 committed by Pierre Riteau
parent 37ff8b22b7
commit 848a68783e
13 changed files with 39 additions and 25 deletions

View File

@ -31,14 +31,15 @@ class API(object):
# Leases operations
@policy.authorize('leases', 'get')
def get_leases(self):
def get_leases(self, query):
"""List all existing leases."""
ctx = context.current()
if policy.enforce(ctx, 'admin', {}, do_raise=False):
project_id = None
else:
project_id = ctx.project_id
return self.manager_rpcapi.list_leases(project_id=project_id)
return self.manager_rpcapi.list_leases(project_id=project_id,
query=query)
@policy.authorize('leases', 'post')
@trusts.use_trust_auth()

View File

@ -28,10 +28,10 @@ _api = utils.LazyProxy(service.API)
# Leases operations
@rest.get('/leases')
def leases_list():
@rest.get('/leases', query=True)
def leases_list(query):
"""List all existing leases."""
return api_utils.render(leases=_api.get_leases())
return api_utils.render(leases=_api.get_leases(query))
@rest.post('/leases')

View File

@ -23,9 +23,9 @@ class API(object):
self.manager_rpcapi = manager_rpcapi.ManagerRPCAPI()
@policy.authorize('oshosts', 'get')
def get_computehosts(self):
def get_computehosts(self, query):
"""List all existing computehosts."""
return self.manager_rpcapi.list_computehosts()
return self.manager_rpcapi.list_computehosts(query=query)
@policy.authorize('oshosts', 'post')
@trusts.use_trust_auth()

View File

@ -25,10 +25,10 @@ _api = utils.LazyProxy(service.API)
# Computehosts operations
@rest.get('')
def computehosts_list():
@rest.get('', query=True)
def computehosts_list(query=None):
"""List all existing computehosts."""
return api_utils.render(hosts=_api.get_computehosts())
return api_utils.render(hosts=_api.get_computehosts(query))
@rest.post('')

View File

@ -33,8 +33,12 @@ LOG = logging.getLogger(__name__)
class Rest(flask.Blueprint):
"""REST helper class."""
def get(self, rule, status_code=200):
return self._mroute('GET', rule, status_code)
def __init__(self, *args, **kwargs):
super(Rest, self).__init__(*args, **kwargs)
self.routes_with_query_support = []
def get(self, rule, status_code=200, query=False):
return self._mroute('GET', rule, status_code, query=query)
def post(self, rule, status_code=201):
return self._mroute('POST', rule, status_code)
@ -55,13 +59,13 @@ class Rest(flask.Blueprint):
"""Routes REST method and its params to the actual request."""
status = options.pop('status_code', None)
file_upload = options.pop('file_upload', False)
query = options.pop('query', False)
def decorator(func):
endpoint = options.pop('endpoint', func.__name__)
def handler(**kwargs):
LOG.debug("Rest.route.decorator.handler, kwargs=%s", kwargs)
_init_resp_type(file_upload)
# update status code
@ -71,6 +75,10 @@ class Rest(flask.Blueprint):
if flask.request.method in ['POST', 'PUT']:
kwargs['data'] = request_data()
if flask.request.endpoint in self.routes_with_query_support:
params = {k: v for k, v in get_request_args().items()}
kwargs['query'] = params
with context.ctx_from_headers(flask.request.headers):
try:
return func(**kwargs)
@ -103,6 +111,9 @@ class Rest(flask.Blueprint):
except Exception as e:
return internal_error(500, 'Internal Server Error', e)
if query:
self.routes_with_query_support.append(
'.'.join([self.name, endpoint]))
self.add_url_rule(rule, endpoint, handler, **options)
self.add_url_rule(rule + '.json', endpoint, handler, **options)

View File

@ -30,9 +30,9 @@ class ManagerRPCAPI(service.RPCClient):
"""Get detailed info about some lease."""
return self.call('get_lease', lease_id=lease_id)
def list_leases(self, project_id=None):
def list_leases(self, project_id=None, query=None):
"""List all leases."""
return self.call('list_leases', project_id=project_id)
return self.call('list_leases', project_id=project_id, query=query)
def create_lease(self, lease_values):
"""Create lease with specified parameters."""

View File

@ -37,9 +37,9 @@ class ManagerRPCAPI(service.RPCClient):
"""Get detailed info about some computehost."""
return self.call('physical:host:get_computehost', host_id=host_id)
def list_computehosts(self):
def list_computehosts(self, query=None):
"""List all computehosts."""
return self.call('physical:host:list_computehosts')
return self.call('physical:host:list_computehosts', query=query)
def create_computehost(self, host_values):
"""Create computehost with specified parameters."""

View File

@ -215,7 +215,7 @@ class ManagerService(service_utils.RPCServer):
def get_lease(self, lease_id):
return db_api.lease_get(lease_id)
def list_leases(self, project_id=None):
def list_leases(self, project_id=None, query=None):
return db_api.lease_list(project_id)
def create_lease(self, lease_values):

View File

@ -317,7 +317,7 @@ class PhysicalHostPlugin(base.BasePlugin, nova.NovaClientWrapper):
else:
return host
def list_computehosts(self):
def list_computehosts(self, query=None):
raw_host_list = db_api.host_list()
host_list = []
for host in raw_host_list:

View File

@ -36,8 +36,8 @@ class RESTApiTestCase(tests.TestCase):
self.fake_id = '1'
def test_lease_list(self):
self.api.leases_list()
self.render.assert_called_once_with(leases=self.get_leases())
self.api.leases_list(query={})
self.render.assert_called_once_with(leases=self.get_leases(query={}))
def test_leases_create(self):
self.api.leases_create(data=None)

View File

@ -40,8 +40,9 @@ class RESTApiTestCase(tests.TestCase):
self.fake_id = '1'
def test_computehost_list(self):
self.api.computehosts_list()
self.render.assert_called_once_with(hosts=self.get_computehosts())
self.api.computehosts_list(query={})
self.render.assert_called_once_with(
hosts=self.get_computehosts(query={}))
def test_computehosts_create(self):
self.api.computehosts_create(data=None)

View File

@ -36,7 +36,8 @@ class RPCAPITestCase(tests.TestCase):
def test_list_leases(self):
self.manager.list_leases('fake')
self.call.assert_called_once_with('list_leases', project_id='fake')
self.call.assert_called_once_with('list_leases', project_id='fake',
query=None)
def test_create_lease(self):
self.manager.create_lease(self.fake_values)

View File

@ -210,7 +210,7 @@ class PhysicalHostPluginTestCase(tests.TestCase):
@testtools.skip('incorrect decorator')
def test_list_hosts(self):
self.fake_phys_plugin.list_computehosts()
self.fake_phys_plugin.list_computehosts({})
self.db_host_list.assert_called_once_with()
del self.service_utils