Merge "Fix volumes search by metadata"
This commit is contained in:
commit
213ad6b8cb
@ -15,6 +15,7 @@
|
||||
|
||||
"""The volumes api."""
|
||||
|
||||
import ast
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
@ -253,6 +254,9 @@ class VolumeController(wsgi.Controller):
|
||||
search_opts = {}
|
||||
search_opts.update(req.GET)
|
||||
|
||||
if 'metadata' in search_opts:
|
||||
search_opts['metadata'] = ast.literal_eval(search_opts['metadata'])
|
||||
|
||||
context = req.environ['cinder.context']
|
||||
remove_invalid_options(context,
|
||||
search_opts, self._get_volume_search_options())
|
||||
@ -362,7 +366,7 @@ class VolumeController(wsgi.Controller):
|
||||
|
||||
def _get_volume_search_options(self):
|
||||
"""Return volume search options allowed by non-admin."""
|
||||
return ('display_name', 'status')
|
||||
return ('display_name', 'status', 'metadata')
|
||||
|
||||
@wsgi.serializers(xml=VolumeTemplate)
|
||||
def update(self, req, id, body):
|
||||
|
@ -16,6 +16,7 @@
|
||||
"""The volumes api."""
|
||||
|
||||
|
||||
import ast
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
@ -214,6 +215,9 @@ class VolumeController(wsgi.Controller):
|
||||
filters['display_name'] = filters['name']
|
||||
del filters['name']
|
||||
|
||||
if 'metadata' in filters:
|
||||
filters['metadata'] = ast.literal_eval(filters['metadata'])
|
||||
|
||||
volumes = self.volume_api.get_all(context, marker, limit, sort_key,
|
||||
sort_dir, filters)
|
||||
limited_list = common.limited(volumes, req)
|
||||
@ -322,7 +326,7 @@ class VolumeController(wsgi.Controller):
|
||||
|
||||
def _get_volume_filter_options(self):
|
||||
"""Return volume search options allowed by non-admin."""
|
||||
return ('name', 'status')
|
||||
return ('name', 'status', 'metadata')
|
||||
|
||||
@wsgi.serializers(xml=VolumeTemplate)
|
||||
def update(self, req, id, body):
|
||||
|
@ -17,6 +17,7 @@ import datetime
|
||||
|
||||
from lxml import etree
|
||||
from oslo.config import cfg
|
||||
import urllib
|
||||
import webob
|
||||
|
||||
from cinder.api import extensions
|
||||
@ -364,6 +365,64 @@ class VolumeApiTest(test.TestCase):
|
||||
resp = self.controller.index(req)
|
||||
self.assertEqual(len(resp['volumes']), 0)
|
||||
|
||||
def test_volume_list_by_metadata(self):
|
||||
def stub_volume_get_all_by_project(context, project_id, marker, limit,
|
||||
sort_key, sort_dir):
|
||||
return [
|
||||
stubs.stub_volume(1, display_name='vol1',
|
||||
status='available',
|
||||
volume_metadata=[{'key': 'key1',
|
||||
'value': 'value1'}]),
|
||||
stubs.stub_volume(2, display_name='vol2',
|
||||
status='available',
|
||||
volume_metadata=[{'key': 'key1',
|
||||
'value': 'value2'}]),
|
||||
stubs.stub_volume(3, display_name='vol3',
|
||||
status='in-use',
|
||||
volume_metadata=[{'key': 'key1',
|
||||
'value': 'value2'}]),
|
||||
]
|
||||
self.stubs.Set(db, 'volume_get_all_by_project',
|
||||
stub_volume_get_all_by_project)
|
||||
|
||||
# no metadata filter
|
||||
req = fakes.HTTPRequest.blank('/v1/volumes', use_admin_context=True)
|
||||
resp = self.controller.index(req)
|
||||
self.assertEqual(len(resp['volumes']), 3)
|
||||
|
||||
# single match
|
||||
qparams = urllib.urlencode({'metadata': {'key1': 'value1'}})
|
||||
req = fakes.HTTPRequest.blank('/v1/volumes?%s' % qparams,
|
||||
use_admin_context=True)
|
||||
resp = self.controller.index(req)
|
||||
self.assertEqual(len(resp['volumes']), 1)
|
||||
self.assertEqual(resp['volumes'][0]['display_name'], 'vol1')
|
||||
self.assertEqual(resp['volumes'][0]['metadata']['key1'], 'value1')
|
||||
|
||||
# multiple matches
|
||||
qparams = urllib.urlencode({'metadata': {'key1': 'value2'}})
|
||||
req = fakes.HTTPRequest.blank('/v1/volumes?%s' % qparams,
|
||||
use_admin_context=True)
|
||||
resp = self.controller.index(req)
|
||||
self.assertEqual(len(resp['volumes']), 2)
|
||||
for volume in resp['volumes']:
|
||||
self.assertEqual(volume['metadata']['key1'], 'value2')
|
||||
|
||||
# multiple filters
|
||||
qparams = urllib.urlencode({'metadata': {'key1': 'value2'}})
|
||||
req = fakes.HTTPRequest.blank('/v1/volumes?status=in-use&%s' % qparams,
|
||||
use_admin_context=True)
|
||||
resp = self.controller.index(req)
|
||||
self.assertEqual(len(resp['volumes']), 1)
|
||||
self.assertEqual(resp['volumes'][0]['display_name'], 'vol3')
|
||||
|
||||
# no match
|
||||
qparams = urllib.urlencode({'metadata': {'key1': 'value3'}})
|
||||
req = fakes.HTTPRequest.blank('/v1/volumes?%s' % qparams,
|
||||
use_admin_context=True)
|
||||
resp = self.controller.index(req)
|
||||
self.assertEqual(len(resp['volumes']), 0)
|
||||
|
||||
def test_volume_list_by_status(self):
|
||||
def stub_volume_get_all_by_project(context, project_id, marker, limit,
|
||||
sort_key, sort_dir):
|
||||
|
@ -18,6 +18,7 @@ import datetime
|
||||
|
||||
from lxml import etree
|
||||
from oslo.config import cfg
|
||||
import urllib
|
||||
import webob
|
||||
|
||||
from cinder.api import extensions
|
||||
@ -555,6 +556,64 @@ class VolumeApiTest(test.TestCase):
|
||||
resp = self.controller.index(req)
|
||||
self.assertEqual(len(resp['volumes']), 0)
|
||||
|
||||
def test_volume_list_by_metadata(self):
|
||||
def stub_volume_get_all_by_project(context, project_id, marker, limit,
|
||||
sort_key, sort_dir):
|
||||
return [
|
||||
stubs.stub_volume(1, display_name='vol1',
|
||||
status='available',
|
||||
volume_metadata=[{'key': 'key1',
|
||||
'value': 'value1'}]),
|
||||
stubs.stub_volume(2, display_name='vol2',
|
||||
status='available',
|
||||
volume_metadata=[{'key': 'key1',
|
||||
'value': 'value2'}]),
|
||||
stubs.stub_volume(3, display_name='vol3',
|
||||
status='in-use',
|
||||
volume_metadata=[{'key': 'key1',
|
||||
'value': 'value2'}]),
|
||||
]
|
||||
self.stubs.Set(db, 'volume_get_all_by_project',
|
||||
stub_volume_get_all_by_project)
|
||||
|
||||
# no metadata filter
|
||||
req = fakes.HTTPRequest.blank('/v2/volumes', use_admin_context=True)
|
||||
resp = self.controller.detail(req)
|
||||
self.assertEqual(len(resp['volumes']), 3)
|
||||
|
||||
# single match
|
||||
qparams = urllib.urlencode({'metadata': {'key1': 'value1'}})
|
||||
req = fakes.HTTPRequest.blank('/v2/volumes?%s' % qparams,
|
||||
use_admin_context=True)
|
||||
resp = self.controller.detail(req)
|
||||
self.assertEqual(len(resp['volumes']), 1)
|
||||
self.assertEqual(resp['volumes'][0]['name'], 'vol1')
|
||||
self.assertEqual(resp['volumes'][0]['metadata']['key1'], 'value1')
|
||||
|
||||
# multiple matches
|
||||
qparams = urllib.urlencode({'metadata': {'key1': 'value2'}})
|
||||
req = fakes.HTTPRequest.blank('/v2/volumes?%s' % qparams,
|
||||
use_admin_context=True)
|
||||
resp = self.controller.detail(req)
|
||||
self.assertEqual(len(resp['volumes']), 2)
|
||||
for volume in resp['volumes']:
|
||||
self.assertEqual(volume['metadata']['key1'], 'value2')
|
||||
|
||||
# multiple filters
|
||||
qparams = urllib.urlencode({'metadata': {'key1': 'value2'}})
|
||||
req = fakes.HTTPRequest.blank('/v2/volumes?status=in-use&%s' % qparams,
|
||||
use_admin_context=True)
|
||||
resp = self.controller.detail(req)
|
||||
self.assertEqual(len(resp['volumes']), 1)
|
||||
self.assertEqual(resp['volumes'][0]['name'], 'vol3')
|
||||
|
||||
# no match
|
||||
qparams = urllib.urlencode({'metadata': {'key1': 'value3'}})
|
||||
req = fakes.HTTPRequest.blank('/v2/volumes?%s' % qparams,
|
||||
use_admin_context=True)
|
||||
resp = self.controller.detail(req)
|
||||
self.assertEqual(len(resp['volumes']), 0)
|
||||
|
||||
def test_volume_list_by_status(self):
|
||||
def stub_volume_get_all_by_project(context, project_id, marker, limit,
|
||||
sort_key, sort_dir):
|
||||
|
Loading…
x
Reference in New Issue
Block a user