Implement "consistency group list" command

Add "consistency group" object in volume v2 (v2 only)
and implement "consistency group list" command

Change-Id: Ifa90d97f4b223f9a5b00708cff07fa2c5e2635f0
Implements: bp cinder-command-support
Partial-Bug: #1613964
Co-Authored-By: Sheel Rana <ranasheel2000@gmail.com>
This commit is contained in:
Huanxuan Ao 2016-08-17 16:31:40 +08:00
parent 81a2b9a6bc
commit 8d63b8b263
7 changed files with 267 additions and 0 deletions

View File

@ -0,0 +1,26 @@
=================
consistency group
=================
Block Storage v2
consistency group list
----------------------
List consistency groups.
.. program:: consistency group list
.. code:: bash
os consistency group list
[--all-projects]
[--long]
.. option:: --all-projects
Show detail for all projects. Admin only.
(defaults to False)
.. option:: --long
List additional fields in output

View File

@ -80,6 +80,7 @@ referring to both Compute and Volume quotas.
* ``compute agent``: (**Compute**) a cloud Compute agent available to a hypervisor * ``compute agent``: (**Compute**) a cloud Compute agent available to a hypervisor
* ``compute service``: (**Compute**) a cloud Compute process running on a host * ``compute service``: (**Compute**) a cloud Compute process running on a host
* ``configuration``: (**Internal**) OpenStack client configuration * ``configuration``: (**Internal**) OpenStack client configuration
* ``consistency group``: (**Volume**) a consistency group of volumes
* ``console log``: (**Compute**) server console text dump * ``console log``: (**Compute**) server console text dump
* ``console url``: (**Compute**) server remote console URL * ``console url``: (**Compute**) server remote console URL
* ``consumer``: (**Identity**) OAuth-based delegatee * ``consumer``: (**Identity**) OAuth-based delegatee

View File

@ -222,6 +222,8 @@ class FakeVolumeClient(object):
self.quotas.resource_class = fakes.FakeResource(None, {}) self.quotas.resource_class = fakes.FakeResource(None, {})
self.quota_classes = mock.Mock() self.quota_classes = mock.Mock()
self.quota_classes.resource_class = fakes.FakeResource(None, {}) self.quota_classes.resource_class = fakes.FakeResource(None, {})
self.consistencygroups = mock.Mock()
self.consistencygroups.resource_class = fakes.FakeResource(None, {})
self.auth_token = kwargs['token'] self.auth_token = kwargs['token']
self.management_url = kwargs['endpoint'] self.management_url = kwargs['endpoint']
@ -493,6 +495,59 @@ class FakeBackup(object):
return mock.Mock(side_effect=backups) return mock.Mock(side_effect=backups)
class FakeConsistencyGroup(object):
"""Fake one or more consistency group."""
@staticmethod
def create_one_consistency_group(attrs=None):
"""Create a fake consistency group.
:param Dictionary attrs:
A dictionary with all attributes
:return:
A FakeResource object with id, name, description, etc.
"""
attrs = attrs or {}
# Set default attributes.
consistency_group_info = {
"id": 'backup-id-' + uuid.uuid4().hex,
"name": 'backup-name-' + uuid.uuid4().hex,
"description": 'description-' + uuid.uuid4().hex,
"status": "error",
"availability_zone": 'zone' + uuid.uuid4().hex,
"created_at": 'time-' + uuid.uuid4().hex,
"volume_types": ['volume-type1'],
}
# Overwrite default attributes.
consistency_group_info.update(attrs)
consistency_group = fakes.FakeResource(
info=copy.deepcopy(consistency_group_info),
loaded=True)
return consistency_group
@staticmethod
def create_consistency_groups(attrs=None, count=2):
"""Create multiple fake consistency groups.
:param Dictionary attrs:
A dictionary with all attributes
:param int count:
The number of consistency groups to fake
:return:
A list of FakeResource objects faking the consistency groups
"""
consistency_groups = []
for i in range(0, count):
consistency_group = (
FakeConsistencyGroup.create_one_consistency_group(attrs))
consistency_groups.append(consistency_group)
return consistency_groups
class FakeExtension(object): class FakeExtension(object):
"""Fake one or more extension.""" """Fake one or more extension."""

View File

@ -0,0 +1,122 @@
#
# 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 osc_lib import utils
from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
from openstackclient.volume.v2 import consistency_group
class TestConsistencyGroup(volume_fakes.TestVolume):
def setUp(self):
super(TestConsistencyGroup, self).setUp()
# Get a shortcut to the TransferManager Mock
self.consistencygroups_mock = (
self.app.client_manager.volume.consistencygroups)
self.consistencygroups_mock.reset_mock()
class TestConsistencyGroupList(TestConsistencyGroup):
consistency_groups = (
volume_fakes.FakeConsistencyGroup.create_consistency_groups(count=2))
columns = [
'ID',
'Status',
'Name',
]
columns_long = [
'ID',
'Status',
'Availability Zone',
'Name',
'Description',
'Volume Types',
]
data = []
for c in consistency_groups:
data.append((
c.id,
c.status,
c.name,
))
data_long = []
for c in consistency_groups:
data_long.append((
c.id,
c.status,
c.availability_zone,
c.name,
c.description,
utils.format_list(c.volume_types)
))
def setUp(self):
super(TestConsistencyGroupList, self).setUp()
self.consistencygroups_mock.list.return_value = self.consistency_groups
# Get the command to test
self.cmd = consistency_group.ListConsistencyGroup(self.app, None)
def test_consistency_group_list_without_options(self):
arglist = []
verifylist = [
("all_projects", False),
("long", False),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.consistencygroups_mock.list.assert_called_once_with(
detailed=True, search_opts={'all_tenants': False})
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
def test_consistency_group_list_with_all_project(self):
arglist = [
"--all-projects"
]
verifylist = [
("all_projects", True),
("long", False),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.consistencygroups_mock.list.assert_called_once_with(
detailed=True, search_opts={'all_tenants': True})
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
def test_consistency_group_list_with_long(self):
arglist = [
"--long",
]
verifylist = [
("all_projects", False),
("long", True),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.consistencygroups_mock.list.assert_called_once_with(
detailed=True, search_opts={'all_tenants': False})
self.assertEqual(self.columns_long, columns)
self.assertEqual(self.data_long, list(data))

View File

@ -0,0 +1,57 @@
#
# 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.
#
"""Volume v2 consistency group action implementations"""
from osc_lib.command import command
from osc_lib import utils
from openstackclient.i18n import _
class ListConsistencyGroup(command.Lister):
"""List consistency groups."""
def get_parser(self, prog_name):
parser = super(ListConsistencyGroup, self).get_parser(prog_name)
parser.add_argument(
'--all-projects',
action="store_true",
help=_('Show detail for all projects. Admin only. '
'(defaults to False)')
)
parser.add_argument(
'--long',
action="store_true",
help=_('List additional fields in output')
)
return parser
def take_action(self, parsed_args):
if parsed_args.long:
columns = ['ID', 'Status', 'Availability Zone',
'Name', 'Description', 'Volume Types']
else:
columns = ['ID', 'Status', 'Name']
volume_client = self.app.client_manager.volume
consistency_groups = volume_client.consistencygroups.list(
detailed=True,
search_opts={'all_tenants': parsed_args.all_projects}
)
return (columns, (
utils.get_item_properties(
s, columns,
formatters={'Volume Types': utils.format_list})
for s in consistency_groups))

View File

@ -0,0 +1,4 @@
---
features:
- Add ``consistency group list`` command in volume v2.
[Bug `1613964 <https://bugs.launchpad.net/python-openstackclient/+bug/1613964>`_]

View File

@ -499,6 +499,8 @@ openstack.volume.v2 =
backup_restore = openstackclient.volume.v2.backup:RestoreBackup backup_restore = openstackclient.volume.v2.backup:RestoreBackup
backup_show = openstackclient.volume.v2.backup:ShowBackup backup_show = openstackclient.volume.v2.backup:ShowBackup
consistency_group_list = openstackclient.volume.v2.consistency_group:ListConsistencyGroup
snapshot_create = openstackclient.volume.v2.snapshot:CreateSnapshot snapshot_create = openstackclient.volume.v2.snapshot:CreateSnapshot
snapshot_delete = openstackclient.volume.v2.snapshot:DeleteSnapshot snapshot_delete = openstackclient.volume.v2.snapshot:DeleteSnapshot
snapshot_list = openstackclient.volume.v2.snapshot:ListSnapshot snapshot_list = openstackclient.volume.v2.snapshot:ListSnapshot