import ast
+from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import uuidutils
import webob
from cinder.volume import volume_types
+query_volume_filters_opt = cfg.ListOpt('query_volume_filters',
+ default=['name', 'status', 'metadata',
+ 'availability_zone'],
+ help="Volume filter options which "
+ "non-admin user could use to "
+ "query volumes. Default values "
+ "are: ['name', 'status', "
+ "'metadata', 'availability_zone']")
+
+CONF = cfg.CONF
+CONF.register_opt(query_volume_filters_opt)
+
LOG = logging.getLogger(__name__)
SCHEDULER_HINTS_NAMESPACE =\
"http://docs.openstack.org/block-service/ext/scheduler-hints/api/v2"
def _get_volume_filter_options(self):
"""Return volume search options allowed by non-admin."""
- return ('name', 'status', 'metadata')
+ return CONF.query_volume_filters
@wsgi.serializers(xml=VolumeTemplate)
def update(self, req, id, body):
sort_keys=['created_at'], sort_dirs=['desc'],
filters={'display_name': 'd-'}, viewable_admin_meta=True)
+ @mock.patch('cinder.volume.api.API.get_all')
+ def test_get_volumes_filter_with_status(self, get_all):
+ req = mock.MagicMock()
+ ctxt = context.RequestContext('fake', 'fake', auth_token=True)
+ req.environ = {'cinder.context': ctxt}
+ req.params = {'status': 'available'}
+ self.controller._view_builder.detail_list = mock.Mock()
+ self.controller._get_volumes(req, True)
+ get_all.assert_called_once_with(
+ ctxt, None, None,
+ sort_keys=['created_at'], sort_dirs=['desc'],
+ filters={'status': 'available'}, viewable_admin_meta=True)
+
+ @mock.patch('cinder.volume.api.API.get_all')
+ def test_get_volumes_filter_with_metadata(self, get_all):
+ req = mock.MagicMock()
+ ctxt = context.RequestContext('fake', 'fake', auth_token=True)
+ req.environ = {'cinder.context': ctxt}
+ req.params = {'metadata': "{'fake_key': 'fake_value'}"}
+ self.controller._view_builder.detail_list = mock.Mock()
+ self.controller._get_volumes(req, True)
+ get_all.assert_called_once_with(
+ ctxt, None, None,
+ sort_keys=['created_at'], sort_dirs=['desc'],
+ filters={'metadata': {'fake_key': 'fake_value'}},
+ viewable_admin_meta=True)
+
+ @mock.patch('cinder.volume.api.API.get_all')
+ def test_get_volumes_filter_with_availability_zone(self, get_all):
+ req = mock.MagicMock()
+ ctxt = context.RequestContext('fake', 'fake', auth_token=True)
+ req.environ = {'cinder.context': ctxt}
+ req.params = {'availability_zone': 'nova'}
+ self.controller._view_builder.detail_list = mock.Mock()
+ self.controller._get_volumes(req, True)
+ get_all.assert_called_once_with(
+ ctxt, None, None,
+ sort_keys=['created_at'], sort_dirs=['desc'],
+ filters={'availability_zone': 'nova'}, viewable_admin_meta=True)
+
+ @mock.patch('cinder.volume.api.API.get_all')
+ def test_get_volumes_filter_with_invalid_filter(self, get_all):
+ req = mock.MagicMock()
+ ctxt = context.RequestContext('fake', 'fake', auth_token=True)
+ req.environ = {'cinder.context': ctxt}
+ req.params = {'invalid_filter': 'invalid',
+ 'availability_zone': 'nova'}
+ self.controller._view_builder.detail_list = mock.Mock()
+ self.controller._get_volumes(req, True)
+ get_all.assert_called_once_with(
+ ctxt, None, None,
+ sort_keys=['created_at'], sort_dirs=['desc'],
+ filters={'availability_zone': 'nova'}, viewable_admin_meta=True)
+
+ def test_get_volume_filter_options_using_config(self):
+ self.override_config('query_volume_filters', ['name', 'status',
+ 'metadata'])
+ self.assertEqual(['name', 'status', 'metadata'],
+ self.controller._get_volume_filter_options())
+
class VolumeSerializerTest(test.TestCase):
def _verify_volume_attachment(self, attach, tree):