def _items(self, req, entity_maker):
"""Returns a list of volumes, transformed through entity_maker."""
+
+ search_opts = {}
+ search_opts.update(req.GET)
+
context = req.environ['cinder.context']
+ remove_invalid_options(context,
+ search_opts, self._get_volume_search_options())
- volumes = self.volume_api.get_all(context)
+ volumes = self.volume_api.get_all(context, search_opts=search_opts)
limited_list = common.limited(volumes, req)
res = [entity_maker(context, vol) for vol in limited_list]
return {'volumes': res}
return {'volume': retval}
+ def _get_volume_search_options(self):
+ """Return volume search options allowed by non-admin."""
+ return ('name', 'status')
+
def create_resource():
return wsgi.Resource(VolumeController())
+
+
+def remove_invalid_options(context, search_options, allowed_search_options):
+ """Remove search options that are not valid for non-admin API/context."""
+ if context.is_admin:
+ # Allow all options
+ return
+ # Otherwise, strip out all unknown options
+ unknown_options = [opt for opt in search_options
+ if opt not in allowed_search_options]
+ bad_options = ", ".join(unknown_options)
+ log_msg = _("Removing options '%(bad_options)s' from query") % locals()
+ LOG.debug(log_msg)
+ for opt in unknown_options:
+ search_options.pop(opt, None)
raise exc.NotFound
-def stub_volume_get_all(self, context, search_opts=None):
+def stub_volume_get_all(context, search_opts=None):
+ return [stub_volume(100, project_id='fake'),
+ stub_volume(101, project_id='superfake'),
+ stub_volume(102, project_id='superduperfake')]
+
+
+def stub_volume_get_all_by_project(self, context, search_opts=None):
return [stub_volume_get(self, context, '1')]
import webob
from cinder.api.openstack.volume import volumes
+from cinder import db
from cinder import exception
from cinder import flags
from cinder import test
super(VolumeApiTest, self).setUp()
self.controller = volumes.VolumeController()
- self.stubs.Set(volume_api.API, 'get_all', fakes.stub_volume_get_all)
+ self.stubs.Set(db, 'volume_get_all', fakes.stub_volume_get_all)
+ self.stubs.Set(db, 'volume_get_all_by_project',
+ fakes.stub_volume_get_all_by_project)
self.stubs.Set(volume_api.API, 'get', fakes.stub_volume_get)
self.stubs.Set(volume_api.API, 'delete', fakes.stub_volume_delete)
body)
def test_volume_list(self):
+ self.stubs.Set(volume_api.API, 'get_all',
+ fakes.stub_volume_get_all_by_project)
+
req = fakes.HTTPRequest.blank('/v1/volumes')
res_dict = self.controller.index(req)
expected = {'volumes': [{'status': 'fakestatus',
self.assertEqual(res_dict, expected)
def test_volume_list_detail(self):
+ self.stubs.Set(volume_api.API, 'get_all',
+ fakes.stub_volume_get_all_by_project)
req = fakes.HTTPRequest.blank('/v1/volumes/detail')
res_dict = self.controller.index(req)
expected = {'volumes': [{'status': 'fakestatus',
req,
1)
+ def test_admin_list_volumes_limited_to_project(self):
+ req = fakes.HTTPRequest.blank('/v2/fake/volumes',
+ use_admin_context=True)
+ res = self.controller.index(req)
+
+ self.assertTrue('volumes' in res)
+ self.assertEqual(1, len(res['volumes']))
+
+ def test_admin_list_volumes_all_tenants(self):
+ req = fakes.HTTPRequest.blank('/v2/fake/volumes?all_tenants=1',
+ use_admin_context=True)
+ res = self.controller.index(req)
+ self.assertTrue('volumes' in res)
+ self.assertEqual(3, len(res['volumes']))
+
+ def test_all_tenants_non_admin_gets_all_tenants(self):
+ req = fakes.HTTPRequest.blank('/v2/fake/volumes?all_tenants=1')
+ res = self.controller.index(req)
+ self.assertTrue('volumes' in res)
+ self.assertEqual(1, len(res['volumes']))
+
+ def test_non_admin_get_by_project(self):
+ req = fakes.HTTPRequest.blank('/v2/fake/volumes')
+ res = self.controller.index(req)
+ self.assertTrue('volumes' in res)
+ self.assertEqual(1, len(res['volumes']))
+
class VolumeSerializerTest(test.TestCase):
def _verify_volume_attachment(self, attach, tree):
check_policy(context, 'get', volume)
return volume
- def get_all(self, context, search_opts={}):
+ def get_all(self, context, search_opts=None):
check_policy(context, 'get_all')
- if context.is_admin:
+
+ if search_opts is None:
+ search_opts = {}
+
+ if (context.is_admin and 'all_tenants' in search_opts):
+ # Need to remove all_tenants to pass the filtering below.
+ del search_opts['all_tenants']
volumes = self.db.volume_get_all(context)
else:
volumes = self.db.volume_get_all_by_project(context,
- context.project_id)
-
+ context.project_id)
if search_opts:
LOG.debug(_("Searching by: %s") % str(search_opts))