summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Meade <alex.meade@rackspace.com>2011-05-24 16:44:28 -0400
committerAlex Meade <alex.meade@rackspace.com>2011-05-24 16:44:28 -0400
commitf488576ae27f8eb96a04022d0ecd11a28bd15116 (patch)
tree04e0693a78a566ae1cb86b62a10626490d04a470
parente1795bd73c71a20290bc988c410e0cc30afe6bd8 (diff)
downloadnova-f488576ae27f8eb96a04022d0ecd11a28bd15116.tar.gz
nova-f488576ae27f8eb96a04022d0ecd11a28bd15116.tar.xz
nova-f488576ae27f8eb96a04022d0ecd11a28bd15116.zip
Added filtering on image properties
-rw-r--r--nova/api/openstack/images.py23
-rw-r--r--nova/image/fake.py4
-rw-r--r--nova/image/glance.py8
-rw-r--r--nova/tests/api/openstack/fakes.py4
-rw-r--r--nova/tests/api/openstack/test_images.py9
-rw-r--r--nova/tests/image/test_glance.py2
6 files changed, 39 insertions, 11 deletions
diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py
index 34d4c27fc..755ce8ead 100644
--- a/nova/api/openstack/images.py
+++ b/nova/api/openstack/images.py
@@ -28,6 +28,9 @@ from nova.api.openstack.views import images as images_view
LOG = log.getLogger('nova.api.openstack.images')
FLAGS = flags.FLAGS
+SUPPORTED_FILTERS = ['name', 'status', 'container_format', 'disk_format',
+ 'size_min', 'size_max']
+
class Controller(common.OpenstackController):
"""Base `wsgi.Controller` for retrieving/displaying images."""
@@ -59,7 +62,8 @@ class Controller(common.OpenstackController):
:param req: `wsgi.Request` object
"""
context = req.environ['nova.context']
- images = self._image_service.index(context)
+ filters = self._get_filters(req)
+ images = self._image_service.index(context, filters)
images = common.limited(images, req)
builder = self.get_builder(req).build
return dict(images=[builder(image, detail=False) for image in images])
@@ -70,11 +74,26 @@ class Controller(common.OpenstackController):
:param req: `wsgi.Request` object.
"""
context = req.environ['nova.context']
- images = self._image_service.detail(context)
+ filters = self._get_filters(req)
+ images = self._image_service.detail(context, filters)
images = common.limited(images, req)
builder = self.get_builder(req).build
return dict(images=[builder(image, detail=True) for image in images])
+ def _get_filters(self, req):
+ """
+ Return a dictionary of query param filters from the request
+
+ :param req: the Request object coming from the wsgi layer
+ :retval a dict of key/value filters
+ """
+ filters = {}
+ for param in req.str_params:
+ if param in SUPPORTED_FILTERS or param.startswith('property-'):
+ filters[param] = req.str_params.get(param)
+
+ return filters
+
def show(self, req, id):
"""Return detailed information about a specific image.
diff --git a/nova/image/fake.py b/nova/image/fake.py
index b400b2adb..8e84c8597 100644
--- a/nova/image/fake.py
+++ b/nova/image/fake.py
@@ -52,11 +52,11 @@ class FakeImageService(service.BaseImageService):
self.create(None, image)
super(FakeImageService, self).__init__()
- def index(self, context):
+ def index(self, context, filters=None):
"""Returns list of images."""
return copy.deepcopy(self.images.values())
- def detail(self, context):
+ def detail(self, context, filters=None):
"""Return list of detailed image information."""
return copy.deepcopy(self.images.values())
diff --git a/nova/image/glance.py b/nova/image/glance.py
index 193e37273..dec797619 100644
--- a/nova/image/glance.py
+++ b/nova/image/glance.py
@@ -58,23 +58,23 @@ class GlanceImageService(service.BaseImageService):
else:
self.client = client
- def index(self, context):
+ def index(self, context, filters=None):
"""Calls out to Glance for a list of images available."""
# NOTE(sirp): We need to use `get_images_detailed` and not
# `get_images` here because we need `is_public` and `properties`
# included so we can filter by user
filtered = []
- image_metas = self.client.get_images_detailed()
+ image_metas = self.client.get_images_detailed(filters=filters)
for image_meta in image_metas:
if self._is_image_available(context, image_meta):
meta_subset = utils.subset_dict(image_meta, ('id', 'name'))
filtered.append(meta_subset)
return filtered
- def detail(self, context):
+ def detail(self, context, filters=None):
"""Calls out to Glance for a list of detailed image information."""
filtered = []
- image_metas = self.client.get_images_detailed()
+ image_metas = self.client.get_images_detailed(filters=filters)
for image_meta in image_metas:
if self._is_image_available(context, image_meta):
base_image_meta = self._translate_to_base(image_meta)
diff --git a/nova/tests/api/openstack/fakes.py b/nova/tests/api/openstack/fakes.py
index bf51239e6..8e0156afa 100644
--- a/nova/tests/api/openstack/fakes.py
+++ b/nova/tests/api/openstack/fakes.py
@@ -166,11 +166,11 @@ def stub_out_glance(stubs, initial_fixtures=None):
def __init__(self, initial_fixtures):
self.fixtures = initial_fixtures or []
- def fake_get_images(self):
+ def fake_get_images(self, filters=None):
return [dict(id=f['id'], name=f['name'])
for f in self.fixtures]
- def fake_get_images_detailed(self):
+ def fake_get_images_detailed(self, filters=None):
return copy.deepcopy(self.fixtures)
def fake_get_image_meta(self, image_id):
diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py
index 2c329f920..76d4e2f56 100644
--- a/nova/tests/api/openstack/test_images.py
+++ b/nova/tests/api/openstack/test_images.py
@@ -708,6 +708,15 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
self.assertDictListMatch(expected, response_list)
+ def test_get_image_request_filters(self):
+ request =\
+ webob.Request.blank('/v1.1/images/detail?status=ACTIVE&name=testname')
+ filters = images.Controller()._get_filters(request)
+ expected = {'status': 'ACTIVE',
+ 'name': 'testname',
+ }
+ self.assertDictMatch(expected, filters)
+
def test_get_image_found(self):
req = webob.Request.blank('/v1.0/images/123')
res = req.get_response(fakes.wsgi_app())
diff --git a/nova/tests/image/test_glance.py b/nova/tests/image/test_glance.py
index 109905ded..6d108d494 100644
--- a/nova/tests/image/test_glance.py
+++ b/nova/tests/image/test_glance.py
@@ -34,7 +34,7 @@ class StubGlanceClient(object):
def get_image_meta(self, image_id):
return self.images[image_id]
- def get_images_detailed(self):
+ def get_images_detailed(self, filters=None):
return self.images.itervalues()
def get_image(self, image_id):