Skip to content

Commit ca81b1a

Browse files
committed
Add cluster to volume service list
This patch adds the ``Cluster`` and ``Backend State`` columns to the ``openstack volume service list`` command. Note that you need to provide the appropriate microversion to show these columns. Cluster: openstack --os-volume-api-version 3.7 volume service list Backend State: openstack --os-volume-api-version 3.49 volume service list Change-Id: Ie7727d0001307b5d5a40d7ea0348bdb9626f9e03
1 parent dd6ac28 commit ca81b1a

4 files changed

Lines changed: 345 additions & 1 deletion

File tree

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
#
2+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
3+
# not use this file except in compliance with the License. You may obtain
4+
# a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11+
# License for the specific language governing permissions and limitations
12+
# under the License.
13+
#
14+
15+
from cinderclient import api_versions
16+
17+
from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
18+
from openstackclient.volume.v3 import service
19+
20+
21+
class TestService(volume_fakes.TestVolume):
22+
def setUp(self):
23+
super().setUp()
24+
25+
# Get a shortcut to the ServiceManager Mock
26+
self.service_mock = self.volume_client.services
27+
self.service_mock.reset_mock()
28+
29+
30+
class TestServiceList(TestService):
31+
# The service to be listed
32+
services = volume_fakes.create_one_service()
33+
34+
def setUp(self):
35+
super().setUp()
36+
37+
self.service_mock.list.return_value = [self.services]
38+
39+
# Get the command object to test
40+
self.cmd = service.ListService(self.app, None)
41+
42+
def test_service_list(self):
43+
arglist = [
44+
'--host',
45+
self.services.host,
46+
'--service',
47+
self.services.binary,
48+
]
49+
verifylist = [
50+
('host', self.services.host),
51+
('service', self.services.binary),
52+
]
53+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
54+
55+
# In base command class Lister in cliff, abstract method take_action()
56+
# returns a tuple containing the column names and an iterable
57+
# containing the data to be listed.
58+
columns, data = self.cmd.take_action(parsed_args)
59+
60+
expected_columns = [
61+
'Binary',
62+
'Host',
63+
'Zone',
64+
'Status',
65+
'State',
66+
'Updated At',
67+
]
68+
69+
# confirming if all expected columns are present in the result.
70+
self.assertEqual(expected_columns, columns)
71+
72+
datalist = (
73+
(
74+
self.services.binary,
75+
self.services.host,
76+
self.services.zone,
77+
self.services.status,
78+
self.services.state,
79+
self.services.updated_at,
80+
),
81+
)
82+
83+
# confirming if all expected values are present in the result.
84+
self.assertEqual(datalist, tuple(data))
85+
86+
# checking if proper call was made to list services
87+
self.service_mock.list.assert_called_with(
88+
self.services.host,
89+
self.services.binary,
90+
)
91+
92+
# checking if prohibited columns are present in output
93+
self.assertNotIn("Disabled Reason", columns)
94+
self.assertNotIn(self.services.disabled_reason, tuple(data))
95+
96+
def test_service_list_with_long_option(self):
97+
arglist = [
98+
'--host',
99+
self.services.host,
100+
'--service',
101+
self.services.binary,
102+
'--long',
103+
]
104+
verifylist = [
105+
('host', self.services.host),
106+
('service', self.services.binary),
107+
('long', True),
108+
]
109+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
110+
111+
# In base command class Lister in cliff, abstract method take_action()
112+
# returns a tuple containing the column names and an iterable
113+
# containing the data to be listed.
114+
columns, data = self.cmd.take_action(parsed_args)
115+
116+
expected_columns = [
117+
'Binary',
118+
'Host',
119+
'Zone',
120+
'Status',
121+
'State',
122+
'Updated At',
123+
'Disabled Reason',
124+
]
125+
126+
# confirming if all expected columns are present in the result.
127+
self.assertEqual(expected_columns, columns)
128+
129+
datalist = (
130+
(
131+
self.services.binary,
132+
self.services.host,
133+
self.services.zone,
134+
self.services.status,
135+
self.services.state,
136+
self.services.updated_at,
137+
self.services.disabled_reason,
138+
),
139+
)
140+
141+
# confirming if all expected values are present in the result.
142+
self.assertEqual(datalist, tuple(data))
143+
144+
self.service_mock.list.assert_called_with(
145+
self.services.host,
146+
self.services.binary,
147+
)
148+
149+
def test_service_list_with_cluster(self):
150+
self.volume_client.api_version = api_versions.APIVersion('3.7')
151+
cluster = {'cluster': 'fake-cluster'}
152+
cluster_service = volume_fakes.create_one_service(attrs=cluster)
153+
self.service_mock.list.return_value = [cluster_service]
154+
155+
arglist = [
156+
'--host',
157+
cluster_service.host,
158+
'--service',
159+
cluster_service.binary,
160+
]
161+
verifylist = [
162+
('host', cluster_service.host),
163+
('service', cluster_service.binary),
164+
]
165+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
166+
167+
# In base command class Lister in cliff, abstract method take_action()
168+
# returns a tuple containing the column names and an iterable
169+
# containing the data to be listed.
170+
columns, data = self.cmd.take_action(parsed_args)
171+
172+
expected_columns = [
173+
'Binary',
174+
'Host',
175+
'Zone',
176+
'Status',
177+
'State',
178+
'Updated At',
179+
'Cluster',
180+
]
181+
182+
# confirming if all expected columns are present in the result.
183+
self.assertEqual(expected_columns, columns)
184+
185+
datalist = (
186+
(
187+
cluster_service.binary,
188+
cluster_service.host,
189+
cluster_service.zone,
190+
cluster_service.status,
191+
cluster_service.state,
192+
cluster_service.updated_at,
193+
cluster_service.cluster,
194+
),
195+
)
196+
197+
# confirming if all expected values are present in the result.
198+
self.assertEqual(datalist, tuple(data))
199+
200+
# checking if proper call was made to list services
201+
self.service_mock.list.assert_called_with(
202+
cluster_service.host,
203+
cluster_service.binary,
204+
)
205+
206+
# checking if prohibited columns are present in output
207+
self.assertNotIn("Disabled Reason", columns)
208+
self.assertNotIn(cluster_service.disabled_reason, tuple(data))
209+
210+
def test_service_list_with_backend_state(self):
211+
self.volume_client.api_version = api_versions.APIVersion('3.49')
212+
backend_state = {'cluster': 'fake-cluster', 'backend_state': 'up'}
213+
backend_service = volume_fakes.create_one_service(attrs=backend_state)
214+
self.service_mock.list.return_value = [backend_service]
215+
216+
arglist = [
217+
'--host',
218+
backend_service.host,
219+
'--service',
220+
backend_service.binary,
221+
]
222+
verifylist = [
223+
('host', backend_service.host),
224+
('service', backend_service.binary),
225+
]
226+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
227+
228+
# In base command class Lister in cliff, abstract method take_action()
229+
# returns a tuple containing the column names and an iterable
230+
# containing the data to be listed.
231+
columns, data = self.cmd.take_action(parsed_args)
232+
233+
expected_columns = [
234+
'Binary',
235+
'Host',
236+
'Zone',
237+
'Status',
238+
'State',
239+
'Updated At',
240+
'Cluster',
241+
'Backend State',
242+
]
243+
244+
# confirming if all expected columns are present in the result.
245+
self.assertEqual(expected_columns, columns)
246+
247+
datalist = (
248+
(
249+
backend_service.binary,
250+
backend_service.host,
251+
backend_service.zone,
252+
backend_service.status,
253+
backend_service.state,
254+
backend_service.updated_at,
255+
backend_service.cluster,
256+
backend_service.backend_state,
257+
),
258+
)
259+
260+
# confirming if all expected values are present in the result.
261+
self.assertEqual(datalist, tuple(data))
262+
263+
# checking if proper call was made to list services
264+
self.service_mock.list.assert_called_with(
265+
backend_service.host,
266+
backend_service.binary,
267+
)
268+
269+
# checking if prohibited columns are present in output
270+
self.assertNotIn("Disabled Reason", columns)
271+
self.assertNotIn(backend_service.disabled_reason, tuple(data))
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#
2+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
3+
# not use this file except in compliance with the License. You may obtain
4+
# a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11+
# License for the specific language governing permissions and limitations
12+
# under the License.
13+
#
14+
15+
"""Service action implementations"""
16+
17+
from cinderclient import api_versions
18+
from osc_lib import utils
19+
20+
from openstackclient.volume.v2 import service as service_v2
21+
22+
23+
class ListService(service_v2.ListService):
24+
25+
def take_action(self, parsed_args):
26+
service_client = self.app.client_manager.volume
27+
28+
if parsed_args.long:
29+
columns = [
30+
"Binary",
31+
"Host",
32+
"Zone",
33+
"Status",
34+
"State",
35+
"Updated At",
36+
"Disabled Reason",
37+
]
38+
else:
39+
columns = [
40+
"Binary",
41+
"Host",
42+
"Zone",
43+
"Status",
44+
"State",
45+
"Updated At",
46+
]
47+
48+
if service_client.api_version >= api_versions.APIVersion('3.7'):
49+
columns.append("Cluster")
50+
if service_client.api_version >= api_versions.APIVersion('3.49'):
51+
columns.append("Backend State")
52+
53+
data = service_client.services.list(
54+
parsed_args.host, parsed_args.service
55+
)
56+
return (
57+
columns,
58+
(
59+
utils.get_item_properties(
60+
s,
61+
columns,
62+
)
63+
for s in data
64+
),
65+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
features:
3+
- |
4+
Added the ``Cluster`` and ``Backend State`` columns to
5+
``openstack volume service list`` command. Note that the
6+
``Cluster`` parameter is available since microversion 3.7
7+
and ``Backend State`` parameter is available since
8+
microversion 3.49.

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,7 @@ openstack.volume.v3 =
847847
volume_qos_show = openstackclient.volume.v2.qos_specs:ShowQos
848848
volume_qos_unset = openstackclient.volume.v2.qos_specs:UnsetQos
849849

850-
volume_service_list = openstackclient.volume.v2.service:ListService
850+
volume_service_list = openstackclient.volume.v3.service:ListService
851851
volume_service_set = openstackclient.volume.v2.service:SetService
852852

853853
volume_transfer_request_accept = openstackclient.volume.v2.volume_transfer_request:AcceptTransferRequest

0 commit comments

Comments
 (0)