diff --git a/doc/source/command-objects/volume-snapshot.rst b/doc/source/command-objects/volume-snapshot.rst index b84601f464..af93217726 100644 --- a/doc/source/command-objects/volume-snapshot.rst +++ b/doc/source/command-objects/volume-snapshot.rst @@ -51,8 +51,13 @@ Delete volume snapshot(s) .. code:: bash os volume snapshot delete + [--force] [ ...] +.. option:: --force + + Attempt forced removal of snapshot(s), regardless of state (defaults to False) + .. _volume_snapshot_delete-snapshot: .. describe:: diff --git a/openstackclient/tests/unit/volume/v2/test_snapshot.py b/openstackclient/tests/unit/volume/v2/test_snapshot.py index b67dd6ebf5..1d1693addb 100644 --- a/openstackclient/tests/unit/volume/v2/test_snapshot.py +++ b/openstackclient/tests/unit/volume/v2/test_snapshot.py @@ -179,7 +179,24 @@ class TestSnapshotDelete(TestSnapshot): result = self.cmd.take_action(parsed_args) self.snapshots_mock.delete.assert_called_with( - self.snapshots[0].id) + self.snapshots[0].id, False) + self.assertIsNone(result) + + def test_snapshot_delete_with_force(self): + arglist = [ + '--force', + self.snapshots[0].id + ] + verifylist = [ + ('force', True), + ("snapshots", [self.snapshots[0].id]) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + self.snapshots_mock.delete.assert_called_with( + self.snapshots[0].id, True) self.assertIsNone(result) def test_delete_multiple_snapshots(self): @@ -195,7 +212,7 @@ class TestSnapshotDelete(TestSnapshot): calls = [] for s in self.snapshots: - calls.append(call(s.id)) + calls.append(call(s.id, False)) self.snapshots_mock.delete.assert_has_calls(calls) self.assertIsNone(result) @@ -226,7 +243,7 @@ class TestSnapshotDelete(TestSnapshot): self.assertEqual(2, find_mock.call_count) self.snapshots_mock.delete.assert_called_once_with( - self.snapshots[0].id + self.snapshots[0].id, False ) diff --git a/openstackclient/volume/v2/volume_snapshot.py b/openstackclient/volume/v2/volume_snapshot.py index 43f30326ed..5fdeca3acd 100644 --- a/openstackclient/volume/v2/volume_snapshot.py +++ b/openstackclient/volume/v2/volume_snapshot.py @@ -98,6 +98,12 @@ class DeleteVolumeSnapshot(command.Command): nargs="+", help=_("Snapshot(s) to delete (name or ID)") ) + parser.add_argument( + '--force', + action='store_true', + help=_("Attempt forced removal of snapshot(s), " + "regardless of state (defaults to False)") + ) return parser def take_action(self, parsed_args): @@ -108,7 +114,8 @@ class DeleteVolumeSnapshot(command.Command): try: snapshot_id = utils.find_resource( volume_client.volume_snapshots, i).id - volume_client.volume_snapshots.delete(snapshot_id) + volume_client.volume_snapshots.delete( + snapshot_id, parsed_args.force) except Exception as e: result += 1 LOG.error(_("Failed to delete snapshot with " diff --git a/releasenotes/notes/bug-1597195-54ff1ecf381899f6.yaml b/releasenotes/notes/bug-1597195-54ff1ecf381899f6.yaml new file mode 100644 index 0000000000..ad45762027 --- /dev/null +++ b/releasenotes/notes/bug-1597195-54ff1ecf381899f6.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Add ``--force`` option to ``volume snapshot delete`` command to allow delete + in state other than error or available. + [Bug `1597195 `_]