summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNaveed Massjouni <naveedm9@gmail.com>2011-03-18 00:18:55 -0400
committerNaveed Massjouni <naveedm9@gmail.com>2011-03-18 00:18:55 -0400
commitacb7a7355055e04b9bb05fbba5f6590e57d681fa (patch)
treee08b3e3b44fbb5bfd4d996f6108449db811167d2
parent79f2f90feec74b97d55af058c9bec4177bc47a54 (diff)
downloadnova-acb7a7355055e04b9bb05fbba5f6590e57d681fa.tar.gz
nova-acb7a7355055e04b9bb05fbba5f6590e57d681fa.tar.xz
nova-acb7a7355055e04b9bb05fbba5f6590e57d681fa.zip
Support for markers for pagination as defined in the 1.1 spec.
-rw-r--r--nova/api/openstack/common.py28
-rw-r--r--nova/api/openstack/servers.py8
-rw-r--r--nova/tests/api/openstack/test_servers.py7
3 files changed, 42 insertions, 1 deletions
diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py
index b224cbfb4..8106f841b 100644
--- a/nova/api/openstack/common.py
+++ b/nova/api/openstack/common.py
@@ -55,6 +55,34 @@ def limited(items, request, max_limit=1000):
return items[offset:range_end]
+def limited_by_marker(items, request, max_limit=1000):
+ ''' Return a slice of items according to requested marker and limit. '''
+
+ marker = request.GET.get('marker')
+
+ try:
+ limit = int(request.GET.get('limit', max_limit))
+ except ValueError:
+ raise webob.exc.HTTPBadRequest(_('limit param must be an integer'))
+
+ if limit < 0:
+ raise webob.exc.HTTPBadRequest(_('limit param must be positive'))
+
+ limit = min(max_limit, limit or max_limit)
+ start_index = 0
+ if marker != None:
+ found_it = False
+ for i, item in enumerate(items):
+ if str(item['id']) == marker:
+ start_index = i
+ found_it = True
+ break
+ if not found_it:
+ raise webob.exc.HTTPBadRequest(_('marker not found'))
+ range_end = start_index + limit
+ return items[start_index:range_end]
+
+
def get_image_id_from_image_hash(image_service, context, image_hash):
"""Given an Image ID Hash, return an objectstore Image ID.
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index e3141934b..461bf5989 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -81,7 +81,7 @@ class Controller(wsgi.Controller):
builder - the response model builder
"""
instance_list = self.compute_api.get_all(req.environ['nova.context'])
- limited_list = common.limited(instance_list, req)
+ limited_list = self._limit_items(instance_list, req)
builder = self._get_view_builder(req)
servers = [builder.build(inst, is_detail)['server']
for inst in limited_list]
@@ -528,6 +528,9 @@ class ControllerV10(Controller):
def _get_addresses_view_builder(self, req):
return nova.api.openstack.views.addresses.ViewBuilderV10(req)
+ def _limit_items(self, items, req):
+ return common.limited(items, req)
+
class ControllerV11(Controller):
def _image_id_from_req_data(self, data):
@@ -551,6 +554,9 @@ class ControllerV11(Controller):
def _get_addresses_view_builder(self, req):
return nova.api.openstack.views.addresses.ViewBuilderV11(req)
+ def _limit_items(self, items, req):
+ return common.limited_by_marker(items, req)
+
class ServerCreateRequestXMLDeserializer(object):
"""
diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py
index 6e78db9da..e1cadcef6 100644
--- a/nova/tests/api/openstack/test_servers.py
+++ b/nova/tests/api/openstack/test_servers.py
@@ -239,6 +239,13 @@ class ServersTest(test.TestCase):
servers = json.loads(res.body)['servers']
self.assertEqual([s['id'] for s in servers], [1, 2])
+ def test_get_servers_with_marker(self):
+ req = webob.Request.blank('/v1.1/servers?marker=2')
+ res = req.get_response(fakes.wsgi_app())
+ print 'body:', res.body
+ servers = json.loads(res.body)['servers']
+ self.assertEqual([s['id'] for s in servers], [2, 3, 4])
+
def _setup_for_create_instance(self):
"""Shared implementation for tests below that create instance"""
def instance_create(context, inst):