summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean McGinnis <sean.mcginnis@gmail.com>2018-10-08 13:17:54 -0500
committerSean McGinnis <sean.mcginnis@gmail.com>2018-10-09 15:56:58 -0500
commit9647d43bd5e77c815ac2f08b7de2226a657a66bc (patch)
tree9d0ebc83db0a44838abeed100f83d18d79ebbaac
parent4039d0d94f4eaf277f2b42c33ef873555f84f159 (diff)
Add volume backend pool list command
Adds an equivalent for "cinder get-pools" with "volume backend pool list" and "cinder get-pools --detail" with "volume backend pool list --long". Story: 1655624 Task: 136949 Signed-off-by: Sean McGinnis <sean.mcginnis@gmail.com> Change-Id: I826c9946ffe11340d44ad57914f72fc2a72b6938
Notes
Notes (review): Code-Review+2: Steve Martinelli <s.martinelli@gmail.com> Code-Review+2: Dean Troyer <dtroyer@gmail.com> Workflow+1: Dean Troyer <dtroyer@gmail.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Fri, 12 Oct 2018 22:41:43 +0000 Reviewed-on: https://review.openstack.org/608740 Project: openstack/python-openstackclient Branch: refs/heads/master
-rw-r--r--doc/source/cli/data/cinder.csv2
-rw-r--r--openstackclient/tests/unit/volume/v2/fakes.py37
-rw-r--r--openstackclient/tests/unit/volume/v2/test_volume_backend.py95
-rw-r--r--openstackclient/volume/v2/volume_backend.py54
-rw-r--r--releasenotes/notes/volume-backend-c5faae0b31556a24.yaml4
-rw-r--r--setup.cfg1
6 files changed, 191 insertions, 2 deletions
diff --git a/doc/source/cli/data/cinder.csv b/doc/source/cli/data/cinder.csv
index 068ffb7..cc8ef2d 100644
--- a/doc/source/cli/data/cinder.csv
+++ b/doc/source/cli/data/cinder.csv
@@ -33,7 +33,7 @@ failover-host,volume host failover,Failover a replicating cinder-volume host.
33force-delete,volume delete --force,"Attempts force-delete of volume, regardless of state." 33force-delete,volume delete --force,"Attempts force-delete of volume, regardless of state."
34freeze-host,volume host set --disable,Freeze and disable the specified cinder-volume host. 34freeze-host,volume host set --disable,Freeze and disable the specified cinder-volume host.
35get-capabilities,volume backend capability show,Show capabilities of a volume backend. Admin only. 35get-capabilities,volume backend capability show,Show capabilities of a volume backend. Admin only.
36get-pools,,Show pool information for backends. Admin only. 36get-pools,volume backend pool list,Show pool information for backends. Admin only.
37image-metadata,volume set --image-property,Sets or deletes volume image metadata. 37image-metadata,volume set --image-property,Sets or deletes volume image metadata.
38image-metadata-show,volume show,Shows volume image metadata. 38image-metadata-show,volume show,Shows volume image metadata.
39list,volume list,Lists all volumes. 39list,volume list,Lists all volumes.
diff --git a/openstackclient/tests/unit/volume/v2/fakes.py b/openstackclient/tests/unit/volume/v2/fakes.py
index ad13f1b..8d1db63 100644
--- a/openstackclient/tests/unit/volume/v2/fakes.py
+++ b/openstackclient/tests/unit/volume/v2/fakes.py
@@ -252,6 +252,41 @@ class FakeCapability(object):
252 return capability 252 return capability
253 253
254 254
255class FakePool(object):
256 """Fake Pools."""
257
258 @staticmethod
259 def create_one_pool(attrs=None):
260 """Create a fake pool.
261
262 :param Dictionary attrs:
263 A dictionary with all attributes of the pool
264 :return:
265 A FakeResource object with pool name and attrs.
266 """
267 # Set default attribute
268 pool_info = {
269 'name': 'host@lvmdriver-1#lvmdriver-1',
270 'storage_protocol': 'iSCSI',
271 'thick_provisioning_support': False,
272 'thin_provisioning_support': True,
273 'total_volumes': 99,
274 'total_capacity_gb': 1000.00,
275 'allocated_capacity_gb': 100,
276 'max_over_subscription_ratio': 200.0,
277 }
278
279 # Overwrite default attributes if there are some attributes set
280 pool_info.update(attrs or {})
281
282 pool = fakes.FakeResource(
283 None,
284 pool_info,
285 loaded=True)
286
287 return pool
288
289
255class FakeVolumeClient(object): 290class FakeVolumeClient(object):
256 291
257 def __init__(self, **kwargs): 292 def __init__(self, **kwargs):
@@ -294,6 +329,8 @@ class FakeVolumeClient(object):
294 self.management_url = kwargs['endpoint'] 329 self.management_url = kwargs['endpoint']
295 self.capabilities = mock.Mock() 330 self.capabilities = mock.Mock()
296 self.capabilities.resource_class = fakes.FakeResource(None, {}) 331 self.capabilities.resource_class = fakes.FakeResource(None, {})
332 self.pools = mock.Mock()
333 self.pools.resource_class = fakes.FakeResource(None, {})
297 334
298 335
299class TestVolume(utils.TestCommand): 336class TestVolume(utils.TestCommand):
diff --git a/openstackclient/tests/unit/volume/v2/test_volume_backend.py b/openstackclient/tests/unit/volume/v2/test_volume_backend.py
index 73df603..db18866 100644
--- a/openstackclient/tests/unit/volume/v2/test_volume_backend.py
+++ b/openstackclient/tests/unit/volume/v2/test_volume_backend.py
@@ -71,3 +71,98 @@ class TestShowVolumeCapability(volume_fakes.TestVolume):
71 self.capability_mock.get.assert_called_with( 71 self.capability_mock.get.assert_called_with(
72 'fake', 72 'fake',
73 ) 73 )
74
75
76class TestListVolumePool(volume_fakes.TestVolume):
77 """Tests for volume backend pool listing."""
78
79 # The pool to be listed
80 pools = volume_fakes.FakePool.create_one_pool()
81
82 def setUp(self):
83 super(TestListVolumePool, self).setUp()
84
85 self.pool_mock = self.app.client_manager.volume.pools
86 self.pool_mock.list.return_value = [self.pools]
87
88 # Get the command object to test
89 self.cmd = volume_backend.ListPool(self.app, None)
90
91 def test_pool_list(self):
92 arglist = []
93 verifylist = []
94 parsed_args = self.check_parser(self.cmd, arglist, verifylist)
95
96 # In base command class Lister in cliff, abstract method take_action()
97 # returns a tuple containing the column names and an iterable
98 # containing the data to be listed.
99 columns, data = self.cmd.take_action(parsed_args)
100
101 expected_columns = [
102 'Name',
103 ]
104
105 # confirming if all expected columns are present in the result.
106 self.assertEqual(expected_columns, columns)
107
108 datalist = ((
109 self.pools.name,
110 ), )
111
112 # confirming if all expected values are present in the result.
113 self.assertEqual(datalist, tuple(data))
114
115 # checking if proper call was made to list pools
116 self.pool_mock.list.assert_called_with(
117 detailed=False,
118 )
119
120 # checking if long columns are present in output
121 self.assertNotIn("total_volumes", columns)
122 self.assertNotIn("storage_protocol", columns)
123
124 def test_service_list_with_long_option(self):
125 arglist = [
126 '--long'
127 ]
128 verifylist = [
129 ('long', True)
130 ]
131 parsed_args = self.check_parser(self.cmd, arglist, verifylist)
132
133 # In base command class Lister in cliff, abstract method take_action()
134 # returns a tuple containing the column names and an iterable
135 # containing the data to be listed.
136 columns, data = self.cmd.take_action(parsed_args)
137
138 expected_columns = [
139 'Name',
140 'Protocol',
141 'Thick',
142 'Thin',
143 'Volumes',
144 'Capacity',
145 'Allocated',
146 'Max Over Ratio',
147 ]
148
149 # confirming if all expected columns are present in the result.
150 self.assertEqual(expected_columns, columns)
151
152 datalist = ((
153 self.pools.name,
154 self.pools.storage_protocol,
155 self.pools.thick_provisioning_support,
156 self.pools.thin_provisioning_support,
157 self.pools.total_volumes,
158 self.pools.total_capacity_gb,
159 self.pools.allocated_capacity_gb,
160 self.pools.max_over_subscription_ratio,
161 ), )
162
163 # confirming if all expected values are present in the result.
164 self.assertEqual(datalist, tuple(data))
165
166 self.pool_mock.list.assert_called_with(
167 detailed=True,
168 )
diff --git a/openstackclient/volume/v2/volume_backend.py b/openstackclient/volume/v2/volume_backend.py
index 0dff18c..c5194d3 100644
--- a/openstackclient/volume/v2/volume_backend.py
+++ b/openstackclient/volume/v2/volume_backend.py
@@ -12,7 +12,7 @@
12# under the License. 12# under the License.
13# 13#
14 14
15"""Capability action implementations""" 15"""Storage backend action implementations"""
16 16
17from osc_lib.command import command 17from osc_lib.command import command
18from osc_lib import utils 18from osc_lib import utils
@@ -59,3 +59,55 @@ class ShowCapability(command.Lister):
59 (utils.get_dict_properties( 59 (utils.get_dict_properties(
60 s, columns, 60 s, columns,
61 ) for s in print_data)) 61 ) for s in print_data))
62
63
64class ListPool(command.Lister):
65 _description = _("List pool command")
66
67 def get_parser(self, prog_name):
68 parser = super(ListPool, self).get_parser(prog_name)
69 parser.add_argument(
70 "--long",
71 action="store_true",
72 default=False,
73 help=_("Show detailed information about pools.")
74 )
75 # TODO(smcginnis): Starting with Cinder microversion 3.33, user is also
76 # able to pass in --filters with a <key>=<value> pair to filter on.
77 return parser
78
79 def take_action(self, parsed_args):
80 volume_client = self.app.client_manager.volume
81
82 if parsed_args.long:
83 columns = [
84 'name',
85 'storage_protocol',
86 'thick_provisioning_support',
87 'thin_provisioning_support',
88 'total_volumes',
89 'total_capacity_gb',
90 'allocated_capacity_gb',
91 'max_over_subscription_ratio',
92 ]
93 headers = [
94 'Name',
95 'Protocol',
96 'Thick',
97 'Thin',
98 'Volumes',
99 'Capacity',
100 'Allocated',
101 'Max Over Ratio'
102 ]
103 else:
104 columns = [
105 'Name',
106 ]
107 headers = columns
108
109 data = volume_client.pools.list(detailed=parsed_args.long)
110 return (headers,
111 (utils.get_item_properties(
112 s, columns,
113 ) for s in data))
diff --git a/releasenotes/notes/volume-backend-c5faae0b31556a24.yaml b/releasenotes/notes/volume-backend-c5faae0b31556a24.yaml
index 851ab2d..6698309 100644
--- a/releasenotes/notes/volume-backend-c5faae0b31556a24.yaml
+++ b/releasenotes/notes/volume-backend-c5faae0b31556a24.yaml
@@ -5,3 +5,7 @@ features:
5 added which will provide a list of all capabilities that can be configured 5 added which will provide a list of all capabilities that can be configured
6 for the requested backend. The required `<host>` parameter takes the form 6 for the requested backend. The required `<host>` parameter takes the form
7 `host@backend-name`. 7 `host@backend-name`.
8 - |
9 A new command, ``openstack volume backend pool list`` was added which will
10 provide a list of all backend storage pools. The optional ``-long``
11 parameter includes some basic configuration and stats for each pool.
diff --git a/setup.cfg b/setup.cfg
index 888e259..73c5fde 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -630,6 +630,7 @@ openstack.volume.v2 =
630 volume_backup_show = openstackclient.volume.v2.backup:ShowVolumeBackup 630 volume_backup_show = openstackclient.volume.v2.backup:ShowVolumeBackup
631 631
632 volume_backend_capability_show = openstackclient.volume.v2.volume_backend:ShowCapability 632 volume_backend_capability_show = openstackclient.volume.v2.volume_backend:ShowCapability
633 volume_backend_pool_list = openstackclient.volume.v2.volume_backend:ListPool
633 634
634 volume_host_failover = openstackclient.volume.v2.volume_host:FailoverVolumeHost 635 volume_host_failover = openstackclient.volume.v2.volume_host:FailoverVolumeHost
635 volume_host_set = openstackclient.volume.v2.volume_host:SetVolumeHost 636 volume_host_set = openstackclient.volume.v2.volume_host:SetVolumeHost