From: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
GET filter parameter will take effect in two places:
1. process of query resources
2. final resource infomation filtering
If you are adding some collection of get param,
pls explicity add its param to API.json and wrap its model
to accept filter param.
Then we can call it like:
GET /collection?filter_field=value
Signed-off-by: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
---
src/kimchi/control/base.py | 24 ++++++++++++++++--------
src/kimchi/control/storagepools.py | 4 ++--
src/kimchi/control/storagevolumes.py | 2 +-
src/kimchi/control/utils.py | 7 +++++++
4 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/src/kimchi/control/base.py b/src/kimchi/control/base.py
index 185c8d8..ce3101d 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, get_query_params, 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)
res_list = []
for ident in idents:
# internal text, get_list changes ident to unicode for sorted
@@ -234,19 +234,27 @@ 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)
+ if all(key not in res.data or res.data[key] == val \
+ for key, val in filter_params.iteritems()):
+ data.append(res.data)
+ return data
+
+ def get(self, filter_params):
+ resources = self._get_resources(filter_params)
+ data = self.filter_data(resources, filter_params)
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 = get_query_params()
+ 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 814ba20..28733e2 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 get_query_params():
+ return cherrypy.request.params
def internal_redirect(url):
raise cherrypy.InternalRedirect(url.encode("utf-8"))
@@ -98,6 +100,11 @@ def validate_params(params, instance, action):
validator = Draft3Validator(api_schema, format_checker=FormatChecker())
request = {operation: params}
+ if (params and action in ['get_list'] and
+ operation not in validator.schema['properties']):
+ # get_list method does not allow parameter by default
+ raise InvalidParameter("%s does not support param %s" % (operation,
params))
+
try:
validator.validate(request)
except ValidationError:
--
1.8.1.2