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 <sean.mcginnis@gmail.com>
This commit is contained in:
parent
4e6f47e28e
commit
4039d0d94f
8
doc/source/cli/command-objects/volume-backend.rst
Normal file
8
doc/source/cli/command-objects/volume-backend.rst
Normal file
@ -0,0 +1,8 @@
|
||||
==============
|
||||
volume backend
|
||||
==============
|
||||
|
||||
Volume v2
|
||||
|
||||
.. autoprogram-cliff:: openstack.volume.v2
|
||||
:command: volume backend *
|
@ -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
|
||||
|
@ -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.
|
||||
|
|
@ -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):
|
||||
|
73
openstackclient/tests/unit/volume/v2/test_volume_backend.py
Normal file
73
openstackclient/tests/unit/volume/v2/test_volume_backend.py
Normal file
@ -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',
|
||||
)
|
61
openstackclient/volume/v2/volume_backend.py
Normal file
61
openstackclient/volume/v2/volume_backend.py
Normal file
@ -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="<host>",
|
||||
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))
|
7
releasenotes/notes/volume-backend-c5faae0b31556a24.yaml
Normal file
7
releasenotes/notes/volume-backend-c5faae0b31556a24.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
A new command, ``openstack volume backend capability show <host>`` was
|
||||
added which will provide a list of all capabilities that can be configured
|
||||
for the requested backend. The required `<host>` parameter takes the form
|
||||
`host@backend-name`.
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user