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
This commit is contained in:
parent
dd6ac285d5
commit
ca81b1acf0
271
openstackclient/tests/unit/volume/v3/test_service.py
Normal file
271
openstackclient/tests/unit/volume/v3/test_service.py
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
#
|
||||||
|
# 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 cinderclient import api_versions
|
||||||
|
|
||||||
|
from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
|
||||||
|
from openstackclient.volume.v3 import service
|
||||||
|
|
||||||
|
|
||||||
|
class TestService(volume_fakes.TestVolume):
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
|
||||||
|
# Get a shortcut to the ServiceManager Mock
|
||||||
|
self.service_mock = self.volume_client.services
|
||||||
|
self.service_mock.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
class TestServiceList(TestService):
|
||||||
|
# The service to be listed
|
||||||
|
services = volume_fakes.create_one_service()
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
|
||||||
|
self.service_mock.list.return_value = [self.services]
|
||||||
|
|
||||||
|
# Get the command object to test
|
||||||
|
self.cmd = service.ListService(self.app, None)
|
||||||
|
|
||||||
|
def test_service_list(self):
|
||||||
|
arglist = [
|
||||||
|
'--host',
|
||||||
|
self.services.host,
|
||||||
|
'--service',
|
||||||
|
self.services.binary,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('host', self.services.host),
|
||||||
|
('service', self.services.binary),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
# In base command class Lister in cliff, abstract method take_action()
|
||||||
|
# returns a tuple containing the column names and an iterable
|
||||||
|
# containing the data to be listed.
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
expected_columns = [
|
||||||
|
'Binary',
|
||||||
|
'Host',
|
||||||
|
'Zone',
|
||||||
|
'Status',
|
||||||
|
'State',
|
||||||
|
'Updated At',
|
||||||
|
]
|
||||||
|
|
||||||
|
# confirming if all expected columns are present in the result.
|
||||||
|
self.assertEqual(expected_columns, columns)
|
||||||
|
|
||||||
|
datalist = (
|
||||||
|
(
|
||||||
|
self.services.binary,
|
||||||
|
self.services.host,
|
||||||
|
self.services.zone,
|
||||||
|
self.services.status,
|
||||||
|
self.services.state,
|
||||||
|
self.services.updated_at,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# confirming if all expected values are present in the result.
|
||||||
|
self.assertEqual(datalist, tuple(data))
|
||||||
|
|
||||||
|
# checking if proper call was made to list services
|
||||||
|
self.service_mock.list.assert_called_with(
|
||||||
|
self.services.host,
|
||||||
|
self.services.binary,
|
||||||
|
)
|
||||||
|
|
||||||
|
# checking if prohibited columns are present in output
|
||||||
|
self.assertNotIn("Disabled Reason", columns)
|
||||||
|
self.assertNotIn(self.services.disabled_reason, tuple(data))
|
||||||
|
|
||||||
|
def test_service_list_with_long_option(self):
|
||||||
|
arglist = [
|
||||||
|
'--host',
|
||||||
|
self.services.host,
|
||||||
|
'--service',
|
||||||
|
self.services.binary,
|
||||||
|
'--long',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('host', self.services.host),
|
||||||
|
('service', self.services.binary),
|
||||||
|
('long', True),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
# In base command class Lister in cliff, abstract method take_action()
|
||||||
|
# returns a tuple containing the column names and an iterable
|
||||||
|
# containing the data to be listed.
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
expected_columns = [
|
||||||
|
'Binary',
|
||||||
|
'Host',
|
||||||
|
'Zone',
|
||||||
|
'Status',
|
||||||
|
'State',
|
||||||
|
'Updated At',
|
||||||
|
'Disabled Reason',
|
||||||
|
]
|
||||||
|
|
||||||
|
# confirming if all expected columns are present in the result.
|
||||||
|
self.assertEqual(expected_columns, columns)
|
||||||
|
|
||||||
|
datalist = (
|
||||||
|
(
|
||||||
|
self.services.binary,
|
||||||
|
self.services.host,
|
||||||
|
self.services.zone,
|
||||||
|
self.services.status,
|
||||||
|
self.services.state,
|
||||||
|
self.services.updated_at,
|
||||||
|
self.services.disabled_reason,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# confirming if all expected values are present in the result.
|
||||||
|
self.assertEqual(datalist, tuple(data))
|
||||||
|
|
||||||
|
self.service_mock.list.assert_called_with(
|
||||||
|
self.services.host,
|
||||||
|
self.services.binary,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_service_list_with_cluster(self):
|
||||||
|
self.volume_client.api_version = api_versions.APIVersion('3.7')
|
||||||
|
cluster = {'cluster': 'fake-cluster'}
|
||||||
|
cluster_service = volume_fakes.create_one_service(attrs=cluster)
|
||||||
|
self.service_mock.list.return_value = [cluster_service]
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--host',
|
||||||
|
cluster_service.host,
|
||||||
|
'--service',
|
||||||
|
cluster_service.binary,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('host', cluster_service.host),
|
||||||
|
('service', cluster_service.binary),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
# In base command class Lister in cliff, abstract method take_action()
|
||||||
|
# returns a tuple containing the column names and an iterable
|
||||||
|
# containing the data to be listed.
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
expected_columns = [
|
||||||
|
'Binary',
|
||||||
|
'Host',
|
||||||
|
'Zone',
|
||||||
|
'Status',
|
||||||
|
'State',
|
||||||
|
'Updated At',
|
||||||
|
'Cluster',
|
||||||
|
]
|
||||||
|
|
||||||
|
# confirming if all expected columns are present in the result.
|
||||||
|
self.assertEqual(expected_columns, columns)
|
||||||
|
|
||||||
|
datalist = (
|
||||||
|
(
|
||||||
|
cluster_service.binary,
|
||||||
|
cluster_service.host,
|
||||||
|
cluster_service.zone,
|
||||||
|
cluster_service.status,
|
||||||
|
cluster_service.state,
|
||||||
|
cluster_service.updated_at,
|
||||||
|
cluster_service.cluster,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# confirming if all expected values are present in the result.
|
||||||
|
self.assertEqual(datalist, tuple(data))
|
||||||
|
|
||||||
|
# checking if proper call was made to list services
|
||||||
|
self.service_mock.list.assert_called_with(
|
||||||
|
cluster_service.host,
|
||||||
|
cluster_service.binary,
|
||||||
|
)
|
||||||
|
|
||||||
|
# checking if prohibited columns are present in output
|
||||||
|
self.assertNotIn("Disabled Reason", columns)
|
||||||
|
self.assertNotIn(cluster_service.disabled_reason, tuple(data))
|
||||||
|
|
||||||
|
def test_service_list_with_backend_state(self):
|
||||||
|
self.volume_client.api_version = api_versions.APIVersion('3.49')
|
||||||
|
backend_state = {'cluster': 'fake-cluster', 'backend_state': 'up'}
|
||||||
|
backend_service = volume_fakes.create_one_service(attrs=backend_state)
|
||||||
|
self.service_mock.list.return_value = [backend_service]
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--host',
|
||||||
|
backend_service.host,
|
||||||
|
'--service',
|
||||||
|
backend_service.binary,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('host', backend_service.host),
|
||||||
|
('service', backend_service.binary),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
# In base command class Lister in cliff, abstract method take_action()
|
||||||
|
# returns a tuple containing the column names and an iterable
|
||||||
|
# containing the data to be listed.
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
expected_columns = [
|
||||||
|
'Binary',
|
||||||
|
'Host',
|
||||||
|
'Zone',
|
||||||
|
'Status',
|
||||||
|
'State',
|
||||||
|
'Updated At',
|
||||||
|
'Cluster',
|
||||||
|
'Backend State',
|
||||||
|
]
|
||||||
|
|
||||||
|
# confirming if all expected columns are present in the result.
|
||||||
|
self.assertEqual(expected_columns, columns)
|
||||||
|
|
||||||
|
datalist = (
|
||||||
|
(
|
||||||
|
backend_service.binary,
|
||||||
|
backend_service.host,
|
||||||
|
backend_service.zone,
|
||||||
|
backend_service.status,
|
||||||
|
backend_service.state,
|
||||||
|
backend_service.updated_at,
|
||||||
|
backend_service.cluster,
|
||||||
|
backend_service.backend_state,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# confirming if all expected values are present in the result.
|
||||||
|
self.assertEqual(datalist, tuple(data))
|
||||||
|
|
||||||
|
# checking if proper call was made to list services
|
||||||
|
self.service_mock.list.assert_called_with(
|
||||||
|
backend_service.host,
|
||||||
|
backend_service.binary,
|
||||||
|
)
|
||||||
|
|
||||||
|
# checking if prohibited columns are present in output
|
||||||
|
self.assertNotIn("Disabled Reason", columns)
|
||||||
|
self.assertNotIn(backend_service.disabled_reason, tuple(data))
|
65
openstackclient/volume/v3/service.py
Normal file
65
openstackclient/volume/v3/service.py
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""Service action implementations"""
|
||||||
|
|
||||||
|
from cinderclient import api_versions
|
||||||
|
from osc_lib import utils
|
||||||
|
|
||||||
|
from openstackclient.volume.v2 import service as service_v2
|
||||||
|
|
||||||
|
|
||||||
|
class ListService(service_v2.ListService):
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
service_client = self.app.client_manager.volume
|
||||||
|
|
||||||
|
if parsed_args.long:
|
||||||
|
columns = [
|
||||||
|
"Binary",
|
||||||
|
"Host",
|
||||||
|
"Zone",
|
||||||
|
"Status",
|
||||||
|
"State",
|
||||||
|
"Updated At",
|
||||||
|
"Disabled Reason",
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
columns = [
|
||||||
|
"Binary",
|
||||||
|
"Host",
|
||||||
|
"Zone",
|
||||||
|
"Status",
|
||||||
|
"State",
|
||||||
|
"Updated At",
|
||||||
|
]
|
||||||
|
|
||||||
|
if service_client.api_version >= api_versions.APIVersion('3.7'):
|
||||||
|
columns.append("Cluster")
|
||||||
|
if service_client.api_version >= api_versions.APIVersion('3.49'):
|
||||||
|
columns.append("Backend State")
|
||||||
|
|
||||||
|
data = service_client.services.list(
|
||||||
|
parsed_args.host, parsed_args.service
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
columns,
|
||||||
|
(
|
||||||
|
utils.get_item_properties(
|
||||||
|
s,
|
||||||
|
columns,
|
||||||
|
)
|
||||||
|
for s in data
|
||||||
|
),
|
||||||
|
)
|
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Added the ``Cluster`` and ``Backend State`` columns to
|
||||||
|
``openstack volume service list`` command. Note that the
|
||||||
|
``Cluster`` parameter is available since microversion 3.7
|
||||||
|
and ``Backend State`` parameter is available since
|
||||||
|
microversion 3.49.
|
@ -847,7 +847,7 @@ openstack.volume.v3 =
|
|||||||
volume_qos_show = openstackclient.volume.v2.qos_specs:ShowQos
|
volume_qos_show = openstackclient.volume.v2.qos_specs:ShowQos
|
||||||
volume_qos_unset = openstackclient.volume.v2.qos_specs:UnsetQos
|
volume_qos_unset = openstackclient.volume.v2.qos_specs:UnsetQos
|
||||||
|
|
||||||
volume_service_list = openstackclient.volume.v2.service:ListService
|
volume_service_list = openstackclient.volume.v3.service:ListService
|
||||||
volume_service_set = openstackclient.volume.v2.service:SetService
|
volume_service_set = openstackclient.volume.v2.service:SetService
|
||||||
|
|
||||||
volume_transfer_request_accept = openstackclient.volume.v2.volume_transfer_request:AcceptTransferRequest
|
volume_transfer_request_accept = openstackclient.volume.v2.volume_transfer_request:AcceptTransferRequest
|
||||||
|
Loading…
Reference in New Issue
Block a user