diff options
author | Vivek Agrawal <vivek.agrawal@veritas.com> | 2017-01-06 13:29:40 -0800 |
---|---|---|
committer | Vivek Agrawal <vivek.agrawal@veritas.com> | 2017-01-18 06:28:21 -0800 |
commit | 056cf5c0591465dadd5017be9349d8f272fdddd0 (patch) | |
tree | 2435ad507029e25d8499a4b2c5debedcc5a185b1 | |
parent | 93d09ebc06c16be71cc8ca231eab91a67f55fb63 (diff) | |
download | python-cinderclient-056cf5c0591465dadd5017be9349d8f272fdddd0.tar.gz |
Metadata based snapshop filtering
The snpapshot-list API for cinder gives a list of snapshots based
on certain criteria to the user. From microversion 3.22 onwards
the snapshot-list API has been enhanced to support snapshot list
filtering based on metadata of snapshots. The metadata is stored
as key-value pair for every snapshot.
With this commit cinder will be queried based on metadata key and
value specified in the API snaphot-list. All the snapshots which
match the key, value provided by the user along with any other
filter criteria will be returned.
Added the test cases for the CLI and web requests.
DocImpact: "Filters results by a metadata key and value pair.
Default=None." on cinder snapshot-list
APIImpact
Closes-bug: #1569554
Change-Id: Idec0d0d02e7956843f202508e32c023c3cafbb0f
-rw-r--r-- | cinderclient/tests/unit/v3/test_shell.py | 9 | ||||
-rw-r--r-- | cinderclient/tests/unit/v3/test_volumes.py | 9 | ||||
-rw-r--r-- | cinderclient/v3/shell.py | 91 |
3 files changed, 109 insertions, 0 deletions
diff --git a/cinderclient/tests/unit/v3/test_shell.py b/cinderclient/tests/unit/v3/test_shell.py index e6a1eca..e3b2617 100644 --- a/cinderclient/tests/unit/v3/test_shell.py +++ b/cinderclient/tests/unit/v3/test_shell.py @@ -26,6 +26,8 @@ from cinderclient.tests.unit import utils from cinderclient.tests.unit.v3 import fakes from cinderclient.tests.unit.fixture_data import keystone_client +from six.moves.urllib import parse + @ddt.ddt @mock.patch.object(client, 'Client', fakes.FakeClient) @@ -344,6 +346,13 @@ class ShellTest(utils.TestCase): self.run_command('--os-volume-api-version 3.3 message-list') self.assert_called('GET', '/messages') + def test_snapshot_list_with_metadata(self): + self.run_command('--os-volume-api-version 3.22 ' + 'snapshot-list --metadata key1=val1') + expected = ("/snapshots/detail?metadata=%s" + % parse.quote_plus("{'key1': 'val1'}")) + self.assert_called('GET', expected) + @ddt.data(('resource_type',), ('event_id',), ('resource_uuid',), ('level', 'message_level'), ('request_id',)) def test_list_messages_with_filters(self, filter): diff --git a/cinderclient/tests/unit/v3/test_volumes.py b/cinderclient/tests/unit/v3/test_volumes.py index 22ffa75..fe27a51 100644 --- a/cinderclient/tests/unit/v3/test_volumes.py +++ b/cinderclient/tests/unit/v3/test_volumes.py @@ -20,6 +20,8 @@ from cinderclient.tests.unit import utils from cinderclient.tests.unit.v3 import fakes from cinderclient.v3 import volumes +from six.moves.urllib import parse + cs = fakes.FakeClient() @@ -84,3 +86,10 @@ class VolumesTest(utils.TestCase): cs = fakes.FakeClient(api_versions.APIVersion('3.8')) cs.volume_snapshots.list_manageable('host1', detailed=True) cs.assert_called('GET', '/manageable_snapshots/detail?host=host1') + + def test_snapshot_list_with_metadata(self): + cs = fakes.FakeClient(api_versions.APIVersion('3.22')) + cs.volume_snapshots.list(search_opts={'metadata': {'key1': 'val1'}}) + expected = ("/snapshots/detail?metadata=%s" + % parse.quote_plus("{'key1': 'val1'}")) + cs.assert_called('GET', expected) diff --git a/cinderclient/v3/shell.py b/cinderclient/v3/shell.py index 6a5d355..d89e10c 100644 --- a/cinderclient/v3/shell.py +++ b/cinderclient/v3/shell.py @@ -1210,3 +1210,94 @@ def do_message_delete(cs, args): if failure_count == len(args.message): raise exceptions.CommandError("Unable to delete any of the specified " "messages.") + + +@utils.arg('--all-tenants', + dest='all_tenants', + metavar='<0|1>', + nargs='?', + type=int, + const=1, + default=0, + help='Shows details for all tenants. Admin only.') +@utils.arg('--all_tenants', + nargs='?', + type=int, + const=1, + help=argparse.SUPPRESS) +@utils.arg('--name', + metavar='<name>', + default=None, + help='Filters results by a name. Default=None.') +@utils.arg('--display-name', + help=argparse.SUPPRESS) +@utils.arg('--display_name', + help=argparse.SUPPRESS) +@utils.arg('--status', + metavar='<status>', + default=None, + help='Filters results by a status. Default=None.') +@utils.arg('--volume-id', + metavar='<volume-id>', + default=None, + help='Filters results by a volume ID. Default=None.') +@utils.arg('--volume_id', + help=argparse.SUPPRESS) +@utils.arg('--marker', + metavar='<marker>', + default=None, + help='Begin returning snapshots that appear later in the snapshot ' + 'list than that represented by this id. ' + 'Default=None.') +@utils.arg('--limit', + metavar='<limit>', + default=None, + help='Maximum number of snapshots to return. Default=None.') +@utils.arg('--sort', + metavar='<key>[:<direction>]', + default=None, + help=(('Comma-separated list of sort keys and directions in the ' + 'form of <key>[:<asc|desc>]. ' + 'Valid keys: %s. ' + 'Default=None.') % ', '.join(base.SORT_KEY_VALUES))) +@utils.arg('--tenant', + type=str, + dest='tenant', + nargs='?', + metavar='<tenant>', + help='Display information from single tenant (Admin only).') +@utils.arg('--metadata', + nargs='*', + metavar='<key=value>', + default=None, + start_version='3.22', + help='Filters results by a metadata key and value pair. Require ' + 'volume api version >=3.22. Default=None.') +@utils.service_type('volumev3') +def do_snapshot_list(cs, args): + """Lists all snapshots.""" + all_tenants = (1 if args.tenant else + int(os.environ.get("ALL_TENANTS", args.all_tenants))) + + if args.display_name is not None: + args.name = args.display_name + + search_opts = { + 'all_tenants': all_tenants, + 'name': args.name, + 'status': args.status, + 'volume_id': args.volume_id, + 'project_id': args.tenant, + 'metadata': shell_utils.extract_metadata(args) + if args.metadata else None, + } + + snapshots = cs.volume_snapshots.list(search_opts=search_opts, + marker=args.marker, + limit=args.limit, + sort=args.sort) + shell_utils.translate_volume_snapshot_keys(snapshots) + sortby_index = None if args.sort else 0 + utils.print_list(snapshots, + ['ID', 'Volume ID', 'Status', 'Name', 'Size'], + sortby_index=sortby_index)
\ No newline at end of file |