From 7357b24d3a63be612aa32c901e15424ff92beca0 Mon Sep 17 00:00:00 2001 From: Huanxuan Ao Date: Sun, 25 Sep 2016 11:49:47 +0800 Subject: [PATCH] Add "--remote-source" option to "volume snapshot create" command Add "--remote-source" option to "volume snapshot create" command to support creating snapshot from an existing remote snapshot in volume v2 (v2 only), also add the doc, unit tests and release note. Change-Id: I9e5fad4f0db5b44d528eb6b930edbc816e392c3a Implements: bp cinder-command-support Closes-Bug: #1618676 Co-Authored-By: Sheel Rana --- .../command-objects/volume-snapshot.rst | 9 +++++ .../tests/unit/volume/v2/test_snapshot.py | 28 +++++++++++++ openstackclient/volume/v2/volume_snapshot.py | 39 +++++++++++++++---- .../notes/bug-1618676-04ff0f335b670567.yaml | 5 +++ 4 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 releasenotes/notes/bug-1618676-04ff0f335b670567.yaml diff --git a/doc/source/command-objects/volume-snapshot.rst b/doc/source/command-objects/volume-snapshot.rst index 141e9f78bf..1744903515 100644 --- a/doc/source/command-objects/volume-snapshot.rst +++ b/doc/source/command-objects/volume-snapshot.rst @@ -17,6 +17,7 @@ Create new volume snapshot [--description ] [--force] [--property [...] ] + [--remote-source [...]] .. option:: --volume @@ -37,6 +38,14 @@ Create new volume snapshot *Volume version 2 only* +.. option:: --remote-source + + The attribute(s) of the exsiting remote volume snapshot + (admin required) (repeat option to specify multiple attributes) + e.g.: '--remote-source source-name=test_name --remote-source source-id=test_id' + + *Volume version 2 only* + .. _volume_snapshot_create-snapshot-name: .. describe:: diff --git a/openstackclient/tests/unit/volume/v2/test_snapshot.py b/openstackclient/tests/unit/volume/v2/test_snapshot.py index cedf21a916..8ce356aea8 100644 --- a/openstackclient/tests/unit/volume/v2/test_snapshot.py +++ b/openstackclient/tests/unit/volume/v2/test_snapshot.py @@ -67,6 +67,7 @@ class TestSnapshotCreate(TestSnapshot): self.volumes_mock.get.return_value = self.volume self.snapshots_mock.create.return_value = self.new_snapshot + self.snapshots_mock.manage.return_value = self.new_snapshot # Get the command object to test self.cmd = volume_snapshot.CreateVolumeSnapshot(self.app, None) @@ -152,6 +153,33 @@ class TestSnapshotCreate(TestSnapshot): self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) + def test_snapshot_create_without_remote_source(self): + arglist = [ + '--remote-source', 'source-name=test_source_name', + '--remote-source', 'source-id=test_source_id', + '--volume', self.new_snapshot.volume_id, + ] + ref_dict = {'source-name': 'test_source_name', + 'source-id': 'test_source_id'} + verifylist = [ + ('remote_source', ref_dict), + ('volume', self.new_snapshot.volume_id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.snapshots_mock.manage.assert_called_with( + volume_id=self.new_snapshot.volume_id, + ref=ref_dict, + name=None, + description=None, + metadata=None, + ) + self.snapshots_mock.create.assert_not_called() + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + class TestSnapshotDelete(TestSnapshot): diff --git a/openstackclient/volume/v2/volume_snapshot.py b/openstackclient/volume/v2/volume_snapshot.py index d95a49a448..34b8fb82c2 100644 --- a/openstackclient/volume/v2/volume_snapshot.py +++ b/openstackclient/volume/v2/volume_snapshot.py @@ -65,6 +65,15 @@ class CreateVolumeSnapshot(command.ShowOne): help=_("Set a property to this snapshot " "(repeat option to set multiple properties)"), ) + parser.add_argument( + "--remote-source", + metavar="", + action=parseractions.KeyValueAction, + help=_("The attribute(s) of the exsiting remote volume snapshot " + "(admin required) (repeat option to specify multiple " + "attributes) e.g.: '--remote-source source-name=test_name " + "--remote-source source-id=test_id'"), + ) return parser def take_action(self, parsed_args): @@ -74,13 +83,29 @@ class CreateVolumeSnapshot(command.ShowOne): volume = parsed_args.snapshot_name volume_id = utils.find_resource( volume_client.volumes, volume).id - snapshot = volume_client.volume_snapshots.create( - volume_id, - force=parsed_args.force, - name=parsed_args.snapshot_name, - description=parsed_args.description, - metadata=parsed_args.property, - ) + if parsed_args.remote_source: + # Create a new snapshot from an existing remote snapshot source + if parsed_args.force: + msg = (_("'--force' option will not work when you create " + "new volume snapshot from an existing remote " + "volume snapshot")) + LOG.warning(msg) + snapshot = volume_client.volume_snapshots.manage( + volume_id=volume_id, + ref=parsed_args.remote_source, + name=parsed_args.snapshot_name, + description=parsed_args.description, + metadata=parsed_args.property, + ) + else: + # create a new snapshot from scratch + snapshot = volume_client.volume_snapshots.create( + volume_id, + force=parsed_args.force, + name=parsed_args.snapshot_name, + description=parsed_args.description, + metadata=parsed_args.property, + ) snapshot._info.update( {'properties': utils.format_dict(snapshot._info.pop('metadata'))} ) diff --git a/releasenotes/notes/bug-1618676-04ff0f335b670567.yaml b/releasenotes/notes/bug-1618676-04ff0f335b670567.yaml new file mode 100644 index 0000000000..69282252bb --- /dev/null +++ b/releasenotes/notes/bug-1618676-04ff0f335b670567.yaml @@ -0,0 +1,5 @@ +--- +features: + - Add ``--remote-source`` option to ``volume snapshot create`` command to support + creating volume snapshot from an existing remote volume snapshot in volume v2. + [Bug `1618676 `_]