Improve share list API filtering
1) Added new params for filtering by: - share network - snapshot - volume type - host - limit and offset a la pagination - project id (useful with '--all-tenants') - metadata* - extra-specs* - direction (asc, desc)* - key of share* * requires server-side update 2) Added aliases for params, mostly in perspective to avoid mess of underscore and dash symbols. 3) Updated utils.print_list func to print results as is without reordering. Implements blueprint improve-share-list-filtering Change-Id: I6fe92c5242f18c900e109271f9182bd5ed287b25
This commit is contained in:
parent
5e71ffc159
commit
c7456c675f
0
manilaclient/common/__init__.py
Normal file
0
manilaclient/common/__init__.py
Normal file
29
manilaclient/common/constants.py
Normal file
29
manilaclient/common/constants.py
Normal file
@ -0,0 +1,29 @@
|
||||
# Copyright 2014 Mirantis, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Common constants that can be used all over the manilaclient."""
|
||||
|
||||
# These are used for providing desired sorting params with list requests
|
||||
SORT_DIR_VALUES = ('asc', 'desc')
|
||||
SHARE_SORT_KEY_VALUES = (
|
||||
'id', 'status', 'size', 'host', 'share_proto',
|
||||
'export_location', 'availability_zone',
|
||||
'user_id', 'project_id',
|
||||
'created_at', 'updated_at',
|
||||
'display_name', 'name',
|
||||
'volume_type_id', 'volume_type',
|
||||
'share_network_id', 'share_network',
|
||||
'snapshot_id', 'snapshot',
|
||||
)
|
@ -20,15 +20,14 @@ import six
|
||||
from manilaclient.openstack.common import strutils
|
||||
|
||||
|
||||
def _print(pt, order):
|
||||
def _print(pt, order=None):
|
||||
output = pt.get_string(sortby=order) if order else pt.get_string()
|
||||
if sys.version_info >= (3, 0):
|
||||
print(pt.get_string(sortby=order))
|
||||
print(output)
|
||||
else:
|
||||
print(strutils.safe_encode(pt.get_string(sortby=order)))
|
||||
print(strutils.safe_encode(output))
|
||||
|
||||
|
||||
# NOTE(vponomaryov): replace function 'print_list' and 'print_dict'
|
||||
# with functions from cliutils, when bug #1342050 is fixed
|
||||
def print_list(objs, fields, formatters={}, order_by=None):
|
||||
mixed_case_fields = ['serverId']
|
||||
pt = prettytable.PrettyTable([f for f in fields], caching=False)
|
||||
@ -47,10 +46,6 @@ def print_list(objs, fields, formatters={}, order_by=None):
|
||||
data = getattr(o, field_name, '')
|
||||
row.append(data)
|
||||
pt.add_row(row)
|
||||
|
||||
if order_by is None:
|
||||
order_by = fields[0]
|
||||
|
||||
_print(pt, order_by)
|
||||
|
||||
|
||||
|
@ -22,6 +22,7 @@ except ImportError:
|
||||
from urllib.parse import urlencode # noqa
|
||||
|
||||
from manilaclient import base
|
||||
from manilaclient.common import constants
|
||||
from manilaclient import exceptions
|
||||
from manilaclient.openstack.common.apiclient import base as common_base
|
||||
|
||||
@ -175,11 +176,40 @@ class ShareManager(base.ManagerWithFind):
|
||||
body = {'share': kwargs, }
|
||||
return self._update("/shares/%s" % share.id, body)
|
||||
|
||||
def list(self, detailed=True, search_opts=None):
|
||||
def list(self, detailed=True, search_opts=None,
|
||||
sort_key=None, sort_dir=None):
|
||||
"""Get a list of all shares.
|
||||
|
||||
:param detailed: Whether to return detailed share info.
|
||||
:param search_opts: Search options to filter out shares.
|
||||
:param sort_key: Key to be sorted.
|
||||
:param sort_dir: Sort direction, should be 'desc' or 'asc'.
|
||||
:rtype: list of :class:`Share`
|
||||
"""
|
||||
if search_opts is None:
|
||||
search_opts = {}
|
||||
|
||||
if sort_key is not None:
|
||||
if sort_key in constants.SHARE_SORT_KEY_VALUES:
|
||||
search_opts['sort_key'] = sort_key
|
||||
# NOTE(vponomaryov): Replace aliases with appropriate keys
|
||||
if sort_key == 'volume_type':
|
||||
search_opts['sort_key'] = 'volume_type_id'
|
||||
elif sort_key == 'snapshot':
|
||||
search_opts['sort_key'] = 'snapshot_id'
|
||||
elif sort_key == 'share_network':
|
||||
search_opts['sort_key'] = 'share_network_id'
|
||||
else:
|
||||
raise ValueError('sort_key must be one of the following: %s.'
|
||||
% ', '.join(constants.SHARE_SORT_KEY_VALUES))
|
||||
|
||||
if sort_dir is not None:
|
||||
if sort_dir in constants.SORT_DIR_VALUES:
|
||||
search_opts['sort_dir'] = sort_dir
|
||||
else:
|
||||
raise ValueError('sort_dir must be one of the following: %s.'
|
||||
% ', '.join(constants.SORT_DIR_VALUES))
|
||||
|
||||
if search_opts:
|
||||
query_string = urlencode(
|
||||
sorted([(k, v) for (k, v) in list(search_opts.items()) if v]))
|
||||
|
@ -19,6 +19,7 @@ import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
from manilaclient.common import constants
|
||||
from manilaclient import exceptions
|
||||
from manilaclient.openstack.common import cliutils
|
||||
from manilaclient import utils
|
||||
@ -96,6 +97,7 @@ def _translate_keys(collection, convert):
|
||||
|
||||
def _extract_metadata(args):
|
||||
metadata = {}
|
||||
if args.metadata:
|
||||
for metadatum in args.metadata:
|
||||
# unset doesn't require a val, so we have the if/else
|
||||
if '=' in metadatum:
|
||||
@ -108,6 +110,21 @@ def _extract_metadata(args):
|
||||
return metadata
|
||||
|
||||
|
||||
def _extract_extra_specs(args):
|
||||
extra_specs = {}
|
||||
if args.extra_specs:
|
||||
for extra_spec in args.extra_specs:
|
||||
# unset doesn't require a val, so we have the if/else
|
||||
if '=' in extra_spec:
|
||||
(key, value) = extra_spec.split('=', 1)
|
||||
else:
|
||||
key = extra_spec
|
||||
value = None
|
||||
|
||||
extra_specs[key] = value
|
||||
return extra_specs
|
||||
|
||||
|
||||
def do_endpoints(cs, args):
|
||||
"""Discover endpoints that get returned from the authenticate services."""
|
||||
catalog = cs.client.service_catalog.catalog
|
||||
@ -545,32 +562,147 @@ def do_access_list(cs, args):
|
||||
@cliutils.arg(
|
||||
'--name',
|
||||
metavar='<name>',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Filter results by name.')
|
||||
@cliutils.arg(
|
||||
'--status',
|
||||
metavar='<status>',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Filter results by status.')
|
||||
@cliutils.arg(
|
||||
'--share-server-id',
|
||||
'--share-server_id', '--share_server-id', '--share_server_id', # aliases
|
||||
metavar='<share_server_id>',
|
||||
type=str,
|
||||
default=None,
|
||||
action='single_alias',
|
||||
help='Filter results by share server ID.')
|
||||
@cliutils.arg(
|
||||
'--metadata',
|
||||
type=str,
|
||||
nargs='*',
|
||||
metavar='<key=value>',
|
||||
help='Filters results by a metadata key and value. OPTIONAL: Default=None',
|
||||
default=None)
|
||||
@cliutils.arg(
|
||||
'--extra-specs',
|
||||
'--extra_specs', # alias
|
||||
type=str,
|
||||
nargs='*',
|
||||
metavar='<key=value>',
|
||||
action='single_alias',
|
||||
help='Filters results by a extra specs key and value of volume type that '
|
||||
'was used for share creation. OPTIONAL: Default=None',
|
||||
default=None)
|
||||
@cliutils.arg(
|
||||
'--volume-type',
|
||||
'--volume_type', '--volume-type-id', # aliases
|
||||
'--volume-type_id', '--volume_type-id', '--volume_type_id', # aliases
|
||||
metavar='<volume_type>',
|
||||
type=str,
|
||||
default=None,
|
||||
action='single_alias',
|
||||
help='Filter results by a volume type id or name that was used for share '
|
||||
'creation.')
|
||||
@cliutils.arg(
|
||||
'--limit',
|
||||
metavar='<limit>',
|
||||
type=int,
|
||||
default=None,
|
||||
help='Maximum number of shares to return. OPTIONAL: Default=None.')
|
||||
@cliutils.arg(
|
||||
'--offset',
|
||||
metavar='<offset>',
|
||||
type=int,
|
||||
default=None,
|
||||
help='Set offset to define start point of share listing. '
|
||||
'OPTIONAL: Default=None.')
|
||||
@cliutils.arg(
|
||||
'--sort-key',
|
||||
'--sort_key', # alias
|
||||
metavar='<sort_key>',
|
||||
type=str,
|
||||
default=None,
|
||||
action='single_alias',
|
||||
help='Key to be sorted, available keys are %(keys)s. '
|
||||
'OPTIONAL: Default=None.' % {'keys': constants.SHARE_SORT_KEY_VALUES})
|
||||
@cliutils.arg(
|
||||
'--sort-dir',
|
||||
'--sort_dir', # alias
|
||||
metavar='<sort_dir>',
|
||||
type=str,
|
||||
default=None,
|
||||
action='single_alias',
|
||||
help='Sort direction, available values are %(values)s. '
|
||||
'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES})
|
||||
@cliutils.arg(
|
||||
'--snapshot',
|
||||
metavar='<snapshot>',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Filer results by snapshot name or id, that was used for share.')
|
||||
@cliutils.arg(
|
||||
'--host',
|
||||
metavar='<host>',
|
||||
default=None,
|
||||
help='Filter results by host.')
|
||||
@cliutils.arg(
|
||||
'--share-network',
|
||||
'--share_network', # alias
|
||||
metavar='<share_network>',
|
||||
type=str,
|
||||
default=None,
|
||||
action='single_alias',
|
||||
help='Filter results by share-network name or id.')
|
||||
@cliutils.arg(
|
||||
'--project-id',
|
||||
'--project_id', # alias
|
||||
metavar='<project_id>',
|
||||
type=str,
|
||||
default=None,
|
||||
action='single_alias',
|
||||
help="Filter results by project id. Useful with set key '--all-tenants'.")
|
||||
@cliutils.service_type('share')
|
||||
def do_list(cs, args):
|
||||
"""List all NAS shares."""
|
||||
"""List NAS shares with filters."""
|
||||
list_of_keys = [
|
||||
'ID', 'Name', 'Size', 'Share Proto', 'Status', 'Volume Type',
|
||||
'Export location', 'Host',
|
||||
]
|
||||
all_tenants = int(os.environ.get("ALL_TENANTS", args.all_tenants))
|
||||
|
||||
empty_obj = type('Empty', (object,), {'id': None})
|
||||
volume_type = (_find_volume_type(cs, args.volume_type)
|
||||
if args.volume_type else empty_obj)
|
||||
|
||||
snapshot = (_find_share_snapshot(cs, args.snapshot)
|
||||
if args.snapshot else empty_obj)
|
||||
|
||||
share_network = (_find_share_network(cs, args.share_network)
|
||||
if args.share_network else empty_obj)
|
||||
search_opts = {
|
||||
'offset': args.offset,
|
||||
'limit': args.limit,
|
||||
'all_tenants': all_tenants,
|
||||
'name': args.name,
|
||||
'status': args.status,
|
||||
'host': args.host,
|
||||
'share_network_id': share_network.id,
|
||||
'snapshot_id': snapshot.id,
|
||||
'volume_type_id': volume_type.id,
|
||||
'metadata': _extract_metadata(args),
|
||||
'extra_specs': _extract_extra_specs(args),
|
||||
'share_server_id': args.share_server_id,
|
||||
'project_id': args.project_id,
|
||||
}
|
||||
shares = cs.shares.list(search_opts=search_opts)
|
||||
utils.print_list(shares,
|
||||
['ID', 'Name', 'Size', 'Share Proto', 'Status',
|
||||
'Export location'])
|
||||
shares = cs.shares.list(
|
||||
search_opts=search_opts,
|
||||
sort_key=args.sort_key,
|
||||
sort_dir=args.sort_dir,
|
||||
)
|
||||
utils.print_list(shares, list_of_keys)
|
||||
|
||||
|
||||
@cliutils.arg(
|
||||
|
@ -73,7 +73,7 @@ class ShellTest(utils.TestCase):
|
||||
def test_help_on_subcommand(self):
|
||||
required = [
|
||||
'.*?^usage: manila list',
|
||||
'.*?(?m)^List all NAS shares.',
|
||||
'.*?(?m)^List NAS shares with filters.',
|
||||
]
|
||||
help_text = self.shell('help list')
|
||||
for r in required:
|
||||
|
@ -34,10 +34,43 @@ class FakeHTTPClient(fakes.FakeHTTPClient):
|
||||
share = {'share': {'id': 1234, 'name': 'sharename'}}
|
||||
return (200, {}, share)
|
||||
|
||||
def get_shares_detail(self, **kw):
|
||||
shares = {'shares': [{'id': 1234,
|
||||
def get_shares(self, **kw):
|
||||
endpoint = "http://127.0.0.1:8786/v1"
|
||||
share_id = '1234'
|
||||
shares = {
|
||||
'shares': [
|
||||
{
|
||||
'id': share_id,
|
||||
'name': 'sharename',
|
||||
'attachments': [{'server_id': 111}]}]}
|
||||
'links': [
|
||||
{"href": endpoint + "/fake_project/shares/" + share_id,
|
||||
"rel": "self"},
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
return (200, {}, shares)
|
||||
|
||||
def get_shares_detail(self, **kw):
|
||||
endpoint = "http://127.0.0.1:8786/v1"
|
||||
share_id = '1234'
|
||||
shares = {
|
||||
'shares': [
|
||||
{
|
||||
'id': share_id,
|
||||
'name': 'sharename',
|
||||
'status': 'fake_status',
|
||||
'size': 1,
|
||||
'host': 'fake_host',
|
||||
'export_location': 'fake_export_location',
|
||||
'snapshot_id': 'fake_snapshot_id',
|
||||
'links': [
|
||||
{"href": endpoint + "/fake_project/shares/" + share_id,
|
||||
"rel": "self"},
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
return (200, {}, shares)
|
||||
|
||||
def get_snapshots_1234(self, **kw):
|
||||
|
@ -90,10 +90,57 @@ class SharesTest(utils.TestCase):
|
||||
cs.assert_called('POST', '/shares/1234/action',
|
||||
{'os-force_delete': None})
|
||||
|
||||
def test_list_shares(self):
|
||||
cs.shares.list()
|
||||
def test_list_shares_index(self):
|
||||
cs.shares.list(detailed=False)
|
||||
cs.assert_called('GET', '/shares')
|
||||
|
||||
def test_list_shares_index_with_search_opts(self):
|
||||
search_opts = {
|
||||
'fake_str': 'fake_str_value',
|
||||
'fake_int': 1,
|
||||
}
|
||||
cs.shares.list(detailed=False, search_opts=search_opts)
|
||||
cs.assert_called('GET', '/shares?fake_int=1&fake_str=fake_str_value')
|
||||
|
||||
def test_list_shares_detailed(self):
|
||||
cs.shares.list(detailed=True)
|
||||
cs.assert_called('GET', '/shares/detail')
|
||||
|
||||
def test_list_shares_detailed_with_search_opts(self):
|
||||
search_opts = {
|
||||
'fake_str': 'fake_str_value',
|
||||
'fake_int': 1,
|
||||
}
|
||||
cs.shares.list(detailed=True, search_opts=search_opts)
|
||||
cs.assert_called(
|
||||
'GET', '/shares/detail?fake_int=1&fake_str=fake_str_value')
|
||||
|
||||
def test_list_shares_sort_by_asc_and_host_key(self):
|
||||
cs.shares.list(detailed=False, sort_key='host', sort_dir='asc')
|
||||
cs.assert_called('GET', '/shares?sort_dir=asc&sort_key=host')
|
||||
|
||||
def test_list_shares_sort_by_desc_and_size_key(self):
|
||||
cs.shares.list(detailed=False, sort_key='size', sort_dir='desc')
|
||||
cs.assert_called('GET', '/shares?sort_dir=desc&sort_key=size')
|
||||
|
||||
def test_list_shares_filter_by_share_network_alias(self):
|
||||
cs.shares.list(detailed=False, sort_key='share_network')
|
||||
cs.assert_called('GET', '/shares?sort_key=share_network_id')
|
||||
|
||||
def test_list_shares_filter_by_snapshot_alias(self):
|
||||
cs.shares.list(detailed=False, sort_key='snapshot')
|
||||
cs.assert_called('GET', '/shares?sort_key=snapshot_id')
|
||||
|
||||
def test_list_shares_filter_by_volume_type_alias(self):
|
||||
cs.shares.list(detailed=False, sort_key='volume_type')
|
||||
cs.assert_called('GET', '/shares?sort_key=volume_type_id')
|
||||
|
||||
def test_list_shares_by_improper_direction(self):
|
||||
self.assertRaises(ValueError, cs.shares.list, sort_dir='fake')
|
||||
|
||||
def test_list_shares_by_improper_key(self):
|
||||
self.assertRaises(ValueError, cs.shares.list, sort_key='fake')
|
||||
|
||||
def test_allow_access_to_share(self):
|
||||
share = cs.shares.get(1234)
|
||||
ip = '192.168.0.1'
|
||||
|
@ -1,4 +1,5 @@
|
||||
# Copyright 2013 OpenStack LLC.
|
||||
# Copyright 2014 Mirantis, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@ -18,7 +19,9 @@ import mock
|
||||
import requests
|
||||
|
||||
from manilaclient import client
|
||||
from manilaclient.common import constants
|
||||
from manilaclient import exceptions
|
||||
from manilaclient.openstack.common import cliutils
|
||||
from manilaclient.openstack.common import jsonutils
|
||||
from manilaclient import shell
|
||||
from manilaclient.v1 import client as client_v1
|
||||
@ -51,6 +54,10 @@ class ShellTest(utils.TestCase):
|
||||
self.old_get_client_class = client.get_client_class
|
||||
client.get_client_class = lambda *_: fakes.FakeClient
|
||||
|
||||
# Following shows available separators for optional params
|
||||
# and its values
|
||||
self.separators = [' ', '=']
|
||||
|
||||
def tearDown(self):
|
||||
# For some method like test_image_meta_bad_action we are
|
||||
# testing a SystemExit to be thrown and object self.shell has
|
||||
@ -79,20 +86,169 @@ class ShellTest(utils.TestCase):
|
||||
self.assert_called('GET', '/shares/detail')
|
||||
|
||||
def test_list_filter_status(self):
|
||||
self.run_command('list --status=available')
|
||||
for separator in self.separators:
|
||||
self.run_command('list --status' + separator + 'available')
|
||||
self.assert_called('GET', '/shares/detail?status=available')
|
||||
|
||||
def test_list_filter_name(self):
|
||||
self.run_command('list --name=1234')
|
||||
for separator in self.separators:
|
||||
self.run_command('list --name' + separator + '1234')
|
||||
self.assert_called('GET', '/shares/detail?name=1234')
|
||||
|
||||
def test_list_all_tenants(self):
|
||||
self.run_command('list --all-tenants=1')
|
||||
def test_list_all_tenants_only_key(self):
|
||||
self.run_command('list --all-tenants')
|
||||
self.assert_called('GET', '/shares/detail?all_tenants=1')
|
||||
|
||||
def test_list_filter_share_server_id(self):
|
||||
self.run_command('list --share-server-id=1234')
|
||||
self.assert_called('GET', '/shares/detail?share_server_id=1234')
|
||||
def test_list_all_tenants_key_and_value_1(self):
|
||||
for separator in self.separators:
|
||||
self.run_command('list --all-tenants' + separator + '1')
|
||||
self.assert_called('GET', '/shares/detail?all_tenants=1')
|
||||
|
||||
def test_list_all_tenants_key_and_value_0(self):
|
||||
for separator in self.separators:
|
||||
self.run_command('list --all-tenants' + separator + '0')
|
||||
self.assert_called('GET', '/shares/detail')
|
||||
|
||||
def test_list_filter_by_share_server_and_its_aliases(self):
|
||||
aliases = [
|
||||
'--share-server-id', '--share-server_id',
|
||||
'--share_server-id', '--share_server_id',
|
||||
]
|
||||
for alias in aliases:
|
||||
for separator in self.separators:
|
||||
self.run_command('list ' + alias + separator + '1234')
|
||||
self.assert_called(
|
||||
'GET', '/shares/detail?share_server_id=1234')
|
||||
|
||||
def test_list_filter_by_metadata(self):
|
||||
self.run_command('list --metadata key=value')
|
||||
self.assert_called(
|
||||
'GET', '/shares/detail?metadata=%7B%27key%27%3A+%27value%27%7D')
|
||||
|
||||
def test_list_filter_by_extra_specs_and_its_aliases(self):
|
||||
aliases = ['--extra-specs', '--extra_specs', ]
|
||||
for alias in aliases:
|
||||
self.run_command('list ' + alias + ' key=value')
|
||||
self.assert_called(
|
||||
'GET',
|
||||
'/shares/detail?extra_specs=%7B%27key%27%3A+%27value%27%7D',
|
||||
)
|
||||
|
||||
def test_list_filter_by_volume_type_and_its_aliases(self):
|
||||
fake_vt = type('Empty', (object,), {'id': 'fake_vt'})
|
||||
aliases = [
|
||||
'--volume-type', '--volume_type', '--volume-type-id',
|
||||
'--volume-type_id', '--volume_type-id', '--volume_type_id',
|
||||
]
|
||||
for alias in aliases:
|
||||
for separator in self.separators:
|
||||
with mock.patch.object(cliutils, 'find_resource',
|
||||
mock.Mock(return_value=fake_vt)):
|
||||
self.run_command('list ' + alias + separator + fake_vt.id)
|
||||
self.assert_called(
|
||||
'GET', '/shares/detail?volume_type_id=' + fake_vt.id)
|
||||
|
||||
def test_list_filter_by_volume_type_not_found(self):
|
||||
for separator in self.separators:
|
||||
self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.run_command,
|
||||
'list --volume-type' + separator + 'not_found_expected',
|
||||
)
|
||||
self.assert_called('GET', '/types')
|
||||
|
||||
def test_list_with_limit(self):
|
||||
for separator in self.separators:
|
||||
self.run_command('list --limit' + separator + '50')
|
||||
self.assert_called('GET', '/shares/detail?limit=50')
|
||||
|
||||
def test_list_with_offset(self):
|
||||
for separator in self.separators:
|
||||
self.run_command('list --offset' + separator + '50')
|
||||
self.assert_called('GET', '/shares/detail?offset=50')
|
||||
|
||||
def test_list_with_sort_dir_verify_keys(self):
|
||||
# Verify allowed aliases and keys
|
||||
aliases = ['--sort_dir', '--sort-dir']
|
||||
for alias in aliases:
|
||||
for key in constants.SORT_DIR_VALUES:
|
||||
for separator in self.separators:
|
||||
self.run_command('list ' + alias + separator + key)
|
||||
self.assert_called('GET', '/shares/detail?sort_dir=' + key)
|
||||
|
||||
def test_list_with_fake_sort_dir(self):
|
||||
self.assertRaises(
|
||||
ValueError,
|
||||
self.run_command,
|
||||
'list --sort-dir fake_sort_dir',
|
||||
)
|
||||
|
||||
def test_list_with_sort_key_verify_keys(self):
|
||||
# Verify allowed aliases and keys
|
||||
aliases = ['--sort_key', '--sort-key']
|
||||
for alias in aliases:
|
||||
for key in constants.SHARE_SORT_KEY_VALUES:
|
||||
for separator in self.separators:
|
||||
self.run_command('list ' + alias + separator + key)
|
||||
key = 'share_network_id' if key == 'share_network' else key
|
||||
key = 'snapshot_id' if key == 'snapshot' else key
|
||||
key = 'volume_type_id' if key == 'volume_type' else key
|
||||
self.assert_called('GET', '/shares/detail?sort_key=' + key)
|
||||
|
||||
def test_list_with_fake_sort_key(self):
|
||||
self.assertRaises(
|
||||
ValueError,
|
||||
self.run_command,
|
||||
'list --sort-key fake_sort_key',
|
||||
)
|
||||
|
||||
def test_list_filter_by_snapshot(self):
|
||||
fake_s = type('Empty', (object,), {'id': 'fake_snapshot_id'})
|
||||
for separator in self.separators:
|
||||
with mock.patch.object(cliutils, 'find_resource',
|
||||
mock.Mock(return_value=fake_s)):
|
||||
self.run_command('list --snapshot' + separator + fake_s.id)
|
||||
self.assert_called(
|
||||
'GET', '/shares/detail?snapshot_id=' + fake_s.id)
|
||||
|
||||
def test_list_filter_by_snapshot_not_found(self):
|
||||
self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.run_command,
|
||||
'list --snapshot not_found_expected',
|
||||
)
|
||||
self.assert_called('GET', '/snapshots/detail')
|
||||
|
||||
def test_list_filter_by_host(self):
|
||||
for separator in self.separators:
|
||||
self.run_command('list --host' + separator + 'fake_host')
|
||||
self.assert_called('GET', '/shares/detail?host=fake_host')
|
||||
|
||||
def test_list_filter_by_share_network(self):
|
||||
aliases = ['--share-network', '--share_network', ]
|
||||
fake_sn = type('Empty', (object,), {'id': 'fake_share_network_id'})
|
||||
for alias in aliases:
|
||||
for separator in self.separators:
|
||||
with mock.patch.object(cliutils, 'find_resource',
|
||||
mock.Mock(return_value=fake_sn)):
|
||||
self.run_command('list ' + alias + separator + fake_sn.id)
|
||||
self.assert_called(
|
||||
'GET', '/shares/detail?share_network_id=' + fake_sn.id)
|
||||
|
||||
def test_list_filter_by_share_network_not_found(self):
|
||||
self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.run_command,
|
||||
'list --share-network not_found_expected',
|
||||
)
|
||||
self.assert_called('GET', '/share-networks/detail')
|
||||
|
||||
def test_list_filter_by_project_id(self):
|
||||
aliases = ['--project-id', '--project_id']
|
||||
for alias in aliases:
|
||||
for separator in self.separators:
|
||||
self.run_command('list ' + alias + separator + 'fake_id')
|
||||
self.assert_called('GET', '/shares/detail?project_id=fake_id')
|
||||
|
||||
def test_show(self):
|
||||
self.run_command('show 1234')
|
||||
|
Loading…
Reference in New Issue
Block a user