Skip to content

Commit e7ebf75

Browse files
committed
Add volume revert command
This command allows users to revert a volume to a given snapshot. Change-Id: If35ee394d654f5264558a281c835affff524ca50
1 parent 1e0880e commit e7ebf75

File tree

6 files changed

+101
-1
lines changed

6 files changed

+101
-1
lines changed

doc/source/cli/command-objects/volume.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,3 +393,6 @@ Block Storage v3
393393
394394
.. autoprogram-cliff:: openstack.volume.v3
395395
:command: volume summary
396+
397+
.. autoprogram-cliff:: openstack.volume.v3
398+
:command: volume revert

doc/source/cli/data/cinder.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ readonly-mode-update,volume set --read-only-mode | --read-write-mode,Updates vol
100100
rename,volume set --name,Renames a volume.
101101
reset-state,volume set --state,Explicitly updates the volume state.
102102
retype,volume type set --type,Changes the volume type for a volume.
103-
revert-to-snapshot,,Revert a volume to the specified snapshot. (Supported by API versions 3.40 - 3.latest)
103+
revert-to-snapshot,volume revert,Revert a volume to the specified snapshot. (Supported by API versions 3.40 - 3.latest)
104104
service-disable,volume service set --disable,Disables the service.
105105
service-enable,volume service set --enable,Enables the service.
106106
service-get-log,,(Supported by API versions 3.32 - 3.latest)

openstackclient/tests/unit/volume/v3/test_volume.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
#
1414

1515
import copy
16+
from unittest import mock
1617

1718
from cinderclient import api_versions
1819
from osc_lib.cli import format_columns
1920
from osc_lib import exceptions
21+
from osc_lib import utils
2022

2123
from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
2224
from openstackclient.volume.v3 import volume
@@ -119,3 +121,59 @@ def test_volume_summary_with_metadata(self):
119121
self.mock_vol_1.size + self.mock_vol_2.size,
120122
format_columns.DictColumn(combine_meta))
121123
self.assertCountEqual(datalist, tuple(data))
124+
125+
126+
class TestVolumeRevertToSnapshot(volume_fakes.TestVolume):
127+
128+
def setUp(self):
129+
super().setUp()
130+
131+
self.volumes_mock = self.app.client_manager.volume.volumes
132+
self.volumes_mock.reset_mock()
133+
self.snapshots_mock = self.app.client_manager.volume.volume_snapshots
134+
self.snapshots_mock.reset_mock()
135+
self.mock_volume = volume_fakes.create_one_volume()
136+
self.mock_snapshot = volume_fakes.create_one_snapshot(
137+
attrs={'volume_id': self.volumes_mock.id})
138+
139+
# Get the command object to test
140+
self.cmd = volume.VolumeRevertToSnapshot(self.app, None)
141+
142+
def test_volume_revert_to_snapshot_pre_340(self):
143+
arglist = [
144+
self.mock_snapshot.id,
145+
]
146+
verifylist = [
147+
('snapshot', self.mock_snapshot.id),
148+
]
149+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
150+
151+
exc = self.assertRaises(
152+
exceptions.CommandError,
153+
self.cmd.take_action,
154+
parsed_args)
155+
self.assertIn(
156+
'--os-volume-api-version 3.40 or greater is required',
157+
str(exc))
158+
159+
def test_volume_revert_to_snapshot(self):
160+
self.app.client_manager.volume.api_version = \
161+
api_versions.APIVersion('3.40')
162+
arglist = [
163+
self.mock_snapshot.id,
164+
]
165+
verifylist = [
166+
('snapshot', self.mock_snapshot.id),
167+
]
168+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
169+
170+
find_mock_result = [self.mock_snapshot, self.mock_volume]
171+
with mock.patch.object(utils, 'find_resource',
172+
side_effect=find_mock_result) as find_mock:
173+
self.cmd.take_action(parsed_args)
174+
175+
self.volumes_mock.revert_to_snapshot.assert_called_once_with(
176+
volume=self.mock_volume,
177+
snapshot=self.mock_snapshot,
178+
)
179+
self.assertEqual(2, find_mock.call_count)

openstackclient/volume/v3/volume.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,36 @@ def take_action(self, parsed_args):
7979
formatters={'metadata': format_columns.DictColumn},
8080
),
8181
)
82+
83+
84+
class VolumeRevertToSnapshot(command.Command):
85+
_description = _("Revert a volume to a snapshot.")
86+
87+
def get_parser(self, prog_name):
88+
parser = super().get_parser(prog_name)
89+
parser.add_argument(
90+
'snapshot',
91+
metavar="<snapshot>",
92+
help=_('Name or ID of the snapshot to restore. The snapshot must '
93+
'be the most recent one known to cinder.'),
94+
)
95+
return parser
96+
97+
def take_action(self, parsed_args):
98+
99+
volume_client = self.app.client_manager.volume
100+
101+
if volume_client.api_version < api_versions.APIVersion('3.40'):
102+
msg = _(
103+
"--os-volume-api-version 3.40 or greater is required to "
104+
"support the 'volume revert snapshot' command"
105+
)
106+
raise exceptions.CommandError(msg)
107+
108+
snapshot = utils.find_resource(
109+
volume_client.volume_snapshots, parsed_args.snapshot)
110+
volume = utils.find_resource(
111+
volume_client.volumes, snapshot.volume_id)
112+
113+
volume_client.volumes.revert_to_snapshot(
114+
volume=volume, snapshot=snapshot)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
features:
3+
- |
4+
Added ``volume revert`` command that reverts
5+
the volume to the given snapshot.

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,3 +821,4 @@ openstack.volume.v3 =
821821
volume_transfer_request_show = openstackclient.volume.v2.volume_transfer_request:ShowTransferRequest
822822

823823
volume_summary = openstackclient.volume.v3.volume:VolumeSummary
824+
volume_revert = openstackclient.volume.v3.volume:VolumeRevertToSnapshot

0 commit comments

Comments
 (0)