On 01/14/2014 11:47 PM, lvroyce0210(a)gmail.com wrote:
From: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
Add support for passing params for GET method,
This include add param to get_list method,
and filter the result with given params.
we will call it like:
GET /collection?filter_field=value
With current implementation with a wrapper,
we can easily support any collection query with param.
Signed-off-by: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
---
src/kimchi/control/base.py | 28 ++++++++++++++++++++--------
src/kimchi/control/storagepools.py | 4 ++--
src/kimchi/control/storagevolumes.py | 2 +-
src/kimchi/control/utils.py | 2 ++
4 files changed, 25 insertions(+), 11 deletions(-)
diff --git a/src/kimchi/control/base.py b/src/kimchi/control/base.py
index 185c8d8..a477abb 100644
--- a/src/kimchi/control/base.py
+++ b/src/kimchi/control/base.py
@@ -28,7 +28,7 @@ import urllib2
import kimchi.template
from kimchi.control.utils import get_class_name, internal_redirect, model_fn
-from kimchi.control.utils import parse_request, validate_method
+from kimchi.control.utils import parse_request, parse_param, validate_method
from kimchi.control.utils import validate_params
from kimchi.exception import InvalidOperation, InvalidParameter
from kimchi.exception import MissingParameter, NotFoundError, OperationFailed
@@ -212,10 +212,10 @@ class Collection(object):
return res.get()
- def _get_resources(self):
+ def _get_resources(self, filter_params):
try:
get_list = getattr(self.model, model_fn(self, 'get_list'))
- idents = get_list(*self.model_args)
+ idents = get_list(*self.model_args, **filter_params)
For the methods
doesn't support filter params, it will break if add a
param in url.
res_list = []
for ident in idents:
# internal text, get_list changes ident to unicode for sorted
@@ -234,19 +234,31 @@ class Collection(object):
args = self.resource_args + [ident.decode("utf-8")]
return self.resource(self.model, *args)
- def get(self):
- resources = self._get_resources()
+ def filter_data(self, resources, filter_params):
data = []
for res in resources:
- data.append(res.data)
+ valid = True
+ for key, val in filter_params.items():
+ if key in res.data and res.data[key] != val:
+ valid = False
+ break
+ if valid:
if all(key in res.data and
res.data[key] == val
for key, val in filter_params.iteritems()):
data.append(res.data)
+ data.append(res.data)
+ return data
or return [res.data for res in resources
if all(key in res.data and res.data[key] == val for
key, val in filter_params.iteritems())]
:)
+
+ def get(self, filter_params):
+ resources = self._get_resources(filter_params)
+ data = self.filter_data(resources, filter_params)
I guess there're two
kinds of filter parameters in your mind: one takes
effect during model's get_list method while the other works based the
return value from model. So please make those two params explicit and
ensure one param only can take effect in one place.
return kimchi.template.render(get_class_name(self), data)
@cherrypy.expose
- def index(self, *args):
+ def index(self, *args, **kwargs):
method = validate_method(('GET', 'POST'))
if method == 'GET':
try:
- return self.get()
+ filter_params = parse_param()
+ validate_params(filter_params, self, 'get_list')
+ return self.get(filter_params)
except InvalidOperation, param:
error = "Invalid operation: '%s'" % param
raise cherrypy.HTTPError(400, error)
diff --git a/src/kimchi/control/storagepools.py b/src/kimchi/control/storagepools.py
index 782f5a6..e3236a7 100644
--- a/src/kimchi/control/storagepools.py
+++ b/src/kimchi/control/storagepools.py
@@ -63,9 +63,9 @@ class StoragePools(Collection):
return resp
- def _get_resources(self):
+ def _get_resources(self, filter_params):
try:
- res_list = super(StoragePools, self)._get_resources()
+ res_list = super(StoragePools, self)._get_resources(filter_params)
# Append reserved pools
isos = getattr(self, ISO_POOL_NAME)
isos.lookup()
diff --git a/src/kimchi/control/storagevolumes.py b/src/kimchi/control/storagevolumes.py
index d541807..cd15bcc 100644
--- a/src/kimchi/control/storagevolumes.py
+++ b/src/kimchi/control/storagevolumes.py
@@ -70,7 +70,7 @@ class IsoVolumes(Collection):
super(IsoVolumes, self).__init__(model)
self.pool = pool
- def get(self):
+ def get(self, filter_params):
res_list = []
try:
get_list = getattr(self.model, model_fn(self, 'get_list'))
diff --git a/src/kimchi/control/utils.py b/src/kimchi/control/utils.py
index c3c5f8e..4b3c4b0 100644
--- a/src/kimchi/control/utils.py
+++ b/src/kimchi/control/utils.py
@@ -81,6 +81,8 @@ def parse_request():
raise cherrypy.HTTPError(415, "This API only supports"
" 'application/json'")
+def parse_param():
+ return cherrypy.request.params
It's not a good function name for me,
because you didn't do any parsing
in it. get_query_params or
just use cherrypy.request.params?
def internal_redirect(url):
raise cherrypy.InternalRedirect(url.encode("utf-8"))