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:
space 2017-03-23 08:03:38 -04:00
parent 8bed0bc429
commit d6068bec44
3 changed files with 48 additions and 3 deletions

View File

@ -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)

View File

@ -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

View File

@ -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'])