summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/api/rackspace/__init__.py20
-rw-r--r--nova/api/rackspace/flavors.py5
-rw-r--r--nova/api/rackspace/images.py2
-rw-r--r--nova/api/rackspace/servers.py18
-rw-r--r--nova/tests/api/rackspace/__init__.py29
5 files changed, 67 insertions, 7 deletions
diff --git a/nova/api/rackspace/__init__.py b/nova/api/rackspace/__init__.py
index c85e90ab9..89a4693ad 100644
--- a/nova/api/rackspace/__init__.py
+++ b/nova/api/rackspace/__init__.py
@@ -168,3 +168,23 @@ class APIRouter(wsgi.Router):
controller=sharedipgroups.Controller())
super(APIRouter, self).__init__(mapper)
+
+
+def limited(items, req):
+ """Return a slice of items according to requested offset and limit.
+
+ items - a sliceable
+ req - wobob.Request possibly containing offset and limit GET variables.
+ offset is where to start in the list, and limit is the maximum number
+ of items to return.
+
+ If limit is not specified, 0, or > 1000, defaults to 1000.
+ """
+ offset = int(req.GET.get('offset', 0))
+ limit = int(req.GET.get('limit', 0))
+ if not limit:
+ limit = 1000
+ limit = min(1000, limit)
+ range_end = offset + limit
+ return items[offset:range_end]
+
diff --git a/nova/api/rackspace/flavors.py b/nova/api/rackspace/flavors.py
index 556a7b471..916449854 100644
--- a/nova/api/rackspace/flavors.py
+++ b/nova/api/rackspace/flavors.py
@@ -15,10 +15,12 @@
# License for the specific language governing permissions and limitations
# under the License.
+from webob import exc
+
from nova.api.rackspace import faults
from nova.compute import instance_types
from nova import wsgi
-from webob import exc
+import nova.api.rackspace
class Controller(wsgi.Controller):
"""Flavor controller for the Rackspace API."""
@@ -39,6 +41,7 @@ class Controller(wsgi.Controller):
def detail(self, req):
"""Return all flavors in detail."""
items = [self.show(req, id)['flavor'] for id in self._all_ids()]
+ items = nova.api.rackspace.limited(items, req)
return dict(flavors=items)
def show(self, req, id):
diff --git a/nova/api/rackspace/images.py b/nova/api/rackspace/images.py
index 2e2cc0c6b..4a7dd489c 100644
--- a/nova/api/rackspace/images.py
+++ b/nova/api/rackspace/images.py
@@ -19,6 +19,7 @@ from webob import exc
from nova import wsgi
from nova.api.rackspace import _id_translator
+import nova.api.rackspace
import nova.image.service
from nova.api.rackspace import faults
@@ -46,6 +47,7 @@ class Controller(wsgi.Controller):
def detail(self, req):
"""Return all public images in detail."""
data = self._service.index()
+ data = nova.api.rackspace.limited(data, req)
for img in data:
img['id'] = self._id_translator.to_rs_id(img['id'])
return dict(images=data)
diff --git a/nova/api/rackspace/servers.py b/nova/api/rackspace/servers.py
index 888d67542..08d533563 100644
--- a/nova/api/rackspace/servers.py
+++ b/nova/api/rackspace/servers.py
@@ -26,6 +26,7 @@ from nova import wsgi
from nova.api.rackspace import _id_translator
from nova.api.rackspace import faults
from nova.compute import power_state
+import nova.api.rackspace
import nova.image.service
FLAGS = flags.FLAGS
@@ -102,16 +103,21 @@ class Controller(wsgi.Controller):
def index(self, req):
""" Returns a list of server names and ids for a given user """
- user_id = req.environ['nova.context']['user']['id']
- instance_list = self.db_driver.instance_get_all_by_user(None, user_id)
- res = [_entity_inst(inst)['server'] for inst in instance_list]
- return _entity_list(res)
+ return self._items(req, entity_maker=_entity_inst)
def detail(self, req):
""" Returns a list of server details for a given user """
+ return self._items(req, entity_maker=_entity_detail)
+
+ def _items(self, req, entity_maker):
+ """Returns a list of servers for a given user.
+
+ entity_maker - either _entity_detail or _entity_inst
+ """
user_id = req.environ['nova.context']['user']['id']
- res = [_entity_detail(inst)['server'] for inst in
- self.db_driver.instance_get_all_by_user(None, user_id)]
+ instance_list = self.db_driver.instance_get_all_by_user(None, user_id)
+ limited_list = nova.api.rackspace.limited(instance_list, req)
+ res = [entity_maker(inst)['server'] for inst in limited_list]
return _entity_list(res)
def show(self, req, id):
diff --git a/nova/tests/api/rackspace/__init__.py b/nova/tests/api/rackspace/__init__.py
index 622cb4335..bfd0f87a7 100644
--- a/nova/tests/api/rackspace/__init__.py
+++ b/nova/tests/api/rackspace/__init__.py
@@ -17,6 +17,7 @@
import unittest
+from nova.api.rackspace import limited
from nova.api.rackspace import RateLimitingMiddleware
from nova.tests.api.test_helper import *
from webob import Request
@@ -77,3 +78,31 @@ class RateLimitingMiddlewareTest(unittest.TestCase):
self.assertEqual(middleware.limiter.__class__.__name__, "Limiter")
middleware = RateLimitingMiddleware(APIStub(), service_host='foobar')
self.assertEqual(middleware.limiter.__class__.__name__, "WSGIAppProxy")
+
+
+class LimiterTest(unittest.TestCase):
+
+ def testLimiter(self):
+ items = range(2000)
+ req = Request.blank('/')
+ self.assertEqual(limited(items, req), items[ :1000])
+ req = Request.blank('/?offset=0')
+ self.assertEqual(limited(items, req), items[ :1000])
+ req = Request.blank('/?offset=3')
+ self.assertEqual(limited(items, req), items[3:1003])
+ req = Request.blank('/?offset=2005')
+ self.assertEqual(limited(items, req), [])
+ req = Request.blank('/?limit=10')
+ self.assertEqual(limited(items, req), items[ :10])
+ req = Request.blank('/?limit=0')
+ self.assertEqual(limited(items, req), items[ :1000])
+ req = Request.blank('/?limit=3000')
+ self.assertEqual(limited(items, req), items[ :1000])
+ req = Request.blank('/?offset=1&limit=3')
+ self.assertEqual(limited(items, req), items[1:4])
+ req = Request.blank('/?offset=3&limit=0')
+ self.assertEqual(limited(items, req), items[3:1003])
+ req = Request.blank('/?offset=3&limit=1500')
+ self.assertEqual(limited(items, req), items[3:1003])
+ req = Request.blank('/?offset=3000&limit=10')
+ self.assertEqual(limited(items, req), [])