Remove deprecated volume commands and args
The following were deprecated over two years ago and can now be removed: * Remove ``backup`` commands in favor of ``volume backup`` * Remove ``snapshot`` commands in favor of ``volume snapshot`` * Remove ``volume create`` options ``--project``, ``--user`` and ``--multi-attach`` * Use of an auth-key positional argument in volume transfers * ``volume transfer request`` no longer accepts 'auth_key' as a positional arg, ``--auth-key`` is now required Internal (non-user-visible) * Rename backup.py to volume_backup.py for Volume v1 and v2, update tests These are backwards incompatible changes and will require a major version bump after they are merged. Change-Id: I94aa7a9824e44f9585ffb45e5e7637b9588539b4 Signed-off-by: Sean McGinnis <sean.mcginnis@gmail.com> Signed-off-by: Dean Troyer <dtroyer@gmail.com>
This commit is contained in:
parent
5a0fc68a87
commit
e76e10c0ba
@ -73,12 +73,28 @@ Release 4.0
|
||||
* Removed in: 4.0
|
||||
* Commit: https://review.opendev.org/613644
|
||||
|
||||
.. 1. Change ``volume transfer request accept`` to use new option ``--auth-key``
|
||||
.. rather than a second positional argument.
|
||||
10. Remove ``backup`` commands.
|
||||
Use ``volume backup`` commands instead.
|
||||
|
||||
.. * As of: 4.0
|
||||
.. * Remove in: <5.0>
|
||||
.. * Commit: <tbd>
|
||||
* Removed in: 4.0
|
||||
* Commit: https://review.opendev.org/612751
|
||||
|
||||
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
|
||||
------------
|
||||
|
@ -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 ' +
|
||||
vol_id
|
||||
))
|
||||
self.wait_for_status("backup", backup['id'], "available")
|
||||
self.wait_for_status("volume backup", backup['id'], "available")
|
||||
|
||||
# restore the backup
|
||||
backup_restored = json.loads(self.openstack(
|
||||
'volume backup restore -f json %s %s'
|
||||
% (backup['id'], vol_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'],
|
||||
"available")
|
||||
self.addCleanup(self.openstack, 'volume delete %s' % vol_id)
|
@ -10,7 +10,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# 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
|
||||
|
||||
|
@ -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.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):
|
||||
arglist = [
|
||||
self.volume_transfer.id,
|
||||
|
@ -19,7 +19,7 @@ from osc_lib import exceptions
|
||||
from osc_lib import utils
|
||||
|
||||
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):
|
||||
@ -74,7 +74,7 @@ class TestBackupCreate(TestBackup):
|
||||
self.backups_mock.create.return_value = self.new_backup
|
||||
|
||||
# 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):
|
||||
arglist = [
|
||||
@ -139,7 +139,7 @@ class TestBackupDelete(TestBackup):
|
||||
self.backups_mock.delete.return_value = None
|
||||
|
||||
# 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):
|
||||
arglist = [
|
||||
@ -251,7 +251,7 @@ class TestBackupList(TestBackup):
|
||||
self.backups_mock.list.return_value = self.backups
|
||||
self.volumes_mock.get.return_value = self.volume
|
||||
# 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):
|
||||
arglist = []
|
||||
@ -325,7 +325,7 @@ class TestBackupRestore(TestBackup):
|
||||
self.volumes_mock.get.return_value = self.volume
|
||||
self.restores_mock.restore.return_value = None
|
||||
# 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):
|
||||
arglist = [
|
||||
@ -376,7 +376,7 @@ class TestBackupShow(TestBackup):
|
||||
)
|
||||
self.backups_mock.get.return_value = self.backup
|
||||
# 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):
|
||||
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 utils
|
||||
|
||||
from openstackclient.tests.unit import utils as test_utils
|
||||
from openstackclient.tests.unit.volume.v2 import fakes as transfer_fakes
|
||||
from openstackclient.volume.v2 import volume_transfer_request
|
||||
|
||||
@ -85,26 +86,6 @@ class TestTransferAccept(TestTransfer):
|
||||
self.assertEqual(self.columns, columns)
|
||||
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):
|
||||
arglist = [
|
||||
self.volume_transfer.id,
|
||||
@ -112,12 +93,13 @@ class TestTransferAccept(TestTransfer):
|
||||
verifylist = [
|
||||
('transfer_request', self.volume_transfer.id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args,
|
||||
test_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist,
|
||||
)
|
||||
|
||||
|
||||
|
@ -183,40 +183,6 @@ class TestVolumeCreate(TestVolume):
|
||||
self.assertEqual(self.columns, columns)
|
||||
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):
|
||||
arglist = [
|
||||
'--property', 'Alpha=a',
|
||||
|
@ -19,7 +19,7 @@ from osc_lib import exceptions
|
||||
from osc_lib import utils
|
||||
|
||||
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):
|
||||
@ -77,7 +77,7 @@ class TestBackupCreate(TestBackup):
|
||||
self.backups_mock.create.return_value = self.new_backup
|
||||
|
||||
# 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):
|
||||
arglist = [
|
||||
@ -154,7 +154,7 @@ class TestBackupDelete(TestBackup):
|
||||
self.backups_mock.delete.return_value = None
|
||||
|
||||
# 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):
|
||||
arglist = [
|
||||
@ -283,7 +283,7 @@ class TestBackupList(TestBackup):
|
||||
self.volumes_mock.get.return_value = self.volume
|
||||
self.backups_mock.get.return_value = self.backups[0]
|
||||
# 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):
|
||||
arglist = []
|
||||
@ -371,7 +371,7 @@ class TestBackupRestore(TestBackup):
|
||||
volume_fakes.FakeVolume.create_one_volume(
|
||||
{'id': self.volume['id']}))
|
||||
# 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):
|
||||
arglist = [
|
||||
@ -400,7 +400,7 @@ class TestBackupSet(TestBackup):
|
||||
self.backups_mock.get.return_value = self.backup
|
||||
|
||||
# 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):
|
||||
arglist = [
|
||||
@ -517,7 +517,7 @@ class TestBackupShow(TestBackup):
|
||||
|
||||
self.backups_mock.get.return_value = self.backup
|
||||
# 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):
|
||||
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)))
|
||||
|
||||
|
||||
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):
|
||||
_description = _("Delete volume backup(s)")
|
||||
|
||||
@ -124,23 +107,6 @@ class DeleteVolumeBackup(command.Command):
|
||||
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):
|
||||
_description = _("List volume backups")
|
||||
|
||||
@ -234,23 +200,6 @@ class ListVolumeBackup(command.Lister):
|
||||
) 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):
|
||||
_description = _("Restore volume backup")
|
||||
|
||||
@ -278,23 +227,6 @@ class RestoreVolumeBackup(command.Command):
|
||||
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):
|
||||
_description = _("Display volume backup details")
|
||||
|
||||
@ -313,20 +245,3 @@ class ShowVolumeBackup(command.ShowOne):
|
||||
parsed_args.backup)
|
||||
backup._info.pop('links')
|
||||
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"""
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
|
||||
from osc_lib.command import command
|
||||
@ -38,12 +37,6 @@ class AcceptTransferRequest(command.ShowOne):
|
||||
metavar="<transfer-request-id>",
|
||||
help=_('Volume transfer request to accept (ID only)'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'old_auth_key',
|
||||
metavar="<key>",
|
||||
nargs="?",
|
||||
help=argparse.SUPPRESS,
|
||||
)
|
||||
parser.add_argument(
|
||||
'--auth-key',
|
||||
metavar="<key>",
|
||||
@ -64,18 +57,7 @@ class AcceptTransferRequest(command.ShowOne):
|
||||
# move on and attempt with the user-supplied information
|
||||
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)
|
||||
|
||||
|
@ -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>",
|
||||
help=_("Volume description"),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--user',
|
||||
metavar='<user>',
|
||||
help=argparse.SUPPRESS,
|
||||
)
|
||||
parser.add_argument(
|
||||
'--project',
|
||||
metavar='<project>',
|
||||
help=argparse.SUPPRESS,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--availability-zone",
|
||||
metavar="<availability-zone>",
|
||||
@ -127,12 +117,6 @@ class CreateVolume(command.ShowOne):
|
||||
help=_("Arbitrary scheduler hint key-value pairs to help boot "
|
||||
"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.add_argument(
|
||||
"--bootable",
|
||||
@ -196,26 +180,6 @@ class CreateVolume(command.ShowOne):
|
||||
# snapshot 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(
|
||||
size=size,
|
||||
snapshot_id=snapshot,
|
||||
|
@ -94,23 +94,6 @@ class CreateVolumeBackup(command.ShowOne):
|
||||
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):
|
||||
_description = _("Delete volume backup(s)")
|
||||
|
||||
@ -152,23 +135,6 @@ class DeleteVolumeBackup(command.Command):
|
||||
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):
|
||||
_description = _("List volume backups")
|
||||
|
||||
@ -280,23 +246,6 @@ class ListVolumeBackup(command.Lister):
|
||||
) 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):
|
||||
_description = _("Restore volume backup")
|
||||
|
||||
@ -324,23 +273,6 @@ class RestoreVolumeBackup(command.ShowOne):
|
||||
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):
|
||||
_description = _("Set volume backup properties")
|
||||
|
||||
@ -421,20 +353,3 @@ class ShowVolumeBackup(command.ShowOne):
|
||||
parsed_args.backup)
|
||||
backup._info.pop("links", None)
|
||||
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"""
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
|
||||
from osc_lib.command import command
|
||||
@ -38,15 +37,10 @@ class AcceptTransferRequest(command.ShowOne):
|
||||
metavar="<transfer-request-id>",
|
||||
help=_('Volume transfer request to accept (ID only)'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'old_auth_key',
|
||||
metavar="<key>",
|
||||
nargs="?",
|
||||
help=argparse.SUPPRESS,
|
||||
)
|
||||
parser.add_argument(
|
||||
'--auth-key',
|
||||
metavar="<key>",
|
||||
required=True,
|
||||
help=_('Volume transfer request authentication key'),
|
||||
)
|
||||
return parser
|
||||
@ -64,21 +58,6 @@ class AcceptTransferRequest(command.ShowOne):
|
||||
# move on and attempt with the user-supplied information
|
||||
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_request_id,
|
||||
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
|
||||
|
||||
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_delete = openstackclient.volume.v1.volume:DeleteVolume
|
||||
volume_list = openstackclient.volume.v1.volume:ListVolume
|
||||
@ -547,11 +534,11 @@ openstack.volume.v1 =
|
||||
volume_show = openstackclient.volume.v1.volume:ShowVolume
|
||||
volume_unset = openstackclient.volume.v1.volume:UnsetVolume
|
||||
|
||||
volume_backup_create = openstackclient.volume.v1.backup:CreateVolumeBackup
|
||||
volume_backup_delete = openstackclient.volume.v1.backup:DeleteVolumeBackup
|
||||
volume_backup_list = openstackclient.volume.v1.backup:ListVolumeBackup
|
||||
volume_backup_restore = openstackclient.volume.v1.backup:RestoreVolumeBackup
|
||||
volume_backup_show = openstackclient.volume.v1.backup:ShowVolumeBackup
|
||||
volume_backup_create = openstackclient.volume.v1.volume_backup:CreateVolumeBackup
|
||||
volume_backup_delete = openstackclient.volume.v1.volume_backup:DeleteVolumeBackup
|
||||
volume_backup_list = openstackclient.volume.v1.volume_backup:ListVolumeBackup
|
||||
volume_backup_restore = openstackclient.volume.v1.volume_backup:RestoreVolumeBackup
|
||||
volume_backup_show = openstackclient.volume.v1.volume_backup:ShowVolumeBackup
|
||||
|
||||
volume_snapshot_create = openstackclient.volume.v1.volume_snapshot:CreateVolumeSnapshot
|
||||
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
|
||||
|
||||
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_create = openstackclient.volume.v2.consistency_group:CreateConsistencyGroup
|
||||
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_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_delete = openstackclient.volume.v2.volume:DeleteVolume
|
||||
volume_list = openstackclient.volume.v2.volume:ListVolume
|
||||
@ -620,12 +594,12 @@ openstack.volume.v2 =
|
||||
volume_show = openstackclient.volume.v2.volume:ShowVolume
|
||||
volume_unset = openstackclient.volume.v2.volume:UnsetVolume
|
||||
|
||||
volume_backup_create = openstackclient.volume.v2.backup:CreateVolumeBackup
|
||||
volume_backup_delete = openstackclient.volume.v2.backup:DeleteVolumeBackup
|
||||
volume_backup_list = openstackclient.volume.v2.backup:ListVolumeBackup
|
||||
volume_backup_restore = openstackclient.volume.v2.backup:RestoreVolumeBackup
|
||||
volume_backup_set = openstackclient.volume.v2.backup:SetVolumeBackup
|
||||
volume_backup_show = openstackclient.volume.v2.backup:ShowVolumeBackup
|
||||
volume_backup_create = openstackclient.volume.v2.volume_backup:CreateVolumeBackup
|
||||
volume_backup_delete = openstackclient.volume.v2.volume_backup:DeleteVolumeBackup
|
||||
volume_backup_list = openstackclient.volume.v2.volume_backup:ListVolumeBackup
|
||||
volume_backup_restore = openstackclient.volume.v2.volume_backup:RestoreVolumeBackup
|
||||
volume_backup_set = openstackclient.volume.v2.volume_backup:SetVolumeBackup
|
||||
volume_backup_show = openstackclient.volume.v2.volume_backup:ShowVolumeBackup
|
||||
|
||||
volume_backup_record_export = openstackclient.volume.v2.backup_record:ExportBackupRecord
|
||||
volume_backup_record_import = openstackclient.volume.v2.backup_record:ImportBackupRecord
|
||||
|
Loading…
Reference in New Issue
Block a user