Refactor "snapshot" commands
1.change the command name ``snapshot create/delete/list/ show/set/unset`` to ``volume snapshot create/delete/list/ show/set/unset``. 2.change the optional parameter "--name <name>" to a positional parameter "<snapshot-name>"; Change the positional parameter "<volume>" to a optional parameter "--volume <volume>" Change-Id: If03276ecdf6f0d96893d5ecf91c2aaa64929cff3 Implements: bp backup-snapshot-renamed-for-volume-resource Co-Authored-By: Sheel Rana <ranasheel2000@gmail.com>
This commit is contained in:
		| @@ -8,6 +8,7 @@ snapshot create | |||||||
| --------------- | --------------- | ||||||
|  |  | ||||||
| Create new snapshot | Create new snapshot | ||||||
|  | (Deprecated, please use ``volume snapshot create`` instead) | ||||||
|  |  | ||||||
| .. program:: snapshot create | .. program:: snapshot create | ||||||
| .. code:: bash | .. code:: bash | ||||||
| @@ -46,6 +47,7 @@ snapshot delete | |||||||
| --------------- | --------------- | ||||||
|  |  | ||||||
| Delete snapshot(s) | Delete snapshot(s) | ||||||
|  | (Deprecated, please use ``volume snapshot delete`` instead) | ||||||
|  |  | ||||||
| .. program:: snapshot delete | .. program:: snapshot delete | ||||||
| .. code:: bash | .. code:: bash | ||||||
| @@ -62,6 +64,7 @@ snapshot list | |||||||
| ------------- | ------------- | ||||||
|  |  | ||||||
| List snapshots | List snapshots | ||||||
|  | (Deprecated, please use ``volume snapshot list`` instead) | ||||||
|  |  | ||||||
| .. program:: snapshot list | .. program:: snapshot list | ||||||
| .. code:: bash | .. code:: bash | ||||||
| @@ -96,6 +99,7 @@ snapshot set | |||||||
| ------------ | ------------ | ||||||
|  |  | ||||||
| Set snapshot properties | Set snapshot properties | ||||||
|  | (Deprecated, please use ``volume snapshot set`` instead) | ||||||
|  |  | ||||||
| .. program:: snapshot set | .. program:: snapshot set | ||||||
| .. code:: bash | .. code:: bash | ||||||
| @@ -137,6 +141,7 @@ snapshot show | |||||||
| ------------- | ------------- | ||||||
|  |  | ||||||
| Display snapshot details | Display snapshot details | ||||||
|  | (Deprecated, please use ``volume snapshot show`` instead) | ||||||
|  |  | ||||||
| .. program:: snapshot show | .. program:: snapshot show | ||||||
| .. code:: bash | .. code:: bash | ||||||
| @@ -153,6 +158,7 @@ snapshot unset | |||||||
| -------------- | -------------- | ||||||
|  |  | ||||||
| Unset snapshot properties | Unset snapshot properties | ||||||
|  | (Deprecated, please use ``volume snapshot unset`` instead) | ||||||
|  |  | ||||||
| .. program:: snapshot unset | .. program:: snapshot unset | ||||||
| .. code:: bash | .. code:: bash | ||||||
|   | |||||||
							
								
								
									
										171
									
								
								doc/source/command-objects/volume-snapshot.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								doc/source/command-objects/volume-snapshot.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,171 @@ | |||||||
|  | =============== | ||||||
|  | volume snapshot | ||||||
|  | =============== | ||||||
|  |  | ||||||
|  | Block Storage v1, v2 | ||||||
|  |  | ||||||
|  | volume snapshot create | ||||||
|  | ---------------------- | ||||||
|  |  | ||||||
|  | Create new volume snapshot | ||||||
|  |  | ||||||
|  | .. program:: volume snapshot create | ||||||
|  | .. code:: bash | ||||||
|  |  | ||||||
|  |     os volume snapshot create | ||||||
|  |         [--volume <volume>] | ||||||
|  |         [--description <description>] | ||||||
|  |         [--force] | ||||||
|  |         [--property <key=value> [...] ] | ||||||
|  |         <snapshot-name> | ||||||
|  |  | ||||||
|  | .. option:: --volume <volume> | ||||||
|  |  | ||||||
|  |     Volume to snapshot (name or ID) (default is <snapshot-name>) | ||||||
|  |  | ||||||
|  | .. option:: --description <description> | ||||||
|  |  | ||||||
|  |     Description of the snapshot | ||||||
|  |  | ||||||
|  | .. option:: --force | ||||||
|  |  | ||||||
|  |     Create a snapshot attached to an instance. Default is False | ||||||
|  |  | ||||||
|  | .. option:: --property <key=value> | ||||||
|  |  | ||||||
|  |     Set a property to this snapshot (repeat option to set multiple properties) | ||||||
|  |  | ||||||
|  |     *Volume version 2 only* | ||||||
|  |  | ||||||
|  | .. _volume_snapshot_create-snapshot-name: | ||||||
|  | .. describe:: <snapshot-name> | ||||||
|  |  | ||||||
|  |     Name of the new snapshot (default to None) | ||||||
|  |  | ||||||
|  | volume snapshot delete | ||||||
|  | ---------------------- | ||||||
|  |  | ||||||
|  | Delete volume snapshot(s) | ||||||
|  |  | ||||||
|  | .. program:: volume snapshot delete | ||||||
|  | .. code:: bash | ||||||
|  |  | ||||||
|  |     os volume snapshot delete | ||||||
|  |         <snapshot> [<snapshot> ...] | ||||||
|  |  | ||||||
|  | .. _volume_snapshot_delete-snapshot: | ||||||
|  | .. describe:: <snapshot> | ||||||
|  |  | ||||||
|  |     Snapshot(s) to delete (name or ID) | ||||||
|  |  | ||||||
|  | volume snapshot list | ||||||
|  | -------------------- | ||||||
|  |  | ||||||
|  | List volume snapshots | ||||||
|  |  | ||||||
|  | .. program:: volume snapshot list | ||||||
|  | .. code:: bash | ||||||
|  |  | ||||||
|  |     os volume snapshot list | ||||||
|  |         [--all-projects] | ||||||
|  |         [--long] | ||||||
|  |         [--limit <limit>] | ||||||
|  |         [--marker <marker>] | ||||||
|  |  | ||||||
|  | .. option:: --all-projects | ||||||
|  |  | ||||||
|  |     Include all projects (admin only) | ||||||
|  |  | ||||||
|  | .. option:: --long | ||||||
|  |  | ||||||
|  |     List additional fields in output | ||||||
|  |  | ||||||
|  | .. option:: --limit <limit> | ||||||
|  |  | ||||||
|  |     Maximum number of snapshots to display | ||||||
|  |  | ||||||
|  |     *Volume version 2 only* | ||||||
|  |  | ||||||
|  | .. option:: --marker <marker> | ||||||
|  |  | ||||||
|  |     The last snapshot ID of the previous page | ||||||
|  |  | ||||||
|  |     *Volume version 2 only* | ||||||
|  |  | ||||||
|  | volume snapshot set | ||||||
|  | ------------------- | ||||||
|  |  | ||||||
|  | Set volume snapshot properties | ||||||
|  |  | ||||||
|  | .. program:: volume snapshot set | ||||||
|  | .. code:: bash | ||||||
|  |  | ||||||
|  |     os volume snapshot set | ||||||
|  |         [--name <name>] | ||||||
|  |         [--description <description>] | ||||||
|  |         [--property <key=value> [...] ] | ||||||
|  |         [--state <state>] | ||||||
|  |         <snapshot> | ||||||
|  |  | ||||||
|  | .. option:: --name <name> | ||||||
|  |  | ||||||
|  |     New snapshot name | ||||||
|  |  | ||||||
|  | .. option:: --description <description> | ||||||
|  |  | ||||||
|  |     New snapshot description | ||||||
|  |  | ||||||
|  | .. option:: --property <key=value> | ||||||
|  |  | ||||||
|  |     Property to add or modify for this snapshot (repeat option to set multiple properties) | ||||||
|  |  | ||||||
|  | .. option:: --state <state> | ||||||
|  |  | ||||||
|  |     New snapshot state. | ||||||
|  |     ("available", "error", "creating", "deleting", or "error_deleting") (admin only) | ||||||
|  |     (This option simply changes the state of the snapshot in the database with | ||||||
|  |     no regard to actual status, exercise caution when using) | ||||||
|  |  | ||||||
|  |     *Volume version 2 only* | ||||||
|  |  | ||||||
|  | .. _volume_snapshot_set-snapshot: | ||||||
|  | .. describe:: <snapshot> | ||||||
|  |  | ||||||
|  |     Snapshot to modify (name or ID) | ||||||
|  |  | ||||||
|  | volume snapshot show | ||||||
|  | -------------------- | ||||||
|  |  | ||||||
|  | Display volume snapshot details | ||||||
|  |  | ||||||
|  | .. program:: volume snapshot show | ||||||
|  | .. code:: bash | ||||||
|  |  | ||||||
|  |     os volume snapshot show | ||||||
|  |         <snapshot> | ||||||
|  |  | ||||||
|  | .. _volume_snapshot_show-snapshot: | ||||||
|  | .. describe:: <snapshot> | ||||||
|  |  | ||||||
|  |     Snapshot to display (name or ID) | ||||||
|  |  | ||||||
|  | volume snapshot unset | ||||||
|  | --------------------- | ||||||
|  |  | ||||||
|  | Unset volume snapshot properties | ||||||
|  |  | ||||||
|  | .. program:: volume snapshot unset | ||||||
|  | .. code:: bash | ||||||
|  |  | ||||||
|  |     os volume snapshot unset | ||||||
|  |         [--property <key>] | ||||||
|  |         <snapshot> | ||||||
|  |  | ||||||
|  | .. option:: --property <key> | ||||||
|  |  | ||||||
|  |     Property to remove from snapshot (repeat option to remove multiple properties) | ||||||
|  |  | ||||||
|  | .. _volume_snapshot_unset-snapshot: | ||||||
|  | .. describe:: <snapshot> | ||||||
|  |  | ||||||
|  |     Snapshot to modify (name or ID) | ||||||
| @@ -74,7 +74,6 @@ referring to both Compute and Volume quotas. | |||||||
| * ``address scope``: (**Network**) a scope of IPv4 or IPv6 addresses | * ``address scope``: (**Network**) a scope of IPv4 or IPv6 addresses | ||||||
| * ``aggregate``: (**Compute**) a grouping of compute hosts | * ``aggregate``: (**Compute**) a grouping of compute hosts | ||||||
| * ``availability zone``: (**Compute**, **Network**, **Volume**) a logical partition of hosts or block storage or network services | * ``availability zone``: (**Compute**, **Network**, **Volume**) a logical partition of hosts or block storage or network services | ||||||
| * ``backup``: (**Volume**) a volume copy |  | ||||||
| * ``catalog``: (**Identity**) service catalog | * ``catalog``: (**Identity**) service catalog | ||||||
| * ``command``: (**Internal**) installed commands in the OSC process | * ``command``: (**Internal**) installed commands in the OSC process | ||||||
| * ``compute agent``: (**Compute**) a cloud Compute agent available to a hypervisor | * ``compute agent``: (**Compute**) a cloud Compute agent available to a hypervisor | ||||||
| @@ -134,7 +133,6 @@ referring to both Compute and Volume quotas. | |||||||
| * ``server image``: (**Compute**) saved server disk image | * ``server image``: (**Compute**) saved server disk image | ||||||
| * ``service``: (**Identity**) a cloud service | * ``service``: (**Identity**) a cloud service | ||||||
| * ``service provider``: (**Identity**) a resource that consumes assertions from an ``identity provider`` | * ``service provider``: (**Identity**) a resource that consumes assertions from an ``identity provider`` | ||||||
| * ``snapshot``: (**Volume**) a point-in-time copy of a volume |  | ||||||
| * ``subnet``: (**Network**) - a contiguous range of IP addresses assigned to a network | * ``subnet``: (**Network**) - a contiguous range of IP addresses assigned to a network | ||||||
| * ``subnet pool``: (**Network**) - a pool of subnets | * ``subnet pool``: (**Network**) - a pool of subnets | ||||||
| * ``token``: (**Identity**) a bearer token managed by Identity service | * ``token``: (**Identity**) a bearer token managed by Identity service | ||||||
| @@ -145,6 +143,7 @@ referring to both Compute and Volume quotas. | |||||||
| * ``volume``: (**Volume**) block volumes | * ``volume``: (**Volume**) block volumes | ||||||
| * ``volume backup``: (**Volume**) backup for volumes | * ``volume backup``: (**Volume**) backup for volumes | ||||||
| * ``volume qos``: (**Volume**) quality-of-service (QoS) specification for volumes | * ``volume qos``: (**Volume**) quality-of-service (QoS) specification for volumes | ||||||
|  | * ``volume snapshot``: (**Volume**) a point-in-time copy of a volume | ||||||
| * ``volume type``: (**Volume**) deployment-specific types of volumes available | * ``volume type``: (**Volume**) deployment-specific types of volumes available | ||||||
| * ``volume service``: (**Volume**) services to manage block storage operations | * ``volume service``: (**Volume**) services to manage block storage operations | ||||||
| * ``volume transfer request``: (**Volume**) volume owner transfer request | * ``volume transfer request``: (**Volume**) volume owner transfer request | ||||||
|   | |||||||
| @@ -16,8 +16,8 @@ import uuid | |||||||
| from openstackclient.tests.functional.volume.v1 import common | from openstackclient.tests.functional.volume.v1 import common | ||||||
|  |  | ||||||
|  |  | ||||||
| class SnapshotTests(common.BaseVolumeTests): | class VolumeSnapshotTests(common.BaseVolumeTests): | ||||||
|     """Functional tests for snapshot. """ |     """Functional tests for volume snapshot. """ | ||||||
|  |  | ||||||
|     VOLLY = uuid.uuid4().hex |     VOLLY = uuid.uuid4().hex | ||||||
|     NAME = uuid.uuid4().hex |     NAME = uuid.uuid4().hex | ||||||
| @@ -36,24 +36,25 @@ class SnapshotTests(common.BaseVolumeTests): | |||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def setUpClass(cls): |     def setUpClass(cls): | ||||||
|         super(SnapshotTests, cls).setUpClass() |         super(VolumeSnapshotTests, cls).setUpClass() | ||||||
|         cls.openstack('volume create --size 1 ' + cls.VOLLY) |         cls.openstack('volume create --size 1 ' + cls.VOLLY) | ||||||
|         cls.wait_for_status('volume show ' + cls.VOLLY, 'available\n', 3) |         cls.wait_for_status('volume show ' + cls.VOLLY, 'available\n', 3) | ||||||
|         opts = cls.get_opts(['status']) |         opts = cls.get_opts(['status']) | ||||||
|         raw_output = cls.openstack('snapshot create --name ' + cls.NAME + |         raw_output = cls.openstack('volume snapshot create --volume ' + | ||||||
|                                    ' ' + cls.VOLLY + opts) |                                    cls.VOLLY + ' ' + cls.NAME + opts) | ||||||
|         cls.assertOutput('creating\n', raw_output) |         cls.assertOutput('creating\n', raw_output) | ||||||
|         cls.wait_for_status('snapshot show ' + cls.NAME, 'available\n', 3) |         cls.wait_for_status( | ||||||
|  |             'volume snapshot show ' + cls.NAME, 'available\n', 3) | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def tearDownClass(cls): |     def tearDownClass(cls): | ||||||
|         # Rename test |         # Rename test | ||||||
|         raw_output = cls.openstack( |         raw_output = cls.openstack( | ||||||
|             'snapshot set --name ' + cls.OTHER_NAME + ' ' + cls.NAME) |             'volume snapshot set --name ' + cls.OTHER_NAME + ' ' + cls.NAME) | ||||||
|         cls.assertOutput('', raw_output) |         cls.assertOutput('', raw_output) | ||||||
|         # Delete test |         # Delete test | ||||||
|         raw_output_snapshot = cls.openstack( |         raw_output_snapshot = cls.openstack( | ||||||
|             'snapshot delete ' + cls.OTHER_NAME) |             'volume snapshot delete ' + cls.OTHER_NAME) | ||||||
|         cls.wait_for_status('volume show ' + cls.VOLLY, 'available\n', 6) |         cls.wait_for_status('volume show ' + cls.VOLLY, 'available\n', 6) | ||||||
|         raw_output_volume = cls.openstack('volume delete --force ' + cls.VOLLY) |         raw_output_volume = cls.openstack('volume delete --force ' + cls.VOLLY) | ||||||
|         cls.assertOutput('', raw_output_snapshot) |         cls.assertOutput('', raw_output_snapshot) | ||||||
| @@ -61,26 +62,27 @@ class SnapshotTests(common.BaseVolumeTests): | |||||||
|  |  | ||||||
|     def test_snapshot_list(self): |     def test_snapshot_list(self): | ||||||
|         opts = self.get_opts(self.HEADERS) |         opts = self.get_opts(self.HEADERS) | ||||||
|         raw_output = self.openstack('snapshot list' + opts) |         raw_output = self.openstack('volume snapshot list' + opts) | ||||||
|         self.assertIn(self.NAME, raw_output) |         self.assertIn(self.NAME, raw_output) | ||||||
|  |  | ||||||
|     def test_snapshot_set_unset_properties(self): |     def test_snapshot_set_unset_properties(self): | ||||||
|         raw_output = self.openstack( |         raw_output = self.openstack( | ||||||
|             'snapshot set --property a=b --property c=d ' + self.NAME) |             'volume snapshot set --property a=b --property c=d ' + self.NAME) | ||||||
|         self.assertEqual("", raw_output) |         self.assertEqual("", raw_output) | ||||||
|         opts = self.get_opts(["properties"]) |         opts = self.get_opts(["properties"]) | ||||||
|         raw_output = self.openstack('snapshot show ' + self.NAME + opts) |         raw_output = self.openstack('volume snapshot show ' + self.NAME + opts) | ||||||
|         self.assertEqual("a='b', c='d'\n", raw_output) |         self.assertEqual("a='b', c='d'\n", raw_output) | ||||||
|  |  | ||||||
|         raw_output = self.openstack('snapshot unset --property a ' + self.NAME) |         raw_output = self.openstack( | ||||||
|  |             'volume snapshot unset --property a ' + self.NAME) | ||||||
|         self.assertEqual("", raw_output) |         self.assertEqual("", raw_output) | ||||||
|         raw_output = self.openstack('snapshot show ' + self.NAME + opts) |         raw_output = self.openstack('volume snapshot show ' + self.NAME + opts) | ||||||
|         self.assertEqual("c='d'\n", raw_output) |         self.assertEqual("c='d'\n", raw_output) | ||||||
|  |  | ||||||
|     def test_snapshot_set_description(self): |     def test_snapshot_set_description(self): | ||||||
|         raw_output = self.openstack( |         raw_output = self.openstack( | ||||||
|             'snapshot set --description backup ' + self.NAME) |             'volume snapshot set --description backup ' + self.NAME) | ||||||
|         self.assertEqual("", raw_output) |         self.assertEqual("", raw_output) | ||||||
|         opts = self.get_opts(["display_description", "display_name"]) |         opts = self.get_opts(["display_description", "display_name"]) | ||||||
|         raw_output = self.openstack('snapshot show ' + self.NAME + opts) |         raw_output = self.openstack('volume snapshot show ' + self.NAME + opts) | ||||||
|         self.assertEqual("backup\n" + self.NAME + "\n", raw_output) |         self.assertEqual("backup\n" + self.NAME + "\n", raw_output) | ||||||
|   | |||||||
| @@ -16,8 +16,8 @@ import uuid | |||||||
| from openstackclient.tests.functional.volume.v2 import common | from openstackclient.tests.functional.volume.v2 import common | ||||||
|  |  | ||||||
|  |  | ||||||
| class SnapshotTests(common.BaseVolumeTests): | class VolumeSnapshotTests(common.BaseVolumeTests): | ||||||
|     """Functional tests for snapshot. """ |     """Functional tests for volume snapshot. """ | ||||||
|  |  | ||||||
|     VOLLY = uuid.uuid4().hex |     VOLLY = uuid.uuid4().hex | ||||||
|     NAME = uuid.uuid4().hex |     NAME = uuid.uuid4().hex | ||||||
| @@ -36,24 +36,25 @@ class SnapshotTests(common.BaseVolumeTests): | |||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def setUpClass(cls): |     def setUpClass(cls): | ||||||
|         super(SnapshotTests, cls).setUpClass() |         super(VolumeSnapshotTests, cls).setUpClass() | ||||||
|         cls.openstack('volume create --size 1 ' + cls.VOLLY) |         cls.openstack('volume create --size 1 ' + cls.VOLLY) | ||||||
|         cls.wait_for_status('volume show ' + cls.VOLLY, 'available\n', 3) |         cls.wait_for_status('volume show ' + cls.VOLLY, 'available\n', 3) | ||||||
|         opts = cls.get_opts(['status']) |         opts = cls.get_opts(['status']) | ||||||
|         raw_output = cls.openstack('snapshot create --name ' + cls.NAME + |         raw_output = cls.openstack('volume snapshot create --volume ' + | ||||||
|                                    ' ' + cls.VOLLY + opts) |                                    cls.VOLLY + ' ' + cls.NAME + opts) | ||||||
|         cls.assertOutput('creating\n', raw_output) |         cls.assertOutput('creating\n', raw_output) | ||||||
|         cls.wait_for_status('snapshot show ' + cls.NAME, 'available\n', 3) |         cls.wait_for_status( | ||||||
|  |             'volume snapshot show ' + cls.NAME, 'available\n', 3) | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def tearDownClass(cls): |     def tearDownClass(cls): | ||||||
|         # Rename test |         # Rename test | ||||||
|         raw_output = cls.openstack( |         raw_output = cls.openstack( | ||||||
|             'snapshot set --name ' + cls.OTHER_NAME + ' ' + cls.NAME) |             'volume snapshot set --name ' + cls.OTHER_NAME + ' ' + cls.NAME) | ||||||
|         cls.assertOutput('', raw_output) |         cls.assertOutput('', raw_output) | ||||||
|         # Delete test |         # Delete test | ||||||
|         raw_output_snapshot = cls.openstack( |         raw_output_snapshot = cls.openstack( | ||||||
|             'snapshot delete ' + cls.OTHER_NAME) |             'volume snapshot delete ' + cls.OTHER_NAME) | ||||||
|         cls.wait_for_status('volume show ' + cls.VOLLY, 'available\n', 6) |         cls.wait_for_status('volume show ' + cls.VOLLY, 'available\n', 6) | ||||||
|         raw_output_volume = cls.openstack('volume delete --force ' + cls.VOLLY) |         raw_output_volume = cls.openstack('volume delete --force ' + cls.VOLLY) | ||||||
|         cls.assertOutput('', raw_output_snapshot) |         cls.assertOutput('', raw_output_snapshot) | ||||||
| @@ -61,26 +62,27 @@ class SnapshotTests(common.BaseVolumeTests): | |||||||
|  |  | ||||||
|     def test_snapshot_list(self): |     def test_snapshot_list(self): | ||||||
|         opts = self.get_opts(self.HEADERS) |         opts = self.get_opts(self.HEADERS) | ||||||
|         raw_output = self.openstack('snapshot list' + opts) |         raw_output = self.openstack('volume snapshot list' + opts) | ||||||
|         self.assertIn(self.NAME, raw_output) |         self.assertIn(self.NAME, raw_output) | ||||||
|  |  | ||||||
|     def test_snapshot_properties(self): |     def test_snapshot_properties(self): | ||||||
|         raw_output = self.openstack( |         raw_output = self.openstack( | ||||||
|             'snapshot set --property a=b --property c=d ' + self.NAME) |             'volume snapshot set --property a=b --property c=d ' + self.NAME) | ||||||
|         self.assertEqual("", raw_output) |         self.assertEqual("", raw_output) | ||||||
|         opts = self.get_opts(["properties"]) |         opts = self.get_opts(["properties"]) | ||||||
|         raw_output = self.openstack('snapshot show ' + self.NAME + opts) |         raw_output = self.openstack('volume snapshot show ' + self.NAME + opts) | ||||||
|         self.assertEqual("a='b', c='d'\n", raw_output) |         self.assertEqual("a='b', c='d'\n", raw_output) | ||||||
|  |  | ||||||
|         raw_output = self.openstack('snapshot unset --property a ' + self.NAME) |         raw_output = self.openstack( | ||||||
|  |             'volume snapshot unset --property a ' + self.NAME) | ||||||
|         self.assertEqual("", raw_output) |         self.assertEqual("", raw_output) | ||||||
|         raw_output = self.openstack('snapshot show ' + self.NAME + opts) |         raw_output = self.openstack('volume snapshot show ' + self.NAME + opts) | ||||||
|         self.assertEqual("c='d'\n", raw_output) |         self.assertEqual("c='d'\n", raw_output) | ||||||
|  |  | ||||||
|     def test_snapshot_set(self): |     def test_snapshot_set(self): | ||||||
|         raw_output = self.openstack( |         raw_output = self.openstack( | ||||||
|             'snapshot set --description backup ' + self.NAME) |             'volume snapshot set --description backup ' + self.NAME) | ||||||
|         self.assertEqual("", raw_output) |         self.assertEqual("", raw_output) | ||||||
|         opts = self.get_opts(["description", "name"]) |         opts = self.get_opts(["description", "name"]) | ||||||
|         raw_output = self.openstack('snapshot show ' + self.NAME + opts) |         raw_output = self.openstack('volume snapshot show ' + self.NAME + opts) | ||||||
|         self.assertEqual("backup\n" + self.NAME + "\n", raw_output) |         self.assertEqual("backup\n" + self.NAME + "\n", raw_output) | ||||||
|   | |||||||
| @@ -106,11 +106,12 @@ class VolumeTests(common.BaseVolumeTests): | |||||||
|         opts = self.get_opts(self.FIELDS) |         opts = self.get_opts(self.FIELDS) | ||||||
|  |  | ||||||
|         # Create snapshot from test volume |         # Create snapshot from test volume | ||||||
|         raw_output = self.openstack('snapshot create ' + self.NAME + |         raw_output = self.openstack('volume snapshot create ' + | ||||||
|                                     ' --name ' + self.SNAPSHOT_NAME + opts) |                                     self.SNAPSHOT_NAME + | ||||||
|  |                                     ' --volume ' + self.NAME + opts) | ||||||
|         expected = self.SNAPSHOT_NAME + '\n' |         expected = self.SNAPSHOT_NAME + '\n' | ||||||
|         self.assertOutput(expected, raw_output) |         self.assertOutput(expected, raw_output) | ||||||
|         self.wait_for("snapshot", self.SNAPSHOT_NAME, "available") |         self.wait_for("volume snapshot", self.SNAPSHOT_NAME, "available") | ||||||
|  |  | ||||||
|         # Create volume from snapshot |         # Create volume from snapshot | ||||||
|         raw_output = self.openstack('volume create --size 2 --snapshot ' + |         raw_output = self.openstack('volume create --size 2 --snapshot ' + | ||||||
| @@ -126,7 +127,8 @@ class VolumeTests(common.BaseVolumeTests): | |||||||
|         self.assertOutput('', raw_output) |         self.assertOutput('', raw_output) | ||||||
|  |  | ||||||
|         # Delete test snapshot |         # Delete test snapshot | ||||||
|         raw_output = self.openstack('snapshot delete ' + self.SNAPSHOT_NAME) |         raw_output = self.openstack( | ||||||
|  |             'volume snapshot delete ' + self.SNAPSHOT_NAME) | ||||||
|         self.assertOutput('', raw_output) |         self.assertOutput('', raw_output) | ||||||
|         self.wait_for("volume", self.NAME, "available") |         self.wait_for("volume", self.NAME, "available") | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ from osc_lib import exceptions | |||||||
| from osc_lib import utils | from osc_lib import utils | ||||||
|  |  | ||||||
| from openstackclient.tests.unit.volume.v1 import fakes as volume_fakes | from openstackclient.tests.unit.volume.v1 import fakes as volume_fakes | ||||||
| from openstackclient.volume.v1 import snapshot | from openstackclient.volume.v1 import volume_snapshot | ||||||
|  |  | ||||||
|  |  | ||||||
| class TestSnapshot(volume_fakes.TestVolumev1): | class TestSnapshot(volume_fakes.TestVolumev1): | ||||||
| @@ -67,20 +67,20 @@ class TestSnapshotCreate(TestSnapshot): | |||||||
|         self.volumes_mock.get.return_value = self.volume |         self.volumes_mock.get.return_value = self.volume | ||||||
|         self.snapshots_mock.create.return_value = self.new_snapshot |         self.snapshots_mock.create.return_value = self.new_snapshot | ||||||
|         # Get the command object to test |         # Get the command object to test | ||||||
|         self.cmd = snapshot.CreateSnapshot(self.app, None) |         self.cmd = volume_snapshot.CreateVolumeSnapshot(self.app, None) | ||||||
|  |  | ||||||
|     def test_snapshot_create(self): |     def test_snapshot_create(self): | ||||||
|         arglist = [ |         arglist = [ | ||||||
|             "--name", self.new_snapshot.display_name, |             "--volume", self.new_snapshot.volume_id, | ||||||
|             "--description", self.new_snapshot.display_description, |             "--description", self.new_snapshot.display_description, | ||||||
|             "--force", |             "--force", | ||||||
|             self.new_snapshot.volume_id, |             self.new_snapshot.display_name, | ||||||
|         ] |         ] | ||||||
|         verifylist = [ |         verifylist = [ | ||||||
|             ("name", self.new_snapshot.display_name), |             ("volume", self.new_snapshot.volume_id), | ||||||
|             ("description", self.new_snapshot.display_description), |             ("description", self.new_snapshot.display_description), | ||||||
|             ("force", True), |             ("force", True), | ||||||
|             ("volume", self.new_snapshot.volume_id), |             ("snapshot_name", self.new_snapshot.display_name), | ||||||
|         ] |         ] | ||||||
|         parsed_args = self.check_parser(self.cmd, arglist, verifylist) |         parsed_args = self.check_parser(self.cmd, arglist, verifylist) | ||||||
|  |  | ||||||
| @@ -97,7 +97,7 @@ class TestSnapshotCreate(TestSnapshot): | |||||||
|  |  | ||||||
|     def test_snapshot_create_without_name(self): |     def test_snapshot_create_without_name(self): | ||||||
|         arglist = [ |         arglist = [ | ||||||
|             self.new_snapshot.volume_id, |             "--volume", self.new_snapshot.volume_id, | ||||||
|             "--description", self.new_snapshot.display_description, |             "--description", self.new_snapshot.display_description, | ||||||
|             "--force" |             "--force" | ||||||
|         ] |         ] | ||||||
| @@ -119,6 +119,32 @@ class TestSnapshotCreate(TestSnapshot): | |||||||
|         self.assertEqual(self.columns, columns) |         self.assertEqual(self.columns, columns) | ||||||
|         self.assertEqual(self.data, data) |         self.assertEqual(self.data, data) | ||||||
|  |  | ||||||
|  |     def test_snapshot_create_without_volume(self): | ||||||
|  |         arglist = [ | ||||||
|  |             "--description", self.new_snapshot.display_description, | ||||||
|  |             "--force", | ||||||
|  |             self.new_snapshot.display_name | ||||||
|  |         ] | ||||||
|  |         verifylist = [ | ||||||
|  |             ("description", self.new_snapshot.display_description), | ||||||
|  |             ("force", True), | ||||||
|  |             ("snapshot_name", self.new_snapshot.display_name) | ||||||
|  |         ] | ||||||
|  |         parsed_args = self.check_parser(self.cmd, arglist, verifylist) | ||||||
|  |  | ||||||
|  |         columns, data = self.cmd.take_action(parsed_args) | ||||||
|  |  | ||||||
|  |         self.volumes_mock.get.assert_called_once_with( | ||||||
|  |             self.new_snapshot.display_name) | ||||||
|  |         self.snapshots_mock.create.assert_called_once_with( | ||||||
|  |             self.new_snapshot.volume_id, | ||||||
|  |             True, | ||||||
|  |             self.new_snapshot.display_name, | ||||||
|  |             self.new_snapshot.display_description, | ||||||
|  |         ) | ||||||
|  |         self.assertEqual(self.columns, columns) | ||||||
|  |         self.assertEqual(self.data, data) | ||||||
|  |  | ||||||
|  |  | ||||||
| class TestSnapshotDelete(TestSnapshot): | class TestSnapshotDelete(TestSnapshot): | ||||||
|  |  | ||||||
| @@ -132,7 +158,7 @@ class TestSnapshotDelete(TestSnapshot): | |||||||
|         self.snapshots_mock.delete.return_value = None |         self.snapshots_mock.delete.return_value = None | ||||||
|  |  | ||||||
|         # Get the command object to mock |         # Get the command object to mock | ||||||
|         self.cmd = snapshot.DeleteSnapshot(self.app, None) |         self.cmd = volume_snapshot.DeleteVolumeSnapshot(self.app, None) | ||||||
|  |  | ||||||
|     def test_snapshot_delete(self): |     def test_snapshot_delete(self): | ||||||
|         arglist = [ |         arglist = [ | ||||||
| @@ -244,7 +270,7 @@ class TestSnapshotList(TestSnapshot): | |||||||
|         self.volumes_mock.list.return_value = [self.volume] |         self.volumes_mock.list.return_value = [self.volume] | ||||||
|         self.snapshots_mock.list.return_value = self.snapshots |         self.snapshots_mock.list.return_value = self.snapshots | ||||||
|         # Get the command to test |         # Get the command to test | ||||||
|         self.cmd = snapshot.ListSnapshot(self.app, None) |         self.cmd = volume_snapshot.ListVolumeSnapshot(self.app, None) | ||||||
|  |  | ||||||
|     def test_snapshot_list_without_options(self): |     def test_snapshot_list_without_options(self): | ||||||
|         arglist = [] |         arglist = [] | ||||||
| @@ -307,7 +333,7 @@ class TestSnapshotSet(TestSnapshot): | |||||||
|         self.snapshots_mock.get.return_value = self.snapshot |         self.snapshots_mock.get.return_value = self.snapshot | ||||||
|         self.snapshots_mock.set_metadata.return_value = None |         self.snapshots_mock.set_metadata.return_value = None | ||||||
|         # Get the command object to mock |         # Get the command object to mock | ||||||
|         self.cmd = snapshot.SetSnapshot(self.app, None) |         self.cmd = volume_snapshot.SetVolumeSnapshot(self.app, None) | ||||||
|  |  | ||||||
|     def test_snapshot_set_all(self): |     def test_snapshot_set_all(self): | ||||||
|         arglist = [ |         arglist = [ | ||||||
| @@ -404,7 +430,7 @@ class TestSnapshotShow(TestSnapshot): | |||||||
|  |  | ||||||
|         self.snapshots_mock.get.return_value = self.snapshot |         self.snapshots_mock.get.return_value = self.snapshot | ||||||
|         # Get the command object to test |         # Get the command object to test | ||||||
|         self.cmd = snapshot.ShowSnapshot(self.app, None) |         self.cmd = volume_snapshot.ShowVolumeSnapshot(self.app, None) | ||||||
|  |  | ||||||
|     def test_snapshot_show(self): |     def test_snapshot_show(self): | ||||||
|         arglist = [ |         arglist = [ | ||||||
| @@ -432,7 +458,7 @@ class TestSnapshotUnset(TestSnapshot): | |||||||
|         self.snapshots_mock.get.return_value = self.snapshot |         self.snapshots_mock.get.return_value = self.snapshot | ||||||
|         self.snapshots_mock.delete_metadata.return_value = None |         self.snapshots_mock.delete_metadata.return_value = None | ||||||
|         # Get the command object to mock |         # Get the command object to mock | ||||||
|         self.cmd = snapshot.UnsetSnapshot(self.app, None) |         self.cmd = volume_snapshot.UnsetVolumeSnapshot(self.app, None) | ||||||
|  |  | ||||||
|     def test_snapshot_unset(self): |     def test_snapshot_unset(self): | ||||||
|         arglist = [ |         arglist = [ | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ from osc_lib import exceptions | |||||||
| from osc_lib import utils | from osc_lib import utils | ||||||
|  |  | ||||||
| from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes | from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes | ||||||
| from openstackclient.volume.v2 import snapshot | from openstackclient.volume.v2 import volume_snapshot | ||||||
|  |  | ||||||
|  |  | ||||||
| class TestSnapshot(volume_fakes.TestVolume): | class TestSnapshot(volume_fakes.TestVolume): | ||||||
| @@ -68,23 +68,23 @@ class TestSnapshotCreate(TestSnapshot): | |||||||
|         self.volumes_mock.get.return_value = self.volume |         self.volumes_mock.get.return_value = self.volume | ||||||
|         self.snapshots_mock.create.return_value = self.new_snapshot |         self.snapshots_mock.create.return_value = self.new_snapshot | ||||||
|         # Get the command object to test |         # Get the command object to test | ||||||
|         self.cmd = snapshot.CreateSnapshot(self.app, None) |         self.cmd = volume_snapshot.CreateVolumeSnapshot(self.app, None) | ||||||
|  |  | ||||||
|     def test_snapshot_create(self): |     def test_snapshot_create(self): | ||||||
|         arglist = [ |         arglist = [ | ||||||
|             "--name", self.new_snapshot.name, |             "--volume", self.new_snapshot.volume_id, | ||||||
|             "--description", self.new_snapshot.description, |             "--description", self.new_snapshot.description, | ||||||
|             "--force", |             "--force", | ||||||
|             '--property', 'Alpha=a', |             '--property', 'Alpha=a', | ||||||
|             '--property', 'Beta=b', |             '--property', 'Beta=b', | ||||||
|             self.new_snapshot.volume_id, |             self.new_snapshot.name, | ||||||
|         ] |         ] | ||||||
|         verifylist = [ |         verifylist = [ | ||||||
|             ("name", self.new_snapshot.name), |             ("volume", self.new_snapshot.volume_id), | ||||||
|             ("description", self.new_snapshot.description), |             ("description", self.new_snapshot.description), | ||||||
|             ("force", True), |             ("force", True), | ||||||
|             ('property', {'Alpha': 'a', 'Beta': 'b'}), |             ('property', {'Alpha': 'a', 'Beta': 'b'}), | ||||||
|             ("volume", self.new_snapshot.volume_id), |             ("snapshot_name", self.new_snapshot.name), | ||||||
|         ] |         ] | ||||||
|         parsed_args = self.check_parser(self.cmd, arglist, verifylist) |         parsed_args = self.check_parser(self.cmd, arglist, verifylist) | ||||||
|  |  | ||||||
| @@ -102,7 +102,7 @@ class TestSnapshotCreate(TestSnapshot): | |||||||
|  |  | ||||||
|     def test_snapshot_create_without_name(self): |     def test_snapshot_create_without_name(self): | ||||||
|         arglist = [ |         arglist = [ | ||||||
|             self.new_snapshot.volume_id, |             "--volume", self.new_snapshot.volume_id, | ||||||
|             "--description", self.new_snapshot.description, |             "--description", self.new_snapshot.description, | ||||||
|             "--force" |             "--force" | ||||||
|         ] |         ] | ||||||
| @@ -125,6 +125,33 @@ class TestSnapshotCreate(TestSnapshot): | |||||||
|         self.assertEqual(self.columns, columns) |         self.assertEqual(self.columns, columns) | ||||||
|         self.assertEqual(self.data, data) |         self.assertEqual(self.data, data) | ||||||
|  |  | ||||||
|  |     def test_snapshot_create_without_volume(self): | ||||||
|  |         arglist = [ | ||||||
|  |             "--description", self.new_snapshot.description, | ||||||
|  |             "--force", | ||||||
|  |             self.new_snapshot.name | ||||||
|  |         ] | ||||||
|  |         verifylist = [ | ||||||
|  |             ("description", self.new_snapshot.description), | ||||||
|  |             ("force", True), | ||||||
|  |             ("snapshot_name", self.new_snapshot.name) | ||||||
|  |         ] | ||||||
|  |         parsed_args = self.check_parser(self.cmd, arglist, verifylist) | ||||||
|  |  | ||||||
|  |         columns, data = self.cmd.take_action(parsed_args) | ||||||
|  |  | ||||||
|  |         self.volumes_mock.get.assert_called_once_with( | ||||||
|  |             self.new_snapshot.name) | ||||||
|  |         self.snapshots_mock.create.assert_called_once_with( | ||||||
|  |             self.new_snapshot.volume_id, | ||||||
|  |             force=True, | ||||||
|  |             name=self.new_snapshot.name, | ||||||
|  |             description=self.new_snapshot.description, | ||||||
|  |             metadata=None, | ||||||
|  |         ) | ||||||
|  |         self.assertEqual(self.columns, columns) | ||||||
|  |         self.assertEqual(self.data, data) | ||||||
|  |  | ||||||
|  |  | ||||||
| class TestSnapshotDelete(TestSnapshot): | class TestSnapshotDelete(TestSnapshot): | ||||||
|  |  | ||||||
| @@ -138,7 +165,7 @@ class TestSnapshotDelete(TestSnapshot): | |||||||
|         self.snapshots_mock.delete.return_value = None |         self.snapshots_mock.delete.return_value = None | ||||||
|  |  | ||||||
|         # Get the command object to mock |         # Get the command object to mock | ||||||
|         self.cmd = snapshot.DeleteSnapshot(self.app, None) |         self.cmd = volume_snapshot.DeleteVolumeSnapshot(self.app, None) | ||||||
|  |  | ||||||
|     def test_snapshot_delete(self): |     def test_snapshot_delete(self): | ||||||
|         arglist = [ |         arglist = [ | ||||||
| @@ -250,7 +277,7 @@ class TestSnapshotList(TestSnapshot): | |||||||
|         self.volumes_mock.list.return_value = [self.volume] |         self.volumes_mock.list.return_value = [self.volume] | ||||||
|         self.snapshots_mock.list.return_value = self.snapshots |         self.snapshots_mock.list.return_value = self.snapshots | ||||||
|         # Get the command to test |         # Get the command to test | ||||||
|         self.cmd = snapshot.ListSnapshot(self.app, None) |         self.cmd = volume_snapshot.ListVolumeSnapshot(self.app, None) | ||||||
|  |  | ||||||
|     def test_snapshot_list_without_options(self): |     def test_snapshot_list_without_options(self): | ||||||
|         arglist = [] |         arglist = [] | ||||||
| @@ -330,7 +357,7 @@ class TestSnapshotSet(TestSnapshot): | |||||||
|         self.snapshots_mock.set_metadata.return_value = None |         self.snapshots_mock.set_metadata.return_value = None | ||||||
|         self.snapshots_mock.update.return_value = None |         self.snapshots_mock.update.return_value = None | ||||||
|         # Get the command object to mock |         # Get the command object to mock | ||||||
|         self.cmd = snapshot.SetSnapshot(self.app, None) |         self.cmd = volume_snapshot.SetVolumeSnapshot(self.app, None) | ||||||
|  |  | ||||||
|     def test_snapshot_set(self): |     def test_snapshot_set(self): | ||||||
|         arglist = [ |         arglist = [ | ||||||
| @@ -457,7 +484,7 @@ class TestSnapshotShow(TestSnapshot): | |||||||
|  |  | ||||||
|         self.snapshots_mock.get.return_value = self.snapshot |         self.snapshots_mock.get.return_value = self.snapshot | ||||||
|         # Get the command object to test |         # Get the command object to test | ||||||
|         self.cmd = snapshot.ShowSnapshot(self.app, None) |         self.cmd = volume_snapshot.ShowVolumeSnapshot(self.app, None) | ||||||
|  |  | ||||||
|     def test_snapshot_show(self): |     def test_snapshot_show(self): | ||||||
|         arglist = [ |         arglist = [ | ||||||
| @@ -485,7 +512,7 @@ class TestSnapshotUnset(TestSnapshot): | |||||||
|         self.snapshots_mock.get.return_value = self.snapshot |         self.snapshots_mock.get.return_value = self.snapshot | ||||||
|         self.snapshots_mock.delete_metadata.return_value = None |         self.snapshots_mock.delete_metadata.return_value = None | ||||||
|         # Get the command object to mock |         # Get the command object to mock | ||||||
|         self.cmd = snapshot.UnsetSnapshot(self.app, None) |         self.cmd = volume_snapshot.UnsetVolumeSnapshot(self.app, None) | ||||||
|  |  | ||||||
|     def test_snapshot_unset(self): |     def test_snapshot_unset(self): | ||||||
|         arglist = [ |         arglist = [ | ||||||
|   | |||||||
| @@ -13,6 +13,10 @@ | |||||||
| #   under the License. | #   under the License. | ||||||
| # | # | ||||||
|  |  | ||||||
|  | # TODO(Huanxuan Ao): Remove this file and "snapshot create", "snapshot delete", | ||||||
|  | #                    "snapshot set", "snapshot show" and "snapshot unset" | ||||||
|  | #                    commands two cycles after Ocata. | ||||||
|  |  | ||||||
| """Volume v1 Snapshot action implementations""" | """Volume v1 Snapshot action implementations""" | ||||||
|  |  | ||||||
| import copy | import copy | ||||||
| @@ -27,6 +31,8 @@ import six | |||||||
| from openstackclient.i18n import _ | from openstackclient.i18n import _ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | deprecated = True | ||||||
|  | LOG_DEP = logging.getLogger('deprecated') | ||||||
| LOG = logging.getLogger(__name__) | LOG = logging.getLogger(__name__) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -61,6 +67,8 @@ class CreateSnapshot(command.ShowOne): | |||||||
|         return parser |         return parser | ||||||
|  |  | ||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|  |         LOG_DEP.warning(_('This command has been deprecated. ' | ||||||
|  |                           'Please use "volume snapshot create" instead.')) | ||||||
|         volume_client = self.app.client_manager.volume |         volume_client = self.app.client_manager.volume | ||||||
|         volume_id = utils.find_resource(volume_client.volumes, |         volume_id = utils.find_resource(volume_client.volumes, | ||||||
|                                         parsed_args.volume).id |                                         parsed_args.volume).id | ||||||
| @@ -92,6 +100,8 @@ class DeleteSnapshot(command.Command): | |||||||
|         return parser |         return parser | ||||||
|  |  | ||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|  |         LOG_DEP.warning(_('This command has been deprecated. ' | ||||||
|  |                           'Please use "volume snapshot delete" instead.')) | ||||||
|         volume_client = self.app.client_manager.volume |         volume_client = self.app.client_manager.volume | ||||||
|         result = 0 |         result = 0 | ||||||
|  |  | ||||||
| @@ -133,6 +143,8 @@ class ListSnapshot(command.Lister): | |||||||
|         return parser |         return parser | ||||||
|  |  | ||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|  |         LOG_DEP.warning(_('This command has been deprecated. ' | ||||||
|  |                           'Please use "volume snapshot list" instead.')) | ||||||
|  |  | ||||||
|         def _format_volume_id(volume_id): |         def _format_volume_id(volume_id): | ||||||
|             """Return a volume name if available |             """Return a volume name if available | ||||||
| @@ -214,6 +226,8 @@ class SetSnapshot(command.Command): | |||||||
|         return parser |         return parser | ||||||
|  |  | ||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|  |         LOG_DEP.warning(_('This command has been deprecated. ' | ||||||
|  |                           'Please use "volume snapshot set" instead.')) | ||||||
|         volume_client = self.app.client_manager.volume |         volume_client = self.app.client_manager.volume | ||||||
|         snapshot = utils.find_resource(volume_client.volume_snapshots, |         snapshot = utils.find_resource(volume_client.volume_snapshots, | ||||||
|                                        parsed_args.snapshot) |                                        parsed_args.snapshot) | ||||||
| @@ -258,6 +272,8 @@ class ShowSnapshot(command.ShowOne): | |||||||
|         return parser |         return parser | ||||||
|  |  | ||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|  |         LOG_DEP.warning(_('This command has been deprecated. ' | ||||||
|  |                           'Please use "volume snapshot show" instead.')) | ||||||
|         volume_client = self.app.client_manager.volume |         volume_client = self.app.client_manager.volume | ||||||
|         snapshot = utils.find_resource(volume_client.volume_snapshots, |         snapshot = utils.find_resource(volume_client.volume_snapshots, | ||||||
|                                        parsed_args.snapshot) |                                        parsed_args.snapshot) | ||||||
| @@ -289,6 +305,8 @@ class UnsetSnapshot(command.Command): | |||||||
|         return parser |         return parser | ||||||
|  |  | ||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|  |         LOG_DEP.warning(_('This command has been deprecated. ' | ||||||
|  |                           'Please use "volume snapshot unset" instead.')) | ||||||
|         volume_client = self.app.client_manager.volume |         volume_client = self.app.client_manager.volume | ||||||
|         snapshot = utils.find_resource( |         snapshot = utils.find_resource( | ||||||
|             volume_client.volume_snapshots, parsed_args.snapshot) |             volume_client.volume_snapshots, parsed_args.snapshot) | ||||||
|   | |||||||
							
								
								
									
										305
									
								
								openstackclient/volume/v1/volume_snapshot.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										305
									
								
								openstackclient/volume/v1/volume_snapshot.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,305 @@ | |||||||
|  | #   Copyright 2012-2013 OpenStack Foundation | ||||||
|  | # | ||||||
|  | #   Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||||
|  | #   not use this file except in compliance with the License. You may obtain | ||||||
|  | #   a copy of the License at | ||||||
|  | # | ||||||
|  | #        http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | #   Unless required by applicable law or agreed to in writing, software | ||||||
|  | #   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||||
|  | #   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||||
|  | #   License for the specific language governing permissions and limitations | ||||||
|  | #   under the License. | ||||||
|  | # | ||||||
|  |  | ||||||
|  | """Volume v1 Snapshot action implementations""" | ||||||
|  |  | ||||||
|  | import copy | ||||||
|  | import logging | ||||||
|  |  | ||||||
|  | from osc_lib.cli import parseractions | ||||||
|  | from osc_lib.command import command | ||||||
|  | from osc_lib import exceptions | ||||||
|  | from osc_lib import utils | ||||||
|  | import six | ||||||
|  |  | ||||||
|  | from openstackclient.i18n import _ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | LOG = logging.getLogger(__name__) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class CreateVolumeSnapshot(command.ShowOne): | ||||||
|  |     """Create new volume snapshot""" | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         parser = super(CreateVolumeSnapshot, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             'snapshot_name', | ||||||
|  |             metavar='<snapshot-name>', | ||||||
|  |             nargs="?", | ||||||
|  |             help=_('Name of the snapshot (default to None)'), | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--volume', | ||||||
|  |             metavar='<volume>', | ||||||
|  |             help=_('Volume to snapshot (name or ID) ' | ||||||
|  |                    '(default is <snapshot-name>)'), | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--description', | ||||||
|  |             metavar='<description>', | ||||||
|  |             help=_('Description of the snapshot'), | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--force', | ||||||
|  |             dest='force', | ||||||
|  |             action='store_true', | ||||||
|  |             default=False, | ||||||
|  |             help=_('Create a snapshot attached to an instance. ' | ||||||
|  |                    'Default is False'), | ||||||
|  |         ) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         volume_client = self.app.client_manager.volume | ||||||
|  |         volume = parsed_args.volume | ||||||
|  |         if not parsed_args.volume: | ||||||
|  |             volume = parsed_args.snapshot_name | ||||||
|  |         volume_id = utils.find_resource(volume_client.volumes, | ||||||
|  |                                         volume).id | ||||||
|  |         snapshot = volume_client.volume_snapshots.create( | ||||||
|  |             volume_id, | ||||||
|  |             parsed_args.force, | ||||||
|  |             parsed_args.snapshot_name, | ||||||
|  |             parsed_args.description | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         snapshot._info.update( | ||||||
|  |             {'properties': utils.format_dict(snapshot._info.pop('metadata'))} | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         return zip(*sorted(six.iteritems(snapshot._info))) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class DeleteVolumeSnapshot(command.Command): | ||||||
|  |     """Delete volume snapshot(s)""" | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         parser = super(DeleteVolumeSnapshot, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             'snapshots', | ||||||
|  |             metavar='<snapshot>', | ||||||
|  |             nargs="+", | ||||||
|  |             help=_('Snapshot(s) to delete (name or ID)'), | ||||||
|  |         ) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         volume_client = self.app.client_manager.volume | ||||||
|  |         result = 0 | ||||||
|  |  | ||||||
|  |         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) | ||||||
|  |             except Exception as e: | ||||||
|  |                 result += 1 | ||||||
|  |                 LOG.error(_("Failed to delete snapshot with " | ||||||
|  |                             "name or ID '%(snapshot)s': %(e)s"), | ||||||
|  |                           {'snapshot': i, 'e': e}) | ||||||
|  |  | ||||||
|  |         if result > 0: | ||||||
|  |             total = len(parsed_args.snapshots) | ||||||
|  |             msg = (_("%(result)s of %(total)s snapshots failed " | ||||||
|  |                    "to delete.") % {'result': result, 'total': total}) | ||||||
|  |             raise exceptions.CommandError(msg) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ListVolumeSnapshot(command.Lister): | ||||||
|  |     """List volume snapshots""" | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         parser = super(ListVolumeSnapshot, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--all-projects', | ||||||
|  |             action='store_true', | ||||||
|  |             default=False, | ||||||
|  |             help=_('Include all projects (admin only)'), | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--long', | ||||||
|  |             action='store_true', | ||||||
|  |             default=False, | ||||||
|  |             help=_('List additional fields in output'), | ||||||
|  |         ) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |  | ||||||
|  |         def _format_volume_id(volume_id): | ||||||
|  |             """Return a volume name if available | ||||||
|  |  | ||||||
|  |             :param volume_id: a volume ID | ||||||
|  |             :rtype: either the volume ID or name | ||||||
|  |             """ | ||||||
|  |  | ||||||
|  |             volume = volume_id | ||||||
|  |             if volume_id in volume_cache.keys(): | ||||||
|  |                 volume = volume_cache[volume_id].display_name | ||||||
|  |             return volume | ||||||
|  |  | ||||||
|  |         if parsed_args.long: | ||||||
|  |             columns = ['ID', 'Display Name', 'Display Description', 'Status', | ||||||
|  |                        'Size', 'Created At', 'Volume ID', 'Metadata'] | ||||||
|  |             column_headers = copy.deepcopy(columns) | ||||||
|  |             column_headers[6] = 'Volume' | ||||||
|  |             column_headers[7] = 'Properties' | ||||||
|  |         else: | ||||||
|  |             columns = ['ID', 'Display Name', 'Display Description', 'Status', | ||||||
|  |                        'Size'] | ||||||
|  |             column_headers = copy.deepcopy(columns) | ||||||
|  |  | ||||||
|  |         # Always update Name and Description | ||||||
|  |         column_headers[1] = 'Name' | ||||||
|  |         column_headers[2] = 'Description' | ||||||
|  |  | ||||||
|  |         # Cache the volume list | ||||||
|  |         volume_cache = {} | ||||||
|  |         try: | ||||||
|  |             for s in self.app.client_manager.volume.volumes.list(): | ||||||
|  |                 volume_cache[s.id] = s | ||||||
|  |         except Exception: | ||||||
|  |             # Just forget it if there's any trouble | ||||||
|  |             pass | ||||||
|  |  | ||||||
|  |         search_opts = { | ||||||
|  |             'all_tenants': parsed_args.all_projects, | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         data = self.app.client_manager.volume.volume_snapshots.list( | ||||||
|  |             search_opts=search_opts) | ||||||
|  |         return (column_headers, | ||||||
|  |                 (utils.get_item_properties( | ||||||
|  |                     s, columns, | ||||||
|  |                     formatters={'Metadata': utils.format_dict, | ||||||
|  |                                 'Volume ID': _format_volume_id}, | ||||||
|  |                 ) for s in data)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class SetVolumeSnapshot(command.Command): | ||||||
|  |     """Set volume snapshot properties""" | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         parser = super(SetVolumeSnapshot, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             'snapshot', | ||||||
|  |             metavar='<snapshot>', | ||||||
|  |             help=_('Snapshot to modify (name or ID)') | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--name', | ||||||
|  |             metavar='<name>', | ||||||
|  |             help=_('New snapshot name') | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--description', | ||||||
|  |             metavar='<description>', | ||||||
|  |             help=_('New snapshot description') | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--property', | ||||||
|  |             metavar='<key=value>', | ||||||
|  |             action=parseractions.KeyValueAction, | ||||||
|  |             help=_('Property to add/change for this snapshot ' | ||||||
|  |                    '(repeat option to set multiple properties)'), | ||||||
|  |         ) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         volume_client = self.app.client_manager.volume | ||||||
|  |         snapshot = utils.find_resource(volume_client.volume_snapshots, | ||||||
|  |                                        parsed_args.snapshot) | ||||||
|  |  | ||||||
|  |         result = 0 | ||||||
|  |         if parsed_args.property: | ||||||
|  |             try: | ||||||
|  |                 volume_client.volume_snapshots.set_metadata( | ||||||
|  |                     snapshot.id, parsed_args.property) | ||||||
|  |             except Exception as e: | ||||||
|  |                 LOG.error(_("Failed to set snapshot property: %s"), e) | ||||||
|  |                 result += 1 | ||||||
|  |  | ||||||
|  |         kwargs = {} | ||||||
|  |         if parsed_args.name: | ||||||
|  |             kwargs['display_name'] = parsed_args.name | ||||||
|  |         if parsed_args.description: | ||||||
|  |             kwargs['display_description'] = parsed_args.description | ||||||
|  |         if kwargs: | ||||||
|  |             try: | ||||||
|  |                 snapshot.update(**kwargs) | ||||||
|  |             except Exception as e: | ||||||
|  |                 LOG.error(_("Failed to update snapshot display name " | ||||||
|  |                           "or display description: %s"), e) | ||||||
|  |                 result += 1 | ||||||
|  |  | ||||||
|  |         if result > 0: | ||||||
|  |             raise exceptions.CommandError(_("One or more of the " | ||||||
|  |                                           "set operations failed")) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ShowVolumeSnapshot(command.ShowOne): | ||||||
|  |     """Display volume snapshot details""" | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         parser = super(ShowVolumeSnapshot, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             'snapshot', | ||||||
|  |             metavar='<snapshot>', | ||||||
|  |             help=_('Snapshot to display (name or ID)') | ||||||
|  |         ) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         volume_client = self.app.client_manager.volume | ||||||
|  |         snapshot = utils.find_resource(volume_client.volume_snapshots, | ||||||
|  |                                        parsed_args.snapshot) | ||||||
|  |  | ||||||
|  |         snapshot._info.update( | ||||||
|  |             {'properties': utils.format_dict(snapshot._info.pop('metadata'))} | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         return zip(*sorted(six.iteritems(snapshot._info))) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class UnsetVolumeSnapshot(command.Command): | ||||||
|  |     """Unset volume snapshot properties""" | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         parser = super(UnsetVolumeSnapshot, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             'snapshot', | ||||||
|  |             metavar='<snapshot>', | ||||||
|  |             help=_('Snapshot to modify (name or ID)'), | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--property', | ||||||
|  |             metavar='<key>', | ||||||
|  |             action='append', | ||||||
|  |             help=_('Property to remove from snapshot ' | ||||||
|  |                    '(repeat option to remove multiple properties)'), | ||||||
|  |         ) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         volume_client = self.app.client_manager.volume | ||||||
|  |         snapshot = utils.find_resource( | ||||||
|  |             volume_client.volume_snapshots, parsed_args.snapshot) | ||||||
|  |  | ||||||
|  |         if parsed_args.property: | ||||||
|  |             volume_client.volume_snapshots.delete_metadata( | ||||||
|  |                 snapshot.id, | ||||||
|  |                 parsed_args.property, | ||||||
|  |             ) | ||||||
| @@ -12,6 +12,10 @@ | |||||||
| #   under the License. | #   under the License. | ||||||
| # | # | ||||||
|  |  | ||||||
|  | # TODO(Huanxuan Ao): Remove this file and "snapshot create", "snapshot delete", | ||||||
|  | #                    "snapshot set", "snapshot show" and "snapshot unset" | ||||||
|  | #                    commands two cycles after Ocata. | ||||||
|  |  | ||||||
| """Volume v2 snapshot action implementations""" | """Volume v2 snapshot action implementations""" | ||||||
|  |  | ||||||
| import copy | import copy | ||||||
| @@ -26,6 +30,8 @@ import six | |||||||
| from openstackclient.i18n import _ | from openstackclient.i18n import _ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | deprecated = True | ||||||
|  | LOG_DEP = logging.getLogger('deprecated') | ||||||
| LOG = logging.getLogger(__name__) | LOG = logging.getLogger(__name__) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -66,6 +72,8 @@ class CreateSnapshot(command.ShowOne): | |||||||
|         return parser |         return parser | ||||||
|  |  | ||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|  |         LOG_DEP.warning(_('This command has been deprecated. ' | ||||||
|  |                           'Please use "volume snapshot create" instead.')) | ||||||
|         volume_client = self.app.client_manager.volume |         volume_client = self.app.client_manager.volume | ||||||
|         volume_id = utils.find_resource( |         volume_id = utils.find_resource( | ||||||
|             volume_client.volumes, parsed_args.volume).id |             volume_client.volumes, parsed_args.volume).id | ||||||
| @@ -96,6 +104,8 @@ class DeleteSnapshot(command.Command): | |||||||
|         return parser |         return parser | ||||||
|  |  | ||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|  |         LOG_DEP.warning(_('This command has been deprecated. ' | ||||||
|  |                           'Please use "volume snapshot delete" instead.')) | ||||||
|         volume_client = self.app.client_manager.volume |         volume_client = self.app.client_manager.volume | ||||||
|         result = 0 |         result = 0 | ||||||
|  |  | ||||||
| @@ -149,6 +159,8 @@ class ListSnapshot(command.Lister): | |||||||
|         return parser |         return parser | ||||||
|  |  | ||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|  |         LOG_DEP.warning(_('This command has been deprecated. ' | ||||||
|  |                           'Please use "volume snapshot list" instead.')) | ||||||
|  |  | ||||||
|         def _format_volume_id(volume_id): |         def _format_volume_id(volume_id): | ||||||
|             """Return a volume name if available |             """Return a volume name if available | ||||||
| @@ -239,6 +251,8 @@ class SetSnapshot(command.Command): | |||||||
|         return parser |         return parser | ||||||
|  |  | ||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|  |         LOG_DEP.warning(_('This command has been deprecated. ' | ||||||
|  |                           'Please use "volume snapshot set" instead.')) | ||||||
|         volume_client = self.app.client_manager.volume |         volume_client = self.app.client_manager.volume | ||||||
|         snapshot = utils.find_resource(volume_client.volume_snapshots, |         snapshot = utils.find_resource(volume_client.volume_snapshots, | ||||||
|                                        parsed_args.snapshot) |                                        parsed_args.snapshot) | ||||||
| @@ -292,6 +306,8 @@ class ShowSnapshot(command.ShowOne): | |||||||
|         return parser |         return parser | ||||||
|  |  | ||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|  |         LOG_DEP.warning(_('This command has been deprecated. ' | ||||||
|  |                           'Please use "volume snapshot show" instead.')) | ||||||
|         volume_client = self.app.client_manager.volume |         volume_client = self.app.client_manager.volume | ||||||
|         snapshot = utils.find_resource( |         snapshot = utils.find_resource( | ||||||
|             volume_client.volume_snapshots, parsed_args.snapshot) |             volume_client.volume_snapshots, parsed_args.snapshot) | ||||||
| @@ -322,6 +338,8 @@ class UnsetSnapshot(command.Command): | |||||||
|         return parser |         return parser | ||||||
|  |  | ||||||
|     def take_action(self, parsed_args): |     def take_action(self, parsed_args): | ||||||
|  |         LOG_DEP.warning(_('This command has been deprecated. ' | ||||||
|  |                           'Please use "volume snapshot unset" instead.')) | ||||||
|         volume_client = self.app.client_manager.volume |         volume_client = self.app.client_manager.volume | ||||||
|         snapshot = utils.find_resource( |         snapshot = utils.find_resource( | ||||||
|             volume_client.volume_snapshots, parsed_args.snapshot) |             volume_client.volume_snapshots, parsed_args.snapshot) | ||||||
|   | |||||||
							
								
								
									
										338
									
								
								openstackclient/volume/v2/volume_snapshot.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										338
									
								
								openstackclient/volume/v2/volume_snapshot.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,338 @@ | |||||||
|  | # | ||||||
|  | #   Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||||
|  | #   not use this file except in compliance with the License. You may obtain | ||||||
|  | #   a copy of the License at | ||||||
|  | # | ||||||
|  | #        http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | #   Unless required by applicable law or agreed to in writing, software | ||||||
|  | #   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||||
|  | #   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||||
|  | #   License for the specific language governing permissions and limitations | ||||||
|  | #   under the License. | ||||||
|  | # | ||||||
|  |  | ||||||
|  | """Volume v2 snapshot action implementations""" | ||||||
|  |  | ||||||
|  | import copy | ||||||
|  | import logging | ||||||
|  |  | ||||||
|  | from osc_lib.cli import parseractions | ||||||
|  | from osc_lib.command import command | ||||||
|  | from osc_lib import exceptions | ||||||
|  | from osc_lib import utils | ||||||
|  | import six | ||||||
|  |  | ||||||
|  | from openstackclient.i18n import _ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | LOG = logging.getLogger(__name__) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class CreateVolumeSnapshot(command.ShowOne): | ||||||
|  |     """Create new volume snapshot""" | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         parser = super(CreateVolumeSnapshot, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             "snapshot_name", | ||||||
|  |             metavar="<snapshot-name>", | ||||||
|  |             nargs="?", | ||||||
|  |             help=_("Name of the new snapshot (default to None)") | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             "--volume", | ||||||
|  |             metavar="<volume>", | ||||||
|  |             help=_("Volume to snapshot (name or ID) " | ||||||
|  |                    "(default is <snapshot-name>)") | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             "--description", | ||||||
|  |             metavar="<description>", | ||||||
|  |             help=_("Description of the snapshot") | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             "--force", | ||||||
|  |             action="store_true", | ||||||
|  |             default=False, | ||||||
|  |             help=_("Create a snapshot attached to an instance. " | ||||||
|  |                    "Default is False") | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             "--property", | ||||||
|  |             metavar="<key=value>", | ||||||
|  |             action=parseractions.KeyValueAction, | ||||||
|  |             help=_("Set a property to this snapshot " | ||||||
|  |                    "(repeat option to set multiple properties)"), | ||||||
|  |         ) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         volume_client = self.app.client_manager.volume | ||||||
|  |         volume = parsed_args.volume | ||||||
|  |         if not parsed_args.volume: | ||||||
|  |             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, | ||||||
|  |         ) | ||||||
|  |         snapshot._info.update( | ||||||
|  |             {'properties': utils.format_dict(snapshot._info.pop('metadata'))} | ||||||
|  |         ) | ||||||
|  |         return zip(*sorted(six.iteritems(snapshot._info))) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class DeleteVolumeSnapshot(command.Command): | ||||||
|  |     """Delete volume snapshot(s)""" | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         parser = super(DeleteVolumeSnapshot, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             "snapshots", | ||||||
|  |             metavar="<snapshot>", | ||||||
|  |             nargs="+", | ||||||
|  |             help=_("Snapshot(s) to delete (name or ID)") | ||||||
|  |         ) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         volume_client = self.app.client_manager.volume | ||||||
|  |         result = 0 | ||||||
|  |  | ||||||
|  |         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) | ||||||
|  |             except Exception as e: | ||||||
|  |                 result += 1 | ||||||
|  |                 LOG.error(_("Failed to delete snapshot with " | ||||||
|  |                             "name or ID '%(snapshot)s': %(e)s") | ||||||
|  |                           % {'snapshot': i, 'e': e}) | ||||||
|  |  | ||||||
|  |         if result > 0: | ||||||
|  |             total = len(parsed_args.snapshots) | ||||||
|  |             msg = (_("%(result)s of %(total)s snapshots failed " | ||||||
|  |                    "to delete.") % {'result': result, 'total': total}) | ||||||
|  |             raise exceptions.CommandError(msg) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ListVolumeSnapshot(command.Lister): | ||||||
|  |     """List volume snapshots""" | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         parser = super(ListVolumeSnapshot, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--all-projects', | ||||||
|  |             action='store_true', | ||||||
|  |             default=False, | ||||||
|  |             help=_('Include all projects (admin only)'), | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--long', | ||||||
|  |             action='store_true', | ||||||
|  |             default=False, | ||||||
|  |             help=_('List additional fields in output'), | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--marker', | ||||||
|  |             metavar='<marker>', | ||||||
|  |             help=_('The last snapshot ID of the previous page'), | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--limit', | ||||||
|  |             type=int, | ||||||
|  |             action=parseractions.NonNegativeAction, | ||||||
|  |             metavar='<limit>', | ||||||
|  |             help=_('Maximum number of snapshots to display'), | ||||||
|  |         ) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |  | ||||||
|  |         def _format_volume_id(volume_id): | ||||||
|  |             """Return a volume name if available | ||||||
|  |  | ||||||
|  |             :param volume_id: a volume ID | ||||||
|  |             :rtype: either the volume ID or name | ||||||
|  |             """ | ||||||
|  |  | ||||||
|  |             volume = volume_id | ||||||
|  |             if volume_id in volume_cache.keys(): | ||||||
|  |                 volume = volume_cache[volume_id].name | ||||||
|  |             return volume | ||||||
|  |  | ||||||
|  |         if parsed_args.long: | ||||||
|  |             columns = ['ID', 'Name', 'Description', 'Status', | ||||||
|  |                        'Size', 'Created At', 'Volume ID', 'Metadata'] | ||||||
|  |             column_headers = copy.deepcopy(columns) | ||||||
|  |             column_headers[6] = 'Volume' | ||||||
|  |             column_headers[7] = 'Properties' | ||||||
|  |         else: | ||||||
|  |             columns = ['ID', 'Name', 'Description', 'Status', 'Size'] | ||||||
|  |             column_headers = copy.deepcopy(columns) | ||||||
|  |  | ||||||
|  |         # Cache the volume list | ||||||
|  |         volume_cache = {} | ||||||
|  |         try: | ||||||
|  |             for s in self.app.client_manager.volume.volumes.list(): | ||||||
|  |                 volume_cache[s.id] = s | ||||||
|  |         except Exception: | ||||||
|  |             # Just forget it if there's any trouble | ||||||
|  |             pass | ||||||
|  |  | ||||||
|  |         search_opts = { | ||||||
|  |             'all_tenants': parsed_args.all_projects, | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         data = self.app.client_manager.volume.volume_snapshots.list( | ||||||
|  |             search_opts=search_opts, | ||||||
|  |             marker=parsed_args.marker, | ||||||
|  |             limit=parsed_args.limit, | ||||||
|  |         ) | ||||||
|  |         return (column_headers, | ||||||
|  |                 (utils.get_item_properties( | ||||||
|  |                     s, columns, | ||||||
|  |                     formatters={'Metadata': utils.format_dict, | ||||||
|  |                                 'Volume ID': _format_volume_id}, | ||||||
|  |                 ) for s in data)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class SetVolumeSnapshot(command.Command): | ||||||
|  |     """Set volume snapshot properties""" | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         parser = super(SetVolumeSnapshot, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             'snapshot', | ||||||
|  |             metavar='<snapshot>', | ||||||
|  |             help=_('Snapshot to modify (name or ID)') | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--name', | ||||||
|  |             metavar='<name>', | ||||||
|  |             help=_('New snapshot name') | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--description', | ||||||
|  |             metavar='<description>', | ||||||
|  |             help=_('New snapshot description') | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--property', | ||||||
|  |             metavar='<key=value>', | ||||||
|  |             action=parseractions.KeyValueAction, | ||||||
|  |             help=_('Property to add/change for this snapshot ' | ||||||
|  |                    '(repeat option to set multiple properties)'), | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--state', | ||||||
|  |             metavar='<state>', | ||||||
|  |             choices=['available', 'error', 'creating', 'deleting', | ||||||
|  |                      'error-deleting'], | ||||||
|  |             help=_('New snapshot state. ("available", "error", "creating", ' | ||||||
|  |                    '"deleting", or "error_deleting") (admin only) ' | ||||||
|  |                    '(This option simply changes the state of the snapshot ' | ||||||
|  |                    'in the database with no regard to actual status, ' | ||||||
|  |                    'exercise caution when using)'), | ||||||
|  |         ) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         volume_client = self.app.client_manager.volume | ||||||
|  |         snapshot = utils.find_resource(volume_client.volume_snapshots, | ||||||
|  |                                        parsed_args.snapshot) | ||||||
|  |  | ||||||
|  |         result = 0 | ||||||
|  |         if parsed_args.property: | ||||||
|  |             try: | ||||||
|  |                 volume_client.volume_snapshots.set_metadata( | ||||||
|  |                     snapshot.id, parsed_args.property) | ||||||
|  |             except Exception as e: | ||||||
|  |                 LOG.error(_("Failed to set snapshot property: %s"), e) | ||||||
|  |                 result += 1 | ||||||
|  |  | ||||||
|  |         if parsed_args.state: | ||||||
|  |             try: | ||||||
|  |                 volume_client.volume_snapshots.reset_state( | ||||||
|  |                     snapshot.id, parsed_args.state) | ||||||
|  |             except Exception as e: | ||||||
|  |                 LOG.error(_("Failed to set snapshot state: %s"), e) | ||||||
|  |                 result += 1 | ||||||
|  |  | ||||||
|  |         kwargs = {} | ||||||
|  |         if parsed_args.name: | ||||||
|  |             kwargs['name'] = parsed_args.name | ||||||
|  |         if parsed_args.description: | ||||||
|  |             kwargs['description'] = parsed_args.description | ||||||
|  |         if kwargs: | ||||||
|  |             try: | ||||||
|  |                 volume_client.volume_snapshots.update( | ||||||
|  |                     snapshot.id, **kwargs) | ||||||
|  |             except Exception as e: | ||||||
|  |                 LOG.error(_("Failed to update snapshot name " | ||||||
|  |                           "or description: %s"), e) | ||||||
|  |                 result += 1 | ||||||
|  |  | ||||||
|  |         if result > 0: | ||||||
|  |             raise exceptions.CommandError(_("One or more of the " | ||||||
|  |                                           "set operations failed")) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ShowVolumeSnapshot(command.ShowOne): | ||||||
|  |     """Display volume snapshot details""" | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         parser = super(ShowVolumeSnapshot, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             "snapshot", | ||||||
|  |             metavar="<snapshot>", | ||||||
|  |             help=_("Snapshot to display (name or ID)") | ||||||
|  |         ) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         volume_client = self.app.client_manager.volume | ||||||
|  |         snapshot = utils.find_resource( | ||||||
|  |             volume_client.volume_snapshots, parsed_args.snapshot) | ||||||
|  |         snapshot._info.update( | ||||||
|  |             {'properties': utils.format_dict(snapshot._info.pop('metadata'))} | ||||||
|  |         ) | ||||||
|  |         return zip(*sorted(six.iteritems(snapshot._info))) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class UnsetVolumeSnapshot(command.Command): | ||||||
|  |     """Unset volume snapshot properties""" | ||||||
|  |  | ||||||
|  |     def get_parser(self, prog_name): | ||||||
|  |         parser = super(UnsetVolumeSnapshot, self).get_parser(prog_name) | ||||||
|  |         parser.add_argument( | ||||||
|  |             'snapshot', | ||||||
|  |             metavar='<snapshot>', | ||||||
|  |             help=_('Snapshot to modify (name or ID)'), | ||||||
|  |         ) | ||||||
|  |         parser.add_argument( | ||||||
|  |             '--property', | ||||||
|  |             metavar='<key>', | ||||||
|  |             action='append', | ||||||
|  |             default=[], | ||||||
|  |             help=_('Property to remove from snapshot ' | ||||||
|  |                    '(repeat option to remove multiple properties)'), | ||||||
|  |         ) | ||||||
|  |         return parser | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         volume_client = self.app.client_manager.volume | ||||||
|  |         snapshot = utils.find_resource( | ||||||
|  |             volume_client.volume_snapshots, parsed_args.snapshot) | ||||||
|  |  | ||||||
|  |         if parsed_args.property: | ||||||
|  |             volume_client.volume_snapshots.delete_metadata( | ||||||
|  |                 snapshot.id, | ||||||
|  |                 parsed_args.property, | ||||||
|  |             ) | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | --- | ||||||
|  | features: | ||||||
|  |   - Add new commands ``volume snapshot create/delete/list/show/set/unset``. they are | ||||||
|  |     used to replace the old commands ``snapshot create/delete/list/show/set/unset``. | ||||||
|  |     [Blueprint `backup-snapshot-renamed-for-volume-resource <https://blueprints.launchpad.net/python-openstackclient/+spec/backup-snapshot-renamed-for-volume-resource>`_] | ||||||
|  | deprecations: | ||||||
|  |   - Deprecate commands ``snapshot create/delete/list/show/set/unset``. | ||||||
|  |     [Blueprint `backup-snapshot-renamed-for-volume-resource <https://blueprints.launchpad.net/python-openstackclient/+spec/backup-snapshot-renamed-for-volume-resource>`_] | ||||||
							
								
								
									
										14
									
								
								setup.cfg
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								setup.cfg
									
									
									
									
									
								
							| @@ -473,6 +473,13 @@ openstack.volume.v1 = | |||||||
|     volume_backup_restore = openstackclient.volume.v1.backup:RestoreVolumeBackup |     volume_backup_restore = openstackclient.volume.v1.backup:RestoreVolumeBackup | ||||||
|     volume_backup_show = openstackclient.volume.v1.backup:ShowVolumeBackup |     volume_backup_show = openstackclient.volume.v1.backup:ShowVolumeBackup | ||||||
|  |  | ||||||
|  |     volume_snapshot_create = openstackclient.volume.v1.volume_snapshot:CreateVolumeSnapshot | ||||||
|  |     volume_snapshot_delete = openstackclient.volume.v1.volume_snapshot:DeleteVolumeSnapshot | ||||||
|  |     volume_snapshot_list = openstackclient.volume.v1.volume_snapshot:ListVolumeSnapshot | ||||||
|  |     volume_snapshot_set = openstackclient.volume.v1.volume_snapshot:SetVolumeSnapshot | ||||||
|  |     volume_snapshot_show = openstackclient.volume.v1.volume_snapshot:ShowVolumeSnapshot | ||||||
|  |     volume_snapshot_unset = openstackclient.volume.v1.volume_snapshot:UnsetVolumeSnapshot | ||||||
|  |  | ||||||
|     volume_type_create = openstackclient.volume.v1.volume_type:CreateVolumeType |     volume_type_create = openstackclient.volume.v1.volume_type:CreateVolumeType | ||||||
|     volume_type_delete = openstackclient.volume.v1.volume_type:DeleteVolumeType |     volume_type_delete = openstackclient.volume.v1.volume_type:DeleteVolumeType | ||||||
|     volume_type_list = openstackclient.volume.v1.volume_type:ListVolumeType |     volume_type_list = openstackclient.volume.v1.volume_type:ListVolumeType | ||||||
| @@ -528,6 +535,13 @@ openstack.volume.v2 = | |||||||
|     volume_backup_set = openstackclient.volume.v2.backup:SetVolumeBackup |     volume_backup_set = openstackclient.volume.v2.backup:SetVolumeBackup | ||||||
|     volume_backup_show = openstackclient.volume.v2.backup:ShowVolumeBackup |     volume_backup_show = openstackclient.volume.v2.backup:ShowVolumeBackup | ||||||
|  |  | ||||||
|  |     volume_snapshot_create = openstackclient.volume.v2.volume_snapshot:CreateVolumeSnapshot | ||||||
|  |     volume_snapshot_delete = openstackclient.volume.v2.volume_snapshot:DeleteVolumeSnapshot | ||||||
|  |     volume_snapshot_list = openstackclient.volume.v2.volume_snapshot:ListVolumeSnapshot | ||||||
|  |     volume_snapshot_set = openstackclient.volume.v2.volume_snapshot:SetVolumeSnapshot | ||||||
|  |     volume_snapshot_show = openstackclient.volume.v2.volume_snapshot:ShowVolumeSnapshot | ||||||
|  |     volume_snapshot_unset = openstackclient.volume.v2.volume_snapshot:UnsetVolumeSnapshot | ||||||
|  |  | ||||||
|     volume_type_create = openstackclient.volume.v2.volume_type:CreateVolumeType |     volume_type_create = openstackclient.volume.v2.volume_type:CreateVolumeType | ||||||
|     volume_type_delete = openstackclient.volume.v2.volume_type:DeleteVolumeType |     volume_type_delete = openstackclient.volume.v2.volume_type:DeleteVolumeType | ||||||
|     volume_type_list = openstackclient.volume.v2.volume_type:ListVolumeType |     volume_type_list = openstackclient.volume.v2.volume_type:ListVolumeType | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Huanxuan Ao
					Huanxuan Ao