Skip to content

Commit 08df1d0

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Implement "consistency group list" command"
2 parents f41e27e + 8d63b8b commit 08df1d0

7 files changed

Lines changed: 267 additions & 0 deletions

File tree

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
=================
2+
consistency group
3+
=================
4+
5+
Block Storage v2
6+
7+
consistency group list
8+
----------------------
9+
10+
List consistency groups.
11+
12+
.. program:: consistency group list
13+
.. code:: bash
14+
15+
os consistency group list
16+
[--all-projects]
17+
[--long]
18+
19+
.. option:: --all-projects
20+
21+
Show detail for all projects. Admin only.
22+
(defaults to False)
23+
24+
.. option:: --long
25+
26+
List additional fields in output

doc/source/commands.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ referring to both Compute and Volume quotas.
8080
* ``compute agent``: (**Compute**) a cloud Compute agent available to a hypervisor
8181
* ``compute service``: (**Compute**) a cloud Compute process running on a host
8282
* ``configuration``: (**Internal**) OpenStack client configuration
83+
* ``consistency group``: (**Volume**) a consistency group of volumes
8384
* ``console log``: (**Compute**) server console text dump
8485
* ``console url``: (**Compute**) server remote console URL
8586
* ``consumer``: (**Identity**) OAuth-based delegatee

openstackclient/tests/unit/volume/v2/fakes.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ def __init__(self, **kwargs):
222222
self.quotas.resource_class = fakes.FakeResource(None, {})
223223
self.quota_classes = mock.Mock()
224224
self.quota_classes.resource_class = fakes.FakeResource(None, {})
225+
self.consistencygroups = mock.Mock()
226+
self.consistencygroups.resource_class = fakes.FakeResource(None, {})
225227
self.auth_token = kwargs['token']
226228
self.management_url = kwargs['endpoint']
227229

@@ -493,6 +495,59 @@ def get_backups(backups=None, count=2):
493495
return mock.Mock(side_effect=backups)
494496

495497

498+
class FakeConsistencyGroup(object):
499+
"""Fake one or more consistency group."""
500+
501+
@staticmethod
502+
def create_one_consistency_group(attrs=None):
503+
"""Create a fake consistency group.
504+
505+
:param Dictionary attrs:
506+
A dictionary with all attributes
507+
:return:
508+
A FakeResource object with id, name, description, etc.
509+
"""
510+
attrs = attrs or {}
511+
512+
# Set default attributes.
513+
consistency_group_info = {
514+
"id": 'backup-id-' + uuid.uuid4().hex,
515+
"name": 'backup-name-' + uuid.uuid4().hex,
516+
"description": 'description-' + uuid.uuid4().hex,
517+
"status": "error",
518+
"availability_zone": 'zone' + uuid.uuid4().hex,
519+
"created_at": 'time-' + uuid.uuid4().hex,
520+
"volume_types": ['volume-type1'],
521+
}
522+
523+
# Overwrite default attributes.
524+
consistency_group_info.update(attrs)
525+
526+
consistency_group = fakes.FakeResource(
527+
info=copy.deepcopy(consistency_group_info),
528+
loaded=True)
529+
return consistency_group
530+
531+
@staticmethod
532+
def create_consistency_groups(attrs=None, count=2):
533+
"""Create multiple fake consistency groups.
534+
535+
:param Dictionary attrs:
536+
A dictionary with all attributes
537+
:param int count:
538+
The number of consistency groups to fake
539+
:return:
540+
A list of FakeResource objects faking the consistency groups
541+
"""
542+
consistency_groups = []
543+
for i in range(0, count):
544+
consistency_group = (
545+
FakeConsistencyGroup.create_one_consistency_group(attrs))
546+
consistency_groups.append(consistency_group)
547+
548+
return consistency_groups
549+
550+
496551
class FakeExtension(object):
497552
"""Fake one or more extension."""
498553

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#
2+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
3+
# not use this file except in compliance with the License. You may obtain
4+
# a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11+
# License for the specific language governing permissions and limitations
12+
# under the License.
13+
#
14+
15+
from osc_lib import utils
16+
17+
from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
18+
from openstackclient.volume.v2 import consistency_group
19+
20+
21+
class TestConsistencyGroup(volume_fakes.TestVolume):
22+
23+
def setUp(self):
24+
super(TestConsistencyGroup, self).setUp()
25+
26+
# Get a shortcut to the TransferManager Mock
27+
self.consistencygroups_mock = (
28+
self.app.client_manager.volume.consistencygroups)
29+
self.consistencygroups_mock.reset_mock()
30+
31+
32+
class TestConsistencyGroupList(TestConsistencyGroup):
33+
34+
consistency_groups = (
35+
volume_fakes.FakeConsistencyGroup.create_consistency_groups(count=2))
36+
37+
columns = [
38+
'ID',
39+
'Status',
40+
'Name',
41+
]
42+
columns_long = [
43+
'ID',
44+
'Status',
45+
'Availability Zone',
46+
'Name',
47+
'Description',
48+
'Volume Types',
49+
]
50+
data = []
51+
for c in consistency_groups:
52+
data.append((
53+
c.id,
54+
c.status,
55+
c.name,
56+
))
57+
data_long = []
58+
for c in consistency_groups:
59+
data_long.append((
60+
c.id,
61+
c.status,
62+
c.availability_zone,
63+
c.name,
64+
c.description,
65+
utils.format_list(c.volume_types)
66+
))
67+
68+
def setUp(self):
69+
super(TestConsistencyGroupList, self).setUp()
70+
71+
self.consistencygroups_mock.list.return_value = self.consistency_groups
72+
# Get the command to test
73+
self.cmd = consistency_group.ListConsistencyGroup(self.app, None)
74+
75+
def test_consistency_group_list_without_options(self):
76+
arglist = []
77+
verifylist = [
78+
("all_projects", False),
79+
("long", False),
80+
]
81+
82+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
83+
columns, data = self.cmd.take_action(parsed_args)
84+
85+
self.consistencygroups_mock.list.assert_called_once_with(
86+
detailed=True, search_opts={'all_tenants': False})
87+
self.assertEqual(self.columns, columns)
88+
self.assertEqual(self.data, list(data))
89+
90+
def test_consistency_group_list_with_all_project(self):
91+
arglist = [
92+
"--all-projects"
93+
]
94+
verifylist = [
95+
("all_projects", True),
96+
("long", False),
97+
]
98+
99+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
100+
columns, data = self.cmd.take_action(parsed_args)
101+
102+
self.consistencygroups_mock.list.assert_called_once_with(
103+
detailed=True, search_opts={'all_tenants': True})
104+
self.assertEqual(self.columns, columns)
105+
self.assertEqual(self.data, list(data))
106+
107+
def test_consistency_group_list_with_long(self):
108+
arglist = [
109+
"--long",
110+
]
111+
verifylist = [
112+
("all_projects", False),
113+
("long", True),
114+
]
115+
116+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
117+
columns, data = self.cmd.take_action(parsed_args)
118+
119+
self.consistencygroups_mock.list.assert_called_once_with(
120+
detailed=True, search_opts={'all_tenants': False})
121+
self.assertEqual(self.columns_long, columns)
122+
self.assertEqual(self.data_long, list(data))
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#
2+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
3+
# not use this file except in compliance with the License. You may obtain
4+
# a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11+
# License for the specific language governing permissions and limitations
12+
# under the License.
13+
#
14+
15+
"""Volume v2 consistency group action implementations"""
16+
17+
from osc_lib.command import command
18+
from osc_lib import utils
19+
20+
from openstackclient.i18n import _
21+
22+
23+
class ListConsistencyGroup(command.Lister):
24+
"""List consistency groups."""
25+
26+
def get_parser(self, prog_name):
27+
parser = super(ListConsistencyGroup, self).get_parser(prog_name)
28+
parser.add_argument(
29+
'--all-projects',
30+
action="store_true",
31+
help=_('Show detail for all projects. Admin only. '
32+
'(defaults to False)')
33+
)
34+
parser.add_argument(
35+
'--long',
36+
action="store_true",
37+
help=_('List additional fields in output')
38+
)
39+
return parser
40+
41+
def take_action(self, parsed_args):
42+
if parsed_args.long:
43+
columns = ['ID', 'Status', 'Availability Zone',
44+
'Name', 'Description', 'Volume Types']
45+
else:
46+
columns = ['ID', 'Status', 'Name']
47+
volume_client = self.app.client_manager.volume
48+
consistency_groups = volume_client.consistencygroups.list(
49+
detailed=True,
50+
search_opts={'all_tenants': parsed_args.all_projects}
51+
)
52+
53+
return (columns, (
54+
utils.get_item_properties(
55+
s, columns,
56+
formatters={'Volume Types': utils.format_list})
57+
for s in consistency_groups))
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
features:
3+
- Add ``consistency group list`` command in volume v2.
4+
[Bug `1613964 <https://bugs.launchpad.net/python-openstackclient/+bug/1613964>`_]

setup.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,8 @@ openstack.volume.v2 =
499499
backup_restore = openstackclient.volume.v2.backup:RestoreBackup
500500
backup_show = openstackclient.volume.v2.backup:ShowBackup
501501

502+
consistency_group_list = openstackclient.volume.v2.consistency_group:ListConsistencyGroup
503+
502504
snapshot_create = openstackclient.volume.v2.snapshot:CreateSnapshot
503505
snapshot_delete = openstackclient.volume.v2.snapshot:DeleteSnapshot
504506
snapshot_list = openstackclient.volume.v2.snapshot:ListSnapshot

0 commit comments

Comments
 (0)