Support filter search for share type API
Since manila server allows filter search extra_specs and is_public, so it's better to add this in manila client as well. Change-Id: Ie85a7c09d4d7c6ddc31adb5125feea265ad8fced Depends-On: Id577ae9d08dc0fae3dcac78d98ec0456f8378417 Partially-Implements: blueprint support-filter-search-for-share-type
This commit is contained in:
parent
4197a71623
commit
50a1ef6e65
@ -27,7 +27,7 @@ from manilaclient import utils
|
|||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
MAX_VERSION = '2.42'
|
MAX_VERSION = '2.43'
|
||||||
MIN_VERSION = '2.0'
|
MIN_VERSION = '2.0'
|
||||||
DEPRECATED_VERSION = '1.0'
|
DEPRECATED_VERSION = '1.0'
|
||||||
_VERSIONED_METHOD_MAP = {}
|
_VERSIONED_METHOD_MAP = {}
|
||||||
|
@ -247,16 +247,24 @@ class ManilaCLIClient(base.CLIClient):
|
|||||||
return self.manila(
|
return self.manila(
|
||||||
'type-delete %s' % share_type, microversion=microversion)
|
'type-delete %s' % share_type, microversion=microversion)
|
||||||
|
|
||||||
def list_share_types(self, list_all=True, columns=None, microversion=None):
|
def list_share_types(self, list_all=True, columns=None, search_opts=None,
|
||||||
|
microversion=None):
|
||||||
"""List share types.
|
"""List share types.
|
||||||
|
|
||||||
:param list_all: bool -- whether to list all share types or only public
|
:param list_all: bool -- whether to list all share types or only public
|
||||||
|
:param search_opts: dict search_opts for filter search.
|
||||||
:param columns: comma separated string of columns.
|
:param columns: comma separated string of columns.
|
||||||
Example, "--columns id,name"
|
Example, "--columns id,name"
|
||||||
"""
|
"""
|
||||||
cmd = 'type-list'
|
cmd = 'type-list'
|
||||||
if list_all:
|
if list_all:
|
||||||
cmd += ' --all'
|
cmd += ' --all'
|
||||||
|
if search_opts is not None:
|
||||||
|
extra_specs = search_opts.get('extra_specs')
|
||||||
|
if extra_specs:
|
||||||
|
cmd += ' --extra_specs'
|
||||||
|
for spec_key in extra_specs.keys():
|
||||||
|
cmd += ' ' + spec_key + '=' + extra_specs[spec_key]
|
||||||
if columns is not None:
|
if columns is not None:
|
||||||
cmd += ' --columns ' + columns
|
cmd += ' --columns ' + columns
|
||||||
share_types_raw = self.manila(cmd, microversion=microversion)
|
share_types_raw = self.manila(cmd, microversion=microversion)
|
||||||
|
@ -334,6 +334,38 @@ class ShareTypesReadWriteTest(base.BaseTestCase):
|
|||||||
self.assertTrue(all('visibility' not in s for s in share_types))
|
self.assertTrue(all('visibility' not in s for s in share_types))
|
||||||
self.assertTrue(all('Visibility' not in s for s in share_types))
|
self.assertTrue(all('Visibility' not in s for s in share_types))
|
||||||
|
|
||||||
|
def test_list_share_type_filter_search(self):
|
||||||
|
# Fake extra spec and type name
|
||||||
|
extra_specs = {'aaaa': 'bbbb'}
|
||||||
|
# Create share type
|
||||||
|
name1 = data_utils.rand_name('manilaclient_functional_test1')
|
||||||
|
self.create_share_type(
|
||||||
|
name=name1,
|
||||||
|
driver_handles_share_servers='False')
|
||||||
|
# Create share type
|
||||||
|
name2 = data_utils.rand_name('manilaclient_functional_test2')
|
||||||
|
self.create_share_type(
|
||||||
|
name=name2,
|
||||||
|
extra_specs=extra_specs,
|
||||||
|
driver_handles_share_servers='True')
|
||||||
|
|
||||||
|
# List type by extra_specs
|
||||||
|
list_all = False
|
||||||
|
search_opts = {'extra_specs': extra_specs}
|
||||||
|
share_types = self.admin_client.list_share_types(
|
||||||
|
list_all=list_all,
|
||||||
|
search_opts=search_opts,
|
||||||
|
microversion='2.43'
|
||||||
|
)
|
||||||
|
self.assertTrue(share_types is not None)
|
||||||
|
|
||||||
|
expect = 'aaaa : bbbb'
|
||||||
|
self.assertTrue(len(share_types) == 1)
|
||||||
|
self.assertTrue(all('optional_extra_specs' in s for s in share_types))
|
||||||
|
self.assertTrue(all(s['Name'] == name2 for s in share_types))
|
||||||
|
self.assertTrue(all(s['optional_extra_specs'] ==
|
||||||
|
expect for s in share_types))
|
||||||
|
|
||||||
|
|
||||||
@ddt.ddt
|
@ddt.ddt
|
||||||
class ShareTypeExtraSpecsReadWriteTest(base.BaseTestCase):
|
class ShareTypeExtraSpecsReadWriteTest(base.BaseTestCase):
|
||||||
|
@ -285,7 +285,7 @@ class ShellTest(test_utils.TestCase):
|
|||||||
self.run_command,
|
self.run_command,
|
||||||
'list --share-type' + separator + 'not_found_expected',
|
'list --share-type' + separator + 'not_found_expected',
|
||||||
)
|
)
|
||||||
self.assert_called('GET', '/types?is_public=all')
|
self.assert_called('GET', '/types?is_public=all&all_tenants=1')
|
||||||
|
|
||||||
def test_list_with_limit(self):
|
def test_list_with_limit(self):
|
||||||
for separator in self.separators:
|
for separator in self.separators:
|
||||||
|
@ -150,6 +150,12 @@ class TypesTest(utils.TestCase):
|
|||||||
cs.share_types.list(show_all=False)
|
cs.share_types.list(show_all=False)
|
||||||
cs.assert_called('GET', '/types')
|
cs.assert_called('GET', '/types')
|
||||||
|
|
||||||
|
def test_list_types_search_by_extra_specs(self):
|
||||||
|
search_opts = {'extra_specs': {'aa': 'bb'}}
|
||||||
|
cs.share_types.list(search_opts=search_opts)
|
||||||
|
expect = '/types?is_public=all&extra_specs=%7B%27aa%27%3A+%27bb%27%7D'
|
||||||
|
cs.assert_called('GET', expect)
|
||||||
|
|
||||||
@ddt.data(*get_valid_type_create_data_2_0())
|
@ddt.data(*get_valid_type_create_data_2_0())
|
||||||
@ddt.unpack
|
@ddt.unpack
|
||||||
def test_create_2_7(self, is_public, dhss, snapshot, extra_specs):
|
def test_create_2_7(self, is_public, dhss, snapshot, extra_specs):
|
||||||
|
@ -17,11 +17,13 @@
|
|||||||
"""
|
"""
|
||||||
Share Type interface.
|
Share Type interface.
|
||||||
"""
|
"""
|
||||||
|
from six.moves.urllib import parse
|
||||||
|
|
||||||
from manilaclient import api_versions
|
from manilaclient import api_versions
|
||||||
from manilaclient import base
|
from manilaclient import base
|
||||||
from manilaclient.common.apiclient import base as common_base
|
from manilaclient.common.apiclient import base as common_base
|
||||||
from manilaclient import exceptions
|
from manilaclient import exceptions
|
||||||
|
from manilaclient import utils
|
||||||
|
|
||||||
|
|
||||||
class ShareType(common_base.Resource):
|
class ShareType(common_base.Resource):
|
||||||
@ -115,6 +117,14 @@ class ShareTypeManager(base.ManagerWithFind):
|
|||||||
query_string = ''
|
query_string = ''
|
||||||
if show_all:
|
if show_all:
|
||||||
query_string = '?is_public=all'
|
query_string = '?is_public=all'
|
||||||
|
if search_opts:
|
||||||
|
search_opts = utils.unicode_key_value_to_string(search_opts)
|
||||||
|
params = sorted(
|
||||||
|
[(k, v) for (k, v) in list(search_opts.items()) if v])
|
||||||
|
if params and query_string:
|
||||||
|
query_string += "&%s" % parse.urlencode(params)
|
||||||
|
if params and not query_string:
|
||||||
|
query_string += "?%s" % parse.urlencode(params)
|
||||||
return self._list("/types%s" % query_string, "share_types")
|
return self._list("/types%s" % query_string, "share_types")
|
||||||
|
|
||||||
def show(self, share_type):
|
def show(self, share_type):
|
||||||
|
@ -3673,7 +3673,19 @@ def _find_share_type(cs, stype):
|
|||||||
dest='all',
|
dest='all',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
default=False,
|
default=False,
|
||||||
help='Display all share types (Admin only).')
|
help='Display all share types whatever public or private '
|
||||||
|
'OPTIONAL: Default=False. (Admin only).')
|
||||||
|
@cliutils.arg(
|
||||||
|
'--extra-specs',
|
||||||
|
'--extra_specs',
|
||||||
|
type=str,
|
||||||
|
nargs='*',
|
||||||
|
metavar='<key=value>',
|
||||||
|
action='single_alias',
|
||||||
|
default=None,
|
||||||
|
help='Filters results by a extra specs key and value of share type that '
|
||||||
|
'was used for share creation. Available only for microversion >= '
|
||||||
|
'2.43. OPTIONAL: Default=None.')
|
||||||
@cliutils.arg(
|
@cliutils.arg(
|
||||||
'--columns',
|
'--columns',
|
||||||
metavar='<columns>',
|
metavar='<columns>',
|
||||||
@ -3683,15 +3695,28 @@ def _find_share_type(cs, stype):
|
|||||||
'example --columns "id,name".')
|
'example --columns "id,name".')
|
||||||
def do_type_list(cs, args):
|
def do_type_list(cs, args):
|
||||||
"""Print a list of available 'share types'."""
|
"""Print a list of available 'share types'."""
|
||||||
|
search_opts = None
|
||||||
|
show_all = args.all
|
||||||
|
extra_specs = _extract_extra_specs(args)
|
||||||
|
if extra_specs:
|
||||||
|
if cs.api_version < api_versions.APIVersion("2.43"):
|
||||||
|
raise exceptions.CommandError(
|
||||||
|
"Filter by 'extra_specs' is available only starting with "
|
||||||
|
"'2.43' API microversion.")
|
||||||
|
search_opts = {
|
||||||
|
'extra_specs': extra_specs
|
||||||
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
default = cs.share_types.get()
|
default = cs.share_types.get()
|
||||||
except exceptions.NotFound:
|
except exceptions.NotFound:
|
||||||
default = None
|
default = None
|
||||||
|
|
||||||
stypes = cs.share_types.list(show_all=args.all)
|
share_types = cs.share_types.list(show_all=show_all,
|
||||||
|
search_opts=search_opts)
|
||||||
show_des = cs.api_version.matches(
|
show_des = cs.api_version.matches(
|
||||||
api_versions.APIVersion("2.41"), api_versions.APIVersion())
|
api_versions.APIVersion("2.41"), api_versions.APIVersion())
|
||||||
_print_share_type_list(stypes, default_share_type=default,
|
_print_share_type_list(share_types, default_share_type=default,
|
||||||
columns=args.columns, description=show_des)
|
columns=args.columns, description=show_des)
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Share types can now be filtered with its extra_specs.
|
Loading…
Reference in New Issue
Block a user