Merge "Support for volume service list"
This commit is contained in:
		
							
								
								
									
										31
									
								
								doc/source/command-objects/volume-service.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								doc/source/command-objects/volume-service.rst
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
==============
 | 
			
		||||
volume service
 | 
			
		||||
==============
 | 
			
		||||
 | 
			
		||||
Volume v1, v2
 | 
			
		||||
 | 
			
		||||
volume service list
 | 
			
		||||
-------------------
 | 
			
		||||
 | 
			
		||||
List volume service
 | 
			
		||||
 | 
			
		||||
.. program:: volume service list
 | 
			
		||||
.. code:: bash
 | 
			
		||||
 | 
			
		||||
    os volume service list
 | 
			
		||||
        [--host <host>]
 | 
			
		||||
        [--service <service>]
 | 
			
		||||
        [--long]
 | 
			
		||||
 | 
			
		||||
.. _volume-service-list:
 | 
			
		||||
.. option:: --host <host>
 | 
			
		||||
 | 
			
		||||
    List services on specified host (name only)
 | 
			
		||||
 | 
			
		||||
.. option:: --service <service>
 | 
			
		||||
 | 
			
		||||
    List only specified service (name only)
 | 
			
		||||
 | 
			
		||||
.. option:: --long
 | 
			
		||||
 | 
			
		||||
    List additional fields in output
 | 
			
		||||
@@ -133,6 +133,7 @@ referring to both Compute and Volume quotas.
 | 
			
		||||
* ``volume``: (**Volume**) block volumes
 | 
			
		||||
* ``volume qos``: (**Volume**) quality-of-service (QoS) specification for volumes
 | 
			
		||||
* ``volume type``: (**Volume**) deployment-specific types of volumes available
 | 
			
		||||
* ``volume service``: (**Volume**) services to manage block storage operations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Plugin Objects
 | 
			
		||||
 
 | 
			
		||||
@@ -129,6 +129,97 @@ QOS_WITH_ASSOCIATIONS = {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FakeServiceClient(object):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, **kwargs):
 | 
			
		||||
        self.services = mock.Mock()
 | 
			
		||||
        self.services.resource_class = fakes.FakeResource(None, {})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestService(utils.TestCommand):
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestService, self).setUp()
 | 
			
		||||
 | 
			
		||||
        self.app.client_manager.volume = FakeServiceClient(
 | 
			
		||||
            endpoint=fakes.AUTH_URL,
 | 
			
		||||
            token=fakes.AUTH_TOKEN
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FakeService(object):
 | 
			
		||||
    """Fake one or more Services."""
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def create_one_service(attrs=None):
 | 
			
		||||
        """Create a fake service.
 | 
			
		||||
 | 
			
		||||
        :param Dictionary attrs:
 | 
			
		||||
            A dictionary with all attributes of service
 | 
			
		||||
        :retrun:
 | 
			
		||||
            A FakeResource object with host, status, etc.
 | 
			
		||||
        """
 | 
			
		||||
        # Set default attribute
 | 
			
		||||
        service_info = {
 | 
			
		||||
            'host': 'host_test',
 | 
			
		||||
            'binary': 'cinder_test',
 | 
			
		||||
            'status': 'enabled',
 | 
			
		||||
            'disabled_reason': 'LongHoliday-GoldenWeek',
 | 
			
		||||
            'zone': 'fake_zone',
 | 
			
		||||
            'updated_at': 'fake_date',
 | 
			
		||||
            'state': 'fake_state',
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Overwrite default attributes if there are some attributes set
 | 
			
		||||
        if attrs is None:
 | 
			
		||||
            attrs = {}
 | 
			
		||||
        service_info.update(attrs)
 | 
			
		||||
 | 
			
		||||
        service = fakes.FakeResource(
 | 
			
		||||
            None,
 | 
			
		||||
            service_info,
 | 
			
		||||
            loaded=True)
 | 
			
		||||
 | 
			
		||||
        return service
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def create_services(attrs=None, count=2):
 | 
			
		||||
        """Create multiple fake services.
 | 
			
		||||
 | 
			
		||||
        :param Dictionary attrs:
 | 
			
		||||
            A dictionary with all attributes of service
 | 
			
		||||
        :param Integer count:
 | 
			
		||||
            The number of services to be faked
 | 
			
		||||
        :return:
 | 
			
		||||
            A list of FakeResource objects
 | 
			
		||||
        """
 | 
			
		||||
        services = []
 | 
			
		||||
        for n in range(0, count):
 | 
			
		||||
            services.append(FakeService.create_one_service(attrs))
 | 
			
		||||
 | 
			
		||||
        return services
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def get_services(services=None, count=2):
 | 
			
		||||
        """Get an iterable MagicMock object with a list of faked services.
 | 
			
		||||
 | 
			
		||||
        If services list is provided, then initialize the Mock object with the
 | 
			
		||||
        list. Otherwise create one.
 | 
			
		||||
 | 
			
		||||
        :param List services:
 | 
			
		||||
            A list of FakeResource objects faking services
 | 
			
		||||
        :param Integer count:
 | 
			
		||||
            The number of services to be faked
 | 
			
		||||
        :return
 | 
			
		||||
            An iterable Mock object with side_effect set to a list of faked
 | 
			
		||||
            services
 | 
			
		||||
        """
 | 
			
		||||
        if services is None:
 | 
			
		||||
            services = FakeService.create_services(count)
 | 
			
		||||
 | 
			
		||||
        return mock.MagicMock(side_effect=services)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FakeImagev1Client(object):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, **kwargs):
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										141
									
								
								openstackclient/tests/volume/v1/test_service.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								openstackclient/tests/volume/v1/test_service.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,141 @@
 | 
			
		||||
#
 | 
			
		||||
#   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.volume.v1 import fakes as service_fakes
 | 
			
		||||
from openstackclient.volume.v1 import service
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestService(service_fakes.TestService):
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestService, self).setUp()
 | 
			
		||||
 | 
			
		||||
        # Get a shortcut to the ServiceManager Mock
 | 
			
		||||
        self.service_mock = self.app.client_manager.volume.services
 | 
			
		||||
        self.service_mock.reset_mock()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestServiceList(TestService):
 | 
			
		||||
 | 
			
		||||
    # The service to be listed
 | 
			
		||||
    services = service_fakes.FakeService.create_one_service()
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestServiceList, self).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,
 | 
			
		||||
        )
 | 
			
		||||
@@ -232,6 +232,97 @@ EXTENSION = {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FakeServiceClient(object):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, **kwargs):
 | 
			
		||||
        self.services = mock.Mock()
 | 
			
		||||
        self.services.resource_class = fakes.FakeResource(None, {})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestService(utils.TestCommand):
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestService, self).setUp()
 | 
			
		||||
 | 
			
		||||
        self.app.client_manager.volume = FakeServiceClient(
 | 
			
		||||
            endpoint=fakes.AUTH_URL,
 | 
			
		||||
            token=fakes.AUTH_TOKEN
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FakeService(object):
 | 
			
		||||
    """Fake one or more Services."""
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def create_one_service(attrs=None):
 | 
			
		||||
        """Create a fake service.
 | 
			
		||||
 | 
			
		||||
        :param Dictionary attrs:
 | 
			
		||||
            A dictionary with all attributes of service
 | 
			
		||||
        :retrun:
 | 
			
		||||
            A FakeResource object with host, status, etc.
 | 
			
		||||
        """
 | 
			
		||||
        # Set default attribute
 | 
			
		||||
        service_info = {
 | 
			
		||||
            'host': 'host_test',
 | 
			
		||||
            'binary': 'cinder_test',
 | 
			
		||||
            'status': 'enabled',
 | 
			
		||||
            'disabled_reason': 'LongHoliday-GoldenWeek',
 | 
			
		||||
            'zone': 'fake_zone',
 | 
			
		||||
            'updated_at': 'fake_date',
 | 
			
		||||
            'state': 'fake_state',
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Overwrite default attributes if there are some attributes set
 | 
			
		||||
        if attrs is None:
 | 
			
		||||
            attrs = {}
 | 
			
		||||
        service_info.update(attrs)
 | 
			
		||||
 | 
			
		||||
        service = fakes.FakeResource(
 | 
			
		||||
            None,
 | 
			
		||||
            service_info,
 | 
			
		||||
            loaded=True)
 | 
			
		||||
 | 
			
		||||
        return service
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def create_services(attrs=None, count=2):
 | 
			
		||||
        """Create multiple fake services.
 | 
			
		||||
 | 
			
		||||
        :param Dictionary attrs:
 | 
			
		||||
            A dictionary with all attributes of service
 | 
			
		||||
        :param Integer count:
 | 
			
		||||
            The number of services to be faked
 | 
			
		||||
        :return:
 | 
			
		||||
            A list of FakeResource objects
 | 
			
		||||
        """
 | 
			
		||||
        services = []
 | 
			
		||||
        for n in range(0, count):
 | 
			
		||||
            services.append(FakeService.create_one_service(attrs))
 | 
			
		||||
 | 
			
		||||
        return services
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def get_services(services=None, count=2):
 | 
			
		||||
        """Get an iterable MagicMock object with a list of faked services.
 | 
			
		||||
 | 
			
		||||
        If services list is provided, then initialize the Mock object with the
 | 
			
		||||
        list. Otherwise create one.
 | 
			
		||||
 | 
			
		||||
        :param List services:
 | 
			
		||||
            A list of FakeResource objects faking services
 | 
			
		||||
        :param Integer count:
 | 
			
		||||
            The number of services to be faked
 | 
			
		||||
        :return
 | 
			
		||||
            An iterable Mock object with side_effect set to a list of faked
 | 
			
		||||
            services
 | 
			
		||||
        """
 | 
			
		||||
        if services is None:
 | 
			
		||||
            services = FakeService.create_services(count)
 | 
			
		||||
 | 
			
		||||
        return mock.MagicMock(side_effect=services)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FakeVolumeClient(object):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, **kwargs):
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										141
									
								
								openstackclient/tests/volume/v2/test_service.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								openstackclient/tests/volume/v2/test_service.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,141 @@
 | 
			
		||||
#
 | 
			
		||||
#   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.volume.v2 import fakes as service_fakes
 | 
			
		||||
from openstackclient.volume.v2 import service
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestService(service_fakes.TestService):
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestService, self).setUp()
 | 
			
		||||
 | 
			
		||||
        # Get a shortcut to the ServiceManager Mock
 | 
			
		||||
        self.service_mock = self.app.client_manager.volume.services
 | 
			
		||||
        self.service_mock.reset_mock()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestServiceList(TestService):
 | 
			
		||||
 | 
			
		||||
    # The service to be listed
 | 
			
		||||
    services = service_fakes.FakeService.create_one_service()
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestServiceList, self).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,
 | 
			
		||||
        )
 | 
			
		||||
							
								
								
									
										70
									
								
								openstackclient/volume/v1/service.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								openstackclient/volume/v1/service.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
#
 | 
			
		||||
#   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 openstackclient.common import command
 | 
			
		||||
from openstackclient.common import utils
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListService(command.Lister):
 | 
			
		||||
    """List service command"""
 | 
			
		||||
 | 
			
		||||
    def get_parser(self, prog_name):
 | 
			
		||||
        parser = super(ListService, self).get_parser(prog_name)
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            "--host",
 | 
			
		||||
            metavar="<host>",
 | 
			
		||||
            help="List services on specified host (name only)")
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            "--service",
 | 
			
		||||
            metavar="<service>",
 | 
			
		||||
            help="List only specified service (name only)")
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            "--long",
 | 
			
		||||
            action="store_true",
 | 
			
		||||
            default=False,
 | 
			
		||||
            help="List additional fields in output"
 | 
			
		||||
        )
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
    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"
 | 
			
		||||
            ]
 | 
			
		||||
 | 
			
		||||
        data = service_client.services.list(parsed_args.host,
 | 
			
		||||
                                            parsed_args.service)
 | 
			
		||||
        return (columns,
 | 
			
		||||
                (utils.get_item_properties(
 | 
			
		||||
                    s, columns,
 | 
			
		||||
                ) for s in data))
 | 
			
		||||
							
								
								
									
										70
									
								
								openstackclient/volume/v2/service.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								openstackclient/volume/v2/service.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
#
 | 
			
		||||
#   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 openstackclient.common import command
 | 
			
		||||
from openstackclient.common import utils
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListService(command.Lister):
 | 
			
		||||
    """List service command"""
 | 
			
		||||
 | 
			
		||||
    def get_parser(self, prog_name):
 | 
			
		||||
        parser = super(ListService, self).get_parser(prog_name)
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            "--host",
 | 
			
		||||
            metavar="<host>",
 | 
			
		||||
            help="List services on specified host (name only)")
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            "--service",
 | 
			
		||||
            metavar="<service>",
 | 
			
		||||
            help="List only specified service (name only)")
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            "--long",
 | 
			
		||||
            action="store_true",
 | 
			
		||||
            default=False,
 | 
			
		||||
            help="List additional fields in output"
 | 
			
		||||
        )
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
    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"
 | 
			
		||||
            ]
 | 
			
		||||
 | 
			
		||||
        data = service_client.services.list(parsed_args.host,
 | 
			
		||||
                                            parsed_args.service)
 | 
			
		||||
        return (columns,
 | 
			
		||||
                (utils.get_item_properties(
 | 
			
		||||
                    s, columns,
 | 
			
		||||
                ) for s in data))
 | 
			
		||||
							
								
								
									
										9
									
								
								releasenotes/notes/volume_service-5e352a71dfbc828d.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								releasenotes/notes/volume_service-5e352a71dfbc828d.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
---
 | 
			
		||||
features:
 | 
			
		||||
  - |
 | 
			
		||||
    Adds support for volume service list.
 | 
			
		||||
 | 
			
		||||
    An user can list available volume services by using
 | 
			
		||||
    ``volume service list``
 | 
			
		||||
 | 
			
		||||
    [Bug 1550999 'https://bugs.launchpad.net/python-openstackclient/+bug/1550999'_]
 | 
			
		||||
@@ -430,6 +430,8 @@ openstack.volume.v1 =
 | 
			
		||||
    volume_qos_show = openstackclient.volume.v1.qos_specs:ShowQos
 | 
			
		||||
    volume_qos_unset = openstackclient.volume.v1.qos_specs:UnsetQos
 | 
			
		||||
 | 
			
		||||
    volume_service_list = openstackclient.volume.v1.service:ListService
 | 
			
		||||
 | 
			
		||||
openstack.volume.v2 =
 | 
			
		||||
    backup_create = openstackclient.volume.v2.backup:CreateBackup
 | 
			
		||||
    backup_delete = openstackclient.volume.v2.backup:DeleteBackup
 | 
			
		||||
@@ -467,6 +469,8 @@ openstack.volume.v2 =
 | 
			
		||||
    volume_qos_show = openstackclient.volume.v2.qos_specs:ShowQos
 | 
			
		||||
    volume_qos_unset = openstackclient.volume.v2.qos_specs:UnsetQos
 | 
			
		||||
 | 
			
		||||
    volume_service_list = openstackclient.volume.v2.service:ListService
 | 
			
		||||
 | 
			
		||||
[build_sphinx]
 | 
			
		||||
source-dir = doc/source
 | 
			
		||||
build-dir = doc/build
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user