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:
		
							
								
								
									
										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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user