Merge "Remove deprecated volume commands and args"
This commit is contained in:
commit
c20421c467
@ -73,12 +73,28 @@ Release 4.0
|
|||||||
* Removed in: 4.0
|
* Removed in: 4.0
|
||||||
* Commit: https://review.opendev.org/613644
|
* Commit: https://review.opendev.org/613644
|
||||||
|
|
||||||
.. 1. Change ``volume transfer request accept`` to use new option ``--auth-key``
|
10. Remove ``backup`` commands.
|
||||||
.. rather than a second positional argument.
|
Use ``volume backup`` commands instead.
|
||||||
|
|
||||||
.. * As of: 4.0
|
* Removed in: 4.0
|
||||||
.. * Remove in: <5.0>
|
* Commit: https://review.opendev.org/612751
|
||||||
.. * Commit: <tbd>
|
|
||||||
|
11. Remove ``snapshot`` commands.
|
||||||
|
Use ``volume snapshot`` commands instead.
|
||||||
|
|
||||||
|
* Removed in: 4.0
|
||||||
|
* Commit: https://review.opendev.org/612751
|
||||||
|
|
||||||
|
12. Remove ``volume create`` options ``--project``, ``--user``, ``--multi-attach``.
|
||||||
|
|
||||||
|
* Removed in: 4.0
|
||||||
|
* Commit: https://review.opendev.org/612751
|
||||||
|
|
||||||
|
13. Change ``volume transfer request accept`` to use new option ``--auth-key``
|
||||||
|
rather than a second positional argument.
|
||||||
|
|
||||||
|
* Removed in: 4.0
|
||||||
|
* Commit: https://review.opendev.org/612751
|
||||||
|
|
||||||
Release 3.12
|
Release 3.12
|
||||||
------------
|
------------
|
||||||
|
@ -1,137 +0,0 @@
|
|||||||
======
|
|
||||||
backup
|
|
||||||
======
|
|
||||||
|
|
||||||
Block Storage v1, v2
|
|
||||||
|
|
||||||
backup create
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Create new backup
|
|
||||||
(Deprecated, please use ``volume backup create`` instead)
|
|
||||||
|
|
||||||
.. program:: backup create
|
|
||||||
.. code:: bash
|
|
||||||
|
|
||||||
openstack backup create
|
|
||||||
[--container <container>]
|
|
||||||
[--name <name>]
|
|
||||||
[--description <description>]
|
|
||||||
[--snapshot <snapshot>]
|
|
||||||
[--force]
|
|
||||||
[--incremental]
|
|
||||||
<volume>
|
|
||||||
|
|
||||||
.. option:: --container <container>
|
|
||||||
|
|
||||||
Optional backup container name
|
|
||||||
|
|
||||||
.. option:: --name <name>
|
|
||||||
|
|
||||||
Name of the backup
|
|
||||||
|
|
||||||
.. option:: --description <description>
|
|
||||||
|
|
||||||
Description of the backup
|
|
||||||
|
|
||||||
.. option:: --snapshot <snapshot>
|
|
||||||
|
|
||||||
Snapshot to backup (name or ID)
|
|
||||||
|
|
||||||
*Volume version 2 only*
|
|
||||||
|
|
||||||
.. option:: --force
|
|
||||||
|
|
||||||
Allow to back up an in-use volume
|
|
||||||
|
|
||||||
*Volume version 2 only*
|
|
||||||
|
|
||||||
.. option:: --incremental
|
|
||||||
|
|
||||||
Perform an incremental backup
|
|
||||||
|
|
||||||
*Volume version 2 only*
|
|
||||||
|
|
||||||
.. _backup_create-backup:
|
|
||||||
.. describe:: <volume>
|
|
||||||
|
|
||||||
Volume to backup (name or ID)
|
|
||||||
|
|
||||||
backup delete
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Delete backup(s)
|
|
||||||
(Deprecated, please use ``volume backup delete`` instead)
|
|
||||||
|
|
||||||
.. program:: backup delete
|
|
||||||
.. code:: bash
|
|
||||||
|
|
||||||
openstack backup delete
|
|
||||||
[--force]
|
|
||||||
<backup> [<backup> ...]
|
|
||||||
|
|
||||||
.. option:: --force
|
|
||||||
|
|
||||||
Allow delete in state other than error or available
|
|
||||||
|
|
||||||
*Volume version 2 only*
|
|
||||||
|
|
||||||
.. _backup_delete-backup:
|
|
||||||
.. describe:: <backup>
|
|
||||||
|
|
||||||
Backup(s) to delete (name or ID)
|
|
||||||
|
|
||||||
backup list
|
|
||||||
-----------
|
|
||||||
|
|
||||||
List backups
|
|
||||||
(Deprecated, please use ``volume backup list`` instead)
|
|
||||||
|
|
||||||
.. program:: backup list
|
|
||||||
.. code:: bash
|
|
||||||
|
|
||||||
openstack backup list
|
|
||||||
|
|
||||||
.. _backup_list-backup:
|
|
||||||
.. option:: --long
|
|
||||||
|
|
||||||
List additional fields in output
|
|
||||||
|
|
||||||
backup restore
|
|
||||||
--------------
|
|
||||||
|
|
||||||
Restore backup
|
|
||||||
(Deprecated, please use ``volume backup restore`` instead)
|
|
||||||
|
|
||||||
.. program:: backup restore
|
|
||||||
.. code:: bash
|
|
||||||
|
|
||||||
openstack backup restore
|
|
||||||
<backup>
|
|
||||||
<volume>
|
|
||||||
|
|
||||||
.. _backup_restore-backup:
|
|
||||||
.. describe:: <backup>
|
|
||||||
|
|
||||||
Backup to restore (name or ID)
|
|
||||||
|
|
||||||
.. describe:: <volume>
|
|
||||||
|
|
||||||
Volume to restore to (name or ID)
|
|
||||||
|
|
||||||
backup show
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Display backup details
|
|
||||||
(Deprecated, please use ``volume backup show`` instead)
|
|
||||||
|
|
||||||
.. program:: backup show
|
|
||||||
.. code:: bash
|
|
||||||
|
|
||||||
openstack backup show
|
|
||||||
<backup>
|
|
||||||
|
|
||||||
.. _backup_show-backup:
|
|
||||||
.. describe:: <backup>
|
|
||||||
|
|
||||||
Backup to display (name or ID)
|
|
@ -1,176 +0,0 @@
|
|||||||
========
|
|
||||||
snapshot
|
|
||||||
========
|
|
||||||
|
|
||||||
Block Storage v1, v2
|
|
||||||
|
|
||||||
snapshot create
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Create new snapshot
|
|
||||||
(Deprecated, please use ``volume snapshot create`` instead)
|
|
||||||
|
|
||||||
.. program:: snapshot create
|
|
||||||
.. code:: bash
|
|
||||||
|
|
||||||
openstack snapshot create
|
|
||||||
[--name <name>]
|
|
||||||
[--description <description>]
|
|
||||||
[--force]
|
|
||||||
[--property <key=value> [...] ]
|
|
||||||
<volume>
|
|
||||||
|
|
||||||
.. option:: --name <name>
|
|
||||||
|
|
||||||
Name of the snapshot
|
|
||||||
|
|
||||||
.. 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*
|
|
||||||
|
|
||||||
.. _snapshot_create-snapshot:
|
|
||||||
.. describe:: <volume>
|
|
||||||
|
|
||||||
Volume to snapshot (name or ID)
|
|
||||||
|
|
||||||
snapshot delete
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Delete snapshot(s)
|
|
||||||
(Deprecated, please use ``volume snapshot delete`` instead)
|
|
||||||
|
|
||||||
.. program:: snapshot delete
|
|
||||||
.. code:: bash
|
|
||||||
|
|
||||||
openstack snapshot delete
|
|
||||||
<snapshot> [<snapshot> ...]
|
|
||||||
|
|
||||||
.. _snapshot_delete-snapshot:
|
|
||||||
.. describe:: <snapshot>
|
|
||||||
|
|
||||||
Snapshot(s) to delete (name or ID)
|
|
||||||
|
|
||||||
snapshot list
|
|
||||||
-------------
|
|
||||||
|
|
||||||
List snapshots
|
|
||||||
(Deprecated, please use ``volume snapshot list`` instead)
|
|
||||||
|
|
||||||
.. program:: snapshot list
|
|
||||||
.. code:: bash
|
|
||||||
|
|
||||||
openstack snapshot list
|
|
||||||
[--all-projects]
|
|
||||||
[--long]
|
|
||||||
[--limit <num-snapshots>]
|
|
||||||
[--marker <snapshot>]
|
|
||||||
|
|
||||||
.. option:: --all-projects
|
|
||||||
|
|
||||||
Include all projects (admin only)
|
|
||||||
|
|
||||||
.. option:: --long
|
|
||||||
|
|
||||||
List additional fields in output
|
|
||||||
|
|
||||||
.. option:: --limit <num-snapshots>
|
|
||||||
|
|
||||||
Maximum number of snapshots to display
|
|
||||||
|
|
||||||
*Volume version 2 only*
|
|
||||||
|
|
||||||
.. option:: --marker <snapshot>
|
|
||||||
|
|
||||||
The last snapshot ID of the previous page
|
|
||||||
|
|
||||||
*Volume version 2 only*
|
|
||||||
|
|
||||||
snapshot set
|
|
||||||
------------
|
|
||||||
|
|
||||||
Set snapshot properties
|
|
||||||
(Deprecated, please use ``volume snapshot set`` instead)
|
|
||||||
|
|
||||||
.. program:: snapshot set
|
|
||||||
.. code:: bash
|
|
||||||
|
|
||||||
openstack snapshot set
|
|
||||||
[--name <name>]
|
|
||||||
[--description <description>]
|
|
||||||
[--property <key=value> [...] ]
|
|
||||||
[--state <state>]
|
|
||||||
<snapshot>
|
|
||||||
|
|
||||||
.. _snapshot_restore-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*
|
|
||||||
|
|
||||||
.. describe:: <snapshot>
|
|
||||||
|
|
||||||
Snapshot to modify (name or ID)
|
|
||||||
|
|
||||||
snapshot show
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Display snapshot details
|
|
||||||
(Deprecated, please use ``volume snapshot show`` instead)
|
|
||||||
|
|
||||||
.. program:: snapshot show
|
|
||||||
.. code:: bash
|
|
||||||
|
|
||||||
openstack snapshot show
|
|
||||||
<snapshot>
|
|
||||||
|
|
||||||
.. _snapshot_show-snapshot:
|
|
||||||
.. describe:: <snapshot>
|
|
||||||
|
|
||||||
Snapshot to display (name or ID)
|
|
||||||
|
|
||||||
snapshot unset
|
|
||||||
--------------
|
|
||||||
|
|
||||||
Unset snapshot properties
|
|
||||||
(Deprecated, please use ``volume snapshot unset`` instead)
|
|
||||||
|
|
||||||
.. program:: snapshot unset
|
|
||||||
.. code:: bash
|
|
||||||
|
|
||||||
openstack snapshot unset
|
|
||||||
[--property <key>]
|
|
||||||
<snapshot>
|
|
||||||
|
|
||||||
.. option:: --property <key>
|
|
||||||
|
|
||||||
Property to remove from snapshot (repeat option to remove multiple properties)
|
|
||||||
|
|
||||||
.. describe:: <snapshot>
|
|
||||||
|
|
||||||
Snapshot to modify (name or ID)
|
|
@ -46,14 +46,14 @@ class VolumeBackupTests(common.BaseVolumeTests):
|
|||||||
'volume backup create -f json ' +
|
'volume backup create -f json ' +
|
||||||
vol_id
|
vol_id
|
||||||
))
|
))
|
||||||
self.wait_for_status("backup", backup['id'], "available")
|
self.wait_for_status("volume backup", backup['id'], "available")
|
||||||
|
|
||||||
# restore the backup
|
# restore the backup
|
||||||
backup_restored = json.loads(self.openstack(
|
backup_restored = json.loads(self.openstack(
|
||||||
'volume backup restore -f json %s %s'
|
'volume backup restore -f json %s %s'
|
||||||
% (backup['id'], vol_id)))
|
% (backup['id'], vol_id)))
|
||||||
self.assertEqual(backup_restored['backup_id'], backup['id'])
|
self.assertEqual(backup_restored['backup_id'], backup['id'])
|
||||||
self.wait_for_status("backup", backup['id'], "available")
|
self.wait_for_status("volume backup", backup['id'], "available")
|
||||||
self.wait_for_status("volume", backup_restored['volume_id'],
|
self.wait_for_status("volume", backup_restored['volume_id'],
|
||||||
"available")
|
"available")
|
||||||
self.addCleanup(self.openstack, 'volume delete %s' % vol_id)
|
self.addCleanup(self.openstack, 'volume delete %s' % vol_id)
|
@ -10,7 +10,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from openstackclient.tests.functional.volume.v2 import test_snapshot as v2
|
from openstackclient.tests.functional.volume.v2 import test_volume_snapshot as v2 # noqa
|
||||||
from openstackclient.tests.functional.volume.v3 import common
|
from openstackclient.tests.functional.volume.v3 import common
|
||||||
|
|
||||||
|
|
@ -1,580 +0,0 @@
|
|||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
import mock
|
|
||||||
from mock import call
|
|
||||||
|
|
||||||
from osc_lib import exceptions
|
|
||||||
from osc_lib import utils
|
|
||||||
|
|
||||||
from openstackclient.tests.unit import utils as tests_utils
|
|
||||||
from openstackclient.tests.unit.volume.v1 import fakes as volume_fakes
|
|
||||||
from openstackclient.volume.v1 import volume_snapshot
|
|
||||||
|
|
||||||
|
|
||||||
class TestSnapshot(volume_fakes.TestVolumev1):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSnapshot, self).setUp()
|
|
||||||
|
|
||||||
self.snapshots_mock = self.app.client_manager.volume.volume_snapshots
|
|
||||||
self.snapshots_mock.reset_mock()
|
|
||||||
self.volumes_mock = self.app.client_manager.volume.volumes
|
|
||||||
self.volumes_mock.reset_mock()
|
|
||||||
|
|
||||||
|
|
||||||
class TestSnapshotCreate(TestSnapshot):
|
|
||||||
|
|
||||||
columns = (
|
|
||||||
'created_at',
|
|
||||||
'display_description',
|
|
||||||
'display_name',
|
|
||||||
'id',
|
|
||||||
'properties',
|
|
||||||
'size',
|
|
||||||
'status',
|
|
||||||
'volume_id',
|
|
||||||
)
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSnapshotCreate, self).setUp()
|
|
||||||
|
|
||||||
self.volume = volume_fakes.FakeVolume.create_one_volume()
|
|
||||||
self.new_snapshot = volume_fakes.FakeSnapshot.create_one_snapshot(
|
|
||||||
attrs={'volume_id': self.volume.id})
|
|
||||||
|
|
||||||
self.data = (
|
|
||||||
self.new_snapshot.created_at,
|
|
||||||
self.new_snapshot.display_description,
|
|
||||||
self.new_snapshot.display_name,
|
|
||||||
self.new_snapshot.id,
|
|
||||||
utils.format_dict(self.new_snapshot.metadata),
|
|
||||||
self.new_snapshot.size,
|
|
||||||
self.new_snapshot.status,
|
|
||||||
self.new_snapshot.volume_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.volumes_mock.get.return_value = self.volume
|
|
||||||
self.snapshots_mock.create.return_value = self.new_snapshot
|
|
||||||
# Get the command object to test
|
|
||||||
self.cmd = volume_snapshot.CreateVolumeSnapshot(self.app, None)
|
|
||||||
|
|
||||||
def test_snapshot_create(self):
|
|
||||||
arglist = [
|
|
||||||
"--volume", self.new_snapshot.volume_id,
|
|
||||||
"--description", self.new_snapshot.display_description,
|
|
||||||
"--force",
|
|
||||||
self.new_snapshot.display_name,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("volume", self.new_snapshot.volume_id),
|
|
||||||
("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.snapshots_mock.create.assert_called_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)
|
|
||||||
|
|
||||||
def test_snapshot_create_without_name(self):
|
|
||||||
arglist = [
|
|
||||||
"--volume", self.new_snapshot.volume_id,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("volume", self.new_snapshot.volume_id),
|
|
||||||
]
|
|
||||||
self.assertRaises(
|
|
||||||
tests_utils.ParserException,
|
|
||||||
self.check_parser,
|
|
||||||
self.cmd,
|
|
||||||
arglist,
|
|
||||||
verifylist,
|
|
||||||
)
|
|
||||||
|
|
||||||
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):
|
|
||||||
|
|
||||||
snapshots = volume_fakes.FakeSnapshot.create_snapshots(count=2)
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSnapshotDelete, self).setUp()
|
|
||||||
|
|
||||||
self.snapshots_mock.get = (
|
|
||||||
volume_fakes.FakeSnapshot.get_snapshots(self.snapshots))
|
|
||||||
self.snapshots_mock.delete.return_value = None
|
|
||||||
|
|
||||||
# Get the command object to mock
|
|
||||||
self.cmd = volume_snapshot.DeleteVolumeSnapshot(self.app, None)
|
|
||||||
|
|
||||||
def test_snapshot_delete(self):
|
|
||||||
arglist = [
|
|
||||||
self.snapshots[0].id
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("snapshots", [self.snapshots[0].id])
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.delete.assert_called_with(
|
|
||||||
self.snapshots[0].id)
|
|
||||||
self.assertIsNone(result)
|
|
||||||
|
|
||||||
def test_delete_multiple_snapshots(self):
|
|
||||||
arglist = []
|
|
||||||
for s in self.snapshots:
|
|
||||||
arglist.append(s.id)
|
|
||||||
verifylist = [
|
|
||||||
('snapshots', arglist),
|
|
||||||
]
|
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
calls = []
|
|
||||||
for s in self.snapshots:
|
|
||||||
calls.append(call(s.id))
|
|
||||||
self.snapshots_mock.delete.assert_has_calls(calls)
|
|
||||||
self.assertIsNone(result)
|
|
||||||
|
|
||||||
def test_delete_multiple_snapshots_with_exception(self):
|
|
||||||
arglist = [
|
|
||||||
self.snapshots[0].id,
|
|
||||||
'unexist_snapshot',
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('snapshots', arglist),
|
|
||||||
]
|
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
find_mock_result = [self.snapshots[0], exceptions.CommandError]
|
|
||||||
with mock.patch.object(utils, 'find_resource',
|
|
||||||
side_effect=find_mock_result) as find_mock:
|
|
||||||
try:
|
|
||||||
self.cmd.take_action(parsed_args)
|
|
||||||
self.fail('CommandError should be raised.')
|
|
||||||
except exceptions.CommandError as e:
|
|
||||||
self.assertEqual('1 of 2 snapshots failed to delete.',
|
|
||||||
str(e))
|
|
||||||
|
|
||||||
find_mock.assert_any_call(
|
|
||||||
self.snapshots_mock, self.snapshots[0].id)
|
|
||||||
find_mock.assert_any_call(self.snapshots_mock, 'unexist_snapshot')
|
|
||||||
|
|
||||||
self.assertEqual(2, find_mock.call_count)
|
|
||||||
self.snapshots_mock.delete.assert_called_once_with(
|
|
||||||
self.snapshots[0].id
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TestSnapshotList(TestSnapshot):
|
|
||||||
|
|
||||||
volume = volume_fakes.FakeVolume.create_one_volume()
|
|
||||||
snapshots = volume_fakes.FakeSnapshot.create_snapshots(
|
|
||||||
attrs={'volume_id': volume.display_name}, count=3)
|
|
||||||
|
|
||||||
columns = [
|
|
||||||
"ID",
|
|
||||||
"Name",
|
|
||||||
"Description",
|
|
||||||
"Status",
|
|
||||||
"Size"
|
|
||||||
]
|
|
||||||
columns_long = columns + [
|
|
||||||
"Created At",
|
|
||||||
"Volume",
|
|
||||||
"Properties"
|
|
||||||
]
|
|
||||||
|
|
||||||
data = []
|
|
||||||
for s in snapshots:
|
|
||||||
data.append((
|
|
||||||
s.id,
|
|
||||||
s.display_name,
|
|
||||||
s.display_description,
|
|
||||||
s.status,
|
|
||||||
s.size,
|
|
||||||
))
|
|
||||||
data_long = []
|
|
||||||
for s in snapshots:
|
|
||||||
data_long.append((
|
|
||||||
s.id,
|
|
||||||
s.display_name,
|
|
||||||
s.display_description,
|
|
||||||
s.status,
|
|
||||||
s.size,
|
|
||||||
s.created_at,
|
|
||||||
s.volume_id,
|
|
||||||
utils.format_dict(s.metadata),
|
|
||||||
))
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSnapshotList, self).setUp()
|
|
||||||
|
|
||||||
self.volumes_mock.list.return_value = [self.volume]
|
|
||||||
self.volumes_mock.get.return_value = self.volume
|
|
||||||
self.snapshots_mock.list.return_value = self.snapshots
|
|
||||||
# Get the command to test
|
|
||||||
self.cmd = volume_snapshot.ListVolumeSnapshot(self.app, None)
|
|
||||||
|
|
||||||
def test_snapshot_list_without_options(self):
|
|
||||||
arglist = []
|
|
||||||
verifylist = [
|
|
||||||
('all_projects', False),
|
|
||||||
("long", False)
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
|
||||||
search_opts={
|
|
||||||
'all_tenants': False,
|
|
||||||
'display_name': None,
|
|
||||||
'status': None,
|
|
||||||
'volume_id': None
|
|
||||||
}
|
|
||||||
)
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, list(data))
|
|
||||||
|
|
||||||
def test_snapshot_list_with_long(self):
|
|
||||||
arglist = [
|
|
||||||
"--long",
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("long", True),
|
|
||||||
('all_projects', False),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
|
||||||
search_opts={
|
|
||||||
'all_tenants': False,
|
|
||||||
'display_name': None,
|
|
||||||
'status': None,
|
|
||||||
'volume_id': None
|
|
||||||
}
|
|
||||||
)
|
|
||||||
self.assertEqual(self.columns_long, columns)
|
|
||||||
self.assertEqual(self.data_long, list(data))
|
|
||||||
|
|
||||||
def test_snapshot_list_name_option(self):
|
|
||||||
arglist = [
|
|
||||||
'--name', self.snapshots[0].display_name,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('all_projects', False),
|
|
||||||
('long', False),
|
|
||||||
('name', self.snapshots[0].display_name),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
|
||||||
search_opts={
|
|
||||||
'all_tenants': False,
|
|
||||||
'display_name': self.snapshots[0].display_name,
|
|
||||||
'status': None,
|
|
||||||
'volume_id': None
|
|
||||||
}
|
|
||||||
)
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, list(data))
|
|
||||||
|
|
||||||
def test_snapshot_list_status_option(self):
|
|
||||||
arglist = [
|
|
||||||
'--status', self.snapshots[0].status,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('all_projects', False),
|
|
||||||
('long', False),
|
|
||||||
('status', self.snapshots[0].status),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
|
||||||
search_opts={
|
|
||||||
'all_tenants': False,
|
|
||||||
'display_name': None,
|
|
||||||
'status': self.snapshots[0].status,
|
|
||||||
'volume_id': None
|
|
||||||
}
|
|
||||||
)
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, list(data))
|
|
||||||
|
|
||||||
def test_snapshot_list_volumeid_option(self):
|
|
||||||
arglist = [
|
|
||||||
'--volume', self.volume.id,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('all_projects', False),
|
|
||||||
('long', False),
|
|
||||||
('volume', self.volume.id),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
|
||||||
search_opts={
|
|
||||||
'all_tenants': False,
|
|
||||||
'display_name': None,
|
|
||||||
'status': None,
|
|
||||||
'volume_id': self.volume.id
|
|
||||||
}
|
|
||||||
)
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, list(data))
|
|
||||||
|
|
||||||
def test_snapshot_list_all_projects(self):
|
|
||||||
arglist = [
|
|
||||||
'--all-projects',
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('long', False),
|
|
||||||
('all_projects', True)
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
|
||||||
search_opts={
|
|
||||||
'all_tenants': True,
|
|
||||||
'display_name': None,
|
|
||||||
'status': None,
|
|
||||||
'volume_id': None
|
|
||||||
}
|
|
||||||
)
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, list(data))
|
|
||||||
|
|
||||||
|
|
||||||
class TestSnapshotSet(TestSnapshot):
|
|
||||||
|
|
||||||
snapshot = volume_fakes.FakeSnapshot.create_one_snapshot()
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSnapshotSet, self).setUp()
|
|
||||||
|
|
||||||
self.snapshots_mock.get.return_value = self.snapshot
|
|
||||||
self.snapshots_mock.set_metadata.return_value = None
|
|
||||||
# Get the command object to mock
|
|
||||||
self.cmd = volume_snapshot.SetVolumeSnapshot(self.app, None)
|
|
||||||
|
|
||||||
def test_snapshot_set_all(self):
|
|
||||||
arglist = [
|
|
||||||
"--name", "new_snapshot",
|
|
||||||
"--description", "new_description",
|
|
||||||
"--property", "foo_1=foo_1",
|
|
||||||
"--property", "foo_2=foo_2",
|
|
||||||
"--no-property",
|
|
||||||
self.snapshot.id,
|
|
||||||
]
|
|
||||||
new_property = {"foo_1": "foo_1", "foo_2": "foo_2"}
|
|
||||||
verifylist = [
|
|
||||||
("name", "new_snapshot"),
|
|
||||||
("description", "new_description"),
|
|
||||||
("property", new_property),
|
|
||||||
("no_property", True),
|
|
||||||
("snapshot", self.snapshot.id),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
kwargs = {
|
|
||||||
"display_name": "new_snapshot",
|
|
||||||
"display_description": "new_description",
|
|
||||||
}
|
|
||||||
self.snapshot.update.assert_called_with(**kwargs)
|
|
||||||
self.snapshots_mock.delete_metadata.assert_called_with(
|
|
||||||
self.snapshot.id, ["foo"]
|
|
||||||
)
|
|
||||||
self.snapshots_mock.set_metadata.assert_called_with(
|
|
||||||
self.snapshot.id, {"foo_2": "foo_2", "foo_1": "foo_1"}
|
|
||||||
)
|
|
||||||
self.assertIsNone(result)
|
|
||||||
|
|
||||||
def test_snapshot_set_nothing(self):
|
|
||||||
arglist = [
|
|
||||||
self.snapshot.id,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("snapshot", self.snapshot.id),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
|
||||||
self.assertIsNone(result)
|
|
||||||
|
|
||||||
def test_snapshot_set_fail(self):
|
|
||||||
self.snapshots_mock.set_metadata.side_effect = (
|
|
||||||
exceptions.CommandError())
|
|
||||||
arglist = [
|
|
||||||
"--name", "new_snapshot",
|
|
||||||
"--description", "new_description",
|
|
||||||
"--property", "x=y",
|
|
||||||
"--property", "foo=foo",
|
|
||||||
self.snapshot.id,
|
|
||||||
]
|
|
||||||
new_property = {"x": "y", "foo": "foo"}
|
|
||||||
verifylist = [
|
|
||||||
("name", "new_snapshot"),
|
|
||||||
("description", "new_description"),
|
|
||||||
("property", new_property),
|
|
||||||
("snapshot", self.snapshot.id),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
self.assertRaises(exceptions.CommandError,
|
|
||||||
self.cmd.take_action, parsed_args)
|
|
||||||
|
|
||||||
|
|
||||||
class TestSnapshotShow(TestSnapshot):
|
|
||||||
|
|
||||||
columns = (
|
|
||||||
'created_at',
|
|
||||||
'display_description',
|
|
||||||
'display_name',
|
|
||||||
'id',
|
|
||||||
'properties',
|
|
||||||
'size',
|
|
||||||
'status',
|
|
||||||
'volume_id',
|
|
||||||
)
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSnapshotShow, self).setUp()
|
|
||||||
|
|
||||||
self.snapshot = volume_fakes.FakeSnapshot.create_one_snapshot()
|
|
||||||
|
|
||||||
self.data = (
|
|
||||||
self.snapshot.created_at,
|
|
||||||
self.snapshot.display_description,
|
|
||||||
self.snapshot.display_name,
|
|
||||||
self.snapshot.id,
|
|
||||||
utils.format_dict(self.snapshot.metadata),
|
|
||||||
self.snapshot.size,
|
|
||||||
self.snapshot.status,
|
|
||||||
self.snapshot.volume_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.snapshots_mock.get.return_value = self.snapshot
|
|
||||||
# Get the command object to test
|
|
||||||
self.cmd = volume_snapshot.ShowVolumeSnapshot(self.app, None)
|
|
||||||
|
|
||||||
def test_snapshot_show(self):
|
|
||||||
arglist = [
|
|
||||||
self.snapshot.id
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("snapshot", self.snapshot.id)
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
self.snapshots_mock.get.assert_called_with(self.snapshot.id)
|
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, data)
|
|
||||||
|
|
||||||
|
|
||||||
class TestSnapshotUnset(TestSnapshot):
|
|
||||||
|
|
||||||
snapshot = volume_fakes.FakeSnapshot.create_one_snapshot()
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSnapshotUnset, self).setUp()
|
|
||||||
|
|
||||||
self.snapshots_mock.get.return_value = self.snapshot
|
|
||||||
self.snapshots_mock.delete_metadata.return_value = None
|
|
||||||
# Get the command object to mock
|
|
||||||
self.cmd = volume_snapshot.UnsetVolumeSnapshot(self.app, None)
|
|
||||||
|
|
||||||
def test_snapshot_unset(self):
|
|
||||||
arglist = [
|
|
||||||
"--property", "foo",
|
|
||||||
self.snapshot.id,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("property", ["foo"]),
|
|
||||||
("snapshot", self.snapshot.id),
|
|
||||||
]
|
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.delete_metadata.assert_called_with(
|
|
||||||
self.snapshot.id, ["foo"]
|
|
||||||
)
|
|
||||||
self.assertIsNone(result)
|
|
||||||
|
|
||||||
def test_snapshot_unset_nothing(self):
|
|
||||||
arglist = [
|
|
||||||
self.snapshot.id,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("snapshot", self.snapshot.id),
|
|
||||||
]
|
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
|
||||||
self.assertIsNone(result)
|
|
@ -85,26 +85,6 @@ class TestTransferAccept(TestTransfer):
|
|||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
def test_transfer_accept_deprecated(self):
|
|
||||||
arglist = [
|
|
||||||
self.volume_transfer.id,
|
|
||||||
'key_value',
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('transfer_request', self.volume_transfer.id),
|
|
||||||
('old_auth_key', 'key_value'),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.transfer_mock.accept.assert_called_once_with(
|
|
||||||
self.volume_transfer.id,
|
|
||||||
'key_value',
|
|
||||||
)
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, data)
|
|
||||||
|
|
||||||
def test_transfer_accept_no_option(self):
|
def test_transfer_accept_no_option(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
self.volume_transfer.id,
|
self.volume_transfer.id,
|
||||||
|
@ -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 backup
|
from openstackclient.volume.v1 import volume_backup
|
||||||
|
|
||||||
|
|
||||||
class TestBackup(volume_fakes.TestVolumev1):
|
class TestBackup(volume_fakes.TestVolumev1):
|
||||||
@ -74,7 +74,7 @@ class TestBackupCreate(TestBackup):
|
|||||||
self.backups_mock.create.return_value = self.new_backup
|
self.backups_mock.create.return_value = self.new_backup
|
||||||
|
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = backup.CreateVolumeBackup(self.app, None)
|
self.cmd = volume_backup.CreateVolumeBackup(self.app, None)
|
||||||
|
|
||||||
def test_backup_create(self):
|
def test_backup_create(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -139,7 +139,7 @@ class TestBackupDelete(TestBackup):
|
|||||||
self.backups_mock.delete.return_value = None
|
self.backups_mock.delete.return_value = None
|
||||||
|
|
||||||
# Get the command object to mock
|
# Get the command object to mock
|
||||||
self.cmd = backup.DeleteVolumeBackup(self.app, None)
|
self.cmd = volume_backup.DeleteVolumeBackup(self.app, None)
|
||||||
|
|
||||||
def test_backup_delete(self):
|
def test_backup_delete(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -251,7 +251,7 @@ class TestBackupList(TestBackup):
|
|||||||
self.backups_mock.list.return_value = self.backups
|
self.backups_mock.list.return_value = self.backups
|
||||||
self.volumes_mock.get.return_value = self.volume
|
self.volumes_mock.get.return_value = self.volume
|
||||||
# Get the command to test
|
# Get the command to test
|
||||||
self.cmd = backup.ListVolumeBackup(self.app, None)
|
self.cmd = volume_backup.ListVolumeBackup(self.app, None)
|
||||||
|
|
||||||
def test_backup_list_without_options(self):
|
def test_backup_list_without_options(self):
|
||||||
arglist = []
|
arglist = []
|
||||||
@ -325,7 +325,7 @@ class TestBackupRestore(TestBackup):
|
|||||||
self.volumes_mock.get.return_value = self.volume
|
self.volumes_mock.get.return_value = self.volume
|
||||||
self.restores_mock.restore.return_value = None
|
self.restores_mock.restore.return_value = None
|
||||||
# Get the command object to mock
|
# Get the command object to mock
|
||||||
self.cmd = backup.RestoreVolumeBackup(self.app, None)
|
self.cmd = volume_backup.RestoreVolumeBackup(self.app, None)
|
||||||
|
|
||||||
def test_backup_restore(self):
|
def test_backup_restore(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -376,7 +376,7 @@ class TestBackupShow(TestBackup):
|
|||||||
)
|
)
|
||||||
self.backups_mock.get.return_value = self.backup
|
self.backups_mock.get.return_value = self.backup
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = backup.ShowVolumeBackup(self.app, None)
|
self.cmd = volume_backup.ShowVolumeBackup(self.app, None)
|
||||||
|
|
||||||
def test_backup_show(self):
|
def test_backup_show(self):
|
||||||
arglist = [
|
arglist = [
|
@ -1,741 +0,0 @@
|
|||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
import mock
|
|
||||||
from mock import call
|
|
||||||
from osc_lib import exceptions
|
|
||||||
from osc_lib import utils
|
|
||||||
|
|
||||||
from openstackclient.tests.unit.identity.v3 import fakes as project_fakes
|
|
||||||
from openstackclient.tests.unit import utils as tests_utils
|
|
||||||
from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
|
|
||||||
from openstackclient.volume.v2 import volume_snapshot
|
|
||||||
|
|
||||||
|
|
||||||
class TestSnapshot(volume_fakes.TestVolume):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSnapshot, self).setUp()
|
|
||||||
|
|
||||||
self.snapshots_mock = self.app.client_manager.volume.volume_snapshots
|
|
||||||
self.snapshots_mock.reset_mock()
|
|
||||||
self.volumes_mock = self.app.client_manager.volume.volumes
|
|
||||||
self.volumes_mock.reset_mock()
|
|
||||||
self.project_mock = self.app.client_manager.identity.projects
|
|
||||||
self.project_mock.reset_mock()
|
|
||||||
|
|
||||||
|
|
||||||
class TestSnapshotCreate(TestSnapshot):
|
|
||||||
|
|
||||||
columns = (
|
|
||||||
'created_at',
|
|
||||||
'description',
|
|
||||||
'id',
|
|
||||||
'name',
|
|
||||||
'properties',
|
|
||||||
'size',
|
|
||||||
'status',
|
|
||||||
'volume_id',
|
|
||||||
)
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSnapshotCreate, self).setUp()
|
|
||||||
|
|
||||||
self.volume = volume_fakes.FakeVolume.create_one_volume()
|
|
||||||
self.new_snapshot = volume_fakes.FakeSnapshot.create_one_snapshot(
|
|
||||||
attrs={'volume_id': self.volume.id})
|
|
||||||
|
|
||||||
self.data = (
|
|
||||||
self.new_snapshot.created_at,
|
|
||||||
self.new_snapshot.description,
|
|
||||||
self.new_snapshot.id,
|
|
||||||
self.new_snapshot.name,
|
|
||||||
utils.format_dict(self.new_snapshot.metadata),
|
|
||||||
self.new_snapshot.size,
|
|
||||||
self.new_snapshot.status,
|
|
||||||
self.new_snapshot.volume_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
def test_snapshot_create(self):
|
|
||||||
arglist = [
|
|
||||||
"--volume", self.new_snapshot.volume_id,
|
|
||||||
"--description", self.new_snapshot.description,
|
|
||||||
"--force",
|
|
||||||
'--property', 'Alpha=a',
|
|
||||||
'--property', 'Beta=b',
|
|
||||||
self.new_snapshot.name,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("volume", self.new_snapshot.volume_id),
|
|
||||||
("description", self.new_snapshot.description),
|
|
||||||
("force", True),
|
|
||||||
('property', {'Alpha': 'a', 'Beta': 'b'}),
|
|
||||||
("snapshot_name", self.new_snapshot.name),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.create.assert_called_with(
|
|
||||||
self.new_snapshot.volume_id,
|
|
||||||
force=True,
|
|
||||||
name=self.new_snapshot.name,
|
|
||||||
description=self.new_snapshot.description,
|
|
||||||
metadata={'Alpha': 'a', 'Beta': 'b'},
|
|
||||||
)
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, data)
|
|
||||||
|
|
||||||
def test_snapshot_create_without_name(self):
|
|
||||||
arglist = [
|
|
||||||
"--volume", self.new_snapshot.volume_id,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("volume", self.new_snapshot.volume_id),
|
|
||||||
]
|
|
||||||
self.assertRaises(
|
|
||||||
tests_utils.ParserException,
|
|
||||||
self.check_parser,
|
|
||||||
self.cmd,
|
|
||||||
arglist,
|
|
||||||
verifylist,
|
|
||||||
)
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
def test_snapshot_create_with_remote_source(self):
|
|
||||||
arglist = [
|
|
||||||
'--remote-source', 'source-name=test_source_name',
|
|
||||||
'--remote-source', 'source-id=test_source_id',
|
|
||||||
'--volume', self.new_snapshot.volume_id,
|
|
||||||
self.new_snapshot.name,
|
|
||||||
]
|
|
||||||
ref_dict = {'source-name': 'test_source_name',
|
|
||||||
'source-id': 'test_source_id'}
|
|
||||||
verifylist = [
|
|
||||||
('remote_source', ref_dict),
|
|
||||||
('volume', self.new_snapshot.volume_id),
|
|
||||||
("snapshot_name", self.new_snapshot.name),
|
|
||||||
]
|
|
||||||
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=self.new_snapshot.name,
|
|
||||||
description=None,
|
|
||||||
metadata=None,
|
|
||||||
)
|
|
||||||
self.snapshots_mock.create.assert_not_called()
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, data)
|
|
||||||
|
|
||||||
|
|
||||||
class TestSnapshotDelete(TestSnapshot):
|
|
||||||
|
|
||||||
snapshots = volume_fakes.FakeSnapshot.create_snapshots(count=2)
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSnapshotDelete, self).setUp()
|
|
||||||
|
|
||||||
self.snapshots_mock.get = (
|
|
||||||
volume_fakes.FakeSnapshot.get_snapshots(self.snapshots))
|
|
||||||
self.snapshots_mock.delete.return_value = None
|
|
||||||
|
|
||||||
# Get the command object to mock
|
|
||||||
self.cmd = volume_snapshot.DeleteVolumeSnapshot(self.app, None)
|
|
||||||
|
|
||||||
def test_snapshot_delete(self):
|
|
||||||
arglist = [
|
|
||||||
self.snapshots[0].id
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("snapshots", [self.snapshots[0].id])
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.delete.assert_called_with(
|
|
||||||
self.snapshots[0].id, False)
|
|
||||||
self.assertIsNone(result)
|
|
||||||
|
|
||||||
def test_snapshot_delete_with_force(self):
|
|
||||||
arglist = [
|
|
||||||
'--force',
|
|
||||||
self.snapshots[0].id
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('force', True),
|
|
||||||
("snapshots", [self.snapshots[0].id])
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.delete.assert_called_with(
|
|
||||||
self.snapshots[0].id, True)
|
|
||||||
self.assertIsNone(result)
|
|
||||||
|
|
||||||
def test_delete_multiple_snapshots(self):
|
|
||||||
arglist = []
|
|
||||||
for s in self.snapshots:
|
|
||||||
arglist.append(s.id)
|
|
||||||
verifylist = [
|
|
||||||
('snapshots', arglist),
|
|
||||||
]
|
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
calls = []
|
|
||||||
for s in self.snapshots:
|
|
||||||
calls.append(call(s.id, False))
|
|
||||||
self.snapshots_mock.delete.assert_has_calls(calls)
|
|
||||||
self.assertIsNone(result)
|
|
||||||
|
|
||||||
def test_delete_multiple_snapshots_with_exception(self):
|
|
||||||
arglist = [
|
|
||||||
self.snapshots[0].id,
|
|
||||||
'unexist_snapshot',
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('snapshots', arglist),
|
|
||||||
]
|
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
find_mock_result = [self.snapshots[0], exceptions.CommandError]
|
|
||||||
with mock.patch.object(utils, 'find_resource',
|
|
||||||
side_effect=find_mock_result) as find_mock:
|
|
||||||
try:
|
|
||||||
self.cmd.take_action(parsed_args)
|
|
||||||
self.fail('CommandError should be raised.')
|
|
||||||
except exceptions.CommandError as e:
|
|
||||||
self.assertEqual('1 of 2 snapshots failed to delete.',
|
|
||||||
str(e))
|
|
||||||
|
|
||||||
find_mock.assert_any_call(
|
|
||||||
self.snapshots_mock, self.snapshots[0].id)
|
|
||||||
find_mock.assert_any_call(self.snapshots_mock, 'unexist_snapshot')
|
|
||||||
|
|
||||||
self.assertEqual(2, find_mock.call_count)
|
|
||||||
self.snapshots_mock.delete.assert_called_once_with(
|
|
||||||
self.snapshots[0].id, False
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TestSnapshotList(TestSnapshot):
|
|
||||||
|
|
||||||
volume = volume_fakes.FakeVolume.create_one_volume()
|
|
||||||
project = project_fakes.FakeProject.create_one_project()
|
|
||||||
snapshots = volume_fakes.FakeSnapshot.create_snapshots(
|
|
||||||
attrs={'volume_id': volume.name}, count=3)
|
|
||||||
|
|
||||||
columns = [
|
|
||||||
"ID",
|
|
||||||
"Name",
|
|
||||||
"Description",
|
|
||||||
"Status",
|
|
||||||
"Size"
|
|
||||||
]
|
|
||||||
columns_long = columns + [
|
|
||||||
"Created At",
|
|
||||||
"Volume",
|
|
||||||
"Properties"
|
|
||||||
]
|
|
||||||
|
|
||||||
data = []
|
|
||||||
for s in snapshots:
|
|
||||||
data.append((
|
|
||||||
s.id,
|
|
||||||
s.name,
|
|
||||||
s.description,
|
|
||||||
s.status,
|
|
||||||
s.size,
|
|
||||||
))
|
|
||||||
data_long = []
|
|
||||||
for s in snapshots:
|
|
||||||
data_long.append((
|
|
||||||
s.id,
|
|
||||||
s.name,
|
|
||||||
s.description,
|
|
||||||
s.status,
|
|
||||||
s.size,
|
|
||||||
s.created_at,
|
|
||||||
s.volume_id,
|
|
||||||
utils.format_dict(s.metadata),
|
|
||||||
))
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSnapshotList, self).setUp()
|
|
||||||
|
|
||||||
self.volumes_mock.list.return_value = [self.volume]
|
|
||||||
self.volumes_mock.get.return_value = self.volume
|
|
||||||
self.project_mock.get.return_value = self.project
|
|
||||||
self.snapshots_mock.list.return_value = self.snapshots
|
|
||||||
# Get the command to test
|
|
||||||
self.cmd = volume_snapshot.ListVolumeSnapshot(self.app, None)
|
|
||||||
|
|
||||||
def test_snapshot_list_without_options(self):
|
|
||||||
arglist = []
|
|
||||||
verifylist = [
|
|
||||||
('all_projects', False),
|
|
||||||
('long', False)
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
|
||||||
limit=None, marker=None,
|
|
||||||
search_opts={
|
|
||||||
'all_tenants': False,
|
|
||||||
'name': None,
|
|
||||||
'status': None,
|
|
||||||
'project_id': None,
|
|
||||||
'volume_id': None
|
|
||||||
}
|
|
||||||
)
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, list(data))
|
|
||||||
|
|
||||||
def test_snapshot_list_with_options(self):
|
|
||||||
arglist = [
|
|
||||||
"--long",
|
|
||||||
"--limit", "2",
|
|
||||||
"--project", self.project.id,
|
|
||||||
"--marker", self.snapshots[0].id,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("long", True),
|
|
||||||
("limit", 2),
|
|
||||||
("project", self.project.id),
|
|
||||||
("marker", self.snapshots[0].id),
|
|
||||||
('all_projects', False),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
|
||||||
limit=2,
|
|
||||||
marker=self.snapshots[0].id,
|
|
||||||
search_opts={
|
|
||||||
'all_tenants': True,
|
|
||||||
'project_id': self.project.id,
|
|
||||||
'name': None,
|
|
||||||
'status': None,
|
|
||||||
'volume_id': None
|
|
||||||
}
|
|
||||||
)
|
|
||||||
self.assertEqual(self.columns_long, columns)
|
|
||||||
self.assertEqual(self.data_long, list(data))
|
|
||||||
|
|
||||||
def test_snapshot_list_all_projects(self):
|
|
||||||
arglist = [
|
|
||||||
'--all-projects',
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('long', False),
|
|
||||||
('all_projects', True)
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
|
||||||
limit=None, marker=None,
|
|
||||||
search_opts={
|
|
||||||
'all_tenants': True,
|
|
||||||
'name': None,
|
|
||||||
'status': None,
|
|
||||||
'project_id': None,
|
|
||||||
'volume_id': None
|
|
||||||
}
|
|
||||||
)
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, list(data))
|
|
||||||
|
|
||||||
def test_snapshot_list_name_option(self):
|
|
||||||
arglist = [
|
|
||||||
'--name', self.snapshots[0].name,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('all_projects', False),
|
|
||||||
('long', False),
|
|
||||||
('name', self.snapshots[0].name),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
|
||||||
limit=None, marker=None,
|
|
||||||
search_opts={
|
|
||||||
'all_tenants': False,
|
|
||||||
'name': self.snapshots[0].name,
|
|
||||||
'status': None,
|
|
||||||
'project_id': None,
|
|
||||||
'volume_id': None
|
|
||||||
}
|
|
||||||
)
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, list(data))
|
|
||||||
|
|
||||||
def test_snapshot_list_status_option(self):
|
|
||||||
arglist = [
|
|
||||||
'--status', self.snapshots[0].status,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('all_projects', False),
|
|
||||||
('long', False),
|
|
||||||
('status', self.snapshots[0].status),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
|
||||||
limit=None, marker=None,
|
|
||||||
search_opts={
|
|
||||||
'all_tenants': False,
|
|
||||||
'name': None,
|
|
||||||
'status': self.snapshots[0].status,
|
|
||||||
'project_id': None,
|
|
||||||
'volume_id': None
|
|
||||||
}
|
|
||||||
)
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, list(data))
|
|
||||||
|
|
||||||
def test_snapshot_list_volumeid_option(self):
|
|
||||||
arglist = [
|
|
||||||
'--volume', self.volume.id,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('all_projects', False),
|
|
||||||
('long', False),
|
|
||||||
('volume', self.volume.id),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.list.assert_called_once_with(
|
|
||||||
limit=None, marker=None,
|
|
||||||
search_opts={
|
|
||||||
'all_tenants': False,
|
|
||||||
'name': None,
|
|
||||||
'status': None,
|
|
||||||
'project_id': None,
|
|
||||||
'volume_id': self.volume.id
|
|
||||||
}
|
|
||||||
)
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, list(data))
|
|
||||||
|
|
||||||
def test_snapshot_list_negative_limit(self):
|
|
||||||
arglist = [
|
|
||||||
"--limit", "-2",
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("limit", -2),
|
|
||||||
]
|
|
||||||
self.assertRaises(argparse.ArgumentTypeError, self.check_parser,
|
|
||||||
self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
|
|
||||||
class TestSnapshotSet(TestSnapshot):
|
|
||||||
|
|
||||||
snapshot = volume_fakes.FakeSnapshot.create_one_snapshot()
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSnapshotSet, self).setUp()
|
|
||||||
|
|
||||||
self.snapshots_mock.get.return_value = self.snapshot
|
|
||||||
self.snapshots_mock.set_metadata.return_value = None
|
|
||||||
self.snapshots_mock.update.return_value = None
|
|
||||||
# Get the command object to mock
|
|
||||||
self.cmd = volume_snapshot.SetVolumeSnapshot(self.app, None)
|
|
||||||
|
|
||||||
def test_snapshot_set_no_option(self):
|
|
||||||
arglist = [
|
|
||||||
self.snapshot.id,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("snapshot", self.snapshot.id),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
|
||||||
self.snapshots_mock.get.assert_called_once_with(parsed_args.snapshot)
|
|
||||||
self.assertNotCalled(self.snapshots_mock.reset_state)
|
|
||||||
self.assertNotCalled(self.snapshots_mock.update)
|
|
||||||
self.assertNotCalled(self.snapshots_mock.set_metadata)
|
|
||||||
self.assertIsNone(result)
|
|
||||||
|
|
||||||
def test_snapshot_set_name_and_property(self):
|
|
||||||
arglist = [
|
|
||||||
"--name", "new_snapshot",
|
|
||||||
"--property", "x=y",
|
|
||||||
"--property", "foo=foo",
|
|
||||||
self.snapshot.id,
|
|
||||||
]
|
|
||||||
new_property = {"x": "y", "foo": "foo"}
|
|
||||||
verifylist = [
|
|
||||||
("name", "new_snapshot"),
|
|
||||||
("property", new_property),
|
|
||||||
("snapshot", self.snapshot.id),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
kwargs = {
|
|
||||||
"name": "new_snapshot",
|
|
||||||
}
|
|
||||||
self.snapshots_mock.update.assert_called_with(
|
|
||||||
self.snapshot.id, **kwargs)
|
|
||||||
self.snapshots_mock.set_metadata.assert_called_with(
|
|
||||||
self.snapshot.id, new_property
|
|
||||||
)
|
|
||||||
self.assertIsNone(result)
|
|
||||||
|
|
||||||
def test_snapshot_set_with_no_property(self):
|
|
||||||
arglist = [
|
|
||||||
"--no-property",
|
|
||||||
self.snapshot.id,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("no_property", True),
|
|
||||||
("snapshot", self.snapshot.id),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
|
||||||
self.snapshots_mock.get.assert_called_once_with(parsed_args.snapshot)
|
|
||||||
self.assertNotCalled(self.snapshots_mock.reset_state)
|
|
||||||
self.assertNotCalled(self.snapshots_mock.update)
|
|
||||||
self.assertNotCalled(self.snapshots_mock.set_metadata)
|
|
||||||
self.snapshots_mock.delete_metadata.assert_called_with(
|
|
||||||
self.snapshot.id, ["foo"]
|
|
||||||
)
|
|
||||||
self.assertIsNone(result)
|
|
||||||
|
|
||||||
def test_snapshot_set_with_no_property_and_property(self):
|
|
||||||
arglist = [
|
|
||||||
"--no-property",
|
|
||||||
"--property", "foo_1=bar_1",
|
|
||||||
self.snapshot.id,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("no_property", True),
|
|
||||||
("property", {"foo_1": "bar_1"}),
|
|
||||||
("snapshot", self.snapshot.id),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
|
||||||
self.snapshots_mock.get.assert_called_once_with(parsed_args.snapshot)
|
|
||||||
self.assertNotCalled(self.snapshots_mock.reset_state)
|
|
||||||
self.assertNotCalled(self.snapshots_mock.update)
|
|
||||||
self.snapshots_mock.delete_metadata.assert_called_with(
|
|
||||||
self.snapshot.id, ["foo"]
|
|
||||||
)
|
|
||||||
self.snapshots_mock.set_metadata.assert_called_once_with(
|
|
||||||
self.snapshot.id, {"foo_1": "bar_1"})
|
|
||||||
self.assertIsNone(result)
|
|
||||||
|
|
||||||
def test_snapshot_set_state_to_error(self):
|
|
||||||
arglist = [
|
|
||||||
"--state", "error",
|
|
||||||
self.snapshot.id
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("state", "error"),
|
|
||||||
("snapshot", self.snapshot.id)
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.reset_state.assert_called_with(
|
|
||||||
self.snapshot.id, "error")
|
|
||||||
self.assertIsNone(result)
|
|
||||||
|
|
||||||
def test_volume_set_state_failed(self):
|
|
||||||
self.snapshots_mock.reset_state.side_effect = exceptions.CommandError()
|
|
||||||
arglist = [
|
|
||||||
'--state', 'error',
|
|
||||||
self.snapshot.id
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('state', 'error'),
|
|
||||||
('snapshot', self.snapshot.id)
|
|
||||||
]
|
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
try:
|
|
||||||
self.cmd.take_action(parsed_args)
|
|
||||||
self.fail('CommandError should be raised.')
|
|
||||||
except exceptions.CommandError as e:
|
|
||||||
self.assertEqual('One or more of the set operations failed',
|
|
||||||
str(e))
|
|
||||||
self.snapshots_mock.reset_state.assert_called_once_with(
|
|
||||||
self.snapshot.id, 'error')
|
|
||||||
|
|
||||||
def test_volume_set_name_and_state_failed(self):
|
|
||||||
self.snapshots_mock.reset_state.side_effect = exceptions.CommandError()
|
|
||||||
arglist = [
|
|
||||||
'--state', 'error',
|
|
||||||
"--name", "new_snapshot",
|
|
||||||
self.snapshot.id
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('state', 'error'),
|
|
||||||
("name", "new_snapshot"),
|
|
||||||
('snapshot', self.snapshot.id)
|
|
||||||
]
|
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
try:
|
|
||||||
self.cmd.take_action(parsed_args)
|
|
||||||
self.fail('CommandError should be raised.')
|
|
||||||
except exceptions.CommandError as e:
|
|
||||||
self.assertEqual('One or more of the set operations failed',
|
|
||||||
str(e))
|
|
||||||
kwargs = {
|
|
||||||
"name": "new_snapshot",
|
|
||||||
}
|
|
||||||
self.snapshots_mock.update.assert_called_once_with(
|
|
||||||
self.snapshot.id, **kwargs)
|
|
||||||
self.snapshots_mock.reset_state.assert_called_once_with(
|
|
||||||
self.snapshot.id, 'error')
|
|
||||||
|
|
||||||
|
|
||||||
class TestSnapshotShow(TestSnapshot):
|
|
||||||
|
|
||||||
columns = (
|
|
||||||
'created_at',
|
|
||||||
'description',
|
|
||||||
'id',
|
|
||||||
'name',
|
|
||||||
'properties',
|
|
||||||
'size',
|
|
||||||
'status',
|
|
||||||
'volume_id',
|
|
||||||
)
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSnapshotShow, self).setUp()
|
|
||||||
|
|
||||||
self.snapshot = volume_fakes.FakeSnapshot.create_one_snapshot()
|
|
||||||
|
|
||||||
self.data = (
|
|
||||||
self.snapshot.created_at,
|
|
||||||
self.snapshot.description,
|
|
||||||
self.snapshot.id,
|
|
||||||
self.snapshot.name,
|
|
||||||
utils.format_dict(self.snapshot.metadata),
|
|
||||||
self.snapshot.size,
|
|
||||||
self.snapshot.status,
|
|
||||||
self.snapshot.volume_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.snapshots_mock.get.return_value = self.snapshot
|
|
||||||
# Get the command object to test
|
|
||||||
self.cmd = volume_snapshot.ShowVolumeSnapshot(self.app, None)
|
|
||||||
|
|
||||||
def test_snapshot_show(self):
|
|
||||||
arglist = [
|
|
||||||
self.snapshot.id
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("snapshot", self.snapshot.id)
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
self.snapshots_mock.get.assert_called_with(self.snapshot.id)
|
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, data)
|
|
||||||
|
|
||||||
|
|
||||||
class TestSnapshotUnset(TestSnapshot):
|
|
||||||
|
|
||||||
snapshot = volume_fakes.FakeSnapshot.create_one_snapshot()
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSnapshotUnset, self).setUp()
|
|
||||||
|
|
||||||
self.snapshots_mock.get.return_value = self.snapshot
|
|
||||||
self.snapshots_mock.delete_metadata.return_value = None
|
|
||||||
# Get the command object to mock
|
|
||||||
self.cmd = volume_snapshot.UnsetVolumeSnapshot(self.app, None)
|
|
||||||
|
|
||||||
def test_snapshot_unset(self):
|
|
||||||
arglist = [
|
|
||||||
"--property", "foo",
|
|
||||||
self.snapshot.id,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
("property", ["foo"]),
|
|
||||||
("snapshot", self.snapshot.id),
|
|
||||||
]
|
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.snapshots_mock.delete_metadata.assert_called_with(
|
|
||||||
self.snapshot.id, ["foo"]
|
|
||||||
)
|
|
||||||
self.assertIsNone(result)
|
|
@ -18,6 +18,7 @@ from mock import call
|
|||||||
from osc_lib import exceptions
|
from osc_lib import exceptions
|
||||||
from osc_lib import utils
|
from osc_lib import utils
|
||||||
|
|
||||||
|
from openstackclient.tests.unit import utils as test_utils
|
||||||
from openstackclient.tests.unit.volume.v2 import fakes as transfer_fakes
|
from openstackclient.tests.unit.volume.v2 import fakes as transfer_fakes
|
||||||
from openstackclient.volume.v2 import volume_transfer_request
|
from openstackclient.volume.v2 import volume_transfer_request
|
||||||
|
|
||||||
@ -85,26 +86,6 @@ class TestTransferAccept(TestTransfer):
|
|||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
def test_transfer_accept_deprecated(self):
|
|
||||||
arglist = [
|
|
||||||
self.volume_transfer.id,
|
|
||||||
'key_value',
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('transfer_request', self.volume_transfer.id),
|
|
||||||
('old_auth_key', 'key_value'),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.transfer_mock.accept.assert_called_once_with(
|
|
||||||
self.volume_transfer.id,
|
|
||||||
'key_value',
|
|
||||||
)
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertEqual(self.data, data)
|
|
||||||
|
|
||||||
def test_transfer_accept_no_option(self):
|
def test_transfer_accept_no_option(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
self.volume_transfer.id,
|
self.volume_transfer.id,
|
||||||
@ -112,12 +93,13 @@ class TestTransferAccept(TestTransfer):
|
|||||||
verifylist = [
|
verifylist = [
|
||||||
('transfer_request', self.volume_transfer.id),
|
('transfer_request', self.volume_transfer.id),
|
||||||
]
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
exceptions.CommandError,
|
test_utils.ParserException,
|
||||||
self.cmd.take_action,
|
self.check_parser,
|
||||||
parsed_args,
|
self.cmd,
|
||||||
|
arglist,
|
||||||
|
verifylist,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -183,40 +183,6 @@ class TestVolumeCreate(TestVolume):
|
|||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.datalist, data)
|
self.assertEqual(self.datalist, data)
|
||||||
|
|
||||||
def test_volume_create_user(self):
|
|
||||||
arglist = [
|
|
||||||
'--size', str(self.new_volume.size),
|
|
||||||
'--user', self.user.id,
|
|
||||||
self.new_volume.name,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('size', self.new_volume.size),
|
|
||||||
('user', self.user.id),
|
|
||||||
('name', self.new_volume.name),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
|
||||||
parsed_args)
|
|
||||||
self.volumes_mock.create.assert_not_called()
|
|
||||||
|
|
||||||
def test_volume_create_project(self):
|
|
||||||
arglist = [
|
|
||||||
'--size', str(self.new_volume.size),
|
|
||||||
'--project', self.project.id,
|
|
||||||
self.new_volume.name,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('size', self.new_volume.size),
|
|
||||||
('project', self.project.id),
|
|
||||||
('name', self.new_volume.name),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
|
||||||
parsed_args)
|
|
||||||
self.volumes_mock.create.assert_not_called()
|
|
||||||
|
|
||||||
def test_volume_create_properties(self):
|
def test_volume_create_properties(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
'--property', 'Alpha=a',
|
'--property', 'Alpha=a',
|
||||||
|
@ -19,7 +19,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 backup
|
from openstackclient.volume.v2 import volume_backup
|
||||||
|
|
||||||
|
|
||||||
class TestBackup(volume_fakes.TestVolume):
|
class TestBackup(volume_fakes.TestVolume):
|
||||||
@ -77,7 +77,7 @@ class TestBackupCreate(TestBackup):
|
|||||||
self.backups_mock.create.return_value = self.new_backup
|
self.backups_mock.create.return_value = self.new_backup
|
||||||
|
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = backup.CreateVolumeBackup(self.app, None)
|
self.cmd = volume_backup.CreateVolumeBackup(self.app, None)
|
||||||
|
|
||||||
def test_backup_create(self):
|
def test_backup_create(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -154,7 +154,7 @@ class TestBackupDelete(TestBackup):
|
|||||||
self.backups_mock.delete.return_value = None
|
self.backups_mock.delete.return_value = None
|
||||||
|
|
||||||
# Get the command object to mock
|
# Get the command object to mock
|
||||||
self.cmd = backup.DeleteVolumeBackup(self.app, None)
|
self.cmd = volume_backup.DeleteVolumeBackup(self.app, None)
|
||||||
|
|
||||||
def test_backup_delete(self):
|
def test_backup_delete(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -283,7 +283,7 @@ class TestBackupList(TestBackup):
|
|||||||
self.volumes_mock.get.return_value = self.volume
|
self.volumes_mock.get.return_value = self.volume
|
||||||
self.backups_mock.get.return_value = self.backups[0]
|
self.backups_mock.get.return_value = self.backups[0]
|
||||||
# Get the command to test
|
# Get the command to test
|
||||||
self.cmd = backup.ListVolumeBackup(self.app, None)
|
self.cmd = volume_backup.ListVolumeBackup(self.app, None)
|
||||||
|
|
||||||
def test_backup_list_without_options(self):
|
def test_backup_list_without_options(self):
|
||||||
arglist = []
|
arglist = []
|
||||||
@ -371,7 +371,7 @@ class TestBackupRestore(TestBackup):
|
|||||||
volume_fakes.FakeVolume.create_one_volume(
|
volume_fakes.FakeVolume.create_one_volume(
|
||||||
{'id': self.volume['id']}))
|
{'id': self.volume['id']}))
|
||||||
# Get the command object to mock
|
# Get the command object to mock
|
||||||
self.cmd = backup.RestoreVolumeBackup(self.app, None)
|
self.cmd = volume_backup.RestoreVolumeBackup(self.app, None)
|
||||||
|
|
||||||
def test_backup_restore(self):
|
def test_backup_restore(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -400,7 +400,7 @@ class TestBackupSet(TestBackup):
|
|||||||
self.backups_mock.get.return_value = self.backup
|
self.backups_mock.get.return_value = self.backup
|
||||||
|
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = backup.SetVolumeBackup(self.app, None)
|
self.cmd = volume_backup.SetVolumeBackup(self.app, None)
|
||||||
|
|
||||||
def test_backup_set_name(self):
|
def test_backup_set_name(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -517,7 +517,7 @@ class TestBackupShow(TestBackup):
|
|||||||
|
|
||||||
self.backups_mock.get.return_value = self.backup
|
self.backups_mock.get.return_value = self.backup
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = backup.ShowVolumeBackup(self.app, None)
|
self.cmd = volume_backup.ShowVolumeBackup(self.app, None)
|
||||||
|
|
||||||
def test_backup_show(self):
|
def test_backup_show(self):
|
||||||
arglist = [
|
arglist = [
|
@ -1,318 +0,0 @@
|
|||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
# 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"""
|
|
||||||
|
|
||||||
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 _
|
|
||||||
|
|
||||||
|
|
||||||
deprecated = True
|
|
||||||
LOG_DEP = logging.getLogger('deprecated')
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class CreateSnapshot(command.ShowOne):
|
|
||||||
_description = _("Create new snapshot")
|
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(CreateSnapshot, self).get_parser(prog_name)
|
|
||||||
parser.add_argument(
|
|
||||||
'volume',
|
|
||||||
metavar='<volume>',
|
|
||||||
help=_('Volume to snapshot (name or ID)'),
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'--name',
|
|
||||||
metavar='<name>',
|
|
||||||
help=_('Name of the snapshot'),
|
|
||||||
)
|
|
||||||
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):
|
|
||||||
LOG_DEP.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume snapshot create" instead.'))
|
|
||||||
volume_client = self.app.client_manager.volume
|
|
||||||
volume_id = utils.find_resource(volume_client.volumes,
|
|
||||||
parsed_args.volume).id
|
|
||||||
snapshot = volume_client.volume_snapshots.create(
|
|
||||||
volume_id,
|
|
||||||
parsed_args.force,
|
|
||||||
parsed_args.name,
|
|
||||||
parsed_args.description
|
|
||||||
)
|
|
||||||
|
|
||||||
snapshot._info.update(
|
|
||||||
{'properties': utils.format_dict(snapshot._info.pop('metadata'))}
|
|
||||||
)
|
|
||||||
|
|
||||||
return zip(*sorted(six.iteritems(snapshot._info)))
|
|
||||||
|
|
||||||
|
|
||||||
class DeleteSnapshot(command.Command):
|
|
||||||
_description = _("Delete snapshot(s)")
|
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(DeleteSnapshot, 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):
|
|
||||||
LOG_DEP.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume snapshot delete" instead.'))
|
|
||||||
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 ListSnapshot(command.Lister):
|
|
||||||
_description = _("List snapshots")
|
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(ListSnapshot, 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):
|
|
||||||
LOG_DEP.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume snapshot list" instead.'))
|
|
||||||
|
|
||||||
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 SetSnapshot(command.Command):
|
|
||||||
_description = _("Set snapshot properties")
|
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(SetSnapshot, 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):
|
|
||||||
LOG_DEP.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume snapshot set" instead.'))
|
|
||||||
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 ShowSnapshot(command.ShowOne):
|
|
||||||
_description = _("Display snapshot details")
|
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(ShowSnapshot, 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):
|
|
||||||
LOG_DEP.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume snapshot show" instead.'))
|
|
||||||
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 UnsetSnapshot(command.Command):
|
|
||||||
_description = _("Unset snapshot properties")
|
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(UnsetSnapshot, 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):
|
|
||||||
LOG_DEP.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume snapshot unset" instead.'))
|
|
||||||
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,
|
|
||||||
)
|
|
@ -72,23 +72,6 @@ class CreateVolumeBackup(command.ShowOne):
|
|||||||
return zip(*sorted(six.iteritems(backup._info)))
|
return zip(*sorted(six.iteritems(backup._info)))
|
||||||
|
|
||||||
|
|
||||||
class CreateBackup(CreateVolumeBackup):
|
|
||||||
_description = _("Create new backup")
|
|
||||||
|
|
||||||
# TODO(Huanxuan Ao): Remove this class and ``backup create`` command
|
|
||||||
# two cycles after Newton.
|
|
||||||
|
|
||||||
# This notifies cliff to not display the help for this command
|
|
||||||
deprecated = True
|
|
||||||
|
|
||||||
log = logging.getLogger('deprecated')
|
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
|
||||||
self.log.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume backup create" instead.'))
|
|
||||||
return super(CreateBackup, self).take_action(parsed_args)
|
|
||||||
|
|
||||||
|
|
||||||
class DeleteVolumeBackup(command.Command):
|
class DeleteVolumeBackup(command.Command):
|
||||||
_description = _("Delete volume backup(s)")
|
_description = _("Delete volume backup(s)")
|
||||||
|
|
||||||
@ -124,23 +107,6 @@ class DeleteVolumeBackup(command.Command):
|
|||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
|
|
||||||
class DeleteBackup(DeleteVolumeBackup):
|
|
||||||
_description = _("Delete backup(s)")
|
|
||||||
|
|
||||||
# TODO(Huanxuan Ao): Remove this class and ``backup delete`` command
|
|
||||||
# two cycles after Newton.
|
|
||||||
|
|
||||||
# This notifies cliff to not display the help for this command
|
|
||||||
deprecated = True
|
|
||||||
|
|
||||||
log = logging.getLogger('deprecated')
|
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
|
||||||
self.log.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume backup delete" instead.'))
|
|
||||||
return super(DeleteBackup, self).take_action(parsed_args)
|
|
||||||
|
|
||||||
|
|
||||||
class ListVolumeBackup(command.Lister):
|
class ListVolumeBackup(command.Lister):
|
||||||
_description = _("List volume backups")
|
_description = _("List volume backups")
|
||||||
|
|
||||||
@ -234,23 +200,6 @@ class ListVolumeBackup(command.Lister):
|
|||||||
) for s in data))
|
) for s in data))
|
||||||
|
|
||||||
|
|
||||||
class ListBackup(ListVolumeBackup):
|
|
||||||
_description = _("List backups")
|
|
||||||
|
|
||||||
# TODO(Huanxuan Ao): Remove this class and ``backup list`` command
|
|
||||||
# two cycles after Newton.
|
|
||||||
|
|
||||||
# This notifies cliff to not display the help for this command
|
|
||||||
deprecated = True
|
|
||||||
|
|
||||||
log = logging.getLogger('deprecated')
|
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
|
||||||
self.log.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume backup list" instead.'))
|
|
||||||
return super(ListBackup, self).take_action(parsed_args)
|
|
||||||
|
|
||||||
|
|
||||||
class RestoreVolumeBackup(command.Command):
|
class RestoreVolumeBackup(command.Command):
|
||||||
_description = _("Restore volume backup")
|
_description = _("Restore volume backup")
|
||||||
|
|
||||||
@ -278,23 +227,6 @@ class RestoreVolumeBackup(command.Command):
|
|||||||
destination_volume.id)
|
destination_volume.id)
|
||||||
|
|
||||||
|
|
||||||
class RestoreBackup(RestoreVolumeBackup):
|
|
||||||
_description = _("Restore backup")
|
|
||||||
|
|
||||||
# TODO(Huanxuan Ao): Remove this class and ``backup restore`` command
|
|
||||||
# two cycles after Newton.
|
|
||||||
|
|
||||||
# This notifies cliff to not display the help for this command
|
|
||||||
deprecated = True
|
|
||||||
|
|
||||||
log = logging.getLogger('deprecated')
|
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
|
||||||
self.log.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume backup restore" instead.'))
|
|
||||||
return super(RestoreBackup, self).take_action(parsed_args)
|
|
||||||
|
|
||||||
|
|
||||||
class ShowVolumeBackup(command.ShowOne):
|
class ShowVolumeBackup(command.ShowOne):
|
||||||
_description = _("Display volume backup details")
|
_description = _("Display volume backup details")
|
||||||
|
|
||||||
@ -313,20 +245,3 @@ class ShowVolumeBackup(command.ShowOne):
|
|||||||
parsed_args.backup)
|
parsed_args.backup)
|
||||||
backup._info.pop('links')
|
backup._info.pop('links')
|
||||||
return zip(*sorted(six.iteritems(backup._info)))
|
return zip(*sorted(six.iteritems(backup._info)))
|
||||||
|
|
||||||
|
|
||||||
class ShowBackup(ShowVolumeBackup):
|
|
||||||
_description = _("Display backup details")
|
|
||||||
|
|
||||||
# TODO(Huanxuan Ao): Remove this class and ``backup show`` command
|
|
||||||
# two cycles after Newton.
|
|
||||||
|
|
||||||
# This notifies cliff to not display the help for this command
|
|
||||||
deprecated = True
|
|
||||||
|
|
||||||
log = logging.getLogger('deprecated')
|
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
|
||||||
self.log.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume backup show" instead.'))
|
|
||||||
return super(ShowBackup, self).take_action(parsed_args)
|
|
@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
"""Volume v1 transfer action implementations"""
|
"""Volume v1 transfer action implementations"""
|
||||||
|
|
||||||
import argparse
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from osc_lib.command import command
|
from osc_lib.command import command
|
||||||
@ -38,12 +37,6 @@ class AcceptTransferRequest(command.ShowOne):
|
|||||||
metavar="<transfer-request-id>",
|
metavar="<transfer-request-id>",
|
||||||
help=_('Volume transfer request to accept (ID only)'),
|
help=_('Volume transfer request to accept (ID only)'),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
|
||||||
'old_auth_key',
|
|
||||||
metavar="<key>",
|
|
||||||
nargs="?",
|
|
||||||
help=argparse.SUPPRESS,
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--auth-key',
|
'--auth-key',
|
||||||
metavar="<key>",
|
metavar="<key>",
|
||||||
@ -64,18 +57,7 @@ class AcceptTransferRequest(command.ShowOne):
|
|||||||
# move on and attempt with the user-supplied information
|
# move on and attempt with the user-supplied information
|
||||||
transfer_request_id = parsed_args.transfer_request
|
transfer_request_id = parsed_args.transfer_request
|
||||||
|
|
||||||
# Remain backward-compatible for the previous command layout
|
|
||||||
# TODO(dtroyer): Remove this back-compat in 4.0 or Oct 2017
|
|
||||||
if not parsed_args.auth_key:
|
if not parsed_args.auth_key:
|
||||||
if parsed_args.old_auth_key:
|
|
||||||
# Move the old one into the correct place
|
|
||||||
parsed_args.auth_key = parsed_args.old_auth_key
|
|
||||||
self.log.warning(_(
|
|
||||||
'Specifying the auth-key as a positional argument '
|
|
||||||
'has been deprecated. Please use the --auth-key '
|
|
||||||
'option in the future.'
|
|
||||||
))
|
|
||||||
else:
|
|
||||||
msg = _("argument --auth-key is required")
|
msg = _("argument --auth-key is required")
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
|
@ -1,351 +0,0 @@
|
|||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
# 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"""
|
|
||||||
|
|
||||||
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 _
|
|
||||||
|
|
||||||
|
|
||||||
deprecated = True
|
|
||||||
LOG_DEP = logging.getLogger('deprecated')
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class CreateSnapshot(command.ShowOne):
|
|
||||||
_description = _("Create new snapshot")
|
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(CreateSnapshot, self).get_parser(prog_name)
|
|
||||||
parser.add_argument(
|
|
||||||
"volume",
|
|
||||||
metavar="<volume>",
|
|
||||||
help=_("Volume to snapshot (name or ID)")
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--name",
|
|
||||||
metavar="<name>",
|
|
||||||
help=_("Name of the snapshot")
|
|
||||||
)
|
|
||||||
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):
|
|
||||||
LOG_DEP.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume snapshot create" instead.'))
|
|
||||||
volume_client = self.app.client_manager.volume
|
|
||||||
volume_id = utils.find_resource(
|
|
||||||
volume_client.volumes, parsed_args.volume).id
|
|
||||||
snapshot = volume_client.volume_snapshots.create(
|
|
||||||
volume_id,
|
|
||||||
force=parsed_args.force,
|
|
||||||
name=parsed_args.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 DeleteSnapshot(command.Command):
|
|
||||||
_description = _("Delete volume snapshot(s)")
|
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(DeleteSnapshot, 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):
|
|
||||||
LOG_DEP.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume snapshot delete" instead.'))
|
|
||||||
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 ListSnapshot(command.Lister):
|
|
||||||
_description = _("List snapshots")
|
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(ListSnapshot, 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='<snapshot>',
|
|
||||||
help=_('The last snapshot ID of the previous page'),
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'--limit',
|
|
||||||
type=int,
|
|
||||||
action=parseractions.NonNegativeAction,
|
|
||||||
metavar='<num-snapshots>',
|
|
||||||
help=_('Maximum number of snapshots to display'),
|
|
||||||
)
|
|
||||||
return parser
|
|
||||||
|
|
||||||
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):
|
|
||||||
"""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 SetSnapshot(command.Command):
|
|
||||||
_description = _("Set snapshot properties")
|
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(SetSnapshot, 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):
|
|
||||||
LOG_DEP.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume snapshot set" instead.'))
|
|
||||||
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 ShowSnapshot(command.ShowOne):
|
|
||||||
_description = _("Display snapshot details")
|
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(ShowSnapshot, 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):
|
|
||||||
LOG_DEP.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume snapshot show" instead.'))
|
|
||||||
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 UnsetSnapshot(command.Command):
|
|
||||||
_description = _("Unset snapshot properties")
|
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(UnsetSnapshot, 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):
|
|
||||||
LOG_DEP.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume snapshot unset" instead.'))
|
|
||||||
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,
|
|
||||||
)
|
|
@ -93,16 +93,6 @@ class CreateVolume(command.ShowOne):
|
|||||||
metavar="<description>",
|
metavar="<description>",
|
||||||
help=_("Volume description"),
|
help=_("Volume description"),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
|
||||||
'--user',
|
|
||||||
metavar='<user>',
|
|
||||||
help=argparse.SUPPRESS,
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'--project',
|
|
||||||
metavar='<project>',
|
|
||||||
help=argparse.SUPPRESS,
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--availability-zone",
|
"--availability-zone",
|
||||||
metavar="<availability-zone>",
|
metavar="<availability-zone>",
|
||||||
@ -127,12 +117,6 @@ class CreateVolume(command.ShowOne):
|
|||||||
help=_("Arbitrary scheduler hint key-value pairs to help boot "
|
help=_("Arbitrary scheduler hint key-value pairs to help boot "
|
||||||
"an instance (repeat option to set multiple hints)"),
|
"an instance (repeat option to set multiple hints)"),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
|
||||||
"--multi-attach",
|
|
||||||
action="store_true",
|
|
||||||
help=_("Allow volume to be attached more than once "
|
|
||||||
"(default to False)")
|
|
||||||
)
|
|
||||||
bootable_group = parser.add_mutually_exclusive_group()
|
bootable_group = parser.add_mutually_exclusive_group()
|
||||||
bootable_group.add_argument(
|
bootable_group.add_argument(
|
||||||
"--bootable",
|
"--bootable",
|
||||||
@ -196,26 +180,6 @@ class CreateVolume(command.ShowOne):
|
|||||||
# snapshot size.
|
# snapshot size.
|
||||||
size = max(size or 0, snapshot_obj.size)
|
size = max(size or 0, snapshot_obj.size)
|
||||||
|
|
||||||
# NOTE(abishop): Cinder's volumes.create() has 'project_id' and
|
|
||||||
# 'user_id' args, but they're not wired up to anything. The only way
|
|
||||||
# to specify an alternate project or user for the volume is to use
|
|
||||||
# the identity overrides (e.g. "--os-project-id").
|
|
||||||
#
|
|
||||||
# Now, if the project or user arg is specified then the command is
|
|
||||||
# rejected. Otherwise, Cinder would actually create a volume, but
|
|
||||||
# without the specified property.
|
|
||||||
if parsed_args.project:
|
|
||||||
raise exceptions.CommandError(
|
|
||||||
_("ERROR: --project is deprecated, please use"
|
|
||||||
" --os-project-name or --os-project-id instead."))
|
|
||||||
if parsed_args.user:
|
|
||||||
raise exceptions.CommandError(
|
|
||||||
_("ERROR: --user is deprecated, please use"
|
|
||||||
" --os-username instead."))
|
|
||||||
if parsed_args.multi_attach:
|
|
||||||
LOG.warning(_("'--multi-attach' option is no longer supported by "
|
|
||||||
"the block storage service."))
|
|
||||||
|
|
||||||
volume = volume_client.volumes.create(
|
volume = volume_client.volumes.create(
|
||||||
size=size,
|
size=size,
|
||||||
snapshot_id=snapshot,
|
snapshot_id=snapshot,
|
||||||
|
@ -94,23 +94,6 @@ class CreateVolumeBackup(command.ShowOne):
|
|||||||
return zip(*sorted(six.iteritems(backup._info)))
|
return zip(*sorted(six.iteritems(backup._info)))
|
||||||
|
|
||||||
|
|
||||||
class CreateBackup(CreateVolumeBackup):
|
|
||||||
_description = _("Create new backup")
|
|
||||||
|
|
||||||
# TODO(Huanxuan Ao): Remove this class and ``backup create`` command
|
|
||||||
# two cycles after Newton.
|
|
||||||
|
|
||||||
# This notifies cliff to not display the help for this command
|
|
||||||
deprecated = True
|
|
||||||
|
|
||||||
log = logging.getLogger('deprecated')
|
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
|
||||||
self.log.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume backup create" instead.'))
|
|
||||||
return super(CreateBackup, self).take_action(parsed_args)
|
|
||||||
|
|
||||||
|
|
||||||
class DeleteVolumeBackup(command.Command):
|
class DeleteVolumeBackup(command.Command):
|
||||||
_description = _("Delete volume backup(s)")
|
_description = _("Delete volume backup(s)")
|
||||||
|
|
||||||
@ -152,23 +135,6 @@ class DeleteVolumeBackup(command.Command):
|
|||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
|
|
||||||
class DeleteBackup(DeleteVolumeBackup):
|
|
||||||
_description = _("Delete backup(s)")
|
|
||||||
|
|
||||||
# TODO(Huanxuan Ao): Remove this class and ``backup delete`` command
|
|
||||||
# two cycles after Newton.
|
|
||||||
|
|
||||||
# This notifies cliff to not display the help for this command
|
|
||||||
deprecated = True
|
|
||||||
|
|
||||||
log = logging.getLogger('deprecated')
|
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
|
||||||
self.log.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume backup delete" instead.'))
|
|
||||||
return super(DeleteBackup, self).take_action(parsed_args)
|
|
||||||
|
|
||||||
|
|
||||||
class ListVolumeBackup(command.Lister):
|
class ListVolumeBackup(command.Lister):
|
||||||
_description = _("List volume backups")
|
_description = _("List volume backups")
|
||||||
|
|
||||||
@ -280,23 +246,6 @@ class ListVolumeBackup(command.Lister):
|
|||||||
) for s in data))
|
) for s in data))
|
||||||
|
|
||||||
|
|
||||||
class ListBackup(ListVolumeBackup):
|
|
||||||
_description = _("List backups")
|
|
||||||
|
|
||||||
# TODO(Huanxuan Ao): Remove this class and ``backup list`` command
|
|
||||||
# two cycles after Newton.
|
|
||||||
|
|
||||||
# This notifies cliff to not display the help for this command
|
|
||||||
deprecated = True
|
|
||||||
|
|
||||||
log = logging.getLogger('deprecated')
|
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
|
||||||
self.log.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume backup list" instead.'))
|
|
||||||
return super(ListBackup, self).take_action(parsed_args)
|
|
||||||
|
|
||||||
|
|
||||||
class RestoreVolumeBackup(command.ShowOne):
|
class RestoreVolumeBackup(command.ShowOne):
|
||||||
_description = _("Restore volume backup")
|
_description = _("Restore volume backup")
|
||||||
|
|
||||||
@ -324,23 +273,6 @@ class RestoreVolumeBackup(command.ShowOne):
|
|||||||
return zip(*sorted(six.iteritems(backup._info)))
|
return zip(*sorted(six.iteritems(backup._info)))
|
||||||
|
|
||||||
|
|
||||||
class RestoreBackup(RestoreVolumeBackup):
|
|
||||||
_description = _("Restore backup")
|
|
||||||
|
|
||||||
# TODO(Huanxuan Ao): Remove this class and ``backup restore`` command
|
|
||||||
# two cycles after Newton.
|
|
||||||
|
|
||||||
# This notifies cliff to not display the help for this command
|
|
||||||
deprecated = True
|
|
||||||
|
|
||||||
log = logging.getLogger('deprecated')
|
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
|
||||||
self.log.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume backup restore" instead.'))
|
|
||||||
return super(RestoreBackup, self).take_action(parsed_args)
|
|
||||||
|
|
||||||
|
|
||||||
class SetVolumeBackup(command.Command):
|
class SetVolumeBackup(command.Command):
|
||||||
_description = _("Set volume backup properties")
|
_description = _("Set volume backup properties")
|
||||||
|
|
||||||
@ -421,20 +353,3 @@ class ShowVolumeBackup(command.ShowOne):
|
|||||||
parsed_args.backup)
|
parsed_args.backup)
|
||||||
backup._info.pop("links", None)
|
backup._info.pop("links", None)
|
||||||
return zip(*sorted(six.iteritems(backup._info)))
|
return zip(*sorted(six.iteritems(backup._info)))
|
||||||
|
|
||||||
|
|
||||||
class ShowBackup(ShowVolumeBackup):
|
|
||||||
_description = _("Display backup details")
|
|
||||||
|
|
||||||
# TODO(Huanxuan Ao): Remove this class and ``backup show`` command
|
|
||||||
# two cycles after Newton.
|
|
||||||
|
|
||||||
# This notifies cliff to not display the help for this command
|
|
||||||
deprecated = True
|
|
||||||
|
|
||||||
log = logging.getLogger('deprecated')
|
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
|
||||||
self.log.warning(_('This command has been deprecated. '
|
|
||||||
'Please use "volume backup show" instead.'))
|
|
||||||
return super(ShowBackup, self).take_action(parsed_args)
|
|
@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
"""Volume v2 transfer action implementations"""
|
"""Volume v2 transfer action implementations"""
|
||||||
|
|
||||||
import argparse
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from osc_lib.command import command
|
from osc_lib.command import command
|
||||||
@ -38,15 +37,10 @@ class AcceptTransferRequest(command.ShowOne):
|
|||||||
metavar="<transfer-request-id>",
|
metavar="<transfer-request-id>",
|
||||||
help=_('Volume transfer request to accept (ID only)'),
|
help=_('Volume transfer request to accept (ID only)'),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
|
||||||
'old_auth_key',
|
|
||||||
metavar="<key>",
|
|
||||||
nargs="?",
|
|
||||||
help=argparse.SUPPRESS,
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--auth-key',
|
'--auth-key',
|
||||||
metavar="<key>",
|
metavar="<key>",
|
||||||
|
required=True,
|
||||||
help=_('Volume transfer request authentication key'),
|
help=_('Volume transfer request authentication key'),
|
||||||
)
|
)
|
||||||
return parser
|
return parser
|
||||||
@ -64,21 +58,6 @@ class AcceptTransferRequest(command.ShowOne):
|
|||||||
# move on and attempt with the user-supplied information
|
# move on and attempt with the user-supplied information
|
||||||
transfer_request_id = parsed_args.transfer_request
|
transfer_request_id = parsed_args.transfer_request
|
||||||
|
|
||||||
# Remain backward-compatible for the previous command layout
|
|
||||||
# TODO(dtroyer): Remove this back-compat in 4.0 or Oct 2017
|
|
||||||
if not parsed_args.auth_key:
|
|
||||||
if parsed_args.old_auth_key:
|
|
||||||
# Move the old one into the correct place
|
|
||||||
parsed_args.auth_key = parsed_args.old_auth_key
|
|
||||||
self.log.warning(_(
|
|
||||||
'Specifying the auth-key as a positional argument '
|
|
||||||
'has been deprecated. Please use the --auth-key '
|
|
||||||
'option in the future.'
|
|
||||||
))
|
|
||||||
else:
|
|
||||||
msg = _("argument --auth-key is required")
|
|
||||||
raise exceptions.CommandError(msg)
|
|
||||||
|
|
||||||
transfer_accept = volume_client.transfers.accept(
|
transfer_accept = volume_client.transfers.accept(
|
||||||
transfer_request_id,
|
transfer_request_id,
|
||||||
parsed_args.auth_key,
|
parsed_args.auth_key,
|
||||||
|
14
releasenotes/notes/osc4-volume-470422e5a453310e.yaml
Normal file
14
releasenotes/notes/osc4-volume-470422e5a453310e.yaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
upgrade:
|
||||||
|
- |
|
||||||
|
Remove deprecated ``backup`` commands.
|
||||||
|
Use ``volume backup`` commands instead.
|
||||||
|
- |
|
||||||
|
Remove deprecated ``snapshot`` commands.
|
||||||
|
Use ``volume snapshot`` commands instead.
|
||||||
|
- |
|
||||||
|
Remove deprecated ``volume create`` options ``--project``, ``--user``
|
||||||
|
and ``--multi-attach``.
|
||||||
|
- |
|
||||||
|
Change ``volume transfer request accept`` to use new required option
|
||||||
|
``--auth-key`` rather than a second positional argument.
|
48
setup.cfg
48
setup.cfg
@ -526,19 +526,6 @@ openstack.object_store.v1 =
|
|||||||
object_unset = openstackclient.object.v1.object:UnsetObject
|
object_unset = openstackclient.object.v1.object:UnsetObject
|
||||||
|
|
||||||
openstack.volume.v1 =
|
openstack.volume.v1 =
|
||||||
backup_create = openstackclient.volume.v1.backup:CreateBackup
|
|
||||||
backup_delete = openstackclient.volume.v1.backup:DeleteBackup
|
|
||||||
backup_list = openstackclient.volume.v1.backup:ListBackup
|
|
||||||
backup_restore = openstackclient.volume.v1.backup:RestoreBackup
|
|
||||||
backup_show = openstackclient.volume.v1.backup:ShowBackup
|
|
||||||
|
|
||||||
snapshot_create = openstackclient.volume.v1.snapshot:CreateSnapshot
|
|
||||||
snapshot_delete = openstackclient.volume.v1.snapshot:DeleteSnapshot
|
|
||||||
snapshot_list = openstackclient.volume.v1.snapshot:ListSnapshot
|
|
||||||
snapshot_set = openstackclient.volume.v1.snapshot:SetSnapshot
|
|
||||||
snapshot_show = openstackclient.volume.v1.snapshot:ShowSnapshot
|
|
||||||
snapshot_unset = openstackclient.volume.v1.snapshot:UnsetSnapshot
|
|
||||||
|
|
||||||
volume_create = openstackclient.volume.v1.volume:CreateVolume
|
volume_create = openstackclient.volume.v1.volume:CreateVolume
|
||||||
volume_delete = openstackclient.volume.v1.volume:DeleteVolume
|
volume_delete = openstackclient.volume.v1.volume:DeleteVolume
|
||||||
volume_list = openstackclient.volume.v1.volume:ListVolume
|
volume_list = openstackclient.volume.v1.volume:ListVolume
|
||||||
@ -547,11 +534,11 @@ openstack.volume.v1 =
|
|||||||
volume_show = openstackclient.volume.v1.volume:ShowVolume
|
volume_show = openstackclient.volume.v1.volume:ShowVolume
|
||||||
volume_unset = openstackclient.volume.v1.volume:UnsetVolume
|
volume_unset = openstackclient.volume.v1.volume:UnsetVolume
|
||||||
|
|
||||||
volume_backup_create = openstackclient.volume.v1.backup:CreateVolumeBackup
|
volume_backup_create = openstackclient.volume.v1.volume_backup:CreateVolumeBackup
|
||||||
volume_backup_delete = openstackclient.volume.v1.backup:DeleteVolumeBackup
|
volume_backup_delete = openstackclient.volume.v1.volume_backup:DeleteVolumeBackup
|
||||||
volume_backup_list = openstackclient.volume.v1.backup:ListVolumeBackup
|
volume_backup_list = openstackclient.volume.v1.volume_backup:ListVolumeBackup
|
||||||
volume_backup_restore = openstackclient.volume.v1.backup:RestoreVolumeBackup
|
volume_backup_restore = openstackclient.volume.v1.volume_backup:RestoreVolumeBackup
|
||||||
volume_backup_show = openstackclient.volume.v1.backup:ShowVolumeBackup
|
volume_backup_show = openstackclient.volume.v1.volume_backup:ShowVolumeBackup
|
||||||
|
|
||||||
volume_snapshot_create = openstackclient.volume.v1.volume_snapshot:CreateVolumeSnapshot
|
volume_snapshot_create = openstackclient.volume.v1.volume_snapshot:CreateVolumeSnapshot
|
||||||
volume_snapshot_delete = openstackclient.volume.v1.volume_snapshot:DeleteVolumeSnapshot
|
volume_snapshot_delete = openstackclient.volume.v1.volume_snapshot:DeleteVolumeSnapshot
|
||||||
@ -586,12 +573,6 @@ openstack.volume.v1 =
|
|||||||
volume_transfer_request_show = openstackclient.volume.v1.volume_transfer_request:ShowTransferRequest
|
volume_transfer_request_show = openstackclient.volume.v1.volume_transfer_request:ShowTransferRequest
|
||||||
|
|
||||||
openstack.volume.v2 =
|
openstack.volume.v2 =
|
||||||
backup_create = openstackclient.volume.v2.backup:CreateBackup
|
|
||||||
backup_delete = openstackclient.volume.v2.backup:DeleteBackup
|
|
||||||
backup_list = openstackclient.volume.v2.backup:ListBackup
|
|
||||||
backup_restore = openstackclient.volume.v2.backup:RestoreBackup
|
|
||||||
backup_show = openstackclient.volume.v2.backup:ShowBackup
|
|
||||||
|
|
||||||
consistency_group_add_volume = openstackclient.volume.v2.consistency_group:AddVolumeToConsistencyGroup
|
consistency_group_add_volume = openstackclient.volume.v2.consistency_group:AddVolumeToConsistencyGroup
|
||||||
consistency_group_create = openstackclient.volume.v2.consistency_group:CreateConsistencyGroup
|
consistency_group_create = openstackclient.volume.v2.consistency_group:CreateConsistencyGroup
|
||||||
consistency_group_delete = openstackclient.volume.v2.consistency_group:DeleteConsistencyGroup
|
consistency_group_delete = openstackclient.volume.v2.consistency_group:DeleteConsistencyGroup
|
||||||
@ -605,13 +586,6 @@ openstack.volume.v2 =
|
|||||||
consistency_group_snapshot_list = openstackclient.volume.v2.consistency_group_snapshot:ListConsistencyGroupSnapshot
|
consistency_group_snapshot_list = openstackclient.volume.v2.consistency_group_snapshot:ListConsistencyGroupSnapshot
|
||||||
consistency_group_snapshot_show = openstackclient.volume.v2.consistency_group_snapshot:ShowConsistencyGroupSnapshot
|
consistency_group_snapshot_show = openstackclient.volume.v2.consistency_group_snapshot:ShowConsistencyGroupSnapshot
|
||||||
|
|
||||||
snapshot_create = openstackclient.volume.v2.snapshot:CreateSnapshot
|
|
||||||
snapshot_delete = openstackclient.volume.v2.snapshot:DeleteSnapshot
|
|
||||||
snapshot_list = openstackclient.volume.v2.snapshot:ListSnapshot
|
|
||||||
snapshot_set = openstackclient.volume.v2.snapshot:SetSnapshot
|
|
||||||
snapshot_show = openstackclient.volume.v2.snapshot:ShowSnapshot
|
|
||||||
snapshot_unset = openstackclient.volume.v2.snapshot:UnsetSnapshot
|
|
||||||
|
|
||||||
volume_create = openstackclient.volume.v2.volume:CreateVolume
|
volume_create = openstackclient.volume.v2.volume:CreateVolume
|
||||||
volume_delete = openstackclient.volume.v2.volume:DeleteVolume
|
volume_delete = openstackclient.volume.v2.volume:DeleteVolume
|
||||||
volume_list = openstackclient.volume.v2.volume:ListVolume
|
volume_list = openstackclient.volume.v2.volume:ListVolume
|
||||||
@ -620,12 +594,12 @@ openstack.volume.v2 =
|
|||||||
volume_show = openstackclient.volume.v2.volume:ShowVolume
|
volume_show = openstackclient.volume.v2.volume:ShowVolume
|
||||||
volume_unset = openstackclient.volume.v2.volume:UnsetVolume
|
volume_unset = openstackclient.volume.v2.volume:UnsetVolume
|
||||||
|
|
||||||
volume_backup_create = openstackclient.volume.v2.backup:CreateVolumeBackup
|
volume_backup_create = openstackclient.volume.v2.volume_backup:CreateVolumeBackup
|
||||||
volume_backup_delete = openstackclient.volume.v2.backup:DeleteVolumeBackup
|
volume_backup_delete = openstackclient.volume.v2.volume_backup:DeleteVolumeBackup
|
||||||
volume_backup_list = openstackclient.volume.v2.backup:ListVolumeBackup
|
volume_backup_list = openstackclient.volume.v2.volume_backup:ListVolumeBackup
|
||||||
volume_backup_restore = openstackclient.volume.v2.backup:RestoreVolumeBackup
|
volume_backup_restore = openstackclient.volume.v2.volume_backup:RestoreVolumeBackup
|
||||||
volume_backup_set = openstackclient.volume.v2.backup:SetVolumeBackup
|
volume_backup_set = openstackclient.volume.v2.volume_backup:SetVolumeBackup
|
||||||
volume_backup_show = openstackclient.volume.v2.backup:ShowVolumeBackup
|
volume_backup_show = openstackclient.volume.v2.volume_backup:ShowVolumeBackup
|
||||||
|
|
||||||
volume_backup_record_export = openstackclient.volume.v2.backup_record:ExportBackupRecord
|
volume_backup_record_export = openstackclient.volume.v2.backup_record:ExportBackupRecord
|
||||||
volume_backup_record_import = openstackclient.volume.v2.backup_record:ImportBackupRecord
|
volume_backup_record_import = openstackclient.volume.v2.backup_record:ImportBackupRecord
|
||||||
|
Loading…
Reference in New Issue
Block a user