Add 'protected' filter to image-list call
Implements v2 API image-list filtering on the 'protected' property following the spec: https://git.openstack.org/cgit/openstack/glance-specs/tree/specs/pike /approved/glance/add-protected-filter.rst The 'protected' query string parameter accepts one of 'true', 'false'. Any other value raises a 400 with an appropriate message. See the discussion on https://review.openstack.org/#/c/451560/ for why this implementation strategy was chosen. Change-Id: Ie90d952edddd3f69b3f489f056ff506e63f96376 Closes-Bug: #1674246
This commit is contained in:
parent
8bed0bc429
commit
d6068bec44
|
@ -121,6 +121,15 @@ class ImagesController(object):
|
|||
filters = {}
|
||||
filters['deleted'] = False
|
||||
|
||||
protected = filters.get('protected')
|
||||
if protected is not None:
|
||||
if protected not in ['true', 'false']:
|
||||
message = _("Invalid value '%s' for 'protected' filter."
|
||||
" Valid values are 'true' or 'false'.") % protected
|
||||
raise webob.exc.HTTPBadRequest(explanation=message)
|
||||
# ensure the type of protected is boolean
|
||||
filters['protected'] = protected == 'true'
|
||||
|
||||
if limit is None:
|
||||
limit = CONF.limit_param_default
|
||||
limit = min(CONF.api_limit_max, limit)
|
||||
|
|
|
@ -118,6 +118,7 @@ class TestDriver(test_utils.BaseTestCase):
|
|||
'created_at': dt1,
|
||||
'updated_at': dt1,
|
||||
'properties': {'foo': 'bar', 'far': 'boo'},
|
||||
'protected': True,
|
||||
'size': 13,
|
||||
},
|
||||
{
|
||||
|
@ -495,6 +496,16 @@ class DriverTests(object):
|
|||
filters={'poo': 'bear'})
|
||||
self.assertEqual(0, len(images))
|
||||
|
||||
def test_image_get_all_with_filter_protected(self):
|
||||
images = self.db_api.image_get_all(self.context,
|
||||
filters={'protected':
|
||||
True})
|
||||
self.assertEqual(1, len(images))
|
||||
images = self.db_api.image_get_all(self.context,
|
||||
filters={'protected':
|
||||
False})
|
||||
self.assertEqual(2, len(images))
|
||||
|
||||
def test_image_get_all_with_filter_comparative_created_at(self):
|
||||
anchor = timeutils.isotime(self.fixtures[0]['created_at'])
|
||||
time_expr = 'lt:' + anchor
|
||||
|
|
|
@ -150,7 +150,8 @@ class TestImages(functional.FunctionalTest):
|
|||
headers = self._headers({'content-type': 'application/json'})
|
||||
data = jsonutils.dumps({'name': 'image-1', 'type': 'kernel',
|
||||
'foo': 'bar', 'disk_format': 'aki',
|
||||
'container_format': 'aki', 'abc': 'xyz'})
|
||||
'container_format': 'aki', 'abc': 'xyz',
|
||||
'protected': True})
|
||||
response = requests.post(path, headers=headers, data=data)
|
||||
self.assertEqual(http.CREATED, response.status_code)
|
||||
image_location_header = response.headers['Location']
|
||||
|
@ -190,7 +191,7 @@ class TestImages(functional.FunctionalTest):
|
|||
'tags': [],
|
||||
'visibility': 'shared',
|
||||
'self': '/v2/images/%s' % image_id,
|
||||
'protected': False,
|
||||
'protected': True,
|
||||
'file': '/v2/images/%s/file' % image_id,
|
||||
'min_disk': 0,
|
||||
'foo': 'bar',
|
||||
|
@ -302,6 +303,30 @@ class TestImages(functional.FunctionalTest):
|
|||
response = requests.get(path, headers=self._headers())
|
||||
self.assertEqual(http.BAD_REQUEST, response.status_code)
|
||||
|
||||
# Image list should list only image-1 based on the filter
|
||||
# 'protected=true'
|
||||
path = self._url('/v2/images?protected=true')
|
||||
response = requests.get(path, headers=self._headers())
|
||||
self.assertEqual(http.OK, response.status_code)
|
||||
images = jsonutils.loads(response.text)['images']
|
||||
self.assertEqual(1, len(images))
|
||||
self.assertEqual(image_id, images[0]['id'])
|
||||
|
||||
# Image list should list only image-2 based on the filter
|
||||
# 'protected=false'
|
||||
path = self._url('/v2/images?protected=false')
|
||||
response = requests.get(path, headers=self._headers())
|
||||
self.assertEqual(http.OK, response.status_code)
|
||||
images = jsonutils.loads(response.text)['images']
|
||||
self.assertEqual(1, len(images))
|
||||
self.assertEqual(image2_id, images[0]['id'])
|
||||
|
||||
# Image list should return 400 based on the filter
|
||||
# 'protected=False'
|
||||
path = self._url('/v2/images?protected=False')
|
||||
response = requests.get(path, headers=self._headers())
|
||||
self.assertEqual(http.BAD_REQUEST, response.status_code)
|
||||
|
||||
# Image list should list only image-1 based on the filter
|
||||
# 'foo=bar&abc=xyz'
|
||||
path = self._url('/v2/images?foo=bar&abc=xyz')
|
||||
|
@ -337,7 +362,7 @@ class TestImages(functional.FunctionalTest):
|
|||
self.assertIsNone(image['size'])
|
||||
self.assertIsNone(image['virtual_size'])
|
||||
self.assertEqual('bar', image['foo'])
|
||||
self.assertFalse(image['protected'])
|
||||
self.assertTrue(image['protected'])
|
||||
self.assertEqual('kernel', image['type'])
|
||||
self.assertTrue(image['created_at'])
|
||||
self.assertTrue(image['updated_at'])
|
||||
|
|
Loading…
Reference in New Issue