volume: Add v3-specific volume module
This makes testing easier. Change-Id: I6b31026ae3c9dc66d828744534b35bb0a0d2ffbe Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
parent
ca91c826e3
commit
65cce3943a
@ -25,7 +25,6 @@ from openstack.block_storage.v3 import capabilities as _capabilities
|
|||||||
from openstack.block_storage.v3 import stats as _stats
|
from openstack.block_storage.v3 import stats as _stats
|
||||||
from openstack.block_storage.v3 import volume as _volume
|
from openstack.block_storage.v3 import volume as _volume
|
||||||
from openstack.image.v2 import _proxy as image_v2_proxy
|
from openstack.image.v2 import _proxy as image_v2_proxy
|
||||||
from osc_lib.cli import format_columns
|
|
||||||
|
|
||||||
from openstackclient.tests.unit import fakes
|
from openstackclient.tests.unit import fakes
|
||||||
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
|
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
|
||||||
@ -472,43 +471,6 @@ def get_volumes(volumes=None, count=2):
|
|||||||
return mock.Mock(side_effect=volumes)
|
return mock.Mock(side_effect=volumes)
|
||||||
|
|
||||||
|
|
||||||
def get_volume_columns(volume=None):
|
|
||||||
"""Get the volume columns from a faked volume object.
|
|
||||||
|
|
||||||
:param volume:
|
|
||||||
A FakeResource objects faking volume
|
|
||||||
:return
|
|
||||||
A tuple which may include the following keys:
|
|
||||||
('id', 'name', 'description', 'status', 'size', 'volume_type',
|
|
||||||
'metadata', 'snapshot', 'availability_zone', 'attachments')
|
|
||||||
"""
|
|
||||||
if volume is not None:
|
|
||||||
return tuple(k for k in sorted(volume.keys()))
|
|
||||||
return tuple([])
|
|
||||||
|
|
||||||
|
|
||||||
def get_volume_data(volume=None):
|
|
||||||
"""Get the volume data from a faked volume object.
|
|
||||||
|
|
||||||
:param volume:
|
|
||||||
A FakeResource objects faking volume
|
|
||||||
:return
|
|
||||||
A tuple which may include the following values:
|
|
||||||
('ce26708d', 'fake_volume', 'fake description', 'available',
|
|
||||||
20, 'fake_lvmdriver-1', "Alpha='a', Beta='b', Gamma='g'",
|
|
||||||
1, 'nova', [{'device': '/dev/ice', 'server_id': '1233'}])
|
|
||||||
"""
|
|
||||||
data_list = []
|
|
||||||
if volume is not None:
|
|
||||||
for x in sorted(volume.keys()):
|
|
||||||
if x == 'tags':
|
|
||||||
# The 'tags' should be format_list
|
|
||||||
data_list.append(format_columns.ListColumn(volume.info.get(x)))
|
|
||||||
else:
|
|
||||||
data_list.append(volume.info.get(x))
|
|
||||||
return tuple(data_list)
|
|
||||||
|
|
||||||
|
|
||||||
def create_one_backup(attrs=None):
|
def create_one_backup(attrs=None):
|
||||||
"""Create a fake backup.
|
"""Create a fake backup.
|
||||||
|
|
||||||
|
@ -12,9 +12,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
from unittest.mock import call
|
|
||||||
|
|
||||||
from cinderclient import api_versions
|
|
||||||
from osc_lib.cli import format_columns
|
from osc_lib.cli import format_columns
|
||||||
from osc_lib import exceptions
|
from osc_lib import exceptions
|
||||||
from osc_lib import utils
|
from osc_lib import utils
|
||||||
@ -42,9 +40,6 @@ class TestVolume(volume_fakes.TestVolume):
|
|||||||
self.snapshots_mock = self.volume_client.volume_snapshots
|
self.snapshots_mock = self.volume_client.volume_snapshots
|
||||||
self.snapshots_mock.reset_mock()
|
self.snapshots_mock.reset_mock()
|
||||||
|
|
||||||
self.backups_mock = self.volume_client.backups
|
|
||||||
self.backups_mock.reset_mock()
|
|
||||||
|
|
||||||
self.types_mock = self.volume_client.volume_types
|
self.types_mock = self.volume_client.volume_types
|
||||||
self.types_mock.reset_mock()
|
self.types_mock.reset_mock()
|
||||||
|
|
||||||
@ -126,7 +121,6 @@ class TestVolumeCreate(TestVolume):
|
|||||||
source_volid=None,
|
source_volid=None,
|
||||||
consistencygroup_id=None,
|
consistencygroup_id=None,
|
||||||
scheduler_hints=None,
|
scheduler_hints=None,
|
||||||
backup_id=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
@ -178,7 +172,6 @@ class TestVolumeCreate(TestVolume):
|
|||||||
source_volid=None,
|
source_volid=None,
|
||||||
consistencygroup_id=consistency_group.id,
|
consistencygroup_id=consistency_group.id,
|
||||||
scheduler_hints={'k': 'v'},
|
scheduler_hints={'k': 'v'},
|
||||||
backup_id=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
@ -218,7 +211,6 @@ class TestVolumeCreate(TestVolume):
|
|||||||
source_volid=None,
|
source_volid=None,
|
||||||
consistencygroup_id=None,
|
consistencygroup_id=None,
|
||||||
scheduler_hints=None,
|
scheduler_hints=None,
|
||||||
backup_id=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
@ -259,7 +251,6 @@ class TestVolumeCreate(TestVolume):
|
|||||||
source_volid=None,
|
source_volid=None,
|
||||||
consistencygroup_id=None,
|
consistencygroup_id=None,
|
||||||
scheduler_hints=None,
|
scheduler_hints=None,
|
||||||
backup_id=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
@ -300,7 +291,6 @@ class TestVolumeCreate(TestVolume):
|
|||||||
source_volid=None,
|
source_volid=None,
|
||||||
consistencygroup_id=None,
|
consistencygroup_id=None,
|
||||||
scheduler_hints=None,
|
scheduler_hints=None,
|
||||||
backup_id=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
@ -339,74 +329,11 @@ class TestVolumeCreate(TestVolume):
|
|||||||
source_volid=None,
|
source_volid=None,
|
||||||
consistencygroup_id=None,
|
consistencygroup_id=None,
|
||||||
scheduler_hints=None,
|
scheduler_hints=None,
|
||||||
backup_id=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertCountEqual(self.datalist, data)
|
self.assertCountEqual(self.datalist, data)
|
||||||
|
|
||||||
def test_volume_create_with_backup(self):
|
|
||||||
backup = volume_fakes.create_one_backup()
|
|
||||||
self.new_volume.backup_id = backup.id
|
|
||||||
arglist = [
|
|
||||||
'--backup',
|
|
||||||
self.new_volume.backup_id,
|
|
||||||
self.new_volume.name,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('backup', self.new_volume.backup_id),
|
|
||||||
('name', self.new_volume.name),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
self.backups_mock.get.return_value = backup
|
|
||||||
|
|
||||||
self.volume_client.api_version = api_versions.APIVersion('3.47')
|
|
||||||
|
|
||||||
# In base command class ShowOne in cliff, abstract method take_action()
|
|
||||||
# returns a two-part tuple with a tuple of column names and a tuple of
|
|
||||||
# data to be shown.
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
|
||||||
|
|
||||||
self.volumes_mock.create.assert_called_once_with(
|
|
||||||
size=backup.size,
|
|
||||||
snapshot_id=None,
|
|
||||||
name=self.new_volume.name,
|
|
||||||
description=None,
|
|
||||||
volume_type=None,
|
|
||||||
availability_zone=None,
|
|
||||||
metadata=None,
|
|
||||||
imageRef=None,
|
|
||||||
source_volid=None,
|
|
||||||
consistencygroup_id=None,
|
|
||||||
scheduler_hints=None,
|
|
||||||
backup_id=backup.id,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
|
||||||
self.assertCountEqual(self.datalist, data)
|
|
||||||
|
|
||||||
def test_volume_create_with_backup_pre_347(self):
|
|
||||||
backup = volume_fakes.create_one_backup()
|
|
||||||
self.new_volume.backup_id = backup.id
|
|
||||||
arglist = [
|
|
||||||
'--backup',
|
|
||||||
self.new_volume.backup_id,
|
|
||||||
self.new_volume.name,
|
|
||||||
]
|
|
||||||
verifylist = [
|
|
||||||
('backup', self.new_volume.backup_id),
|
|
||||||
('name', self.new_volume.name),
|
|
||||||
]
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
|
||||||
|
|
||||||
self.backups_mock.get.return_value = backup
|
|
||||||
|
|
||||||
exc = self.assertRaises(
|
|
||||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
|
||||||
)
|
|
||||||
self.assertIn("--os-volume-api-version 3.47 or greater", str(exc))
|
|
||||||
|
|
||||||
def test_volume_create_with_source_volume(self):
|
def test_volume_create_with_source_volume(self):
|
||||||
source_vol = "source_vol"
|
source_vol = "source_vol"
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -439,7 +366,6 @@ class TestVolumeCreate(TestVolume):
|
|||||||
source_volid=self.new_volume.id,
|
source_volid=self.new_volume.id,
|
||||||
consistencygroup_id=None,
|
consistencygroup_id=None,
|
||||||
scheduler_hints=None,
|
scheduler_hints=None,
|
||||||
backup_id=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
@ -479,7 +405,6 @@ class TestVolumeCreate(TestVolume):
|
|||||||
source_volid=None,
|
source_volid=None,
|
||||||
consistencygroup_id=None,
|
consistencygroup_id=None,
|
||||||
scheduler_hints=None,
|
scheduler_hints=None,
|
||||||
backup_id=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
@ -525,7 +450,6 @@ class TestVolumeCreate(TestVolume):
|
|||||||
source_volid=None,
|
source_volid=None,
|
||||||
consistencygroup_id=None,
|
consistencygroup_id=None,
|
||||||
scheduler_hints=None,
|
scheduler_hints=None,
|
||||||
backup_id=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
@ -580,7 +504,6 @@ class TestVolumeCreate(TestVolume):
|
|||||||
source_volid=None,
|
source_volid=None,
|
||||||
consistencygroup_id=None,
|
consistencygroup_id=None,
|
||||||
scheduler_hints=None,
|
scheduler_hints=None,
|
||||||
backup_id=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(2, mock_error.call_count)
|
self.assertEqual(2, mock_error.call_count)
|
||||||
@ -632,7 +555,6 @@ class TestVolumeCreate(TestVolume):
|
|||||||
source_volid=None,
|
source_volid=None,
|
||||||
consistencygroup_id=None,
|
consistencygroup_id=None,
|
||||||
scheduler_hints=None,
|
scheduler_hints=None,
|
||||||
backup_id=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(2, mock_error.call_count)
|
self.assertEqual(2, mock_error.call_count)
|
||||||
@ -742,7 +664,6 @@ class TestVolumeCreate(TestVolume):
|
|||||||
'local_to_instance': 'v6',
|
'local_to_instance': 'v6',
|
||||||
'different_host': ['v5', 'v7'],
|
'different_host': ['v5', 'v7'],
|
||||||
},
|
},
|
||||||
backup_id=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
@ -789,7 +710,7 @@ class TestVolumeDelete(TestVolume):
|
|||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
calls = [call(v.id, cascade=False) for v in volumes]
|
calls = [mock.call(v.id, cascade=False) for v in volumes]
|
||||||
self.volumes_mock.delete.assert_has_calls(calls)
|
self.volumes_mock.delete.assert_has_calls(calls)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
@ -1721,11 +1642,23 @@ class TestVolumeShow(TestVolume):
|
|||||||
self.volumes_mock.get.assert_called_with(self._volume.id)
|
self.volumes_mock.get.assert_called_with(self._volume.id)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
volume_fakes.get_volume_columns(self._volume),
|
tuple(sorted(self._volume.keys())),
|
||||||
columns,
|
columns,
|
||||||
)
|
)
|
||||||
self.assertCountEqual(
|
self.assertTupleEqual(
|
||||||
volume_fakes.get_volume_data(self._volume),
|
(
|
||||||
|
self._volume.attachments,
|
||||||
|
self._volume.availability_zone,
|
||||||
|
self._volume.bootable,
|
||||||
|
self._volume.description,
|
||||||
|
self._volume.id,
|
||||||
|
self._volume.name,
|
||||||
|
format_columns.DictColumn(self._volume.metadata),
|
||||||
|
self._volume.size,
|
||||||
|
self._volume.snapshot_id,
|
||||||
|
self._volume.status,
|
||||||
|
self._volume.volume_type,
|
||||||
|
),
|
||||||
data,
|
data,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import copy
|
||||||
import random
|
import random
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
import uuid
|
import uuid
|
||||||
@ -21,6 +22,7 @@ from openstack.block_storage.v3 import backup as _backup
|
|||||||
from openstack.block_storage.v3 import extension as _extension
|
from openstack.block_storage.v3 import extension as _extension
|
||||||
from openstack.block_storage.v3 import resource_filter as _filters
|
from openstack.block_storage.v3 import resource_filter as _filters
|
||||||
from openstack.block_storage.v3 import volume as _volume
|
from openstack.block_storage.v3 import volume as _volume
|
||||||
|
from openstack.image.v2 import _proxy as _image_proxy
|
||||||
|
|
||||||
from openstackclient.tests.unit import fakes
|
from openstackclient.tests.unit import fakes
|
||||||
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
|
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
|
||||||
@ -34,12 +36,14 @@ class FakeVolumeClient:
|
|||||||
self.management_url = kwargs['endpoint']
|
self.management_url = kwargs['endpoint']
|
||||||
self.api_version = api_versions.APIVersion('3.0')
|
self.api_version = api_versions.APIVersion('3.0')
|
||||||
|
|
||||||
|
self.attachments = mock.Mock()
|
||||||
|
self.attachments.resource_class = fakes.FakeResource(None, {})
|
||||||
self.availability_zones = mock.Mock()
|
self.availability_zones = mock.Mock()
|
||||||
self.availability_zones.resource_class = fakes.FakeResource(None, {})
|
self.availability_zones.resource_class = fakes.FakeResource(None, {})
|
||||||
self.backups = mock.Mock()
|
self.backups = mock.Mock()
|
||||||
self.backups.resource_class = fakes.FakeResource(None, {})
|
self.backups.resource_class = fakes.FakeResource(None, {})
|
||||||
self.attachments = mock.Mock()
|
self.consistencygroups = mock.Mock()
|
||||||
self.attachments.resource_class = fakes.FakeResource(None, {})
|
self.consistencygroups.resource_class = fakes.FakeResource(None, {})
|
||||||
self.clusters = mock.Mock()
|
self.clusters = mock.Mock()
|
||||||
self.clusters.resource_class = fakes.FakeResource(None, {})
|
self.clusters.resource_class = fakes.FakeResource(None, {})
|
||||||
self.groups = mock.Mock()
|
self.groups = mock.Mock()
|
||||||
@ -106,10 +110,14 @@ class TestVolume(
|
|||||||
)
|
)
|
||||||
self.compute_client = self.app.client_manager.compute
|
self.compute_client = self.app.client_manager.compute
|
||||||
|
|
||||||
|
# avoid circular imports by defining this manually rather than using
|
||||||
|
# openstackclient.tests.unit.image.v2.fakes.FakeClientMixin
|
||||||
|
self.app.client_manager.image = mock.Mock(spec=_image_proxy.Proxy)
|
||||||
|
self.image_client = self.app.client_manager.image
|
||||||
|
|
||||||
|
|
||||||
# TODO(stephenfin): Check if the responses are actually the same
|
# TODO(stephenfin): Check if the responses are actually the same
|
||||||
create_one_snapshot = volume_v2_fakes.create_one_snapshot
|
create_one_snapshot = volume_v2_fakes.create_one_snapshot
|
||||||
create_one_volume = volume_v2_fakes.create_one_volume
|
|
||||||
create_one_volume_type = volume_v2_fakes.create_one_volume_type
|
create_one_volume_type = volume_v2_fakes.create_one_volume_type
|
||||||
|
|
||||||
|
|
||||||
@ -153,6 +161,54 @@ def create_availability_zones(attrs=None, count=2):
|
|||||||
return availability_zones
|
return availability_zones
|
||||||
|
|
||||||
|
|
||||||
|
def create_one_consistency_group(attrs=None):
|
||||||
|
"""Create a fake consistency group.
|
||||||
|
|
||||||
|
:param dict attrs:
|
||||||
|
A dictionary with all attributes
|
||||||
|
:return:
|
||||||
|
A FakeResource object with id, name, description, etc.
|
||||||
|
"""
|
||||||
|
attrs = attrs or {}
|
||||||
|
|
||||||
|
# Set default attributes.
|
||||||
|
consistency_group_info = {
|
||||||
|
"id": 'backup-id-' + uuid.uuid4().hex,
|
||||||
|
"name": 'backup-name-' + uuid.uuid4().hex,
|
||||||
|
"description": 'description-' + uuid.uuid4().hex,
|
||||||
|
"status": "error",
|
||||||
|
"availability_zone": 'zone' + uuid.uuid4().hex,
|
||||||
|
"created_at": 'time-' + uuid.uuid4().hex,
|
||||||
|
"volume_types": ['volume-type1'],
|
||||||
|
}
|
||||||
|
|
||||||
|
# Overwrite default attributes.
|
||||||
|
consistency_group_info.update(attrs)
|
||||||
|
|
||||||
|
consistency_group = fakes.FakeResource(
|
||||||
|
info=copy.deepcopy(consistency_group_info), loaded=True
|
||||||
|
)
|
||||||
|
return consistency_group
|
||||||
|
|
||||||
|
|
||||||
|
def create_consistency_groups(attrs=None, count=2):
|
||||||
|
"""Create multiple fake consistency groups.
|
||||||
|
|
||||||
|
:param dict attrs:
|
||||||
|
A dictionary with all attributes
|
||||||
|
:param int count:
|
||||||
|
The number of consistency groups to fake
|
||||||
|
:return:
|
||||||
|
A list of FakeResource objects faking the consistency groups
|
||||||
|
"""
|
||||||
|
consistency_groups = []
|
||||||
|
for i in range(0, count):
|
||||||
|
consistency_group = create_one_consistency_group(attrs)
|
||||||
|
consistency_groups.append(consistency_group)
|
||||||
|
|
||||||
|
return consistency_groups
|
||||||
|
|
||||||
|
|
||||||
def create_one_extension(attrs=None):
|
def create_one_extension(attrs=None):
|
||||||
"""Create a fake extension.
|
"""Create a fake extension.
|
||||||
|
|
||||||
@ -349,6 +405,84 @@ def create_resource_filters(attrs=None, count=2):
|
|||||||
return resource_filters
|
return resource_filters
|
||||||
|
|
||||||
|
|
||||||
|
def create_one_volume(attrs=None):
|
||||||
|
"""Create a fake volume.
|
||||||
|
|
||||||
|
:param dict attrs:
|
||||||
|
A dictionary with all attributes of volume
|
||||||
|
:return:
|
||||||
|
A FakeResource object with id, name, status, etc.
|
||||||
|
"""
|
||||||
|
attrs = attrs or {}
|
||||||
|
|
||||||
|
# Set default attribute
|
||||||
|
volume_info = {
|
||||||
|
'id': 'volume-id' + uuid.uuid4().hex,
|
||||||
|
'name': 'volume-name' + uuid.uuid4().hex,
|
||||||
|
'description': 'description' + uuid.uuid4().hex,
|
||||||
|
'status': random.choice(['available', 'in_use']),
|
||||||
|
'size': random.randint(1, 20),
|
||||||
|
'volume_type': random.choice(['fake_lvmdriver-1', 'fake_lvmdriver-2']),
|
||||||
|
'bootable': random.randint(0, 1),
|
||||||
|
'metadata': {
|
||||||
|
'key' + uuid.uuid4().hex: 'val' + uuid.uuid4().hex,
|
||||||
|
'key' + uuid.uuid4().hex: 'val' + uuid.uuid4().hex,
|
||||||
|
'key' + uuid.uuid4().hex: 'val' + uuid.uuid4().hex,
|
||||||
|
},
|
||||||
|
'snapshot_id': random.randint(1, 5),
|
||||||
|
'availability_zone': 'zone' + uuid.uuid4().hex,
|
||||||
|
'attachments': [
|
||||||
|
{
|
||||||
|
'device': '/dev/' + uuid.uuid4().hex,
|
||||||
|
'server_id': uuid.uuid4().hex,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
# Overwrite default attributes if there are some attributes set
|
||||||
|
volume_info.update(attrs)
|
||||||
|
|
||||||
|
volume = fakes.FakeResource(None, volume_info, loaded=True)
|
||||||
|
return volume
|
||||||
|
|
||||||
|
|
||||||
|
def create_volumes(attrs=None, count=2):
|
||||||
|
"""Create multiple fake volumes.
|
||||||
|
|
||||||
|
:param dict attrs:
|
||||||
|
A dictionary with all attributes of volume
|
||||||
|
:param Integer count:
|
||||||
|
The number of volumes to be faked
|
||||||
|
:return:
|
||||||
|
A list of FakeResource objects
|
||||||
|
"""
|
||||||
|
volumes = []
|
||||||
|
for n in range(0, count):
|
||||||
|
volumes.append(create_one_volume(attrs))
|
||||||
|
|
||||||
|
return volumes
|
||||||
|
|
||||||
|
|
||||||
|
def get_volumes(volumes=None, count=2):
|
||||||
|
"""Get an iterable MagicMock object with a list of faked volumes.
|
||||||
|
|
||||||
|
If volumes list is provided, then initialize the Mock object with the
|
||||||
|
list. Otherwise create one.
|
||||||
|
|
||||||
|
:param List volumes:
|
||||||
|
A list of FakeResource objects faking volumes
|
||||||
|
:param Integer count:
|
||||||
|
The number of volumes to be faked
|
||||||
|
:return
|
||||||
|
An iterable Mock object with side_effect set to a list of faked
|
||||||
|
volumes
|
||||||
|
"""
|
||||||
|
if volumes is None:
|
||||||
|
volumes = create_volumes(count)
|
||||||
|
|
||||||
|
return mock.Mock(side_effect=volumes)
|
||||||
|
|
||||||
|
|
||||||
def create_one_sdk_volume(attrs=None):
|
def create_one_sdk_volume(attrs=None):
|
||||||
"""Create a fake volume.
|
"""Create a fake volume.
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -99,12 +99,10 @@ class CreateVolume(command.ShowOne):
|
|||||||
volume is not specified.
|
volume is not specified.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if (
|
if (args.snapshot or args.source) is None and args.size is None:
|
||||||
args.snapshot or args.source or args.backup
|
|
||||||
) is None and args.size is None:
|
|
||||||
msg = _(
|
msg = _(
|
||||||
"--size is a required option if snapshot, backup "
|
"--size is a required option if --snapshot or --source are "
|
||||||
"or source volume are not specified."
|
"not specified"
|
||||||
)
|
)
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
@ -121,8 +119,8 @@ class CreateVolume(command.ShowOne):
|
|||||||
metavar="<size>",
|
metavar="<size>",
|
||||||
type=int,
|
type=int,
|
||||||
help=_(
|
help=_(
|
||||||
"Volume size in GB (required unless --snapshot, "
|
"Volume size in GB (required unless --snapshot or "
|
||||||
"--source or --backup is specified)"
|
"--source specified)"
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
@ -146,14 +144,6 @@ class CreateVolume(command.ShowOne):
|
|||||||
metavar="<volume>",
|
metavar="<volume>",
|
||||||
help=_("Volume to clone (name or ID)"),
|
help=_("Volume to clone (name or ID)"),
|
||||||
)
|
)
|
||||||
source_group.add_argument(
|
|
||||||
"--backup",
|
|
||||||
metavar="<backup>",
|
|
||||||
help=_(
|
|
||||||
"Restore backup to a volume (name or ID) "
|
|
||||||
"(supported by --os-volume-api-version 3.47 or later)"
|
|
||||||
),
|
|
||||||
)
|
|
||||||
source_group.add_argument(
|
source_group.add_argument(
|
||||||
"--source-replicated",
|
"--source-replicated",
|
||||||
metavar="<replicated-volume>",
|
metavar="<replicated-volume>",
|
||||||
@ -222,26 +212,17 @@ class CreateVolume(command.ShowOne):
|
|||||||
parser, _ = self._get_parser(prog_name)
|
parser, _ = self._get_parser(prog_name)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def _take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
CreateVolume._check_size_arg(parsed_args)
|
CreateVolume._check_size_arg(parsed_args)
|
||||||
# size is validated in the above call to
|
# size is validated in the above call to
|
||||||
# _check_size_arg where we check that size
|
# _check_size_arg where we check that size
|
||||||
# should be passed if we are not creating a
|
# should be passed if we are not creating a
|
||||||
# volume from snapshot, backup or source volume
|
# volume from snapshot or source volume
|
||||||
size = parsed_args.size
|
size = parsed_args.size
|
||||||
|
|
||||||
volume_client = self.app.client_manager.volume
|
volume_client = self.app.client_manager.volume
|
||||||
image_client = self.app.client_manager.image
|
image_client = self.app.client_manager.image
|
||||||
|
|
||||||
if parsed_args.backup and not (
|
|
||||||
volume_client.api_version.matches('3.47')
|
|
||||||
):
|
|
||||||
msg = _(
|
|
||||||
"--os-volume-api-version 3.47 or greater is required "
|
|
||||||
"to create a volume from backup."
|
|
||||||
)
|
|
||||||
raise exceptions.CommandError(msg)
|
|
||||||
|
|
||||||
source_volume = None
|
source_volume = None
|
||||||
if parsed_args.source:
|
if parsed_args.source:
|
||||||
source_volume_obj = utils.find_resource(
|
source_volume_obj = utils.find_resource(
|
||||||
@ -276,15 +257,6 @@ class CreateVolume(command.ShowOne):
|
|||||||
# snapshot size.
|
# snapshot size.
|
||||||
size = max(size or 0, snapshot_obj.size)
|
size = max(size or 0, snapshot_obj.size)
|
||||||
|
|
||||||
backup = None
|
|
||||||
if parsed_args.backup:
|
|
||||||
backup_obj = utils.find_resource(
|
|
||||||
volume_client.backups, parsed_args.backup
|
|
||||||
)
|
|
||||||
backup = backup_obj.id
|
|
||||||
# As above
|
|
||||||
size = max(size or 0, backup_obj.size)
|
|
||||||
|
|
||||||
volume = volume_client.volumes.create(
|
volume = volume_client.volumes.create(
|
||||||
size=size,
|
size=size,
|
||||||
snapshot_id=snapshot,
|
snapshot_id=snapshot,
|
||||||
@ -297,7 +269,6 @@ class CreateVolume(command.ShowOne):
|
|||||||
source_volid=source_volume,
|
source_volid=source_volume,
|
||||||
consistencygroup_id=consistency_group,
|
consistencygroup_id=consistency_group,
|
||||||
scheduler_hints=parsed_args.hint,
|
scheduler_hints=parsed_args.hint,
|
||||||
backup_id=backup,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if parsed_args.bootable or parsed_args.non_bootable:
|
if parsed_args.bootable or parsed_args.non_bootable:
|
||||||
@ -359,9 +330,6 @@ class CreateVolume(command.ShowOne):
|
|||||||
volume._info.pop("links", None)
|
volume._info.pop("links", None)
|
||||||
return zip(*sorted(volume._info.items()))
|
return zip(*sorted(volume._info.items()))
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
|
||||||
return self._take_action(parsed_args)
|
|
||||||
|
|
||||||
|
|
||||||
class DeleteVolume(command.Command):
|
class DeleteVolume(command.Command):
|
||||||
_description = _("Delete volume(s)")
|
_description = _("Delete volume(s)")
|
||||||
@ -784,10 +752,7 @@ class SetVolume(command.Command):
|
|||||||
_("New size must be greater than %s GB") % volume.size
|
_("New size must be greater than %s GB") % volume.size
|
||||||
)
|
)
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
if (
|
if volume.status != 'available':
|
||||||
volume.status != 'available'
|
|
||||||
and not volume_client.api_version.matches('3.42')
|
|
||||||
):
|
|
||||||
msg = (
|
msg = (
|
||||||
_(
|
_(
|
||||||
"Volume is in %s state, it must be available "
|
"Volume is in %s state, it must be available "
|
||||||
|
File diff suppressed because it is too large
Load Diff
10
setup.cfg
10
setup.cfg
@ -767,11 +767,11 @@ openstack.volume.v3 =
|
|||||||
|
|
||||||
volume_create = openstackclient.volume.v3.volume:CreateVolume
|
volume_create = openstackclient.volume.v3.volume:CreateVolume
|
||||||
volume_delete = openstackclient.volume.v3.volume:DeleteVolume
|
volume_delete = openstackclient.volume.v3.volume:DeleteVolume
|
||||||
volume_list = openstackclient.volume.v2.volume:ListVolume
|
volume_list = openstackclient.volume.v3.volume:ListVolume
|
||||||
volume_migrate = openstackclient.volume.v2.volume:MigrateVolume
|
volume_migrate = openstackclient.volume.v3.volume:MigrateVolume
|
||||||
volume_set = openstackclient.volume.v2.volume:SetVolume
|
volume_set = openstackclient.volume.v3.volume:SetVolume
|
||||||
volume_show = openstackclient.volume.v2.volume:ShowVolume
|
volume_show = openstackclient.volume.v3.volume:ShowVolume
|
||||||
volume_unset = openstackclient.volume.v2.volume:UnsetVolume
|
volume_unset = openstackclient.volume.v3.volume:UnsetVolume
|
||||||
|
|
||||||
volume_attachment_create = openstackclient.volume.v3.volume_attachment:CreateVolumeAttachment
|
volume_attachment_create = openstackclient.volume.v3.volume_attachment:CreateVolumeAttachment
|
||||||
volume_attachment_delete = openstackclient.volume.v3.volume_attachment:DeleteVolumeAttachment
|
volume_attachment_delete = openstackclient.volume.v3.volume_attachment:DeleteVolumeAttachment
|
||||||
|
Loading…
x
Reference in New Issue
Block a user