From 4e94c415ed57c0d6366a7e49259e79fd6505ed6a Mon Sep 17 00:00:00 2001 From: Rajat Dhasmana Date: Tue, 12 Sep 2023 16:08:35 +0530 Subject: [PATCH] Add volume snapshot unmanage support This patch adds support for unmanaging a snapshot with ``openstack volume snapshot delete --remote`` command. Change-Id: I3caf3471a007fcb988835d495727bbc5c66f42f8 --- .../unit/volume/v3/test_volume_snapshot.py | 50 ++++++++++++++++++- openstackclient/volume/v3/volume_snapshot.py | 27 ++++++++-- ...hot-unmanage-command-d4c0c8fd8b638d48.yaml | 5 ++ 3 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 releasenotes/notes/add-snapshot-unmanage-command-d4c0c8fd8b638d48.yaml diff --git a/openstackclient/tests/unit/volume/v3/test_volume_snapshot.py b/openstackclient/tests/unit/volume/v3/test_volume_snapshot.py index 3d5bc528ee..e07679fa83 100644 --- a/openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +++ b/openstackclient/tests/unit/volume/v3/test_volume_snapshot.py @@ -17,16 +17,19 @@ from osc_lib import exceptions from osc_lib import utils from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes +from openstackclient.tests.unit.volume.v3 import fakes as volume_fakes_v3 from openstackclient.volume.v3 import volume_snapshot -class TestVolumeSnapshot(volume_fakes.TestVolume): +class TestVolumeSnapshot(volume_fakes_v3.TestVolume): def setUp(self): super().setUp() self.snapshots_mock = self.volume_client.volume_snapshots self.snapshots_mock.reset_mock() + self.volume_sdk_client.unmanage_snapshot.return_value = None + class TestVolumeSnapshotDelete(TestVolumeSnapshot): snapshots = volume_fakes.create_snapshots(count=2) @@ -111,3 +114,48 @@ class TestVolumeSnapshotDelete(TestVolumeSnapshot): self.snapshots_mock.delete.assert_called_once_with( self.snapshots[0].id, False ) + + def test_snapshot_delete_remote(self): + arglist = ['--remote', self.snapshots[0].id] + verifylist = [('remote', True), ("snapshots", [self.snapshots[0].id])] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + self.volume_sdk_client.unmanage_snapshot.assert_called_with( + self.snapshots[0].id + ) + self.assertIsNone(result) + + def test_snapshot_delete_with_remote_force(self): + arglist = ['--remote', '--force', self.snapshots[0].id] + verifylist = [ + ('remote', True), + ('force', True), + ("snapshots", [self.snapshots[0].id]), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + exc = self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) + self.assertIn( + "The --force option is not supported with the --remote " + "parameter.", + str(exc), + ) + + def test_delete_multiple_snapshots_remote(self): + arglist = ['--remote'] + for s in self.snapshots: + arglist.append(s.id) + verifylist = [('remote', True), ('snapshots', arglist[1:])] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + calls = [] + for s in self.snapshots: + calls.append(mock.call(s.id)) + self.volume_sdk_client.unmanage_snapshot.assert_has_calls(calls) + self.assertIsNone(result) diff --git a/openstackclient/volume/v3/volume_snapshot.py b/openstackclient/volume/v3/volume_snapshot.py index 7b60e0f0da..1e528e8600 100644 --- a/openstackclient/volume/v3/volume_snapshot.py +++ b/openstackclient/volume/v3/volume_snapshot.py @@ -44,20 +44,41 @@ class DeleteVolumeSnapshot(command.Command): "regardless of state (defaults to False)" ), ) + parser.add_argument( + '--remote', + action='store_true', + help=_( + 'Unmanage the snapshot, removing it from the Block Storage ' + 'service management but not from the backend.' + ), + ) return parser def take_action(self, parsed_args): volume_client = self.app.client_manager.volume + volume_client_sdk = self.app.client_manager.sdk_connection.volume + result = 0 + if parsed_args.remote: + if parsed_args.force: + msg = _( + "The --force option is not supported with the " + "--remote parameter." + ) + raise exceptions.CommandError(msg) + for i in parsed_args.snapshots: try: snapshot_id = utils.find_resource( volume_client.volume_snapshots, i ).id - volume_client.volume_snapshots.delete( - snapshot_id, parsed_args.force - ) + if parsed_args.remote: + volume_client_sdk.unmanage_snapshot(snapshot_id) + else: + volume_client.volume_snapshots.delete( + snapshot_id, parsed_args.force + ) except Exception as e: result += 1 LOG.error( diff --git a/releasenotes/notes/add-snapshot-unmanage-command-d4c0c8fd8b638d48.yaml b/releasenotes/notes/add-snapshot-unmanage-command-d4c0c8fd8b638d48.yaml new file mode 100644 index 0000000000..a0abd5e582 --- /dev/null +++ b/releasenotes/notes/add-snapshot-unmanage-command-d4c0c8fd8b638d48.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Added support for unmanaging snapshots with the + ``openstack snapshot delete --remote`` command.