Add --property-filter option to v2 image-list
The option is present in the v1 shell, but missing from the v2 shell. This allows the user to filter based on any image property. Example: $ glance --os-image-api-version 2 image-list --property-filter os_distro=NixOS DocImpact Closes-Bug: #1383326 Change-Id: Ia65a08520e3eaf3ecd9b9018be9f6a8e2d3d4f0b
This commit is contained in:
@@ -93,6 +93,9 @@ def do_image_update(gc, args):
|
|||||||
help='The status of images to display.')
|
help='The status of images to display.')
|
||||||
@utils.arg('--owner', metavar='<OWNER>',
|
@utils.arg('--owner', metavar='<OWNER>',
|
||||||
help='Display images owned by <OWNER>.')
|
help='Display images owned by <OWNER>.')
|
||||||
|
@utils.arg('--property-filter', metavar='<KEY=VALUE>',
|
||||||
|
help="Filter images by a user-defined image property.",
|
||||||
|
action='append', dest='properties', default=[])
|
||||||
@utils.arg('--checksum', metavar='<CHECKSUM>',
|
@utils.arg('--checksum', metavar='<CHECKSUM>',
|
||||||
help='Displays images that match the checksum.')
|
help='Displays images that match the checksum.')
|
||||||
@utils.arg('--tag', metavar='<TAG>', action='append',
|
@utils.arg('--tag', metavar='<TAG>', action='append',
|
||||||
@@ -101,6 +104,12 @@ def do_image_list(gc, args):
|
|||||||
"""List images you can access."""
|
"""List images you can access."""
|
||||||
filter_keys = ['visibility', 'member_status', 'owner', 'checksum', 'tag']
|
filter_keys = ['visibility', 'member_status', 'owner', 'checksum', 'tag']
|
||||||
filter_items = [(key, getattr(args, key)) for key in filter_keys]
|
filter_items = [(key, getattr(args, key)) for key in filter_keys]
|
||||||
|
if args.properties:
|
||||||
|
filter_properties = [prop.split('=', 1) for prop in args.properties]
|
||||||
|
if False in (len(pair) == 2 for pair in filter_properties):
|
||||||
|
utils.exit('Argument --property-filter expected properties in the'
|
||||||
|
' format KEY=VALUE')
|
||||||
|
filter_items += filter_properties
|
||||||
filters = dict([item for item in filter_items if item[1] is not None])
|
filters = dict([item for item in filter_items if item[1] is not None])
|
||||||
|
|
||||||
kwargs = {'filters': filters}
|
kwargs = {'filters': filters}
|
||||||
|
@@ -346,6 +346,25 @@ data_fixtures = {
|
|||||||
'',
|
'',
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
'/v2/images?limit=%d&os_distro=NixOS' % images.DEFAULT_PAGE_SIZE: {
|
||||||
|
'GET': (
|
||||||
|
{},
|
||||||
|
{'images': [
|
||||||
|
{
|
||||||
|
'id': '8b052954-c76c-4e02-8e90-be89a70183a8',
|
||||||
|
'name': 'image-5',
|
||||||
|
'os_distro': 'NixOS',
|
||||||
|
},
|
||||||
|
]},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
'/v2/images?limit=%d&my_little_property=cant_be_this_cute' %
|
||||||
|
images.DEFAULT_PAGE_SIZE: {
|
||||||
|
'GET': (
|
||||||
|
{},
|
||||||
|
{'images': []},
|
||||||
|
),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -503,6 +522,17 @@ class TestController(testtools.TestCase):
|
|||||||
images = list(self.controller.list(**filters))
|
images = list(self.controller.list(**filters))
|
||||||
self.assertEqual(0, len(images))
|
self.assertEqual(0, len(images))
|
||||||
|
|
||||||
|
def test_list_images_for_property(self):
|
||||||
|
filters = {'filters': dict([('os_distro', 'NixOS')])}
|
||||||
|
images = list(self.controller.list(**filters))
|
||||||
|
self.assertEqual(1, len(images))
|
||||||
|
|
||||||
|
def test_list_images_for_non_existent_property(self):
|
||||||
|
filters = {'filters': dict([('my_little_property',
|
||||||
|
'cant_be_this_cute')])}
|
||||||
|
images = list(self.controller.list(**filters))
|
||||||
|
self.assertEqual(0, len(images))
|
||||||
|
|
||||||
def test_get_image(self):
|
def test_get_image(self):
|
||||||
image = self.controller.get('3a4560a1-e585-443e-9b39-553b46ec92d1')
|
image = self.controller.get('3a4560a1-e585-443e-9b39-553b46ec92d1')
|
||||||
self.assertEqual('3a4560a1-e585-443e-9b39-553b46ec92d1', image.id)
|
self.assertEqual('3a4560a1-e585-443e-9b39-553b46ec92d1', image.id)
|
||||||
|
@@ -64,7 +64,8 @@ class ShellV2Test(testtools.TestCase):
|
|||||||
'member_status': 'Fake',
|
'member_status': 'Fake',
|
||||||
'owner': 'test',
|
'owner': 'test',
|
||||||
'checksum': 'fake_checksum',
|
'checksum': 'fake_checksum',
|
||||||
'tag': 'fake tag'
|
'tag': 'fake tag',
|
||||||
|
'properties': []
|
||||||
}
|
}
|
||||||
args = self._make_args(input)
|
args = self._make_args(input)
|
||||||
with mock.patch.object(self.gc.images, 'list') as mocked_list:
|
with mock.patch.object(self.gc.images, 'list') as mocked_list:
|
||||||
@@ -83,6 +84,36 @@ class ShellV2Test(testtools.TestCase):
|
|||||||
filters=exp_img_filters)
|
filters=exp_img_filters)
|
||||||
utils.print_list.assert_called_once_with({}, ['ID', 'Name'])
|
utils.print_list.assert_called_once_with({}, ['ID', 'Name'])
|
||||||
|
|
||||||
|
def test_do_image_list_with_property_filter(self):
|
||||||
|
input = {
|
||||||
|
'page_size': 1,
|
||||||
|
'visibility': True,
|
||||||
|
'member_status': 'Fake',
|
||||||
|
'owner': 'test',
|
||||||
|
'checksum': 'fake_checksum',
|
||||||
|
'tag': 'fake tag',
|
||||||
|
'properties': ['os_distro=NixOS', 'architecture=x86_64']
|
||||||
|
}
|
||||||
|
args = self._make_args(input)
|
||||||
|
with mock.patch.object(self.gc.images, 'list') as mocked_list:
|
||||||
|
mocked_list.return_value = {}
|
||||||
|
|
||||||
|
test_shell.do_image_list(self.gc, args)
|
||||||
|
|
||||||
|
exp_img_filters = {
|
||||||
|
'owner': 'test',
|
||||||
|
'member_status': 'Fake',
|
||||||
|
'visibility': True,
|
||||||
|
'checksum': 'fake_checksum',
|
||||||
|
'tag': 'fake tag',
|
||||||
|
'os_distro': 'NixOS',
|
||||||
|
'architecture': 'x86_64'
|
||||||
|
}
|
||||||
|
|
||||||
|
mocked_list.assert_called_once_with(page_size=1,
|
||||||
|
filters=exp_img_filters)
|
||||||
|
utils.print_list.assert_called_once_with({}, ['ID', 'Name'])
|
||||||
|
|
||||||
def test_do_image_show(self):
|
def test_do_image_show(self):
|
||||||
args = self._make_args({'id': 'pass', 'page_size': 18,
|
args = self._make_args({'id': 'pass', 'page_size': 18,
|
||||||
'max_column_width': 120})
|
'max_column_width': 120})
|
||||||
|
Reference in New Issue
Block a user