diff --git a/doc/source/cli/osc/v2/index.rst b/doc/source/cli/osc/v2/index.rst index a7320f5c2..09be3b6b5 100644 --- a/doc/source/cli/osc/v2/index.rst +++ b/doc/source/cli/osc/v2/index.rst @@ -102,3 +102,10 @@ share services .. autoprogram-cliff:: openstack.share.v2 :command: share service * + +=========== +share pools +=========== + +.. autoprogram-cliff:: openstack.share.v2 + :command: share pool list diff --git a/manilaclient/osc/v2/share_pools.py b/manilaclient/osc/v2/share_pools.py new file mode 100644 index 000000000..13bf815a8 --- /dev/null +++ b/manilaclient/osc/v2/share_pools.py @@ -0,0 +1,101 @@ +# 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. +from osc_lib.command import command +from osc_lib import exceptions +from osc_lib import utils as osc_utils + +from manilaclient import api_versions +from manilaclient.common._i18n import _ +from manilaclient.osc import utils + + +class ListSharePools(command.Lister): + """List all backend storage pools known to the scheduler (Admin only).""" + _description = _( + "List all backend storage pools known to the scheduler (Admin only).") + + def get_parser(self, prog_name): + parser = super(ListSharePools, self).get_parser(prog_name) + parser.add_argument( + "--host", + metavar="", + default=None, + help=_("Filter results by host name. " + "Regular expressions are supported.") + ) + parser.add_argument( + "--backend", + metavar="", + default=None, + help=_("Filter results by backend name. " + "Regular expressions are supported.") + ) + parser.add_argument( + "--pool", + metavar="", + default=None, + help=_("Filter results by pool name. " + "Regular expressions are supported.") + ) + parser.add_argument( + "--detail", + action='store_true', + default=False, + help=_("Show detailed information about pools.") + ) + parser.add_argument( + "--share-type", + metavar="", + default=None, + help=_("Filter results by share type name or ID. " + "Available only for microversion >= 2.23") + ) + return parser + + def take_action(self, parsed_args): + share_client = self.app.client_manager.share + + share_type = None + if parsed_args.share_type: + if share_client.api_version >= api_versions.APIVersion("2.23"): + share_type = osc_utils.find_resource( + share_client.share_types, + parsed_args.share_type).id + else: + raise exceptions.CommandError(_( + "Filtering results by share type is only available with " + "manila API version >= 2.23")) + + search_opts = { + 'host': parsed_args.host, + 'backend': parsed_args.backend, + 'pool': parsed_args.pool, + 'share_type': share_type, + } + + pools = share_client.pools.list( + detailed=parsed_args.detail, search_opts=search_opts) + + columns = ["Name", "Host", "Backend", "Pool"] + + if parsed_args.detail: + columns.append("Capabilities") + if parsed_args.formatter == 'table': + for pool in pools: + pool._info.update({ + 'capabilities': utils.format_properties( + pool.capabilities)}) + + data = (osc_utils.get_dict_properties( + pool._info, columns) for pool in pools) + + return (columns, data) diff --git a/manilaclient/tests/unit/osc/v2/fakes.py b/manilaclient/tests/unit/osc/v2/fakes.py index 6ca3e5ef2..331afb2da 100644 --- a/manilaclient/tests/unit/osc/v2/fakes.py +++ b/manilaclient/tests/unit/osc/v2/fakes.py @@ -44,6 +44,7 @@ class FakeShareClient(object): self.messages = mock.Mock() self.availability_zones = mock.Mock() self.services = mock.Mock() + self.pools = mock.Mock() class ManilaParseException(Exception): @@ -748,3 +749,51 @@ class FakeShareService(object): services.append( FakeShareService.create_fake_service(attrs)) return services + + +class FakeSharePools(object): + """Fake one or more share pool""" + + @staticmethod + def create_one_share_pool(attrs=None): + """Create a fake share pool + + :param Dictionary attrs: + A dictionary with all attributes + :return: + A FakeResource object + """ + + attrs = attrs or {} + + share_pool = { + "name": 'fake_pool@gamma#fake_pool', + "host": 'fake_host_' + uuid.uuid4().hex, + "backend": 'fake_backend_' + uuid.uuid4().hex, + "pool": 'fake_pool_' + uuid.uuid4().hex, + "capabilities": {'fake_capability': uuid.uuid4().hex} + } + + share_pool.update(attrs) + share_pool = osc_fakes.FakeResource(info=copy.deepcopy( + share_pool), + loaded=True) + return share_pool + + @staticmethod + def create_share_pools(attrs=None, count=2): + """Create multiple fake share pools. + + :param Dictionary attrs: + A dictionary with all attributes + :param Integer count: + The number of share pools to be faked + :return: + A list of FakeResource objects + """ + + share_pools = [] + for n in range(count): + share_pools.append( + FakeSharePools.create_one_share_pool(attrs)) + return share_pools diff --git a/manilaclient/tests/unit/osc/v2/test_share_pools.py b/manilaclient/tests/unit/osc/v2/test_share_pools.py new file mode 100644 index 000000000..e59d79210 --- /dev/null +++ b/manilaclient/tests/unit/osc/v2/test_share_pools.py @@ -0,0 +1,160 @@ +# 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. +# +from osc_lib import exceptions +from osc_lib import utils as oscutils + +from manilaclient import api_versions +from manilaclient.osc.v2 import share_pools +from manilaclient.tests.unit.osc.v2 import fakes as manila_fakes + + +class TestPool(manila_fakes.TestShare): + + def setUp(self): + super(TestPool, self).setUp() + + self.pools_mock = self.app.client_manager.share.pools + self.pools_mock.reset_mock() + + self.share_types_mock = self.app.client_manager.share.share_types + self.share_types_mock.reset_mock() + + self.app.client_manager.share.api_version = api_versions.APIVersion( + api_versions.MAX_VERSION) + + +class TestPoolList(TestPool): + + columns = ['Name', 'Host', 'Backend', 'Pool'] + + def setUp(self): + super(TestPoolList, self).setUp() + + self.share_type = manila_fakes.FakeShareType.create_one_sharetype() + self.share_types_mock.get.return_value = self.share_type + + self.share_pools = manila_fakes.FakeSharePools.create_share_pools() + self.pools_mock.list.return_value = self.share_pools + + self.values = (oscutils.get_dict_properties( + pool._info, self.columns) for pool in self.share_pools) + + self.cmd = share_pools.ListSharePools(self.app, None) + + def test_list_share_pools(self): + arglist = [] + verifylist = [] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.pools_mock.list.assert_called_with( + detailed=False, + search_opts={ + 'host': None, + 'backend': None, + 'pool': None, + 'share_type': None, + }) + + self.assertEqual(self.columns, columns) + self.assertEqual(list(self.values), list(data)) + + def test_list_share_pools_filters(self): + arglist = [ + '--host', self.share_pools[0].host, + '--backend', self.share_pools[0].backend, + '--pool', self.share_pools[0].pool + ] + verifylist = [ + ('host', self.share_pools[0].host), + ('backend', self.share_pools[0].backend), + ('pool', self.share_pools[0].pool) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.pools_mock.list.assert_called_with( + detailed=False, + search_opts={ + 'host': self.share_pools[0].host, + 'backend': self.share_pools[0].backend, + 'pool': self.share_pools[0].pool, + 'share_type': None, + }) + + self.assertEqual(self.columns, columns) + self.assertEqual(list(self.values), list(data)) + + def test_list_share_pools_share_type(self): + arglist = [ + '--share-type', self.share_type.id + ] + verifylist = [ + ('share_type', self.share_type.id) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.pools_mock.list.assert_called_with( + detailed=False, + search_opts={ + 'host': None, + 'backend': None, + 'pool': None, + 'share_type': self.share_type.id, + }) + self.assertEqual(self.columns, columns) + self.assertEqual(list(self.values), list(data)) + + def test_list_share_pools_share_type_api_version_exception(self): + self.app.client_manager.share.api_version = api_versions.APIVersion( + "2.22") + + arglist = [ + '--share-type', self.share_type.id + ] + verifylist = [ + ('share_type', self.share_type.id) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args) + + def test_list_share_pools_detail(self): + detail_columns = ['Name', 'Host', 'Backend', 'Pool', 'Capabilities'] + detail_values = (oscutils.get_dict_properties( + pool._info, detail_columns) for pool in self.share_pools) + arglist = [ + '--detail' + ] + verifylist = [ + ('detail', True) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.pools_mock.list.assert_called_with( + detailed=True, + search_opts={ + 'host': None, + 'backend': None, + 'pool': None, + 'share_type': None, + }) + + self.assertEqual(detail_columns, columns) + self.assertEqual(list(detail_values), list(data)) diff --git a/setup.cfg b/setup.cfg index 4d8165f72..a4c67cdb2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -92,6 +92,7 @@ openstack.share.v2 = share_availability_zone_list = manilaclient.osc.v2.availability_zones:ShareAvailabilityZoneList share_service_set = manilaclient.osc.v2.services:SetShareService share_service_list = manilaclient.osc.v2.services:ListShareService + share_pool_list = manilaclient.osc.v2.share_pools:ListSharePools [coverage:run] omit = manilaclient/tests/*