From 4039d0d94f4eaf277f2b42c33ef873555f84f159 Mon Sep 17 00:00:00 2001 From: Sean McGinnis Date: Tue, 9 Oct 2018 15:24:51 -0500 Subject: [PATCH] Add volume backend capability show command Adds and equivalend for "cinder get-capabilities" command to show the capabilities supported by a Cinder backend. Story: 1655624 Task: 26947 Change-Id: I38686a26cd503e45ce0102705a6632994ef10274 Signed-off-by: Sean McGinnis --- .../cli/command-objects/volume-backend.rst | 8 ++ doc/source/cli/commands.rst | 1 + doc/source/cli/data/cinder.csv | 2 +- openstackclient/tests/unit/volume/v2/fakes.py | 61 ++++++++++++++++ .../unit/volume/v2/test_volume_backend.py | 73 +++++++++++++++++++ openstackclient/volume/v2/volume_backend.py | 61 ++++++++++++++++ .../volume-backend-c5faae0b31556a24.yaml | 7 ++ setup.cfg | 2 + 8 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 doc/source/cli/command-objects/volume-backend.rst create mode 100644 openstackclient/tests/unit/volume/v2/test_volume_backend.py create mode 100644 openstackclient/volume/v2/volume_backend.py create mode 100644 releasenotes/notes/volume-backend-c5faae0b31556a24.yaml diff --git a/doc/source/cli/command-objects/volume-backend.rst b/doc/source/cli/command-objects/volume-backend.rst new file mode 100644 index 000000000..0285d61b8 --- /dev/null +++ b/doc/source/cli/command-objects/volume-backend.rst @@ -0,0 +1,8 @@ +============== +volume backend +============== + +Volume v2 + +.. autoprogram-cliff:: openstack.volume.v2 + :command: volume backend * diff --git a/doc/source/cli/commands.rst b/doc/source/cli/commands.rst index 76126a747..1ca674d54 100644 --- a/doc/source/cli/commands.rst +++ b/doc/source/cli/commands.rst @@ -156,6 +156,7 @@ referring to both Compute and Volume quotas. * ``user role``: (**Identity**) roles assigned to a user * ``volume``: (**Volume**) block volumes * ``volume backup``: (**Volume**) backup for volumes +* ``volume backend``: (**volume**) volume backend storage * ``volume host``: (**Volume**) the physical computer for volumes * ``volume qos``: (**Volume**) quality-of-service (QoS) specification for volumes * ``volume snapshot``: (**Volume**) a point-in-time copy of a volume diff --git a/doc/source/cli/data/cinder.csv b/doc/source/cli/data/cinder.csv index 5c89e0864..068ffb7fa 100644 --- a/doc/source/cli/data/cinder.csv +++ b/doc/source/cli/data/cinder.csv @@ -32,7 +32,7 @@ extra-specs-list,volume type list --long,Lists current volume types and extra sp failover-host,volume host failover,Failover a replicating cinder-volume host. force-delete,volume delete --force,"Attempts force-delete of volume, regardless of state." freeze-host,volume host set --disable,Freeze and disable the specified cinder-volume host. -get-capabilities,,Show backend volume stats and properties. Admin only. +get-capabilities,volume backend capability show,Show capabilities of a volume backend. Admin only. get-pools,,Show pool information for backends. Admin only. image-metadata,volume set --image-property,Sets or deletes volume image metadata. image-metadata-show,volume show,Shows volume image metadata. diff --git a/openstackclient/tests/unit/volume/v2/fakes.py b/openstackclient/tests/unit/volume/v2/fakes.py index 481509f3b..ad13f1b9c 100644 --- a/openstackclient/tests/unit/volume/v2/fakes.py +++ b/openstackclient/tests/unit/volume/v2/fakes.py @@ -193,6 +193,65 @@ class FakeService(object): return services +class FakeCapability(object): + """Fake capability.""" + + @staticmethod + def create_one_capability(attrs=None): + """Create a fake volume backend capability. + + :param Dictionary attrs: + A dictionary with all attributes of the Capabilities. + :return: + A FakeResource object with capability name and attrs. + """ + # Set default attribute + capability_info = { + "namespace": "OS::Storage::Capabilities::fake", + "vendor_name": "OpenStack", + "volume_backend_name": "lvmdriver-1", + "pool_name": "pool", + "driver_version": "2.0.0", + "storage_protocol": "iSCSI", + "display_name": "Capabilities of Cinder LVM driver", + "description": "Blah, blah.", + "visibility": "public", + "replication_targets": [], + "properties": { + "compression": { + "title": "Compression", + "description": "Enables compression.", + "type": "boolean" + }, + "qos": { + "title": "QoS", + "description": "Enables QoS.", + "type": "boolean" + }, + "replication": { + "title": "Replication", + "description": "Enables replication.", + "type": "boolean" + }, + "thin_provisioning": { + "title": "Thin Provisioning", + "description": "Sets thin provisioning.", + "type": "boolean" + } + } + } + + # Overwrite default attributes if there are some attributes set + capability_info.update(attrs or {}) + + capability = fakes.FakeResource( + None, + capability_info, + loaded=True) + + return capability + + class FakeVolumeClient(object): def __init__(self, **kwargs): @@ -233,6 +292,8 @@ class FakeVolumeClient(object): self.cgsnapshots.resource_class = fakes.FakeResource(None, {}) self.auth_token = kwargs['token'] self.management_url = kwargs['endpoint'] + self.capabilities = mock.Mock() + self.capabilities.resource_class = fakes.FakeResource(None, {}) class 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 new file mode 100644 index 000000000..73df6032d --- /dev/null +++ b/openstackclient/tests/unit/volume/v2/test_volume_backend.py @@ -0,0 +1,73 @@ +# +# 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 openstackclient.tests.unit.volume.v2 import fakes as volume_fakes +from openstackclient.volume.v2 import volume_backend + + +class TestShowVolumeCapability(volume_fakes.TestVolume): + """Test backend capability functionality.""" + + # The capability to be listed + capability = volume_fakes.FakeCapability.create_one_capability() + + def setUp(self): + super(TestShowVolumeCapability, self).setUp() + + # Get a shortcut to the capability Mock + self.capability_mock = self.app.client_manager.volume.capabilities + self.capability_mock.get.return_value = self.capability + + # Get the command object to test + self.cmd = volume_backend.ShowCapability(self.app, None) + + def test_capability_show(self): + arglist = [ + 'fake', + ] + verifylist = [ + ('host', 'fake'), + ] + 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 = [ + 'Title', + 'Key', + 'Type', + 'Description', + ] + + # confirming if all expected columns are present in the result. + self.assertEqual(expected_columns, columns) + + capabilities = [ + 'Compression', + 'Replication', + 'QoS', + 'Thin Provisioning', + ] + + # confirming if all expected values are present in the result. + for cap in data: + self.assertTrue(cap[0] in capabilities) + + # checking if proper call was made to get capabilities + self.capability_mock.get.assert_called_with( + 'fake', + ) diff --git a/openstackclient/volume/v2/volume_backend.py b/openstackclient/volume/v2/volume_backend.py new file mode 100644 index 000000000..0dff18c9a --- /dev/null +++ b/openstackclient/volume/v2/volume_backend.py @@ -0,0 +1,61 @@ +# +# 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. +# + +"""Capability action implementations""" + +from osc_lib.command import command +from osc_lib import utils + +from openstackclient.i18n import _ + + +class ShowCapability(command.Lister): + _description = _("Show capability command") + + def get_parser(self, prog_name): + parser = super(ShowCapability, self).get_parser(prog_name) + parser.add_argument( + "host", + metavar="", + help=_("List capabilities of specified host (host@backend-name)") + ) + return parser + + def take_action(self, parsed_args): + volume_client = self.app.client_manager.volume + + columns = [ + 'Title', + 'Key', + 'Type', + 'Description', + ] + + data = volume_client.capabilities.get(parsed_args.host) + + # The get capabilities API is... interesting. We only want the names of + # the capabilities that can set for a backend through extra specs, so + # we need to extract out that part of the mess that is returned. + print_data = [] + keys = data.properties + for key in keys: + # Stuff the key into the details to make it easier to output + capability_data = data.properties[key] + capability_data['key'] = key + print_data.append(capability_data) + + return (columns, + (utils.get_dict_properties( + s, columns, + ) for s in print_data)) diff --git a/releasenotes/notes/volume-backend-c5faae0b31556a24.yaml b/releasenotes/notes/volume-backend-c5faae0b31556a24.yaml new file mode 100644 index 000000000..851ab2dec --- /dev/null +++ b/releasenotes/notes/volume-backend-c5faae0b31556a24.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + A new command, ``openstack volume backend capability show `` was + added which will provide a list of all capabilities that can be configured + for the requested backend. The required `` parameter takes the form + `host@backend-name`. diff --git a/setup.cfg b/setup.cfg index d9ca47ca5..888e259b2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -629,6 +629,8 @@ openstack.volume.v2 = volume_backup_set = openstackclient.volume.v2.backup:SetVolumeBackup volume_backup_show = openstackclient.volume.v2.backup:ShowVolumeBackup + volume_backend_capability_show = openstackclient.volume.v2.volume_backend:ShowCapability + volume_host_failover = openstackclient.volume.v2.volume_host:FailoverVolumeHost volume_host_set = openstackclient.volume.v2.volume_host:SetVolumeHost