summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVivek Agrawal <vivek.agrawal@veritas.com>2017-01-06 13:29:40 -0800
committerVivek Agrawal <vivek.agrawal@veritas.com>2017-01-18 06:28:21 -0800
commit056cf5c0591465dadd5017be9349d8f272fdddd0 (patch)
tree2435ad507029e25d8499a4b2c5debedcc5a185b1
parent93d09ebc06c16be71cc8ca231eab91a67f55fb63 (diff)
downloadpython-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.py9
-rw-r--r--cinderclient/tests/unit/v3/test_volumes.py9
-rw-r--r--cinderclient/v3/shell.py91
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