Blacken openstackclient.volume
Black used with the '-l 79 -S' flags. A future change will ignore this commit in git-blame history by adding a 'git-blame-ignore-revs' file. Change-Id: Ic318617c67ab7ce6527f9016b759a1d4b0b80802 Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
This commit is contained in:
parent
28ffa2bf9f
commit
35ba1d8f13
@ -16,11 +16,18 @@ from openstackclient.tests.functional import base
|
||||
|
||||
|
||||
class BaseVolumeTests(base.TestCase):
|
||||
"""Base class for Volume functional tests. """
|
||||
"""Base class for Volume functional tests."""
|
||||
|
||||
@classmethod
|
||||
def wait_for_status(cls, check_type, check_name, desired_status,
|
||||
wait=120, interval=5, failures=None):
|
||||
def wait_for_status(
|
||||
cls,
|
||||
check_type,
|
||||
check_name,
|
||||
desired_status,
|
||||
wait=120,
|
||||
interval=5,
|
||||
failures=None,
|
||||
):
|
||||
current_status = "notset"
|
||||
if failures is None:
|
||||
failures = ['error']
|
||||
@ -32,23 +39,31 @@ class BaseVolumeTests(base.TestCase):
|
||||
)
|
||||
current_status = output['status']
|
||||
if current_status == desired_status:
|
||||
print('{} {} now has status {}'
|
||||
.format(check_type, check_name, current_status))
|
||||
print(
|
||||
'{} {} now has status {}'.format(
|
||||
check_type, check_name, current_status
|
||||
)
|
||||
)
|
||||
return
|
||||
print('Checking {} {} Waiting for {} current status: {}'
|
||||
.format(check_type, check_name,
|
||||
desired_status, current_status))
|
||||
print(
|
||||
'Checking {} {} Waiting for {} current status: {}'.format(
|
||||
check_type, check_name, desired_status, current_status
|
||||
)
|
||||
)
|
||||
if current_status in failures:
|
||||
raise Exception(
|
||||
'Current status {} of {} {} is one of failures {}'
|
||||
.format(current_status, check_type, check_name, failures))
|
||||
'Current status {} of {} {} is one of failures {}'.format(
|
||||
current_status, check_type, check_name, failures
|
||||
)
|
||||
)
|
||||
time.sleep(interval)
|
||||
total_sleep += interval
|
||||
cls.assertOutput(desired_status, current_status)
|
||||
|
||||
@classmethod
|
||||
def wait_for_delete(cls, check_type, check_name, wait=120, interval=5,
|
||||
name_field=None):
|
||||
def wait_for_delete(
|
||||
cls, check_type, check_name, wait=120, interval=5, name_field=None
|
||||
):
|
||||
total_sleep = 0
|
||||
name_field = name_field or 'Name'
|
||||
while total_sleep < wait:
|
||||
@ -57,9 +72,15 @@ class BaseVolumeTests(base.TestCase):
|
||||
if check_name not in names:
|
||||
print('{} {} is now deleted'.format(check_type, check_name))
|
||||
return
|
||||
print('Checking {} {} Waiting for deleted'
|
||||
.format(check_type, check_name))
|
||||
print(
|
||||
'Checking {} {} Waiting for deleted'.format(
|
||||
check_type, check_name
|
||||
)
|
||||
)
|
||||
time.sleep(interval)
|
||||
total_sleep += interval
|
||||
raise Exception('Timeout: {} {} was not deleted in {} seconds'
|
||||
.format(check_type, check_name, wait))
|
||||
raise Exception(
|
||||
'Timeout: {} {} was not deleted in {} seconds'.format(
|
||||
check_type, check_name, wait
|
||||
)
|
||||
)
|
||||
|
@ -16,31 +16,23 @@ from openstackclient.tests.functional.volume.v1 import common
|
||||
|
||||
|
||||
class QosTests(common.BaseVolumeTests):
|
||||
"""Functional tests for volume qos. """
|
||||
"""Functional tests for volume qos."""
|
||||
|
||||
def test_volume_qos_create_list(self):
|
||||
"""Test create, list, delete multiple"""
|
||||
name1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume qos create ' +
|
||||
name1,
|
||||
'volume qos create ' + name1,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
name1,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(name1, cmd_output['name'])
|
||||
|
||||
name2 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume qos create ' +
|
||||
name2,
|
||||
'volume qos create ' + name2,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
name2,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(name2, cmd_output['name'])
|
||||
|
||||
# Test list
|
||||
cmd_output = self.openstack(
|
||||
@ -60,67 +52,43 @@ class QosTests(common.BaseVolumeTests):
|
||||
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume qos create ' +
|
||||
'--consumer front-end '
|
||||
'--property Alpha=a ' +
|
||||
name,
|
||||
'volume qos create ' + '--consumer front-end '
|
||||
'--property Alpha=a ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume qos delete ' + name)
|
||||
self.assertEqual(
|
||||
name,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
|
||||
self.assertEqual(
|
||||
"front-end",
|
||||
cmd_output['consumer']
|
||||
)
|
||||
self.assertEqual("front-end", cmd_output['consumer'])
|
||||
|
||||
# Test volume qos set
|
||||
raw_output = self.openstack(
|
||||
'volume qos set ' +
|
||||
'--property Alpha=c ' +
|
||||
'--property Beta=b ' +
|
||||
name,
|
||||
'volume qos set '
|
||||
+ '--property Alpha=c '
|
||||
+ '--property Beta=b '
|
||||
+ name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
# Test volume qos show
|
||||
cmd_output = self.openstack(
|
||||
'volume qos show ' +
|
||||
name,
|
||||
'volume qos show ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
name,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(
|
||||
{'Alpha': 'c', 'Beta': 'b'},
|
||||
cmd_output['properties']
|
||||
)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
self.assertEqual({'Alpha': 'c', 'Beta': 'b'}, cmd_output['properties'])
|
||||
|
||||
# Test volume qos unset
|
||||
raw_output = self.openstack(
|
||||
'volume qos unset ' +
|
||||
'--property Alpha ' +
|
||||
name,
|
||||
'volume qos unset ' + '--property Alpha ' + name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'volume qos show ' +
|
||||
name,
|
||||
'volume qos show ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
name,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(
|
||||
{'Beta': 'b'},
|
||||
cmd_output['properties']
|
||||
)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
self.assertEqual({'Beta': 'b'}, cmd_output['properties'])
|
||||
|
||||
# TODO(qiangjiahui): Add tests for associate and disassociate volume type
|
||||
|
@ -24,22 +24,16 @@ class VolumeServiceTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume service list --service
|
||||
cmd_output = self.openstack(
|
||||
'volume service list ' +
|
||||
'--service ' +
|
||||
services[0],
|
||||
'volume service list ' + '--service ' + services[0],
|
||||
parse_output=True,
|
||||
)
|
||||
for x in cmd_output:
|
||||
self.assertEqual(
|
||||
services[0],
|
||||
x['Binary']
|
||||
)
|
||||
self.assertEqual(services[0], x['Binary'])
|
||||
|
||||
# TODO(zhiyong.dai): test volume service list --host after solving
|
||||
# https://bugs.launchpad.net/python-openstackclient/+bug/1664451
|
||||
|
||||
def test_volume_service_set(self):
|
||||
|
||||
# Get a service and host
|
||||
cmd_output = self.openstack(
|
||||
'volume service list',
|
||||
@ -50,9 +44,7 @@ class VolumeServiceTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume service set --enable
|
||||
raw_output = self.openstack(
|
||||
'volume service set --enable ' +
|
||||
host_1 + ' ' +
|
||||
service_1
|
||||
'volume service set --enable ' + host_1 + ' ' + service_1
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
@ -60,20 +52,19 @@ class VolumeServiceTests(common.BaseVolumeTests):
|
||||
'volume service list --long',
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
'enabled',
|
||||
cmd_output[0]['Status']
|
||||
)
|
||||
self.assertEqual('enabled', cmd_output[0]['Status'])
|
||||
self.assertIsNone(cmd_output[0]['Disabled Reason'])
|
||||
|
||||
# Test volume service set --disable and --disable-reason
|
||||
disable_reason = 'disable_reason'
|
||||
raw_output = self.openstack(
|
||||
'volume service set --disable ' +
|
||||
'--disable-reason ' +
|
||||
disable_reason + ' ' +
|
||||
host_1 + ' ' +
|
||||
service_1
|
||||
'volume service set --disable '
|
||||
+ '--disable-reason '
|
||||
+ disable_reason
|
||||
+ ' '
|
||||
+ host_1
|
||||
+ ' '
|
||||
+ service_1
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
@ -81,11 +72,5 @@ class VolumeServiceTests(common.BaseVolumeTests):
|
||||
'volume service list --long',
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
'disabled',
|
||||
cmd_output[0]['Status']
|
||||
)
|
||||
self.assertEqual(
|
||||
disable_reason,
|
||||
cmd_output[0]['Disabled Reason']
|
||||
)
|
||||
self.assertEqual('disabled', cmd_output[0]['Status'])
|
||||
self.assertEqual(disable_reason, cmd_output[0]['Disabled Reason'])
|
||||
|
@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v1 import common
|
||||
|
||||
|
||||
class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
"""Functional tests for volume snapshot. """
|
||||
"""Functional tests for volume snapshot."""
|
||||
|
||||
VOLLY = uuid.uuid4().hex
|
||||
|
||||
@ -25,9 +25,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
super(VolumeSnapshotTests, cls).setUpClass()
|
||||
# create a volume for all tests to create snapshot
|
||||
cmd_output = cls.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
cls.VOLLY,
|
||||
'volume create ' + '--size 1 ' + cls.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
cls.wait_for_status('volume', cls.VOLLY, 'available')
|
||||
@ -46,9 +44,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
"""Test create, delete multiple"""
|
||||
name1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
name1 +
|
||||
' --volume ' + self.VOLLY,
|
||||
'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -58,9 +54,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
name2 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
name2 +
|
||||
' --volume ' + self.VOLLY,
|
||||
'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -72,7 +66,8 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
self.wait_for_status('volume snapshot', name2, 'available')
|
||||
|
||||
del_output = self.openstack(
|
||||
'volume snapshot delete ' + name1 + ' ' + name2)
|
||||
'volume snapshot delete ' + name1 + ' ' + name2
|
||||
)
|
||||
self.assertOutput('', del_output)
|
||||
self.wait_for_delete('volume snapshot', name1)
|
||||
self.wait_for_delete('volume snapshot', name2)
|
||||
@ -81,9 +76,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
"""Test create, list filter"""
|
||||
name1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
name1 +
|
||||
' --volume ' + self.VOLLY,
|
||||
'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.wait_for_delete, 'volume snapshot', name1)
|
||||
@ -104,9 +97,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
name2 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
name2 +
|
||||
' --volume ' + self.VOLLY,
|
||||
'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.wait_for_delete, 'volume snapshot', name2)
|
||||
@ -127,9 +118,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test list --long, --status
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot list ' +
|
||||
'--long ' +
|
||||
'--status error',
|
||||
'volume snapshot list ' + '--long ' + '--status error',
|
||||
parse_output=True,
|
||||
)
|
||||
names = [x["Name"] for x in cmd_output]
|
||||
@ -138,8 +127,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test list --volume
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot list ' +
|
||||
'--volume ' + self.VOLLY,
|
||||
'volume snapshot list ' + '--volume ' + self.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
names = [x["Name"] for x in cmd_output]
|
||||
@ -148,8 +136,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test list --name
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot list ' +
|
||||
'--name ' + name1,
|
||||
'volume snapshot list ' + '--name ' + name1,
|
||||
parse_output=True,
|
||||
)
|
||||
names = [x["Name"] for x in cmd_output]
|
||||
@ -161,10 +148,11 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
name = uuid.uuid4().hex
|
||||
new_name = name + "_"
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
'--volume ' + self.VOLLY +
|
||||
' --description aaaa ' +
|
||||
name,
|
||||
'volume snapshot create '
|
||||
+ '--volume '
|
||||
+ self.VOLLY
|
||||
+ ' --description aaaa '
|
||||
+ name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.wait_for_delete, 'volume snapshot', new_name)
|
||||
@ -185,19 +173,19 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume snapshot set
|
||||
raw_output = self.openstack(
|
||||
'volume snapshot set ' +
|
||||
'--name ' + new_name +
|
||||
' --description bbbb ' +
|
||||
'--property Alpha=a ' +
|
||||
'--property Beta=b ' +
|
||||
name,
|
||||
'volume snapshot set '
|
||||
+ '--name '
|
||||
+ new_name
|
||||
+ ' --description bbbb '
|
||||
+ '--property Alpha=a '
|
||||
+ '--property Beta=b '
|
||||
+ name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
# Show snapshot set result
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot show ' +
|
||||
new_name,
|
||||
'volume snapshot show ' + new_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -219,15 +207,12 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume unset
|
||||
raw_output = self.openstack(
|
||||
'volume snapshot unset ' +
|
||||
'--property Alpha ' +
|
||||
new_name,
|
||||
'volume snapshot unset ' + '--property Alpha ' + new_name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot show ' +
|
||||
new_name,
|
||||
'volume snapshot show ' + new_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -237,14 +222,11 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume snapshot set --no-property
|
||||
raw_output = self.openstack(
|
||||
'volume snapshot set ' +
|
||||
'--no-property ' +
|
||||
new_name,
|
||||
'volume snapshot set ' + '--no-property ' + new_name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot show ' +
|
||||
new_name,
|
||||
'volume snapshot show ' + new_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual({}, cmd_output["properties"])
|
||||
|
@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v1 import common
|
||||
|
||||
|
||||
class TransferRequestTests(common.BaseVolumeTests):
|
||||
"""Functional tests for transfer request. """
|
||||
"""Functional tests for transfer request."""
|
||||
|
||||
NAME = uuid.uuid4().hex
|
||||
VOLUME_NAME = uuid.uuid4().hex
|
||||
@ -36,7 +36,8 @@ class TransferRequestTests(common.BaseVolumeTests):
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
raw_output_volume = cls.openstack(
|
||||
'volume delete ' + cls.VOLUME_NAME)
|
||||
'volume delete ' + cls.VOLUME_NAME
|
||||
)
|
||||
cls.assertOutput('', raw_output_volume)
|
||||
finally:
|
||||
super(TransferRequestTests, cls).tearDownClass()
|
||||
@ -55,9 +56,10 @@ class TransferRequestTests(common.BaseVolumeTests):
|
||||
# create volume transfer request for the volume
|
||||
# and get the auth_key of the new transfer request
|
||||
cmd_output = self.openstack(
|
||||
'volume transfer request create ' +
|
||||
volume_name +
|
||||
' --name ' + name,
|
||||
'volume transfer request create '
|
||||
+ volume_name
|
||||
+ ' --name '
|
||||
+ name,
|
||||
parse_output=True,
|
||||
)
|
||||
auth_key = cmd_output['auth_key']
|
||||
@ -65,30 +67,32 @@ class TransferRequestTests(common.BaseVolumeTests):
|
||||
|
||||
# accept the volume transfer request
|
||||
output = self.openstack(
|
||||
'volume transfer request accept ' +
|
||||
name + ' ' +
|
||||
'--auth-key ' + auth_key,
|
||||
'volume transfer request accept '
|
||||
+ name
|
||||
+ ' '
|
||||
+ '--auth-key '
|
||||
+ auth_key,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(name, output.get('name'))
|
||||
|
||||
# the volume transfer will be removed by default after accepted
|
||||
# so just need to delete the volume here
|
||||
raw_output = self.openstack(
|
||||
'volume delete ' + volume_name)
|
||||
raw_output = self.openstack('volume delete ' + volume_name)
|
||||
self.assertEqual('', raw_output)
|
||||
|
||||
def test_volume_transfer_request_list_show(self):
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume transfer request create ' +
|
||||
' --name ' + name + ' ' +
|
||||
self.VOLUME_NAME,
|
||||
'volume transfer request create '
|
||||
+ ' --name '
|
||||
+ name
|
||||
+ ' '
|
||||
+ self.VOLUME_NAME,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(
|
||||
self.openstack,
|
||||
'volume transfer request delete ' + name
|
||||
self.openstack, 'volume transfer request delete ' + name
|
||||
)
|
||||
self.assertOutput(name, cmd_output['name'])
|
||||
auth_key = cmd_output['auth_key']
|
||||
@ -101,8 +105,7 @@ class TransferRequestTests(common.BaseVolumeTests):
|
||||
self.assertIn(name, [req['Name'] for req in cmd_output])
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'volume transfer request show ' +
|
||||
name,
|
||||
'volume transfer request show ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
|
@ -16,15 +16,13 @@ from openstackclient.tests.functional.volume.v1 import common
|
||||
|
||||
|
||||
class VolumeTests(common.BaseVolumeTests):
|
||||
"""Functional tests for volume. """
|
||||
"""Functional tests for volume."""
|
||||
|
||||
def test_volume_create_and_delete(self):
|
||||
"""Test create, delete multiple"""
|
||||
name1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
name1,
|
||||
'volume create ' + '--size 1 ' + name1,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -34,9 +32,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
|
||||
name2 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 2 ' +
|
||||
name2,
|
||||
'volume create ' + '--size 2 ' + name2,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -53,9 +49,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
"""Test create, list filter"""
|
||||
name1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
name1,
|
||||
'volume create ' + '--size 1 ' + name1,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume delete ' + name1)
|
||||
@ -67,9 +61,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
|
||||
name2 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 2 ' +
|
||||
name2,
|
||||
'volume create ' + '--size 2 ' + name2,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume delete ' + name2)
|
||||
@ -98,8 +90,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
|
||||
# Test list --name
|
||||
cmd_output = self.openstack(
|
||||
'volume list ' +
|
||||
'--name ' + name1,
|
||||
'volume list ' + '--name ' + name1,
|
||||
parse_output=True,
|
||||
)
|
||||
names = [x["Name"] for x in cmd_output]
|
||||
@ -110,11 +101,11 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
"""Tests create volume, set, unset, show, delete"""
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
'--description aaaa ' +
|
||||
'--property Alpha=a ' +
|
||||
name,
|
||||
'volume create '
|
||||
+ '--size 1 '
|
||||
+ '--description aaaa '
|
||||
+ '--property Alpha=a '
|
||||
+ name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -143,21 +134,21 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
new_name = uuid.uuid4().hex
|
||||
self.addCleanup(self.openstack, 'volume delete ' + new_name)
|
||||
raw_output = self.openstack(
|
||||
'volume set ' +
|
||||
'--name ' + new_name +
|
||||
' --size 2 ' +
|
||||
'--description bbbb ' +
|
||||
'--no-property ' +
|
||||
'--property Beta=b ' +
|
||||
'--property Gamma=c ' +
|
||||
'--bootable ' +
|
||||
name,
|
||||
'volume set '
|
||||
+ '--name '
|
||||
+ new_name
|
||||
+ ' --size 2 '
|
||||
+ '--description bbbb '
|
||||
+ '--no-property '
|
||||
+ '--property Beta=b '
|
||||
+ '--property Gamma=c '
|
||||
+ '--bootable '
|
||||
+ name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'volume show ' +
|
||||
new_name,
|
||||
'volume show ' + new_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -183,15 +174,12 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume unset
|
||||
raw_output = self.openstack(
|
||||
'volume unset ' +
|
||||
'--property Beta ' +
|
||||
new_name,
|
||||
'volume unset ' + '--property Beta ' + new_name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'volume show ' +
|
||||
new_name,
|
||||
'volume show ' + new_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -203,10 +191,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
"""Test backward compatibility of create, list, show"""
|
||||
name1 = uuid.uuid4().hex
|
||||
output = self.openstack(
|
||||
'volume create ' +
|
||||
'-c display_name -c id ' +
|
||||
'--size 1 ' +
|
||||
name1,
|
||||
'volume create ' + '-c display_name -c id ' + '--size 1 ' + name1,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertIn('display_name', output)
|
||||
@ -220,25 +205,21 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
self.wait_for_status("volume", name1, "available")
|
||||
|
||||
output = self.openstack(
|
||||
'volume list ' +
|
||||
'-c "Display Name"',
|
||||
'volume list ' + '-c "Display Name"',
|
||||
parse_output=True,
|
||||
)
|
||||
for each_volume in output:
|
||||
self.assertIn('Display Name', each_volume)
|
||||
|
||||
output = self.openstack(
|
||||
'volume list ' +
|
||||
'-c "Name"',
|
||||
'volume list ' + '-c "Name"',
|
||||
parse_output=True,
|
||||
)
|
||||
for each_volume in output:
|
||||
self.assertIn('Name', each_volume)
|
||||
|
||||
output = self.openstack(
|
||||
'volume show ' +
|
||||
'-c display_name -c id ' +
|
||||
name1,
|
||||
'volume show ' + '-c display_name -c id ' + name1,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertIn('display_name', output)
|
||||
|
@ -17,19 +17,17 @@ from openstackclient.tests.functional.volume.v1 import common
|
||||
|
||||
|
||||
class VolumeTypeTests(common.BaseVolumeTests):
|
||||
"""Functional tests for volume type. """
|
||||
"""Functional tests for volume type."""
|
||||
|
||||
def test_volume_type_create_list(self):
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume type create --private ' +
|
||||
name,
|
||||
'volume type create --private ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(
|
||||
self.openstack,
|
||||
'volume type delete ' +
|
||||
name,
|
||||
'volume type delete ' + name,
|
||||
)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
|
||||
@ -52,14 +50,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
def test_volume_type_set_unset_properties(self):
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume type create --private ' +
|
||||
name,
|
||||
'volume type create --private ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(
|
||||
self.openstack,
|
||||
'volume type delete ' + name
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume type delete ' + name)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
|
||||
raw_output = self.openstack(
|
||||
@ -72,9 +66,7 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
)
|
||||
self.assertEqual({'a': 'b', 'c': 'd'}, cmd_output['properties'])
|
||||
|
||||
raw_output = self.openstack(
|
||||
'volume type unset --property a %s' % name
|
||||
)
|
||||
raw_output = self.openstack('volume type unset --property a %s' % name)
|
||||
self.assertEqual("", raw_output)
|
||||
cmd_output = self.openstack(
|
||||
'volume type show %s' % name,
|
||||
@ -85,14 +77,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
def test_volume_type_set_unset_multiple_properties(self):
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume type create --private ' +
|
||||
name,
|
||||
'volume type create --private ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(
|
||||
self.openstack,
|
||||
'volume type delete ' + name
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume type delete ' + name)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
|
||||
raw_output = self.openstack(
|
||||
@ -138,12 +126,14 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
'--encryption-provider LuksEncryptor '
|
||||
'--encryption-cipher aes-xts-plain64 '
|
||||
'--encryption-key-size 128 '
|
||||
'--encryption-control-location front-end ' +
|
||||
encryption_type)
|
||||
expected = {'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end'}
|
||||
'--encryption-control-location front-end ' + encryption_type
|
||||
)
|
||||
expected = {
|
||||
'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end',
|
||||
}
|
||||
for attr, value in expected.items():
|
||||
self.assertEqual(value, cmd_output['encryption'][attr])
|
||||
# test show encryption type
|
||||
@ -151,10 +141,12 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
'volume type show --encryption-type ' + encryption_type,
|
||||
parse_output=True,
|
||||
)
|
||||
expected = {'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end'}
|
||||
expected = {
|
||||
'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end',
|
||||
}
|
||||
for attr, value in expected.items():
|
||||
self.assertEqual(value, cmd_output['encryption'][attr])
|
||||
# test list encryption type
|
||||
@ -162,12 +154,15 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
'volume type list --encryption-type',
|
||||
parse_output=True,
|
||||
)
|
||||
encryption_output = [t['Encryption'] for t in cmd_output
|
||||
if t['Name'] == encryption_type][0]
|
||||
expected = {'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end'}
|
||||
encryption_output = [
|
||||
t['Encryption'] for t in cmd_output if t['Name'] == encryption_type
|
||||
][0]
|
||||
expected = {
|
||||
'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end',
|
||||
}
|
||||
for attr, value in expected.items():
|
||||
self.assertEqual(value, encryption_output[attr])
|
||||
# test set new encryption type
|
||||
@ -176,8 +171,8 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
'--encryption-provider LuksEncryptor '
|
||||
'--encryption-cipher aes-xts-plain64 '
|
||||
'--encryption-key-size 128 '
|
||||
'--encryption-control-location front-end ' +
|
||||
self.NAME)
|
||||
'--encryption-control-location front-end ' + self.NAME
|
||||
)
|
||||
self.assertEqual('', raw_output)
|
||||
|
||||
name = uuid.uuid4().hex
|
||||
@ -195,10 +190,12 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
'volume type show --encryption-type ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
expected = {'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end'}
|
||||
expected = {
|
||||
'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end',
|
||||
}
|
||||
for attr, value in expected.items():
|
||||
self.assertEqual(value, cmd_output['encryption'][attr])
|
||||
# test unset encryption type
|
||||
|
@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume import base
|
||||
|
||||
|
||||
class BaseVolumeTests(base.BaseVolumeTests):
|
||||
"""Base class for Volume functional tests. """
|
||||
"""Base class for Volume functional tests."""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
@ -16,31 +16,23 @@ from openstackclient.tests.functional.volume.v2 import common
|
||||
|
||||
|
||||
class QosTests(common.BaseVolumeTests):
|
||||
"""Functional tests for volume qos. """
|
||||
"""Functional tests for volume qos."""
|
||||
|
||||
def test_volume_qos_create_delete_list(self):
|
||||
"""Test create, list, delete multiple"""
|
||||
name1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume qos create ' +
|
||||
name1,
|
||||
'volume qos create ' + name1,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
name1,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(name1, cmd_output['name'])
|
||||
|
||||
name2 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume qos create ' +
|
||||
name2,
|
||||
'volume qos create ' + name2,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
name2,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(name2, cmd_output['name'])
|
||||
|
||||
# Test list
|
||||
cmd_output = self.openstack(
|
||||
@ -60,126 +52,84 @@ class QosTests(common.BaseVolumeTests):
|
||||
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume qos create ' +
|
||||
'--consumer front-end '
|
||||
'--property Alpha=a ' +
|
||||
name,
|
||||
'volume qos create ' + '--consumer front-end '
|
||||
'--property Alpha=a ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume qos delete ' + name)
|
||||
self.assertEqual(
|
||||
name,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
|
||||
self.assertEqual(
|
||||
"front-end",
|
||||
cmd_output['consumer']
|
||||
)
|
||||
self.assertEqual(
|
||||
{'Alpha': 'a'},
|
||||
cmd_output['properties']
|
||||
)
|
||||
self.assertEqual("front-end", cmd_output['consumer'])
|
||||
self.assertEqual({'Alpha': 'a'}, cmd_output['properties'])
|
||||
|
||||
# Test volume qos set
|
||||
raw_output = self.openstack(
|
||||
'volume qos set ' +
|
||||
'--property Alpha=c ' +
|
||||
'--property Beta=b ' +
|
||||
name,
|
||||
'volume qos set '
|
||||
+ '--property Alpha=c '
|
||||
+ '--property Beta=b '
|
||||
+ name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
# Test volume qos show
|
||||
cmd_output = self.openstack(
|
||||
'volume qos show ' +
|
||||
name,
|
||||
'volume qos show ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
name,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(
|
||||
{'Alpha': 'c', 'Beta': 'b'},
|
||||
cmd_output['properties']
|
||||
)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
self.assertEqual({'Alpha': 'c', 'Beta': 'b'}, cmd_output['properties'])
|
||||
|
||||
# Test volume qos unset
|
||||
raw_output = self.openstack(
|
||||
'volume qos unset ' +
|
||||
'--property Alpha ' +
|
||||
name,
|
||||
'volume qos unset ' + '--property Alpha ' + name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'volume qos show ' +
|
||||
name,
|
||||
'volume qos show ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
name,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(
|
||||
{'Beta': 'b'},
|
||||
cmd_output['properties']
|
||||
)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
self.assertEqual({'Beta': 'b'}, cmd_output['properties'])
|
||||
|
||||
def test_volume_qos_asso_disasso(self):
|
||||
"""Tests associate and disassociate qos with volume type"""
|
||||
vol_type1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume type create ' +
|
||||
vol_type1,
|
||||
'volume type create ' + vol_type1,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
vol_type1,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(vol_type1, cmd_output['name'])
|
||||
self.addCleanup(self.openstack, 'volume type delete ' + vol_type1)
|
||||
|
||||
vol_type2 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume type create ' +
|
||||
vol_type2,
|
||||
'volume type create ' + vol_type2,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
vol_type2,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(vol_type2, cmd_output['name'])
|
||||
self.addCleanup(self.openstack, 'volume type delete ' + vol_type2)
|
||||
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume qos create ' +
|
||||
name,
|
||||
'volume qos create ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
name,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
self.addCleanup(self.openstack, 'volume qos delete ' + name)
|
||||
|
||||
# Test associate
|
||||
raw_output = self.openstack(
|
||||
'volume qos associate ' +
|
||||
name + ' ' + vol_type1
|
||||
'volume qos associate ' + name + ' ' + vol_type1
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
raw_output = self.openstack(
|
||||
'volume qos associate ' +
|
||||
name + ' ' + vol_type2
|
||||
'volume qos associate ' + name + ' ' + vol_type2
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'volume qos show ' +
|
||||
name,
|
||||
'volume qos show ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
types = cmd_output["associations"]
|
||||
@ -188,14 +138,15 @@ class QosTests(common.BaseVolumeTests):
|
||||
|
||||
# Test disassociate
|
||||
raw_output = self.openstack(
|
||||
'volume qos disassociate ' +
|
||||
'--volume-type ' + vol_type1 +
|
||||
' ' + name
|
||||
'volume qos disassociate '
|
||||
+ '--volume-type '
|
||||
+ vol_type1
|
||||
+ ' '
|
||||
+ name
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
cmd_output = self.openstack(
|
||||
'volume qos show ' +
|
||||
name,
|
||||
'volume qos show ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
types = cmd_output["associations"]
|
||||
@ -204,13 +155,11 @@ class QosTests(common.BaseVolumeTests):
|
||||
|
||||
# Test disassociate --all
|
||||
raw_output = self.openstack(
|
||||
'volume qos associate ' +
|
||||
name + ' ' + vol_type1
|
||||
'volume qos associate ' + name + ' ' + vol_type1
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
cmd_output = self.openstack(
|
||||
'volume qos show ' +
|
||||
name,
|
||||
'volume qos show ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
types = cmd_output["associations"]
|
||||
@ -218,13 +167,11 @@ class QosTests(common.BaseVolumeTests):
|
||||
self.assertIn(vol_type2, types)
|
||||
|
||||
raw_output = self.openstack(
|
||||
'volume qos disassociate ' +
|
||||
'--all ' + name
|
||||
'volume qos disassociate ' + '--all ' + name
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
cmd_output = self.openstack(
|
||||
'volume qos show ' +
|
||||
name,
|
||||
'volume qos show ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertNotIn("associations", cmd_output.keys())
|
||||
|
@ -25,32 +25,21 @@ class VolumeServiceTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume service list --service
|
||||
cmd_output = self.openstack(
|
||||
'volume service list ' +
|
||||
'--service ' +
|
||||
services[0],
|
||||
'volume service list ' + '--service ' + services[0],
|
||||
parse_output=True,
|
||||
)
|
||||
for x in cmd_output:
|
||||
self.assertEqual(
|
||||
services[0],
|
||||
x['Binary']
|
||||
)
|
||||
self.assertEqual(services[0], x['Binary'])
|
||||
|
||||
# Test volume service list --host
|
||||
cmd_output = self.openstack(
|
||||
'volume service list ' +
|
||||
'--host ' +
|
||||
hosts[0],
|
||||
'volume service list ' + '--host ' + hosts[0],
|
||||
parse_output=True,
|
||||
)
|
||||
for x in cmd_output:
|
||||
self.assertIn(
|
||||
hosts[0],
|
||||
x['Host']
|
||||
)
|
||||
self.assertIn(hosts[0], x['Host'])
|
||||
|
||||
def test_volume_service_set(self):
|
||||
|
||||
# Get a service and host
|
||||
cmd_output = self.openstack(
|
||||
'volume service list',
|
||||
@ -61,9 +50,7 @@ class VolumeServiceTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume service set --enable
|
||||
raw_output = self.openstack(
|
||||
'volume service set --enable ' +
|
||||
host_1 + ' ' +
|
||||
service_1
|
||||
'volume service set --enable ' + host_1 + ' ' + service_1
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
@ -71,22 +58,19 @@ class VolumeServiceTests(common.BaseVolumeTests):
|
||||
'volume service list --long',
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
'enabled',
|
||||
cmd_output[0]['Status']
|
||||
)
|
||||
self.assertIsNone(
|
||||
cmd_output[0]['Disabled Reason']
|
||||
)
|
||||
self.assertEqual('enabled', cmd_output[0]['Status'])
|
||||
self.assertIsNone(cmd_output[0]['Disabled Reason'])
|
||||
|
||||
# Test volume service set --disable and --disable-reason
|
||||
disable_reason = 'disable_reason'
|
||||
raw_output = self.openstack(
|
||||
'volume service set --disable ' +
|
||||
'--disable-reason ' +
|
||||
disable_reason + ' ' +
|
||||
host_1 + ' ' +
|
||||
service_1
|
||||
'volume service set --disable '
|
||||
+ '--disable-reason '
|
||||
+ disable_reason
|
||||
+ ' '
|
||||
+ host_1
|
||||
+ ' '
|
||||
+ service_1
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
@ -94,11 +78,5 @@ class VolumeServiceTests(common.BaseVolumeTests):
|
||||
'volume service list --long',
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
'disabled',
|
||||
cmd_output[0]['Status']
|
||||
)
|
||||
self.assertEqual(
|
||||
disable_reason,
|
||||
cmd_output[0]['Disabled Reason']
|
||||
)
|
||||
self.assertEqual('disabled', cmd_output[0]['Status'])
|
||||
self.assertEqual(disable_reason, cmd_output[0]['Disabled Reason'])
|
||||
|
@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v2 import common
|
||||
|
||||
|
||||
class TransferRequestTests(common.BaseVolumeTests):
|
||||
"""Functional tests for transfer request. """
|
||||
"""Functional tests for transfer request."""
|
||||
|
||||
API_VERSION = '2'
|
||||
|
||||
@ -26,27 +26,31 @@ class TransferRequestTests(common.BaseVolumeTests):
|
||||
|
||||
# create a volume
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
volume_name,
|
||||
'volume create ' + '--size 1 ' + volume_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(volume_name, cmd_output['name'])
|
||||
self.addCleanup(
|
||||
self.openstack,
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume delete ' +
|
||||
volume_name
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume delete '
|
||||
+ volume_name,
|
||||
)
|
||||
self.wait_for_status("volume", volume_name, "available")
|
||||
|
||||
# create volume transfer request for the volume
|
||||
# and get the auth_key of the new transfer request
|
||||
cmd_output = self.openstack(
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume transfer request create ' +
|
||||
' --name ' + xfer_name + ' ' +
|
||||
volume_name,
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume transfer request create '
|
||||
+ ' --name '
|
||||
+ xfer_name
|
||||
+ ' '
|
||||
+ volume_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(xfer_name, cmd_output['name'])
|
||||
@ -57,10 +61,14 @@ class TransferRequestTests(common.BaseVolumeTests):
|
||||
|
||||
# accept the volume transfer request
|
||||
cmd_output = self.openstack(
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume transfer request accept ' +
|
||||
'--auth-key ' + auth_key + ' ' +
|
||||
xfer_id,
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume transfer request accept '
|
||||
+ '--auth-key '
|
||||
+ auth_key
|
||||
+ ' '
|
||||
+ xfer_id,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(xfer_name, cmd_output['name'])
|
||||
@ -72,25 +80,29 @@ class TransferRequestTests(common.BaseVolumeTests):
|
||||
|
||||
# create a volume
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
volume_name,
|
||||
'volume create ' + '--size 1 ' + volume_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(volume_name, cmd_output['name'])
|
||||
self.addCleanup(
|
||||
self.openstack,
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume delete ' +
|
||||
volume_name
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume delete '
|
||||
+ volume_name,
|
||||
)
|
||||
self.wait_for_status("volume", volume_name, "available")
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume transfer request create ' +
|
||||
' --name ' + xfer_name + ' ' +
|
||||
volume_name,
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume transfer request create '
|
||||
+ ' --name '
|
||||
+ xfer_name
|
||||
+ ' '
|
||||
+ volume_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(xfer_name, cmd_output['name'])
|
||||
@ -100,16 +112,20 @@ class TransferRequestTests(common.BaseVolumeTests):
|
||||
self.wait_for_status("volume", volume_name, "awaiting-transfer")
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume transfer request list',
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume transfer request list',
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertIn(xfer_name, [req['Name'] for req in cmd_output])
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume transfer request show ' +
|
||||
xfer_id,
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume transfer request show '
|
||||
+ xfer_id,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(xfer_name, cmd_output['name'])
|
||||
@ -120,8 +136,10 @@ class TransferRequestTests(common.BaseVolumeTests):
|
||||
# to become 'available' before attempting to delete
|
||||
# the volume.
|
||||
cmd_output = self.openstack(
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume transfer request delete ' +
|
||||
xfer_id
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume transfer request delete '
|
||||
+ xfer_id
|
||||
)
|
||||
self.wait_for_status("volume", volume_name, "available")
|
||||
|
@ -16,15 +16,13 @@ from openstackclient.tests.functional.volume.v2 import common
|
||||
|
||||
|
||||
class VolumeTests(common.BaseVolumeTests):
|
||||
"""Functional tests for volume. """
|
||||
"""Functional tests for volume."""
|
||||
|
||||
def test_volume_delete(self):
|
||||
"""Test create, delete multiple"""
|
||||
name1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
name1,
|
||||
'volume create ' + '--size 1 ' + name1,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -34,9 +32,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
|
||||
name2 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 2 ' +
|
||||
name2,
|
||||
'volume create ' + '--size 2 ' + name2,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -53,9 +49,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
"""Test create, list filter"""
|
||||
name1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
name1,
|
||||
'volume create ' + '--size 1 ' + name1,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume delete ' + name1)
|
||||
@ -67,9 +61,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
|
||||
name2 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 2 ' +
|
||||
name2,
|
||||
'volume create ' + '--size 2 ' + name2,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume delete ' + name2)
|
||||
@ -78,17 +70,12 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
cmd_output["size"],
|
||||
)
|
||||
self.wait_for_status("volume", name2, "available")
|
||||
raw_output = self.openstack(
|
||||
'volume set ' +
|
||||
'--state error ' +
|
||||
name2
|
||||
)
|
||||
raw_output = self.openstack('volume set ' + '--state error ' + name2)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
# Test list --long
|
||||
cmd_output = self.openstack(
|
||||
'volume list ' +
|
||||
'--long',
|
||||
'volume list ' + '--long',
|
||||
parse_output=True,
|
||||
)
|
||||
names = [x["Name"] for x in cmd_output]
|
||||
@ -97,8 +84,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
|
||||
# Test list --status
|
||||
cmd_output = self.openstack(
|
||||
'volume list ' +
|
||||
'--status error',
|
||||
'volume list ' + '--status error',
|
||||
parse_output=True,
|
||||
)
|
||||
names = [x["Name"] for x in cmd_output]
|
||||
@ -113,11 +99,11 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
name = uuid.uuid4().hex
|
||||
new_name = name + "_"
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
'--description aaaa ' +
|
||||
'--property Alpha=a ' +
|
||||
name,
|
||||
'volume create '
|
||||
+ '--size 1 '
|
||||
+ '--description aaaa '
|
||||
+ '--property Alpha=a '
|
||||
+ name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume delete ' + new_name)
|
||||
@ -145,23 +131,23 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume set
|
||||
raw_output = self.openstack(
|
||||
'volume set ' +
|
||||
'--name ' + new_name +
|
||||
' --size 2 ' +
|
||||
'--description bbbb ' +
|
||||
'--no-property ' +
|
||||
'--property Beta=b ' +
|
||||
'--property Gamma=c ' +
|
||||
'--image-property a=b ' +
|
||||
'--image-property c=d ' +
|
||||
'--bootable ' +
|
||||
name,
|
||||
'volume set '
|
||||
+ '--name '
|
||||
+ new_name
|
||||
+ ' --size 2 '
|
||||
+ '--description bbbb '
|
||||
+ '--no-property '
|
||||
+ '--property Beta=b '
|
||||
+ '--property Gamma=c '
|
||||
+ '--image-property a=b '
|
||||
+ '--image-property c=d '
|
||||
+ '--bootable '
|
||||
+ name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'volume show ' +
|
||||
new_name,
|
||||
'volume show ' + new_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -191,16 +177,15 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume unset
|
||||
raw_output = self.openstack(
|
||||
'volume unset ' +
|
||||
'--property Beta ' +
|
||||
'--image-property a ' +
|
||||
new_name,
|
||||
'volume unset '
|
||||
+ '--property Beta '
|
||||
+ '--image-property a '
|
||||
+ new_name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'volume show ' +
|
||||
new_name,
|
||||
'volume show ' + new_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -219,9 +204,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
snapshot_name = uuid.uuid4().hex
|
||||
# Make a snapshot
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
volume_name,
|
||||
'volume create ' + '--size 1 ' + volume_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.wait_for_status("volume", volume_name, "available")
|
||||
@ -230,9 +213,10 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
cmd_output["name"],
|
||||
)
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
snapshot_name +
|
||||
' --volume ' + volume_name,
|
||||
'volume snapshot create '
|
||||
+ snapshot_name
|
||||
+ ' --volume '
|
||||
+ volume_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.wait_for_status("volume snapshot", snapshot_name, "available")
|
||||
@ -240,9 +224,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
name = uuid.uuid4().hex
|
||||
# Create volume from snapshot
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--snapshot ' + snapshot_name +
|
||||
' ' + name,
|
||||
'volume create ' + '--snapshot ' + snapshot_name + ' ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume delete ' + name)
|
||||
@ -254,8 +236,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
self.wait_for_status("volume", name, "available")
|
||||
|
||||
# Delete snapshot
|
||||
raw_output = self.openstack(
|
||||
'volume snapshot delete ' + snapshot_name)
|
||||
raw_output = self.openstack('volume snapshot delete ' + snapshot_name)
|
||||
self.assertOutput('', raw_output)
|
||||
# Deleting snapshot may take time. If volume snapshot still exists when
|
||||
# a parent volume delete is requested, the volume deletion will fail.
|
||||
@ -265,9 +246,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
"""Test backward compatibility of list command"""
|
||||
name1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
name1,
|
||||
'volume create ' + '--size 1 ' + name1,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume delete ' + name1)
|
||||
@ -279,8 +258,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
|
||||
# Test list -c "Display Name"
|
||||
cmd_output = self.openstack(
|
||||
'volume list ' +
|
||||
'-c "Display Name"',
|
||||
'volume list ' + '-c "Display Name"',
|
||||
parse_output=True,
|
||||
)
|
||||
for each_volume in cmd_output:
|
||||
@ -288,8 +266,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
|
||||
# Test list -c "Name"
|
||||
cmd_output = self.openstack(
|
||||
'volume list ' +
|
||||
'-c "Name"',
|
||||
'volume list ' + '-c "Name"',
|
||||
parse_output=True,
|
||||
)
|
||||
for each_volume in cmd_output:
|
||||
|
@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v2 import common
|
||||
|
||||
|
||||
class VolumeBackupTests(common.BaseVolumeTests):
|
||||
"""Functional tests for volume backups. """
|
||||
"""Functional tests for volume backups."""
|
||||
|
||||
def setUp(self):
|
||||
super(VolumeBackupTests, self).setUp()
|
||||
@ -34,29 +34,26 @@ class VolumeBackupTests(common.BaseVolumeTests):
|
||||
vol_id = uuid.uuid4().hex
|
||||
# create a volume
|
||||
self.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
vol_id,
|
||||
'volume create ' + '--size 1 ' + vol_id,
|
||||
parse_output=True,
|
||||
)
|
||||
self.wait_for_status("volume", vol_id, "available")
|
||||
|
||||
# create a backup
|
||||
backup = self.openstack(
|
||||
'volume backup create ' +
|
||||
vol_id,
|
||||
'volume backup create ' + vol_id,
|
||||
parse_output=True,
|
||||
)
|
||||
self.wait_for_status("volume backup", backup['id'], "available")
|
||||
|
||||
# restore the backup
|
||||
backup_restored = self.openstack(
|
||||
'volume backup restore %s %s'
|
||||
% (backup['id'], vol_id),
|
||||
'volume backup restore %s %s' % (backup['id'], vol_id),
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(backup_restored['backup_id'], backup['id'])
|
||||
self.wait_for_status("volume backup", backup['id'], "available")
|
||||
self.wait_for_status("volume", backup_restored['volume_id'],
|
||||
"available")
|
||||
self.wait_for_status(
|
||||
"volume", backup_restored['volume_id'], "available"
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume delete %s' % vol_id)
|
||||
|
@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v2 import common
|
||||
|
||||
|
||||
class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
"""Functional tests for volume snapshot. """
|
||||
"""Functional tests for volume snapshot."""
|
||||
|
||||
VOLLY = uuid.uuid4().hex
|
||||
|
||||
@ -25,9 +25,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
super(VolumeSnapshotTests, cls).setUpClass()
|
||||
# create a volume for all tests to create snapshot
|
||||
cmd_output = cls.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
cls.VOLLY,
|
||||
'volume create ' + '--size 1 ' + cls.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
cls.wait_for_status('volume', cls.VOLLY, 'available')
|
||||
@ -37,8 +35,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
cls.wait_for_status('volume', cls.VOLLY, 'available')
|
||||
raw_output = cls.openstack(
|
||||
'volume delete --force ' + cls.VOLLY)
|
||||
raw_output = cls.openstack('volume delete --force ' + cls.VOLLY)
|
||||
cls.assertOutput('', raw_output)
|
||||
finally:
|
||||
super(VolumeSnapshotTests, cls).tearDownClass()
|
||||
@ -47,9 +44,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
"""Test create, delete multiple"""
|
||||
name1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
name1 +
|
||||
' --volume ' + self.VOLLY,
|
||||
'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -59,9 +54,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
name2 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
name2 +
|
||||
' --volume ' + self.VOLLY,
|
||||
'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -73,7 +66,8 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
self.wait_for_status('volume snapshot', name2, 'available')
|
||||
|
||||
del_output = self.openstack(
|
||||
'volume snapshot delete ' + name1 + ' ' + name2)
|
||||
'volume snapshot delete ' + name1 + ' ' + name2
|
||||
)
|
||||
self.assertOutput('', del_output)
|
||||
self.wait_for_delete('volume snapshot', name1)
|
||||
self.wait_for_delete('volume snapshot', name2)
|
||||
@ -82,9 +76,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
"""Test create, list filter"""
|
||||
name1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
name1 +
|
||||
' --volume ' + self.VOLLY,
|
||||
'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.wait_for_delete, 'volume snapshot', name1)
|
||||
@ -105,9 +97,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
name2 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
name2 +
|
||||
' --volume ' + self.VOLLY,
|
||||
'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.wait_for_delete, 'volume snapshot', name2)
|
||||
@ -127,17 +117,13 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
self.wait_for_status('volume snapshot', name2, 'available')
|
||||
|
||||
raw_output = self.openstack(
|
||||
'volume snapshot set ' +
|
||||
'--state error_deleting ' +
|
||||
name2
|
||||
'volume snapshot set ' + '--state error_deleting ' + name2
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
# Test list --long, --status
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot list ' +
|
||||
'--long ' +
|
||||
'--status error_deleting',
|
||||
'volume snapshot list ' + '--long ' + '--status error_deleting',
|
||||
parse_output=True,
|
||||
)
|
||||
names = [x["Name"] for x in cmd_output]
|
||||
@ -145,17 +131,13 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
self.assertIn(name2, names)
|
||||
|
||||
raw_output = self.openstack(
|
||||
'volume snapshot set ' +
|
||||
'--state error ' +
|
||||
name2
|
||||
'volume snapshot set ' + '--state error ' + name2
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
# Test list --long, --status
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot list ' +
|
||||
'--long ' +
|
||||
'--status error',
|
||||
'volume snapshot list ' + '--long ' + '--status error',
|
||||
parse_output=True,
|
||||
)
|
||||
names = [x["Name"] for x in cmd_output]
|
||||
@ -164,8 +146,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test list --volume
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot list ' +
|
||||
'--volume ' + self.VOLLY,
|
||||
'volume snapshot list ' + '--volume ' + self.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
names = [x["Name"] for x in cmd_output]
|
||||
@ -174,8 +155,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test list --name
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot list ' +
|
||||
'--name ' + name1,
|
||||
'volume snapshot list ' + '--name ' + name1,
|
||||
parse_output=True,
|
||||
)
|
||||
names = [x["Name"] for x in cmd_output]
|
||||
@ -187,11 +167,12 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
name = uuid.uuid4().hex
|
||||
new_name = name + "_"
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
'--volume ' + self.VOLLY +
|
||||
' --description aaaa ' +
|
||||
'--property Alpha=a ' +
|
||||
name,
|
||||
'volume snapshot create '
|
||||
+ '--volume '
|
||||
+ self.VOLLY
|
||||
+ ' --description aaaa '
|
||||
+ '--property Alpha=a '
|
||||
+ name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.wait_for_delete, 'volume snapshot', new_name)
|
||||
@ -216,19 +197,19 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume snapshot set
|
||||
raw_output = self.openstack(
|
||||
'volume snapshot set ' +
|
||||
'--name ' + new_name +
|
||||
' --description bbbb ' +
|
||||
'--property Alpha=c ' +
|
||||
'--property Beta=b ' +
|
||||
name,
|
||||
'volume snapshot set '
|
||||
+ '--name '
|
||||
+ new_name
|
||||
+ ' --description bbbb '
|
||||
+ '--property Alpha=c '
|
||||
+ '--property Beta=b '
|
||||
+ name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
# Show snapshot set result
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot show ' +
|
||||
new_name,
|
||||
'volume snapshot show ' + new_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -250,15 +231,12 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume snapshot unset
|
||||
raw_output = self.openstack(
|
||||
'volume snapshot unset ' +
|
||||
'--property Alpha ' +
|
||||
new_name,
|
||||
'volume snapshot unset ' + '--property Alpha ' + new_name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot show ' +
|
||||
new_name,
|
||||
'volume snapshot show ' + new_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -268,14 +246,11 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume snapshot set --no-property
|
||||
raw_output = self.openstack(
|
||||
'volume snapshot set ' +
|
||||
'--no-property ' +
|
||||
new_name,
|
||||
'volume snapshot set ' + '--no-property ' + new_name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot show ' +
|
||||
new_name,
|
||||
'volume snapshot show ' + new_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertNotIn(
|
||||
|
@ -17,13 +17,12 @@ from openstackclient.tests.functional.volume.v2 import common
|
||||
|
||||
|
||||
class VolumeTypeTests(common.BaseVolumeTests):
|
||||
"""Functional tests for volume type. """
|
||||
"""Functional tests for volume type."""
|
||||
|
||||
def test_volume_type_create_list(self):
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume type create --private ' +
|
||||
name,
|
||||
'volume type create --private ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(
|
||||
@ -51,14 +50,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
def test_volume_type_set_unset_properties(self):
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume type create --private ' +
|
||||
name,
|
||||
'volume type create --private ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(
|
||||
self.openstack,
|
||||
'volume type delete ' + name
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume type delete ' + name)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
|
||||
raw_output = self.openstack(
|
||||
@ -71,9 +66,7 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
)
|
||||
self.assertEqual({'a': 'b', 'c': 'd'}, cmd_output['properties'])
|
||||
|
||||
raw_output = self.openstack(
|
||||
'volume type unset --property a %s' % name
|
||||
)
|
||||
raw_output = self.openstack('volume type unset --property a %s' % name)
|
||||
self.assertEqual("", raw_output)
|
||||
cmd_output = self.openstack(
|
||||
'volume type show %s' % name,
|
||||
@ -84,14 +77,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
def test_volume_type_set_unset_multiple_properties(self):
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume type create --private ' +
|
||||
name,
|
||||
'volume type create --private ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(
|
||||
self.openstack,
|
||||
'volume type delete ' + name
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume type delete ' + name)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
|
||||
raw_output = self.openstack(
|
||||
@ -117,14 +106,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
def test_volume_type_set_unset_project(self):
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume type create --private ' +
|
||||
name,
|
||||
'volume type create --private ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(
|
||||
self.openstack,
|
||||
'volume type delete ' + name
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume type delete ' + name)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
|
||||
raw_output = self.openstack(
|
||||
@ -161,14 +146,15 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
'--encryption-provider LuksEncryptor '
|
||||
'--encryption-cipher aes-xts-plain64 '
|
||||
'--encryption-key-size 128 '
|
||||
'--encryption-control-location front-end ' +
|
||||
encryption_type,
|
||||
'--encryption-control-location front-end ' + encryption_type,
|
||||
parse_output=True,
|
||||
)
|
||||
expected = {'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end'}
|
||||
expected = {
|
||||
'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end',
|
||||
}
|
||||
for attr, value in expected.items():
|
||||
self.assertEqual(value, cmd_output['encryption'][attr])
|
||||
# test show encryption type
|
||||
@ -176,10 +162,12 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
'volume type show --encryption-type ' + encryption_type,
|
||||
parse_output=True,
|
||||
)
|
||||
expected = {'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end'}
|
||||
expected = {
|
||||
'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end',
|
||||
}
|
||||
for attr, value in expected.items():
|
||||
self.assertEqual(value, cmd_output['encryption'][attr])
|
||||
# test list encryption type
|
||||
@ -187,35 +175,39 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
'volume type list --encryption-type',
|
||||
parse_output=True,
|
||||
)
|
||||
encryption_output = [t['Encryption'] for t in cmd_output
|
||||
if t['Name'] == encryption_type][0]
|
||||
expected = {'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end'}
|
||||
encryption_output = [
|
||||
t['Encryption'] for t in cmd_output if t['Name'] == encryption_type
|
||||
][0]
|
||||
expected = {
|
||||
'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end',
|
||||
}
|
||||
for attr, value in expected.items():
|
||||
self.assertEqual(value, encryption_output[attr])
|
||||
# test set existing encryption type
|
||||
raw_output = self.openstack(
|
||||
'volume type set '
|
||||
'--encryption-key-size 256 '
|
||||
'--encryption-control-location back-end ' +
|
||||
encryption_type)
|
||||
'--encryption-control-location back-end ' + encryption_type
|
||||
)
|
||||
self.assertEqual('', raw_output)
|
||||
cmd_output = self.openstack(
|
||||
'volume type show --encryption-type ' + encryption_type,
|
||||
parse_output=True,
|
||||
)
|
||||
expected = {'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 256,
|
||||
'control_location': 'back-end'}
|
||||
expected = {
|
||||
'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 256,
|
||||
'control_location': 'back-end',
|
||||
}
|
||||
for attr, value in expected.items():
|
||||
self.assertEqual(value, cmd_output['encryption'][attr])
|
||||
# test set new encryption type
|
||||
cmd_output = self.openstack(
|
||||
'volume type create --private ' +
|
||||
name,
|
||||
'volume type create --private ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(
|
||||
@ -229,18 +221,20 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
'--encryption-provider LuksEncryptor '
|
||||
'--encryption-cipher aes-xts-plain64 '
|
||||
'--encryption-key-size 128 '
|
||||
'--encryption-control-location front-end ' +
|
||||
name)
|
||||
'--encryption-control-location front-end ' + name
|
||||
)
|
||||
self.assertEqual('', raw_output)
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'volume type show --encryption-type ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
expected = {'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end'}
|
||||
expected = {
|
||||
'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end',
|
||||
}
|
||||
for attr, value in expected.items():
|
||||
self.assertEqual(value, cmd_output['encryption'][attr])
|
||||
# test unset encryption type
|
||||
|
@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume import base
|
||||
|
||||
|
||||
class BaseVolumeTests(base.BaseVolumeTests):
|
||||
"""Base class for Volume functional tests. """
|
||||
"""Base class for Volume functional tests."""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
@ -16,31 +16,23 @@ from openstackclient.tests.functional.volume.v3 import common
|
||||
|
||||
|
||||
class QosTests(common.BaseVolumeTests):
|
||||
"""Functional tests for volume qos. """
|
||||
"""Functional tests for volume qos."""
|
||||
|
||||
def test_volume_qos_create_delete_list(self):
|
||||
"""Test create, list, delete multiple"""
|
||||
name1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume qos create ' +
|
||||
name1,
|
||||
'volume qos create ' + name1,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
name1,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(name1, cmd_output['name'])
|
||||
|
||||
name2 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume qos create ' +
|
||||
name2,
|
||||
'volume qos create ' + name2,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
name2,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(name2, cmd_output['name'])
|
||||
|
||||
# Test list
|
||||
cmd_output = self.openstack(
|
||||
@ -60,126 +52,84 @@ class QosTests(common.BaseVolumeTests):
|
||||
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume qos create ' +
|
||||
'--consumer front-end '
|
||||
'--property Alpha=a ' +
|
||||
name,
|
||||
'volume qos create ' + '--consumer front-end '
|
||||
'--property Alpha=a ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume qos delete ' + name)
|
||||
self.assertEqual(
|
||||
name,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
|
||||
self.assertEqual(
|
||||
"front-end",
|
||||
cmd_output['consumer']
|
||||
)
|
||||
self.assertEqual(
|
||||
{'Alpha': 'a'},
|
||||
cmd_output['properties']
|
||||
)
|
||||
self.assertEqual("front-end", cmd_output['consumer'])
|
||||
self.assertEqual({'Alpha': 'a'}, cmd_output['properties'])
|
||||
|
||||
# Test volume qos set
|
||||
raw_output = self.openstack(
|
||||
'volume qos set ' +
|
||||
'--property Alpha=c ' +
|
||||
'--property Beta=b ' +
|
||||
name,
|
||||
'volume qos set '
|
||||
+ '--property Alpha=c '
|
||||
+ '--property Beta=b '
|
||||
+ name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
# Test volume qos show
|
||||
cmd_output = self.openstack(
|
||||
'volume qos show ' +
|
||||
name,
|
||||
'volume qos show ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
name,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(
|
||||
{'Alpha': 'c', 'Beta': 'b'},
|
||||
cmd_output['properties']
|
||||
)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
self.assertEqual({'Alpha': 'c', 'Beta': 'b'}, cmd_output['properties'])
|
||||
|
||||
# Test volume qos unset
|
||||
raw_output = self.openstack(
|
||||
'volume qos unset ' +
|
||||
'--property Alpha ' +
|
||||
name,
|
||||
'volume qos unset ' + '--property Alpha ' + name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'volume qos show ' +
|
||||
name,
|
||||
'volume qos show ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
name,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(
|
||||
{'Beta': 'b'},
|
||||
cmd_output['properties']
|
||||
)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
self.assertEqual({'Beta': 'b'}, cmd_output['properties'])
|
||||
|
||||
def test_volume_qos_asso_disasso(self):
|
||||
"""Tests associate and disassociate qos with volume type"""
|
||||
vol_type1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume type create ' +
|
||||
vol_type1,
|
||||
'volume type create ' + vol_type1,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
vol_type1,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(vol_type1, cmd_output['name'])
|
||||
self.addCleanup(self.openstack, 'volume type delete ' + vol_type1)
|
||||
|
||||
vol_type2 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume type create ' +
|
||||
vol_type2,
|
||||
'volume type create ' + vol_type2,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
vol_type2,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(vol_type2, cmd_output['name'])
|
||||
self.addCleanup(self.openstack, 'volume type delete ' + vol_type2)
|
||||
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume qos create ' +
|
||||
name,
|
||||
'volume qos create ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
name,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
self.addCleanup(self.openstack, 'volume qos delete ' + name)
|
||||
|
||||
# Test associate
|
||||
raw_output = self.openstack(
|
||||
'volume qos associate ' +
|
||||
name + ' ' + vol_type1
|
||||
'volume qos associate ' + name + ' ' + vol_type1
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
raw_output = self.openstack(
|
||||
'volume qos associate ' +
|
||||
name + ' ' + vol_type2
|
||||
'volume qos associate ' + name + ' ' + vol_type2
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'volume qos show ' +
|
||||
name,
|
||||
'volume qos show ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
types = cmd_output["associations"]
|
||||
@ -188,14 +138,15 @@ class QosTests(common.BaseVolumeTests):
|
||||
|
||||
# Test disassociate
|
||||
raw_output = self.openstack(
|
||||
'volume qos disassociate ' +
|
||||
'--volume-type ' + vol_type1 +
|
||||
' ' + name
|
||||
'volume qos disassociate '
|
||||
+ '--volume-type '
|
||||
+ vol_type1
|
||||
+ ' '
|
||||
+ name
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
cmd_output = self.openstack(
|
||||
'volume qos show ' +
|
||||
name,
|
||||
'volume qos show ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
types = cmd_output["associations"]
|
||||
@ -204,13 +155,11 @@ class QosTests(common.BaseVolumeTests):
|
||||
|
||||
# Test disassociate --all
|
||||
raw_output = self.openstack(
|
||||
'volume qos associate ' +
|
||||
name + ' ' + vol_type1
|
||||
'volume qos associate ' + name + ' ' + vol_type1
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
cmd_output = self.openstack(
|
||||
'volume qos show ' +
|
||||
name,
|
||||
'volume qos show ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
types = cmd_output["associations"]
|
||||
@ -218,13 +167,11 @@ class QosTests(common.BaseVolumeTests):
|
||||
self.assertIn(vol_type2, types)
|
||||
|
||||
raw_output = self.openstack(
|
||||
'volume qos disassociate ' +
|
||||
'--all ' + name
|
||||
'volume qos disassociate ' + '--all ' + name
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
cmd_output = self.openstack(
|
||||
'volume qos show ' +
|
||||
name,
|
||||
'volume qos show ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertNotIn("associations", cmd_output.keys())
|
||||
|
@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v3 import common
|
||||
|
||||
|
||||
class TransferRequestTests(common.BaseVolumeTests):
|
||||
"""Functional tests for transfer request. """
|
||||
"""Functional tests for transfer request."""
|
||||
|
||||
API_VERSION = '3'
|
||||
|
||||
@ -26,26 +26,31 @@ class TransferRequestTests(common.BaseVolumeTests):
|
||||
|
||||
# create a volume
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
volume_name,
|
||||
'volume create ' + '--size 1 ' + volume_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(volume_name, cmd_output['name'])
|
||||
self.addCleanup(
|
||||
self.openstack,
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume delete ' +
|
||||
volume_name
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume delete '
|
||||
+ volume_name,
|
||||
)
|
||||
self.wait_for_status("volume", volume_name, "available")
|
||||
|
||||
# create volume transfer request for the volume
|
||||
# and get the auth_key of the new transfer request
|
||||
cmd_output = self.openstack(
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume transfer request create ' +
|
||||
' --name ' + xfer_name + ' ' + volume_name,
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume transfer request create '
|
||||
+ ' --name '
|
||||
+ xfer_name
|
||||
+ ' '
|
||||
+ volume_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(xfer_name, cmd_output['name'])
|
||||
@ -56,9 +61,14 @@ class TransferRequestTests(common.BaseVolumeTests):
|
||||
|
||||
# accept the volume transfer request
|
||||
cmd_output = self.openstack(
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume transfer request accept ' +
|
||||
'--auth-key ' + auth_key + ' ' + xfer_id,
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume transfer request accept '
|
||||
+ '--auth-key '
|
||||
+ auth_key
|
||||
+ ' '
|
||||
+ xfer_id,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(xfer_name, cmd_output['name'])
|
||||
@ -70,23 +80,29 @@ class TransferRequestTests(common.BaseVolumeTests):
|
||||
|
||||
# create a volume
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' + volume_name,
|
||||
'volume create ' + '--size 1 ' + volume_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(volume_name, cmd_output['name'])
|
||||
self.addCleanup(
|
||||
self.openstack,
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume delete ' +
|
||||
volume_name
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume delete '
|
||||
+ volume_name,
|
||||
)
|
||||
self.wait_for_status("volume", volume_name, "available")
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume transfer request create ' +
|
||||
' --name ' + xfer_name + ' ' + volume_name,
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume transfer request create '
|
||||
+ ' --name '
|
||||
+ xfer_name
|
||||
+ ' '
|
||||
+ volume_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(xfer_name, cmd_output['name'])
|
||||
@ -96,16 +112,20 @@ class TransferRequestTests(common.BaseVolumeTests):
|
||||
self.wait_for_status("volume", volume_name, "awaiting-transfer")
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume transfer request list',
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume transfer request list',
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertIn(xfer_name, [req['Name'] for req in cmd_output])
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume transfer request show ' +
|
||||
xfer_id,
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume transfer request show '
|
||||
+ xfer_id,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(xfer_name, cmd_output['name'])
|
||||
@ -116,8 +136,10 @@ class TransferRequestTests(common.BaseVolumeTests):
|
||||
# to become 'available' before attempting to delete
|
||||
# the volume.
|
||||
cmd_output = self.openstack(
|
||||
'--os-volume-api-version ' + self.API_VERSION + ' ' +
|
||||
'volume transfer request delete ' +
|
||||
xfer_id
|
||||
'--os-volume-api-version '
|
||||
+ self.API_VERSION
|
||||
+ ' '
|
||||
+ 'volume transfer request delete '
|
||||
+ xfer_id
|
||||
)
|
||||
self.wait_for_status("volume", volume_name, "available")
|
||||
|
@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v3 import common
|
||||
|
||||
|
||||
class VolumeTests(common.BaseVolumeTests):
|
||||
"""Functional tests for volume. """
|
||||
"""Functional tests for volume."""
|
||||
|
||||
def test_volume_delete(self):
|
||||
"""Test create, delete multiple"""
|
||||
@ -70,11 +70,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
cmd_output["size"],
|
||||
)
|
||||
self.wait_for_status("volume", name2, "available")
|
||||
raw_output = self.openstack(
|
||||
'volume set ' +
|
||||
'--state error ' +
|
||||
name2
|
||||
)
|
||||
raw_output = self.openstack('volume set ' + '--state error ' + name2)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
# Test list --long
|
||||
@ -103,11 +99,11 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
name = uuid.uuid4().hex
|
||||
new_name = name + "_"
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
'--description aaaa ' +
|
||||
'--property Alpha=a ' +
|
||||
name,
|
||||
'volume create '
|
||||
+ '--size 1 '
|
||||
+ '--description aaaa '
|
||||
+ '--property Alpha=a '
|
||||
+ name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume delete ' + new_name)
|
||||
@ -135,17 +131,18 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume set
|
||||
raw_output = self.openstack(
|
||||
'volume set ' +
|
||||
'--name ' + new_name +
|
||||
' --size 2 ' +
|
||||
'--description bbbb ' +
|
||||
'--no-property ' +
|
||||
'--property Beta=b ' +
|
||||
'--property Gamma=c ' +
|
||||
'--image-property a=b ' +
|
||||
'--image-property c=d ' +
|
||||
'--bootable ' +
|
||||
name,
|
||||
'volume set '
|
||||
+ '--name '
|
||||
+ new_name
|
||||
+ ' --size 2 '
|
||||
+ '--description bbbb '
|
||||
+ '--no-property '
|
||||
+ '--property Beta=b '
|
||||
+ '--property Gamma=c '
|
||||
+ '--image-property a=b '
|
||||
+ '--image-property c=d '
|
||||
+ '--bootable '
|
||||
+ name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
self.wait_for_status("volume", new_name, "available")
|
||||
@ -181,10 +178,10 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume unset
|
||||
raw_output = self.openstack(
|
||||
'volume unset ' +
|
||||
'--property Beta ' +
|
||||
'--image-property a ' +
|
||||
new_name,
|
||||
'volume unset '
|
||||
+ '--property Beta '
|
||||
+ '--image-property a '
|
||||
+ new_name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
@ -217,9 +214,10 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
cmd_output["name"],
|
||||
)
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
snapshot_name +
|
||||
' --volume ' + volume_name,
|
||||
'volume snapshot create '
|
||||
+ snapshot_name
|
||||
+ ' --volume '
|
||||
+ volume_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.wait_for_status("volume snapshot", snapshot_name, "available")
|
||||
@ -227,9 +225,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
name = uuid.uuid4().hex
|
||||
# Create volume from snapshot
|
||||
cmd_output = self.openstack(
|
||||
'volume create ' +
|
||||
'--snapshot ' + snapshot_name +
|
||||
' ' + name,
|
||||
'volume create ' + '--snapshot ' + snapshot_name + ' ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume delete ' + name)
|
||||
@ -241,8 +237,7 @@ class VolumeTests(common.BaseVolumeTests):
|
||||
self.wait_for_status("volume", name, "available")
|
||||
|
||||
# Delete snapshot
|
||||
raw_output = self.openstack(
|
||||
'volume snapshot delete ' + snapshot_name)
|
||||
raw_output = self.openstack('volume snapshot delete ' + snapshot_name)
|
||||
self.assertOutput('', raw_output)
|
||||
# Deleting snapshot may take time. If volume snapshot still exists when
|
||||
# a parent volume delete is requested, the volume deletion will fail.
|
||||
|
@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v3 import common
|
||||
|
||||
|
||||
class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
"""Functional tests for volume snapshot. """
|
||||
"""Functional tests for volume snapshot."""
|
||||
|
||||
VOLLY = uuid.uuid4().hex
|
||||
|
||||
@ -25,9 +25,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
super(VolumeSnapshotTests, cls).setUpClass()
|
||||
# create a volume for all tests to create snapshot
|
||||
cmd_output = cls.openstack(
|
||||
'volume create ' +
|
||||
'--size 1 ' +
|
||||
cls.VOLLY,
|
||||
'volume create ' + '--size 1 ' + cls.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
cls.wait_for_status('volume', cls.VOLLY, 'available')
|
||||
@ -37,8 +35,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
cls.wait_for_status('volume', cls.VOLLY, 'available')
|
||||
raw_output = cls.openstack(
|
||||
'volume delete --force ' + cls.VOLLY)
|
||||
raw_output = cls.openstack('volume delete --force ' + cls.VOLLY)
|
||||
cls.assertOutput('', raw_output)
|
||||
finally:
|
||||
super(VolumeSnapshotTests, cls).tearDownClass()
|
||||
@ -47,9 +44,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
"""Test create, delete multiple"""
|
||||
name1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
name1 +
|
||||
' --volume ' + self.VOLLY,
|
||||
'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -59,9 +54,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
name2 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
name2 +
|
||||
' --volume ' + self.VOLLY,
|
||||
'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -73,7 +66,8 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
self.wait_for_status('volume snapshot', name2, 'available')
|
||||
|
||||
del_output = self.openstack(
|
||||
'volume snapshot delete ' + name1 + ' ' + name2)
|
||||
'volume snapshot delete ' + name1 + ' ' + name2
|
||||
)
|
||||
self.assertOutput('', del_output)
|
||||
self.wait_for_delete('volume snapshot', name1)
|
||||
self.wait_for_delete('volume snapshot', name2)
|
||||
@ -82,9 +76,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
"""Test create, list filter"""
|
||||
name1 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
name1 +
|
||||
' --volume ' + self.VOLLY,
|
||||
'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.wait_for_delete, 'volume snapshot', name1)
|
||||
@ -105,9 +97,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
name2 = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
name2 +
|
||||
' --volume ' + self.VOLLY,
|
||||
'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.wait_for_delete, 'volume snapshot', name2)
|
||||
@ -126,17 +116,13 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
)
|
||||
self.wait_for_status('volume snapshot', name2, 'available')
|
||||
raw_output = self.openstack(
|
||||
'volume snapshot set ' +
|
||||
'--state error ' +
|
||||
name2
|
||||
'volume snapshot set ' + '--state error ' + name2
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
# Test list --long, --status
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot list ' +
|
||||
'--long ' +
|
||||
'--status error',
|
||||
'volume snapshot list ' + '--long ' + '--status error',
|
||||
parse_output=True,
|
||||
)
|
||||
names = [x["Name"] for x in cmd_output]
|
||||
@ -145,8 +131,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test list --volume
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot list ' +
|
||||
'--volume ' + self.VOLLY,
|
||||
'volume snapshot list ' + '--volume ' + self.VOLLY,
|
||||
parse_output=True,
|
||||
)
|
||||
names = [x["Name"] for x in cmd_output]
|
||||
@ -155,8 +140,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test list --name
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot list ' +
|
||||
'--name ' + name1,
|
||||
'volume snapshot list ' + '--name ' + name1,
|
||||
parse_output=True,
|
||||
)
|
||||
names = [x["Name"] for x in cmd_output]
|
||||
@ -168,11 +152,12 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
name = uuid.uuid4().hex
|
||||
new_name = name + "_"
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot create ' +
|
||||
'--volume ' + self.VOLLY +
|
||||
' --description aaaa ' +
|
||||
'--property Alpha=a ' +
|
||||
name,
|
||||
'volume snapshot create '
|
||||
+ '--volume '
|
||||
+ self.VOLLY
|
||||
+ ' --description aaaa '
|
||||
+ '--property Alpha=a '
|
||||
+ name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(self.wait_for_delete, 'volume snapshot', new_name)
|
||||
@ -197,19 +182,19 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume snapshot set
|
||||
raw_output = self.openstack(
|
||||
'volume snapshot set ' +
|
||||
'--name ' + new_name +
|
||||
' --description bbbb ' +
|
||||
'--property Alpha=c ' +
|
||||
'--property Beta=b ' +
|
||||
name,
|
||||
'volume snapshot set '
|
||||
+ '--name '
|
||||
+ new_name
|
||||
+ ' --description bbbb '
|
||||
+ '--property Alpha=c '
|
||||
+ '--property Beta=b '
|
||||
+ name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
# Show snapshot set result
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot show ' +
|
||||
new_name,
|
||||
'volume snapshot show ' + new_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -231,15 +216,12 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume snapshot unset
|
||||
raw_output = self.openstack(
|
||||
'volume snapshot unset ' +
|
||||
'--property Alpha ' +
|
||||
new_name,
|
||||
'volume snapshot unset ' + '--property Alpha ' + new_name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot show ' +
|
||||
new_name,
|
||||
'volume snapshot show ' + new_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -249,14 +231,11 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
|
||||
|
||||
# Test volume snapshot set --no-property
|
||||
raw_output = self.openstack(
|
||||
'volume snapshot set ' +
|
||||
'--no-property ' +
|
||||
new_name,
|
||||
'volume snapshot set ' + '--no-property ' + new_name,
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
cmd_output = self.openstack(
|
||||
'volume snapshot show ' +
|
||||
new_name,
|
||||
'volume snapshot show ' + new_name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.assertNotIn(
|
||||
|
@ -17,13 +17,12 @@ from openstackclient.tests.functional.volume.v3 import common
|
||||
|
||||
|
||||
class VolumeTypeTests(common.BaseVolumeTests):
|
||||
"""Functional tests for volume type. """
|
||||
"""Functional tests for volume type."""
|
||||
|
||||
def test_volume_type_create_list(self):
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume type create --private ' +
|
||||
name,
|
||||
'volume type create --private ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(
|
||||
@ -51,14 +50,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
def test_volume_type_set_unset_properties(self):
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume type create --private ' +
|
||||
name,
|
||||
'volume type create --private ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(
|
||||
self.openstack,
|
||||
'volume type delete ' + name
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume type delete ' + name)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
|
||||
raw_output = self.openstack(
|
||||
@ -71,9 +66,7 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
)
|
||||
self.assertEqual({'a': 'b', 'c': 'd'}, cmd_output['properties'])
|
||||
|
||||
raw_output = self.openstack(
|
||||
'volume type unset --property a %s' % name
|
||||
)
|
||||
raw_output = self.openstack('volume type unset --property a %s' % name)
|
||||
self.assertEqual("", raw_output)
|
||||
cmd_output = self.openstack(
|
||||
'volume type show %s' % name,
|
||||
@ -84,14 +77,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
def test_volume_type_set_unset_multiple_properties(self):
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume type create --private ' +
|
||||
name,
|
||||
'volume type create --private ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(
|
||||
self.openstack,
|
||||
'volume type delete ' + name
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume type delete ' + name)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
|
||||
raw_output = self.openstack(
|
||||
@ -117,14 +106,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
def test_volume_type_set_unset_project(self):
|
||||
name = uuid.uuid4().hex
|
||||
cmd_output = self.openstack(
|
||||
'volume type create --private ' +
|
||||
name,
|
||||
'volume type create --private ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(
|
||||
self.openstack,
|
||||
'volume type delete ' + name
|
||||
)
|
||||
self.addCleanup(self.openstack, 'volume type delete ' + name)
|
||||
self.assertEqual(name, cmd_output['name'])
|
||||
|
||||
raw_output = self.openstack(
|
||||
@ -161,14 +146,15 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
'--encryption-provider LuksEncryptor '
|
||||
'--encryption-cipher aes-xts-plain64 '
|
||||
'--encryption-key-size 128 '
|
||||
'--encryption-control-location front-end ' +
|
||||
encryption_type,
|
||||
'--encryption-control-location front-end ' + encryption_type,
|
||||
parse_output=True,
|
||||
)
|
||||
expected = {'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end'}
|
||||
expected = {
|
||||
'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end',
|
||||
}
|
||||
for attr, value in expected.items():
|
||||
self.assertEqual(value, cmd_output['encryption'][attr])
|
||||
# test show encryption type
|
||||
@ -176,10 +162,12 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
'volume type show --encryption-type ' + encryption_type,
|
||||
parse_output=True,
|
||||
)
|
||||
expected = {'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end'}
|
||||
expected = {
|
||||
'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end',
|
||||
}
|
||||
for attr, value in expected.items():
|
||||
self.assertEqual(value, cmd_output['encryption'][attr])
|
||||
# test list encryption type
|
||||
@ -187,35 +175,39 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
'volume type list --encryption-type',
|
||||
parse_output=True,
|
||||
)
|
||||
encryption_output = [t['Encryption'] for t in cmd_output
|
||||
if t['Name'] == encryption_type][0]
|
||||
expected = {'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end'}
|
||||
encryption_output = [
|
||||
t['Encryption'] for t in cmd_output if t['Name'] == encryption_type
|
||||
][0]
|
||||
expected = {
|
||||
'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end',
|
||||
}
|
||||
for attr, value in expected.items():
|
||||
self.assertEqual(value, encryption_output[attr])
|
||||
# test set existing encryption type
|
||||
raw_output = self.openstack(
|
||||
'volume type set '
|
||||
'--encryption-key-size 256 '
|
||||
'--encryption-control-location back-end ' +
|
||||
encryption_type)
|
||||
'--encryption-control-location back-end ' + encryption_type
|
||||
)
|
||||
self.assertEqual('', raw_output)
|
||||
cmd_output = self.openstack(
|
||||
'volume type show --encryption-type ' + encryption_type,
|
||||
parse_output=True,
|
||||
)
|
||||
expected = {'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 256,
|
||||
'control_location': 'back-end'}
|
||||
expected = {
|
||||
'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 256,
|
||||
'control_location': 'back-end',
|
||||
}
|
||||
for attr, value in expected.items():
|
||||
self.assertEqual(value, cmd_output['encryption'][attr])
|
||||
# test set new encryption type
|
||||
cmd_output = self.openstack(
|
||||
'volume type create --private ' +
|
||||
name,
|
||||
'volume type create --private ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
self.addCleanup(
|
||||
@ -229,18 +221,20 @@ class VolumeTypeTests(common.BaseVolumeTests):
|
||||
'--encryption-provider LuksEncryptor '
|
||||
'--encryption-cipher aes-xts-plain64 '
|
||||
'--encryption-key-size 128 '
|
||||
'--encryption-control-location front-end ' +
|
||||
name)
|
||||
'--encryption-control-location front-end ' + name
|
||||
)
|
||||
self.assertEqual('', raw_output)
|
||||
|
||||
cmd_output = self.openstack(
|
||||
'volume type show --encryption-type ' + name,
|
||||
parse_output=True,
|
||||
)
|
||||
expected = {'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end'}
|
||||
expected = {
|
||||
'provider': 'LuksEncryptor',
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
'control_location': 'front-end',
|
||||
}
|
||||
for attr, value in expected.items():
|
||||
self.assertEqual(value, cmd_output['encryption'][attr])
|
||||
# test unset encryption type
|
||||
|
@ -36,7 +36,6 @@ NAME = 'PhilSpector'
|
||||
|
||||
|
||||
class TestFindResourceVolumes(test_utils.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestFindResourceVolumes, self).setUp()
|
||||
api = mock.Mock()
|
||||
@ -44,8 +43,7 @@ class TestFindResourceVolumes(test_utils.TestCase):
|
||||
api.client.get = mock.Mock()
|
||||
resp = mock.Mock()
|
||||
body = {"volumes": [{"id": ID, 'display_name': NAME}]}
|
||||
api.client.get.side_effect = [Exception("Not found"),
|
||||
(resp, body)]
|
||||
api.client.get.side_effect = [Exception("Not found"), (resp, body)]
|
||||
self.manager = volumes.VolumeManager(api)
|
||||
|
||||
def test_find(self):
|
||||
@ -54,12 +52,15 @@ class TestFindResourceVolumes(test_utils.TestCase):
|
||||
self.assertEqual(NAME, result.display_name)
|
||||
|
||||
def test_not_find(self):
|
||||
self.assertRaises(exceptions.CommandError, utils.find_resource,
|
||||
self.manager, 'GeorgeMartin')
|
||||
self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
utils.find_resource,
|
||||
self.manager,
|
||||
'GeorgeMartin',
|
||||
)
|
||||
|
||||
|
||||
class TestFindResourceVolumeSnapshots(test_utils.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestFindResourceVolumeSnapshots, self).setUp()
|
||||
api = mock.Mock()
|
||||
@ -67,8 +68,7 @@ class TestFindResourceVolumeSnapshots(test_utils.TestCase):
|
||||
api.client.get = mock.Mock()
|
||||
resp = mock.Mock()
|
||||
body = {"snapshots": [{"id": ID, 'display_name': NAME}]}
|
||||
api.client.get.side_effect = [Exception("Not found"),
|
||||
(resp, body)]
|
||||
api.client.get.side_effect = [Exception("Not found"), (resp, body)]
|
||||
self.manager = volume_snapshots.SnapshotManager(api)
|
||||
|
||||
def test_find(self):
|
||||
@ -77,5 +77,9 @@ class TestFindResourceVolumeSnapshots(test_utils.TestCase):
|
||||
self.assertEqual(NAME, result.display_name)
|
||||
|
||||
def test_not_find(self):
|
||||
self.assertRaises(exceptions.CommandError, utils.find_resource,
|
||||
self.manager, 'GeorgeMartin')
|
||||
self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
utils.find_resource,
|
||||
self.manager,
|
||||
'GeorgeMartin',
|
||||
)
|
||||
|
@ -26,7 +26,6 @@ from openstackclient.volume.v1 import qos_specs
|
||||
|
||||
|
||||
class TestQos(volume_fakes.TestVolumev1):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -38,7 +37,6 @@ class TestQos(volume_fakes.TestVolumev1):
|
||||
|
||||
|
||||
class TestQosAssociate(TestQos):
|
||||
|
||||
volume_type = volume_fakes.create_one_volume_type()
|
||||
qos_spec = volume_fakes.create_one_qos()
|
||||
|
||||
@ -51,33 +49,23 @@ class TestQosAssociate(TestQos):
|
||||
self.cmd = qos_specs.AssociateQos(self.app, None)
|
||||
|
||||
def test_qos_associate(self):
|
||||
arglist = [
|
||||
self.qos_spec.id,
|
||||
self.volume_type.id
|
||||
]
|
||||
arglist = [self.qos_spec.id, self.volume_type.id]
|
||||
verifylist = [
|
||||
('qos_spec', self.qos_spec.id),
|
||||
('volume_type', self.volume_type.id)
|
||||
('volume_type', self.volume_type.id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.qos_mock.associate.assert_called_with(
|
||||
self.qos_spec.id,
|
||||
self.volume_type.id
|
||||
self.qos_spec.id, self.volume_type.id
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
||||
class TestQosCreate(TestQos):
|
||||
|
||||
columns = (
|
||||
'consumer',
|
||||
'id',
|
||||
'name',
|
||||
'properties'
|
||||
)
|
||||
columns = ('consumer', 'id', 'name', 'properties')
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@ -86,7 +74,7 @@ class TestQosCreate(TestQos):
|
||||
self.new_qos_spec.consumer,
|
||||
self.new_qos_spec.id,
|
||||
self.new_qos_spec.name,
|
||||
format_columns.DictColumn(self.new_qos_spec.specs)
|
||||
format_columns.DictColumn(self.new_qos_spec.specs),
|
||||
)
|
||||
self.qos_mock.create.return_value = self.new_qos_spec
|
||||
# Get the command object to test
|
||||
@ -104,8 +92,7 @@ class TestQosCreate(TestQos):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.qos_mock.create.assert_called_with(
|
||||
self.new_qos_spec.name,
|
||||
{'consumer': 'both'}
|
||||
self.new_qos_spec.name, {'consumer': 'both'}
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
@ -113,7 +100,8 @@ class TestQosCreate(TestQos):
|
||||
|
||||
def test_qos_create_with_consumer(self):
|
||||
arglist = [
|
||||
'--consumer', self.new_qos_spec.consumer,
|
||||
'--consumer',
|
||||
self.new_qos_spec.consumer,
|
||||
self.new_qos_spec.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -125,17 +113,19 @@ class TestQosCreate(TestQos):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.qos_mock.create.assert_called_with(
|
||||
self.new_qos_spec.name,
|
||||
{'consumer': self.new_qos_spec.consumer}
|
||||
self.new_qos_spec.name, {'consumer': self.new_qos_spec.consumer}
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.datalist, data)
|
||||
|
||||
def test_qos_create_with_properties(self):
|
||||
arglist = [
|
||||
'--consumer', self.new_qos_spec.consumer,
|
||||
'--property', 'foo=bar',
|
||||
'--property', 'iops=9001',
|
||||
'--consumer',
|
||||
self.new_qos_spec.consumer,
|
||||
'--property',
|
||||
'foo=bar',
|
||||
'--property',
|
||||
'iops=9001',
|
||||
self.new_qos_spec.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -148,10 +138,10 @@ class TestQosCreate(TestQos):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.new_qos_spec.specs.update(
|
||||
{'consumer': self.new_qos_spec.consumer})
|
||||
{'consumer': self.new_qos_spec.consumer}
|
||||
)
|
||||
self.qos_mock.create.assert_called_with(
|
||||
self.new_qos_spec.name,
|
||||
self.new_qos_spec.specs
|
||||
self.new_qos_spec.name, self.new_qos_spec.specs
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
@ -159,24 +149,18 @@ class TestQosCreate(TestQos):
|
||||
|
||||
|
||||
class TestQosDelete(TestQos):
|
||||
|
||||
qos_specs = volume_fakes.create_qoses(count=2)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.qos_mock.get = (
|
||||
volume_fakes.get_qoses(self.qos_specs))
|
||||
self.qos_mock.get = volume_fakes.get_qoses(self.qos_specs)
|
||||
# Get the command object to test
|
||||
self.cmd = qos_specs.DeleteQos(self.app, None)
|
||||
|
||||
def test_qos_delete_with_id(self):
|
||||
arglist = [
|
||||
self.qos_specs[0].id
|
||||
]
|
||||
verifylist = [
|
||||
('qos_specs', [self.qos_specs[0].id])
|
||||
]
|
||||
arglist = [self.qos_specs[0].id]
|
||||
verifylist = [('qos_specs', [self.qos_specs[0].id])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
@ -185,12 +169,8 @@ class TestQosDelete(TestQos):
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_qos_delete_with_name(self):
|
||||
arglist = [
|
||||
self.qos_specs[0].name
|
||||
]
|
||||
verifylist = [
|
||||
('qos_specs', [self.qos_specs[0].name])
|
||||
]
|
||||
arglist = [self.qos_specs[0].name]
|
||||
verifylist = [('qos_specs', [self.qos_specs[0].name])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
@ -199,14 +179,8 @@ class TestQosDelete(TestQos):
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_qos_delete_with_force(self):
|
||||
arglist = [
|
||||
'--force',
|
||||
self.qos_specs[0].id
|
||||
]
|
||||
verifylist = [
|
||||
('force', True),
|
||||
('qos_specs', [self.qos_specs[0].id])
|
||||
]
|
||||
arglist = ['--force', self.qos_specs[0].id]
|
||||
verifylist = [('force', True), ('qos_specs', [self.qos_specs[0].id])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
@ -243,14 +217,16 @@ class TestQosDelete(TestQos):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
find_mock_result = [self.qos_specs[0], exceptions.CommandError]
|
||||
with mock.patch.object(utils, 'find_resource',
|
||||
side_effect=find_mock_result) as find_mock:
|
||||
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 QoS specifications failed to delete.', str(e))
|
||||
'1 of 2 QoS specifications failed to delete.', str(e)
|
||||
)
|
||||
|
||||
find_mock.assert_any_call(self.qos_mock, self.qos_specs[0].id)
|
||||
find_mock.assert_any_call(self.qos_mock, 'unexist_qos')
|
||||
@ -262,7 +238,6 @@ class TestQosDelete(TestQos):
|
||||
|
||||
|
||||
class TestQosDisassociate(TestQos):
|
||||
|
||||
volume_type = volume_fakes.create_one_volume_type()
|
||||
qos_spec = volume_fakes.create_one_qos()
|
||||
|
||||
@ -276,7 +251,8 @@ class TestQosDisassociate(TestQos):
|
||||
|
||||
def test_qos_disassociate_with_volume_type(self):
|
||||
arglist = [
|
||||
'--volume-type', self.volume_type.id,
|
||||
'--volume-type',
|
||||
self.volume_type.id,
|
||||
self.qos_spec.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -288,8 +264,7 @@ class TestQosDisassociate(TestQos):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.qos_mock.disassociate.assert_called_with(
|
||||
self.qos_spec.id,
|
||||
self.volume_type.id
|
||||
self.qos_spec.id, self.volume_type.id
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
@ -298,9 +273,7 @@ class TestQosDisassociate(TestQos):
|
||||
'--all',
|
||||
self.qos_spec.id,
|
||||
]
|
||||
verifylist = [
|
||||
('qos_spec', self.qos_spec.id)
|
||||
]
|
||||
verifylist = [('qos_spec', self.qos_spec.id)]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
@ -310,7 +283,6 @@ class TestQosDisassociate(TestQos):
|
||||
|
||||
|
||||
class TestQosList(TestQos):
|
||||
|
||||
qos_specs = volume_fakes.create_qoses(count=2)
|
||||
qos_association = volume_fakes.create_one_qos_association()
|
||||
|
||||
@ -323,13 +295,15 @@ class TestQosList(TestQos):
|
||||
)
|
||||
data = []
|
||||
for q in qos_specs:
|
||||
data.append((
|
||||
q.id,
|
||||
q.name,
|
||||
q.consumer,
|
||||
format_columns.ListColumn([qos_association.name]),
|
||||
format_columns.DictColumn(q.specs),
|
||||
))
|
||||
data.append(
|
||||
(
|
||||
q.id,
|
||||
q.name,
|
||||
q.consumer,
|
||||
format_columns.ListColumn([qos_association.name]),
|
||||
format_columns.DictColumn(q.specs),
|
||||
)
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@ -381,7 +355,6 @@ class TestQosList(TestQos):
|
||||
|
||||
|
||||
class TestQosSet(TestQos):
|
||||
|
||||
qos_spec = volume_fakes.create_one_qos()
|
||||
|
||||
def setUp(self):
|
||||
@ -393,8 +366,10 @@ class TestQosSet(TestQos):
|
||||
|
||||
def test_qos_set_with_properties_with_id(self):
|
||||
arglist = [
|
||||
'--property', 'foo=bar',
|
||||
'--property', 'iops=9001',
|
||||
'--property',
|
||||
'foo=bar',
|
||||
'--property',
|
||||
'iops=9001',
|
||||
self.qos_spec.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -406,14 +381,12 @@ class TestQosSet(TestQos):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.qos_mock.set_keys.assert_called_with(
|
||||
self.qos_spec.id,
|
||||
self.qos_spec.specs
|
||||
self.qos_spec.id, self.qos_spec.specs
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
||||
class TestQosShow(TestQos):
|
||||
|
||||
qos_spec = volume_fakes.create_one_qos()
|
||||
qos_association = volume_fakes.create_one_qos_association()
|
||||
|
||||
@ -425,27 +398,15 @@ class TestQosShow(TestQos):
|
||||
self.cmd = qos_specs.ShowQos(self.app, None)
|
||||
|
||||
def test_qos_show(self):
|
||||
arglist = [
|
||||
self.qos_spec.id
|
||||
]
|
||||
verifylist = [
|
||||
('qos_spec', self.qos_spec.id)
|
||||
]
|
||||
arglist = [self.qos_spec.id]
|
||||
verifylist = [('qos_spec', self.qos_spec.id)]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.qos_mock.get.assert_called_with(
|
||||
self.qos_spec.id
|
||||
)
|
||||
self.qos_mock.get.assert_called_with(self.qos_spec.id)
|
||||
|
||||
collist = (
|
||||
'associations',
|
||||
'consumer',
|
||||
'id',
|
||||
'name',
|
||||
'properties'
|
||||
)
|
||||
collist = ('associations', 'consumer', 'id', 'name', 'properties')
|
||||
self.assertEqual(collist, columns)
|
||||
datalist = (
|
||||
format_columns.ListColumn([self.qos_association.name]),
|
||||
@ -458,7 +419,6 @@ class TestQosShow(TestQos):
|
||||
|
||||
|
||||
class TestQosUnset(TestQos):
|
||||
|
||||
qos_spec = volume_fakes.create_one_qos()
|
||||
|
||||
def setUp(self):
|
||||
@ -470,8 +430,10 @@ class TestQosUnset(TestQos):
|
||||
|
||||
def test_qos_unset_with_properties(self):
|
||||
arglist = [
|
||||
'--property', 'iops',
|
||||
'--property', 'foo',
|
||||
'--property',
|
||||
'iops',
|
||||
'--property',
|
||||
'foo',
|
||||
self.qos_spec.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -483,8 +445,7 @@ class TestQosUnset(TestQos):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.qos_mock.unset_keys.assert_called_with(
|
||||
self.qos_spec.id,
|
||||
['iops', 'foo']
|
||||
self.qos_spec.id, ['iops', 'foo']
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
@ -19,7 +19,6 @@ from openstackclient.volume.v1 import service
|
||||
|
||||
|
||||
class TestService(volume_fakes.TestVolumev1):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -29,7 +28,6 @@ class TestService(volume_fakes.TestVolumev1):
|
||||
|
||||
|
||||
class TestServiceList(TestService):
|
||||
|
||||
# The service to be listed
|
||||
services = volume_fakes.create_one_service()
|
||||
|
||||
@ -43,8 +41,10 @@ class TestServiceList(TestService):
|
||||
|
||||
def test_service_list(self):
|
||||
arglist = [
|
||||
'--host', self.services.host,
|
||||
'--service', self.services.binary,
|
||||
'--host',
|
||||
self.services.host,
|
||||
'--service',
|
||||
self.services.binary,
|
||||
]
|
||||
verifylist = [
|
||||
('host', self.services.host),
|
||||
@ -69,14 +69,16 @@ class TestServiceList(TestService):
|
||||
# confirming if all expected columns are present in the result.
|
||||
self.assertEqual(expected_columns, columns)
|
||||
|
||||
datalist = ((
|
||||
self.services.binary,
|
||||
self.services.host,
|
||||
self.services.zone,
|
||||
self.services.status,
|
||||
self.services.state,
|
||||
self.services.updated_at,
|
||||
), )
|
||||
datalist = (
|
||||
(
|
||||
self.services.binary,
|
||||
self.services.host,
|
||||
self.services.zone,
|
||||
self.services.status,
|
||||
self.services.state,
|
||||
self.services.updated_at,
|
||||
),
|
||||
)
|
||||
|
||||
# confirming if all expected values are present in the result.
|
||||
self.assertEqual(datalist, tuple(data))
|
||||
@ -89,19 +91,20 @@ class TestServiceList(TestService):
|
||||
|
||||
# checking if prohibited columns are present in output
|
||||
self.assertNotIn("Disabled Reason", columns)
|
||||
self.assertNotIn(self.services.disabled_reason,
|
||||
tuple(data))
|
||||
self.assertNotIn(self.services.disabled_reason, tuple(data))
|
||||
|
||||
def test_service_list_with_long_option(self):
|
||||
arglist = [
|
||||
'--host', self.services.host,
|
||||
'--service', self.services.binary,
|
||||
'--long'
|
||||
'--host',
|
||||
self.services.host,
|
||||
'--service',
|
||||
self.services.binary,
|
||||
'--long',
|
||||
]
|
||||
verifylist = [
|
||||
('host', self.services.host),
|
||||
('service', self.services.binary),
|
||||
('long', True)
|
||||
('long', True),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
@ -117,21 +120,23 @@ class TestServiceList(TestService):
|
||||
'Status',
|
||||
'State',
|
||||
'Updated At',
|
||||
'Disabled Reason'
|
||||
'Disabled Reason',
|
||||
]
|
||||
|
||||
# confirming if all expected columns are present in the result.
|
||||
self.assertEqual(expected_columns, columns)
|
||||
|
||||
datalist = ((
|
||||
self.services.binary,
|
||||
self.services.host,
|
||||
self.services.zone,
|
||||
self.services.status,
|
||||
self.services.state,
|
||||
self.services.updated_at,
|
||||
self.services.disabled_reason,
|
||||
), )
|
||||
datalist = (
|
||||
(
|
||||
self.services.binary,
|
||||
self.services.host,
|
||||
self.services.zone,
|
||||
self.services.status,
|
||||
self.services.state,
|
||||
self.services.updated_at,
|
||||
self.services.disabled_reason,
|
||||
),
|
||||
)
|
||||
|
||||
# confirming if all expected values are present in the result.
|
||||
self.assertEqual(datalist, tuple(data))
|
||||
@ -143,7 +148,6 @@ class TestServiceList(TestService):
|
||||
|
||||
|
||||
class TestServiceSet(TestService):
|
||||
|
||||
service = volume_fakes.create_one_service()
|
||||
|
||||
def setUp(self):
|
||||
@ -188,8 +192,7 @@ class TestServiceSet(TestService):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.service_mock.enable.assert_called_with(
|
||||
self.service.host,
|
||||
self.service.binary
|
||||
self.service.host, self.service.binary
|
||||
)
|
||||
self.service_mock.disable.assert_not_called()
|
||||
self.service_mock.disable_log_reason.assert_not_called()
|
||||
@ -211,8 +214,7 @@ class TestServiceSet(TestService):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.service_mock.disable.assert_called_with(
|
||||
self.service.host,
|
||||
self.service.binary
|
||||
self.service.host, self.service.binary
|
||||
)
|
||||
self.service_mock.enable.assert_not_called()
|
||||
self.service_mock.disable_log_reason.assert_not_called()
|
||||
@ -222,7 +224,8 @@ class TestServiceSet(TestService):
|
||||
reason = 'earthquake'
|
||||
arglist = [
|
||||
'--disable',
|
||||
'--disable-reason', reason,
|
||||
'--disable-reason',
|
||||
reason,
|
||||
self.service.host,
|
||||
self.service.binary,
|
||||
]
|
||||
@ -237,16 +240,15 @@ class TestServiceSet(TestService):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.service_mock.disable_log_reason.assert_called_with(
|
||||
self.service.host,
|
||||
self.service.binary,
|
||||
reason
|
||||
self.service.host, self.service.binary, reason
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_service_set_only_with_disable_reason(self):
|
||||
reason = 'earthquake'
|
||||
arglist = [
|
||||
'--disable-reason', reason,
|
||||
'--disable-reason',
|
||||
reason,
|
||||
self.service.host,
|
||||
self.service.binary,
|
||||
]
|
||||
@ -260,14 +262,18 @@ class TestServiceSet(TestService):
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.fail("CommandError should be raised.")
|
||||
except exceptions.CommandError as e:
|
||||
self.assertEqual("Cannot specify option --disable-reason without "
|
||||
"--disable specified.", str(e))
|
||||
self.assertEqual(
|
||||
"Cannot specify option --disable-reason without "
|
||||
"--disable specified.",
|
||||
str(e),
|
||||
)
|
||||
|
||||
def test_service_set_enable_with_disable_reason(self):
|
||||
reason = 'earthquake'
|
||||
arglist = [
|
||||
'--enable',
|
||||
'--disable-reason', reason,
|
||||
'--disable-reason',
|
||||
reason,
|
||||
self.service.host,
|
||||
self.service.binary,
|
||||
]
|
||||
@ -282,5 +288,8 @@ class TestServiceSet(TestService):
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.fail("CommandError should be raised.")
|
||||
except exceptions.CommandError as e:
|
||||
self.assertEqual("Cannot specify option --disable-reason without "
|
||||
"--disable specified.", str(e))
|
||||
self.assertEqual(
|
||||
"Cannot specify option --disable-reason without "
|
||||
"--disable specified.",
|
||||
str(e),
|
||||
)
|
||||
|
@ -23,7 +23,6 @@ from openstackclient.volume.v1 import volume_transfer_request
|
||||
|
||||
|
||||
class TestTransfer(volume_fakes.TestVolumev1):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -37,7 +36,6 @@ class TestTransfer(volume_fakes.TestVolumev1):
|
||||
|
||||
|
||||
class TestTransferAccept(TestTransfer):
|
||||
|
||||
columns = (
|
||||
'id',
|
||||
'name',
|
||||
@ -59,11 +57,13 @@ class TestTransferAccept(TestTransfer):
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = volume_transfer_request.AcceptTransferRequest(
|
||||
self.app, None)
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_transfer_accept(self):
|
||||
arglist = [
|
||||
'--auth-key', 'key_value',
|
||||
'--auth-key',
|
||||
'key_value',
|
||||
self.volume_transfer.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -101,7 +101,6 @@ class TestTransferAccept(TestTransfer):
|
||||
|
||||
|
||||
class TestTransferCreate(TestTransfer):
|
||||
|
||||
volume = volume_fakes.create_one_volume()
|
||||
|
||||
columns = (
|
||||
@ -135,7 +134,8 @@ class TestTransferCreate(TestTransfer):
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = volume_transfer_request.CreateTransferRequest(
|
||||
self.app, None)
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_transfer_create_without_name(self):
|
||||
arglist = [
|
||||
@ -148,14 +148,14 @@ class TestTransferCreate(TestTransfer):
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.transfer_mock.create.assert_called_once_with(
|
||||
self.volume.id, None)
|
||||
self.transfer_mock.create.assert_called_once_with(self.volume.id, None)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
|
||||
def test_transfer_create_with_name(self):
|
||||
arglist = [
|
||||
'--name', self.volume_transfer.name,
|
||||
'--name',
|
||||
self.volume_transfer.name,
|
||||
self.volume.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -167,13 +167,14 @@ class TestTransferCreate(TestTransfer):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.transfer_mock.create.assert_called_once_with(
|
||||
self.volume.id, self.volume_transfer.name,)
|
||||
self.volume.id,
|
||||
self.volume_transfer.name,
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
|
||||
|
||||
class TestTransferDelete(TestTransfer):
|
||||
|
||||
volume_transfers = volume_fakes.create_transfers(count=2)
|
||||
|
||||
def setUp(self):
|
||||
@ -186,21 +187,19 @@ class TestTransferDelete(TestTransfer):
|
||||
|
||||
# Get the command object to mock
|
||||
self.cmd = volume_transfer_request.DeleteTransferRequest(
|
||||
self.app, None)
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_transfer_delete(self):
|
||||
arglist = [
|
||||
self.volume_transfers[0].id
|
||||
]
|
||||
verifylist = [
|
||||
("transfer_request", [self.volume_transfers[0].id])
|
||||
]
|
||||
arglist = [self.volume_transfers[0].id]
|
||||
verifylist = [("transfer_request", [self.volume_transfers[0].id])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.transfer_mock.delete.assert_called_with(
|
||||
self.volume_transfers[0].id)
|
||||
self.volume_transfers[0].id
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_delete_multiple_transfers(self):
|
||||
@ -232,17 +231,21 @@ class TestTransferDelete(TestTransfer):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
find_mock_result = [self.volume_transfers[0], exceptions.CommandError]
|
||||
with mock.patch.object(utils, 'find_resource',
|
||||
side_effect=find_mock_result) as find_mock:
|
||||
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 volume transfer requests failed '
|
||||
'to delete', str(e))
|
||||
self.assertEqual(
|
||||
'1 of 2 volume transfer requests failed ' 'to delete',
|
||||
str(e),
|
||||
)
|
||||
|
||||
find_mock.assert_any_call(
|
||||
self.transfer_mock, self.volume_transfers[0].id)
|
||||
self.transfer_mock, self.volume_transfers[0].id
|
||||
)
|
||||
find_mock.assert_any_call(self.transfer_mock, 'unexist_transfer')
|
||||
|
||||
self.assertEqual(2, find_mock.call_count)
|
||||
@ -252,7 +255,6 @@ class TestTransferDelete(TestTransfer):
|
||||
|
||||
|
||||
class TestTransferList(TestTransfer):
|
||||
|
||||
# The Transfers to be listed
|
||||
volume_transfers = volume_fakes.create_one_transfer()
|
||||
|
||||
@ -283,28 +285,25 @@ class TestTransferList(TestTransfer):
|
||||
# confirming if all expected columns are present in the result.
|
||||
self.assertEqual(expected_columns, columns)
|
||||
|
||||
datalist = ((
|
||||
self.volume_transfers.id,
|
||||
self.volume_transfers.name,
|
||||
self.volume_transfers.volume_id,
|
||||
), )
|
||||
datalist = (
|
||||
(
|
||||
self.volume_transfers.id,
|
||||
self.volume_transfers.name,
|
||||
self.volume_transfers.volume_id,
|
||||
),
|
||||
)
|
||||
|
||||
# confirming if all expected values are present in the result.
|
||||
self.assertEqual(datalist, tuple(data))
|
||||
|
||||
# checking if proper call was made to list volume_transfers
|
||||
self.transfer_mock.list.assert_called_with(
|
||||
detailed=True,
|
||||
search_opts={'all_tenants': 0}
|
||||
detailed=True, search_opts={'all_tenants': 0}
|
||||
)
|
||||
|
||||
def test_transfer_list_with_argument(self):
|
||||
arglist = [
|
||||
"--all-projects"
|
||||
]
|
||||
verifylist = [
|
||||
("all_projects", True)
|
||||
]
|
||||
arglist = ["--all-projects"]
|
||||
verifylist = [("all_projects", True)]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
@ -322,24 +321,24 @@ class TestTransferList(TestTransfer):
|
||||
# confirming if all expected columns are present in the result.
|
||||
self.assertEqual(expected_columns, columns)
|
||||
|
||||
datalist = ((
|
||||
self.volume_transfers.id,
|
||||
self.volume_transfers.name,
|
||||
self.volume_transfers.volume_id,
|
||||
), )
|
||||
datalist = (
|
||||
(
|
||||
self.volume_transfers.id,
|
||||
self.volume_transfers.name,
|
||||
self.volume_transfers.volume_id,
|
||||
),
|
||||
)
|
||||
|
||||
# confirming if all expected values are present in the result.
|
||||
self.assertEqual(datalist, tuple(data))
|
||||
|
||||
# checking if proper call was made to list volume_transfers
|
||||
self.transfer_mock.list.assert_called_with(
|
||||
detailed=True,
|
||||
search_opts={'all_tenants': 1}
|
||||
detailed=True, search_opts={'all_tenants': 1}
|
||||
)
|
||||
|
||||
|
||||
class TestTransferShow(TestTransfer):
|
||||
|
||||
columns = (
|
||||
'created_at',
|
||||
'id',
|
||||
@ -363,8 +362,7 @@ class TestTransferShow(TestTransfer):
|
||||
self.transfer_mock.get.return_value = self.volume_transfer
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = volume_transfer_request.ShowTransferRequest(
|
||||
self.app, None)
|
||||
self.cmd = volume_transfer_request.ShowTransferRequest(self.app, None)
|
||||
|
||||
def test_transfer_show(self):
|
||||
arglist = [
|
||||
@ -377,7 +375,6 @@ class TestTransferShow(TestTransfer):
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.transfer_mock.get.assert_called_once_with(
|
||||
self.volume_transfer.id)
|
||||
self.transfer_mock.get.assert_called_once_with(self.volume_transfer.id)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
|
@ -25,7 +25,6 @@ from openstackclient.volume.v1 import volume_type
|
||||
|
||||
|
||||
class TestType(volume_fakes.TestVolumev1):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -33,12 +32,12 @@ class TestType(volume_fakes.TestVolumev1):
|
||||
self.types_mock.reset_mock()
|
||||
|
||||
self.encryption_types_mock = (
|
||||
self.app.client_manager.volume.volume_encryption_types)
|
||||
self.app.client_manager.volume.volume_encryption_types
|
||||
)
|
||||
self.encryption_types_mock.reset_mock()
|
||||
|
||||
|
||||
class TestTypeCreate(TestType):
|
||||
|
||||
columns = (
|
||||
'description',
|
||||
'id',
|
||||
@ -110,10 +109,14 @@ class TestTypeCreate(TestType):
|
||||
self.new_volume_type.name,
|
||||
)
|
||||
arglist = [
|
||||
'--encryption-provider', 'LuksEncryptor',
|
||||
'--encryption-cipher', 'aes-xts-plain64',
|
||||
'--encryption-key-size', '128',
|
||||
'--encryption-control-location', 'front-end',
|
||||
'--encryption-provider',
|
||||
'LuksEncryptor',
|
||||
'--encryption-cipher',
|
||||
'aes-xts-plain64',
|
||||
'--encryption-key-size',
|
||||
'128',
|
||||
'--encryption-control-location',
|
||||
'front-end',
|
||||
self.new_volume_type.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -144,7 +147,6 @@ class TestTypeCreate(TestType):
|
||||
|
||||
|
||||
class TestTypeDelete(TestType):
|
||||
|
||||
volume_types = volume_fakes.create_volume_types(count=2)
|
||||
|
||||
def setUp(self):
|
||||
@ -157,12 +159,8 @@ class TestTypeDelete(TestType):
|
||||
self.cmd = volume_type.DeleteVolumeType(self.app, None)
|
||||
|
||||
def test_type_delete(self):
|
||||
arglist = [
|
||||
self.volume_types[0].id
|
||||
]
|
||||
verifylist = [
|
||||
("volume_types", [self.volume_types[0].id])
|
||||
]
|
||||
arglist = [self.volume_types[0].id]
|
||||
verifylist = [("volume_types", [self.volume_types[0].id])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
@ -199,17 +197,18 @@ class TestTypeDelete(TestType):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
find_mock_result = [self.volume_types[0], exceptions.CommandError]
|
||||
with mock.patch.object(utils, 'find_resource',
|
||||
side_effect=find_mock_result) as find_mock:
|
||||
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 volume types failed to delete.',
|
||||
str(e))
|
||||
self.assertEqual(
|
||||
'1 of 2 volume types failed to delete.', str(e)
|
||||
)
|
||||
|
||||
find_mock.assert_any_call(
|
||||
self.types_mock, self.volume_types[0].id)
|
||||
find_mock.assert_any_call(self.types_mock, self.volume_types[0].id)
|
||||
find_mock.assert_any_call(self.types_mock, 'unexist_type')
|
||||
|
||||
self.assertEqual(2, find_mock.call_count)
|
||||
@ -219,7 +218,6 @@ class TestTypeDelete(TestType):
|
||||
|
||||
|
||||
class TestTypeList(TestType):
|
||||
|
||||
volume_types = volume_fakes.create_volume_types()
|
||||
|
||||
columns = [
|
||||
@ -227,28 +225,27 @@ class TestTypeList(TestType):
|
||||
"Name",
|
||||
"Is Public",
|
||||
]
|
||||
columns_long = [
|
||||
"ID",
|
||||
"Name",
|
||||
"Is Public",
|
||||
"Properties"
|
||||
]
|
||||
columns_long = ["ID", "Name", "Is Public", "Properties"]
|
||||
|
||||
data = []
|
||||
for t in volume_types:
|
||||
data.append((
|
||||
t.id,
|
||||
t.name,
|
||||
t.is_public,
|
||||
))
|
||||
data.append(
|
||||
(
|
||||
t.id,
|
||||
t.name,
|
||||
t.is_public,
|
||||
)
|
||||
)
|
||||
data_long = []
|
||||
for t in volume_types:
|
||||
data_long.append((
|
||||
t.id,
|
||||
t.name,
|
||||
t.is_public,
|
||||
format_columns.DictColumn(t.extra_specs),
|
||||
))
|
||||
data_long.append(
|
||||
(
|
||||
t.id,
|
||||
t.name,
|
||||
t.is_public,
|
||||
format_columns.DictColumn(t.extra_specs),
|
||||
)
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@ -300,21 +297,25 @@ class TestTypeList(TestType):
|
||||
"Encryption",
|
||||
]
|
||||
encryption_data = []
|
||||
encryption_data.append((
|
||||
self.volume_types[0].id,
|
||||
self.volume_types[0].name,
|
||||
self.volume_types[0].is_public,
|
||||
volume_type.EncryptionInfoColumn(
|
||||
encryption_data.append(
|
||||
(
|
||||
self.volume_types[0].id,
|
||||
{self.volume_types[0].id: encryption_info}),
|
||||
))
|
||||
encryption_data.append((
|
||||
self.volume_types[1].id,
|
||||
self.volume_types[1].name,
|
||||
self.volume_types[1].is_public,
|
||||
volume_type.EncryptionInfoColumn(
|
||||
self.volume_types[1].id, {}),
|
||||
))
|
||||
self.volume_types[0].name,
|
||||
self.volume_types[0].is_public,
|
||||
volume_type.EncryptionInfoColumn(
|
||||
self.volume_types[0].id,
|
||||
{self.volume_types[0].id: encryption_info},
|
||||
),
|
||||
)
|
||||
)
|
||||
encryption_data.append(
|
||||
(
|
||||
self.volume_types[1].id,
|
||||
self.volume_types[1].name,
|
||||
self.volume_types[1].is_public,
|
||||
volume_type.EncryptionInfoColumn(self.volume_types[1].id, {}),
|
||||
)
|
||||
)
|
||||
|
||||
self.encryption_types_mock.list.return_value = [encryption_type]
|
||||
arglist = [
|
||||
@ -333,7 +334,6 @@ class TestTypeList(TestType):
|
||||
|
||||
|
||||
class TestTypeSet(TestType):
|
||||
|
||||
volume_type = volume_fakes.create_one_volume_type(
|
||||
methods={'set_keys': None},
|
||||
)
|
||||
@ -361,7 +361,8 @@ class TestTypeSet(TestType):
|
||||
|
||||
def test_type_set_property(self):
|
||||
arglist = [
|
||||
'--property', 'myprop=myvalue',
|
||||
'--property',
|
||||
'myprop=myvalue',
|
||||
self.volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -372,15 +373,20 @@ class TestTypeSet(TestType):
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.volume_type.set_keys.assert_called_once_with(
|
||||
{'myprop': 'myvalue'})
|
||||
{'myprop': 'myvalue'}
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_type_set_new_encryption(self):
|
||||
arglist = [
|
||||
'--encryption-provider', 'LuksEncryptor',
|
||||
'--encryption-cipher', 'aes-xts-plain64',
|
||||
'--encryption-key-size', '128',
|
||||
'--encryption-control-location', 'front-end',
|
||||
'--encryption-provider',
|
||||
'LuksEncryptor',
|
||||
'--encryption-cipher',
|
||||
'aes-xts-plain64',
|
||||
'--encryption-key-size',
|
||||
'128',
|
||||
'--encryption-control-location',
|
||||
'front-end',
|
||||
self.volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -407,9 +413,12 @@ class TestTypeSet(TestType):
|
||||
|
||||
def test_type_set_new_encryption_without_provider(self):
|
||||
arglist = [
|
||||
'--encryption-cipher', 'aes-xts-plain64',
|
||||
'--encryption-key-size', '128',
|
||||
'--encryption-control-location', 'front-end',
|
||||
'--encryption-cipher',
|
||||
'aes-xts-plain64',
|
||||
'--encryption-key-size',
|
||||
'128',
|
||||
'--encryption-control-location',
|
||||
'front-end',
|
||||
self.volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -423,15 +432,15 @@ class TestTypeSet(TestType):
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.fail('CommandError should be raised.')
|
||||
except exceptions.CommandError as e:
|
||||
self.assertEqual("Command Failed: One or more of"
|
||||
" the operations failed",
|
||||
str(e))
|
||||
self.assertEqual(
|
||||
"Command Failed: One or more of" " the operations failed",
|
||||
str(e),
|
||||
)
|
||||
self.encryption_types_mock.create.assert_not_called()
|
||||
self.encryption_types_mock.update.assert_not_called()
|
||||
|
||||
|
||||
class TestTypeShow(TestType):
|
||||
|
||||
columns = (
|
||||
'description',
|
||||
'id',
|
||||
@ -449,7 +458,7 @@ class TestTypeShow(TestType):
|
||||
self.volume_type.id,
|
||||
True,
|
||||
self.volume_type.name,
|
||||
format_columns.DictColumn(self.volume_type.extra_specs)
|
||||
format_columns.DictColumn(self.volume_type.extra_specs),
|
||||
)
|
||||
|
||||
self.types_mock.get.return_value = self.volume_type
|
||||
@ -458,9 +467,7 @@ class TestTypeShow(TestType):
|
||||
self.cmd = volume_type.ShowVolumeType(self.app, None)
|
||||
|
||||
def test_type_show(self):
|
||||
arglist = [
|
||||
self.volume_type.id
|
||||
]
|
||||
arglist = [self.volume_type.id]
|
||||
verifylist = [
|
||||
("volume_type", self.volume_type.id),
|
||||
("encryption_type", False),
|
||||
@ -500,15 +507,12 @@ class TestTypeShow(TestType):
|
||||
self.volume_type.id,
|
||||
True,
|
||||
self.volume_type.name,
|
||||
format_columns.DictColumn(self.volume_type.extra_specs)
|
||||
format_columns.DictColumn(self.volume_type.extra_specs),
|
||||
)
|
||||
arglist = [
|
||||
'--encryption-type',
|
||||
self.volume_type.id
|
||||
]
|
||||
arglist = ['--encryption-type', self.volume_type.id]
|
||||
verifylist = [
|
||||
('encryption_type', True),
|
||||
("volume_type", self.volume_type.id)
|
||||
("volume_type", self.volume_type.id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
@ -520,7 +524,6 @@ class TestTypeShow(TestType):
|
||||
|
||||
|
||||
class TestTypeUnset(TestType):
|
||||
|
||||
volume_type = volume_fakes.create_one_volume_type(
|
||||
methods={'unset_keys': None},
|
||||
)
|
||||
@ -535,8 +538,10 @@ class TestTypeUnset(TestType):
|
||||
|
||||
def test_type_unset_property(self):
|
||||
arglist = [
|
||||
'--property', 'property',
|
||||
'--property', 'multi_property',
|
||||
'--property',
|
||||
'property',
|
||||
'--property',
|
||||
'multi_property',
|
||||
self.volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -549,24 +554,29 @@ class TestTypeUnset(TestType):
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.volume_type.unset_keys.assert_called_once_with(
|
||||
['property', 'multi_property'])
|
||||
['property', 'multi_property']
|
||||
)
|
||||
self.encryption_types_mock.delete.assert_not_called()
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_type_unset_failed_with_missing_volume_type_argument(self):
|
||||
arglist = [
|
||||
'--property', 'property',
|
||||
'--property', 'multi_property',
|
||||
'--property',
|
||||
'property',
|
||||
'--property',
|
||||
'multi_property',
|
||||
]
|
||||
verifylist = [
|
||||
('property', ['property', 'multi_property']),
|
||||
]
|
||||
|
||||
self.assertRaises(tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist)
|
||||
self.assertRaises(
|
||||
tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist,
|
||||
)
|
||||
|
||||
def test_type_unset_nothing(self):
|
||||
arglist = [
|
||||
@ -598,7 +608,6 @@ class TestTypeUnset(TestType):
|
||||
|
||||
|
||||
class TestColumns(TestType):
|
||||
|
||||
def test_encryption_info_column_with_info(self):
|
||||
fake_volume_type = volume_fakes.create_one_volume_type()
|
||||
type_id = fake_volume_type.id
|
||||
@ -609,10 +618,12 @@ class TestColumns(TestType):
|
||||
'key_size': None,
|
||||
'control_location': 'front-end',
|
||||
}
|
||||
col = volume_type.EncryptionInfoColumn(type_id,
|
||||
{type_id: encryption_info})
|
||||
self.assertEqual(utils.format_dict(encryption_info),
|
||||
col.human_readable())
|
||||
col = volume_type.EncryptionInfoColumn(
|
||||
type_id, {type_id: encryption_info}
|
||||
)
|
||||
self.assertEqual(
|
||||
utils.format_dict(encryption_info), col.human_readable()
|
||||
)
|
||||
self.assertEqual(encryption_info, col.machine_readable())
|
||||
|
||||
def test_encryption_info_column_without_info(self):
|
||||
|
@ -29,7 +29,6 @@ from openstackclient.volume.v1 import volume
|
||||
|
||||
|
||||
class TestVolume(volume_fakes.TestVolumev1):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -57,7 +56,6 @@ class TestVolume(volume_fakes.TestVolumev1):
|
||||
|
||||
|
||||
class TestVolumeCreate(TestVolume):
|
||||
|
||||
project = identity_fakes.FakeProject.create_one_project()
|
||||
user = identity_fakes.FakeUser.create_one_user()
|
||||
|
||||
@ -100,7 +98,8 @@ class TestVolumeCreate(TestVolume):
|
||||
|
||||
def test_volume_create_min_options(self):
|
||||
arglist = [
|
||||
'--size', str(self.new_volume.size),
|
||||
'--size',
|
||||
str(self.new_volume.size),
|
||||
self.new_volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -137,10 +136,14 @@ class TestVolumeCreate(TestVolume):
|
||||
|
||||
def test_volume_create_options(self):
|
||||
arglist = [
|
||||
'--size', str(self.new_volume.size),
|
||||
'--description', self.new_volume.display_description,
|
||||
'--type', self.new_volume.volume_type,
|
||||
'--availability-zone', self.new_volume.availability_zone,
|
||||
'--size',
|
||||
str(self.new_volume.size),
|
||||
'--description',
|
||||
self.new_volume.display_description,
|
||||
'--type',
|
||||
self.new_volume.volume_type,
|
||||
'--availability-zone',
|
||||
self.new_volume.availability_zone,
|
||||
self.new_volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -186,9 +189,12 @@ class TestVolumeCreate(TestVolume):
|
||||
self.users_mock.get.return_value = self.user
|
||||
|
||||
arglist = [
|
||||
'--size', str(self.new_volume.size),
|
||||
'--project', self.project.id,
|
||||
'--user', self.user.id,
|
||||
'--size',
|
||||
str(self.new_volume.size),
|
||||
'--project',
|
||||
self.project.id,
|
||||
'--user',
|
||||
self.user.id,
|
||||
self.new_volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -233,9 +239,12 @@ class TestVolumeCreate(TestVolume):
|
||||
self.users_mock.get.return_value = self.user
|
||||
|
||||
arglist = [
|
||||
'--size', str(self.new_volume.size),
|
||||
'--project', self.project.name,
|
||||
'--user', self.user.name,
|
||||
'--size',
|
||||
str(self.new_volume.size),
|
||||
'--project',
|
||||
self.project.name,
|
||||
'--user',
|
||||
self.user.name,
|
||||
self.new_volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -275,9 +284,12 @@ class TestVolumeCreate(TestVolume):
|
||||
|
||||
def test_volume_create_properties(self):
|
||||
arglist = [
|
||||
'--property', 'Alpha=a',
|
||||
'--property', 'Beta=b',
|
||||
'--size', str(self.new_volume.size),
|
||||
'--property',
|
||||
'Alpha=a',
|
||||
'--property',
|
||||
'Beta=b',
|
||||
'--size',
|
||||
str(self.new_volume.size),
|
||||
self.new_volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -319,8 +331,10 @@ class TestVolumeCreate(TestVolume):
|
||||
self.images_mock.get.return_value = image
|
||||
|
||||
arglist = [
|
||||
'--image', image.id,
|
||||
'--size', str(self.new_volume.size),
|
||||
'--image',
|
||||
image.id,
|
||||
'--size',
|
||||
str(self.new_volume.size),
|
||||
self.new_volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -362,8 +376,10 @@ class TestVolumeCreate(TestVolume):
|
||||
self.images_mock.get.return_value = image
|
||||
|
||||
arglist = [
|
||||
'--image', image.name,
|
||||
'--size', str(self.new_volume.size),
|
||||
'--image',
|
||||
image.name,
|
||||
'--size',
|
||||
str(self.new_volume.size),
|
||||
self.new_volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -403,7 +419,8 @@ class TestVolumeCreate(TestVolume):
|
||||
def test_volume_create_with_source(self):
|
||||
self.volumes_mock.get.return_value = self.new_volume
|
||||
arglist = [
|
||||
'--source', self.new_volume.id,
|
||||
'--source',
|
||||
self.new_volume.id,
|
||||
self.new_volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -435,7 +452,8 @@ class TestVolumeCreate(TestVolume):
|
||||
arglist = [
|
||||
'--bootable',
|
||||
'--read-only',
|
||||
'--size', str(self.new_volume.size),
|
||||
'--size',
|
||||
str(self.new_volume.size),
|
||||
self.new_volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -447,8 +465,7 @@ class TestVolumeCreate(TestVolume):
|
||||
('name', self.new_volume.display_name),
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(
|
||||
self.cmd, arglist, verifylist)
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
@ -469,16 +486,19 @@ class TestVolumeCreate(TestVolume):
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.datalist, data)
|
||||
self.volumes_mock.set_bootable.assert_called_with(
|
||||
self.new_volume.id, True)
|
||||
self.new_volume.id, True
|
||||
)
|
||||
self.volumes_mock.update_readonly_flag.assert_called_with(
|
||||
self.new_volume.id, True)
|
||||
self.new_volume.id, True
|
||||
)
|
||||
|
||||
@mock.patch.object(utils, 'wait_for_status', return_value=True)
|
||||
def test_volume_create_with_nonbootable_and_readwrite(self, mock_wait):
|
||||
arglist = [
|
||||
'--non-bootable',
|
||||
'--read-write',
|
||||
'--size', str(self.new_volume.size),
|
||||
'--size',
|
||||
str(self.new_volume.size),
|
||||
self.new_volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -490,8 +510,7 @@ class TestVolumeCreate(TestVolume):
|
||||
('name', self.new_volume.display_name),
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(
|
||||
self.cmd, arglist, verifylist)
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
@ -512,25 +531,28 @@ class TestVolumeCreate(TestVolume):
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.datalist, data)
|
||||
self.volumes_mock.set_bootable.assert_called_with(
|
||||
self.new_volume.id, False)
|
||||
self.new_volume.id, False
|
||||
)
|
||||
self.volumes_mock.update_readonly_flag.assert_called_with(
|
||||
self.new_volume.id, False)
|
||||
self.new_volume.id, False
|
||||
)
|
||||
|
||||
@mock.patch.object(volume.LOG, 'error')
|
||||
@mock.patch.object(utils, 'wait_for_status', return_value=True)
|
||||
def test_volume_create_with_bootable_and_readonly_fail(
|
||||
self, mock_wait, mock_error):
|
||||
|
||||
self.volumes_mock.set_bootable.side_effect = (
|
||||
exceptions.CommandError())
|
||||
self, mock_wait, mock_error
|
||||
):
|
||||
self.volumes_mock.set_bootable.side_effect = exceptions.CommandError()
|
||||
|
||||
self.volumes_mock.update_readonly_flag.side_effect = (
|
||||
exceptions.CommandError())
|
||||
exceptions.CommandError()
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--bootable',
|
||||
'--read-only',
|
||||
'--size', str(self.new_volume.size),
|
||||
'--size',
|
||||
str(self.new_volume.size),
|
||||
self.new_volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -542,8 +564,7 @@ class TestVolumeCreate(TestVolume):
|
||||
('name', self.new_volume.display_name),
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(
|
||||
self.cmd, arglist, verifylist)
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
@ -565,18 +586,22 @@ class TestVolumeCreate(TestVolume):
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.datalist, data)
|
||||
self.volumes_mock.set_bootable.assert_called_with(
|
||||
self.new_volume.id, True)
|
||||
self.new_volume.id, True
|
||||
)
|
||||
self.volumes_mock.update_readonly_flag.assert_called_with(
|
||||
self.new_volume.id, True)
|
||||
self.new_volume.id, True
|
||||
)
|
||||
|
||||
@mock.patch.object(volume.LOG, 'error')
|
||||
@mock.patch.object(utils, 'wait_for_status', return_value=False)
|
||||
def test_volume_create_non_available_with_readonly(
|
||||
self, mock_wait, mock_error):
|
||||
self, mock_wait, mock_error
|
||||
):
|
||||
arglist = [
|
||||
'--non-bootable',
|
||||
'--read-only',
|
||||
'--size', str(self.new_volume.size),
|
||||
'--size',
|
||||
str(self.new_volume.size),
|
||||
self.new_volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -588,8 +613,7 @@ class TestVolumeCreate(TestVolume):
|
||||
('name', self.new_volume.display_name),
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(
|
||||
self.cmd, arglist, verifylist)
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
@ -620,15 +644,20 @@ class TestVolumeCreate(TestVolume):
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
||||
parsed_args)
|
||||
self.assertRaises(
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
|
||||
def test_volume_create_with_multi_source(self):
|
||||
arglist = [
|
||||
'--image', 'source_image',
|
||||
'--source', 'source_volume',
|
||||
'--snapshot', 'source_snapshot',
|
||||
'--size', str(self.new_volume.size),
|
||||
'--image',
|
||||
'source_image',
|
||||
'--source',
|
||||
'source_volume',
|
||||
'--snapshot',
|
||||
'source_snapshot',
|
||||
'--size',
|
||||
str(self.new_volume.size),
|
||||
self.new_volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -639,13 +668,20 @@ class TestVolumeCreate(TestVolume):
|
||||
('name', self.new_volume.display_name),
|
||||
]
|
||||
|
||||
self.assertRaises(tests_utils.ParserException, self.check_parser,
|
||||
self.cmd, arglist, verifylist)
|
||||
self.assertRaises(
|
||||
tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist,
|
||||
)
|
||||
|
||||
def test_volume_create_backward_compatibility(self):
|
||||
arglist = [
|
||||
'-c', 'display_name',
|
||||
'--size', str(self.new_volume.size),
|
||||
'-c',
|
||||
'display_name',
|
||||
'--size',
|
||||
str(self.new_volume.size),
|
||||
self.new_volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -676,7 +712,6 @@ class TestVolumeCreate(TestVolume):
|
||||
|
||||
|
||||
class TestVolumeDelete(TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -688,9 +723,7 @@ class TestVolumeDelete(TestVolume):
|
||||
def test_volume_delete_one_volume(self):
|
||||
volumes = self.setup_volumes_mock(count=1)
|
||||
|
||||
arglist = [
|
||||
volumes[0].id
|
||||
]
|
||||
arglist = [volumes[0].id]
|
||||
verifylist = [
|
||||
("force", False),
|
||||
("volumes", [volumes[0].id]),
|
||||
@ -732,14 +765,14 @@ class TestVolumeDelete(TestVolume):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
find_mock_result = [volumes[0], exceptions.CommandError]
|
||||
with mock.patch.object(utils, 'find_resource',
|
||||
side_effect=find_mock_result) as find_mock:
|
||||
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 volumes failed to delete.',
|
||||
str(e))
|
||||
self.assertEqual('1 of 2 volumes failed to delete.', str(e))
|
||||
|
||||
find_mock.assert_any_call(self.volumes_mock, volumes[0].id)
|
||||
find_mock.assert_any_call(self.volumes_mock, 'unexist_volume')
|
||||
@ -767,7 +800,6 @@ class TestVolumeDelete(TestVolume):
|
||||
|
||||
|
||||
class TestVolumeList(TestVolume):
|
||||
|
||||
_volume = volume_fakes.create_one_volume()
|
||||
columns = (
|
||||
'ID',
|
||||
@ -812,7 +844,8 @@ class TestVolumeList(TestVolume):
|
||||
|
||||
def test_volume_list_name(self):
|
||||
arglist = [
|
||||
'--name', self._volume.display_name,
|
||||
'--name',
|
||||
self._volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
('long', False),
|
||||
@ -829,7 +862,8 @@ class TestVolumeList(TestVolume):
|
||||
|
||||
def test_volume_list_status(self):
|
||||
arglist = [
|
||||
'--status', self._volume.status,
|
||||
'--status',
|
||||
self._volume.status,
|
||||
]
|
||||
verifylist = [
|
||||
('long', False),
|
||||
@ -889,22 +923,26 @@ class TestVolumeList(TestVolume):
|
||||
)
|
||||
self.assertEqual(collist, columns)
|
||||
|
||||
datalist = ((
|
||||
self._volume.id,
|
||||
self._volume.display_name,
|
||||
self._volume.status,
|
||||
self._volume.size,
|
||||
self._volume.volume_type,
|
||||
self._volume.bootable,
|
||||
volume.AttachmentsColumn(self._volume.attachments),
|
||||
format_columns.DictColumn(self._volume.metadata),
|
||||
), )
|
||||
datalist = (
|
||||
(
|
||||
self._volume.id,
|
||||
self._volume.display_name,
|
||||
self._volume.status,
|
||||
self._volume.size,
|
||||
self._volume.volume_type,
|
||||
self._volume.bootable,
|
||||
volume.AttachmentsColumn(self._volume.attachments),
|
||||
format_columns.DictColumn(self._volume.metadata),
|
||||
),
|
||||
)
|
||||
self.assertCountEqual(datalist, tuple(data))
|
||||
|
||||
def test_volume_list_with_limit_and_offset(self):
|
||||
arglist = [
|
||||
'--limit', '2',
|
||||
'--offset', '5',
|
||||
'--limit',
|
||||
'2',
|
||||
'--offset',
|
||||
'5',
|
||||
]
|
||||
verifylist = [
|
||||
('long', False),
|
||||
@ -932,17 +970,24 @@ class TestVolumeList(TestVolume):
|
||||
|
||||
def test_volume_list_negative_limit(self):
|
||||
arglist = [
|
||||
"--limit", "-2",
|
||||
"--limit",
|
||||
"-2",
|
||||
]
|
||||
verifylist = [
|
||||
("limit", -2),
|
||||
]
|
||||
self.assertRaises(argparse.ArgumentTypeError, self.check_parser,
|
||||
self.cmd, arglist, verifylist)
|
||||
self.assertRaises(
|
||||
argparse.ArgumentTypeError,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist,
|
||||
)
|
||||
|
||||
def test_volume_list_backward_compatibility(self):
|
||||
arglist = [
|
||||
'-c', 'Display Name',
|
||||
'-c',
|
||||
'Display Name',
|
||||
]
|
||||
verifylist = [
|
||||
('columns', ['Display Name']),
|
||||
@ -963,7 +1008,6 @@ class TestVolumeList(TestVolume):
|
||||
|
||||
|
||||
class TestVolumeMigrate(TestVolume):
|
||||
|
||||
_volume = volume_fakes.create_one_volume()
|
||||
|
||||
def setUp(self):
|
||||
@ -976,7 +1020,8 @@ class TestVolumeMigrate(TestVolume):
|
||||
|
||||
def test_volume_migrate(self):
|
||||
arglist = [
|
||||
"--host", "host@backend-name#pool",
|
||||
"--host",
|
||||
"host@backend-name#pool",
|
||||
self._volume.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -989,13 +1034,15 @@ class TestVolumeMigrate(TestVolume):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.volumes_mock.get.assert_called_once_with(self._volume.id)
|
||||
self.volumes_mock.migrate_volume.assert_called_once_with(
|
||||
self._volume.id, "host@backend-name#pool", False)
|
||||
self._volume.id, "host@backend-name#pool", False
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_volume_migrate_with_option(self):
|
||||
arglist = [
|
||||
"--force-host-copy",
|
||||
"--host", "host@backend-name#pool",
|
||||
"--host",
|
||||
"host@backend-name#pool",
|
||||
self._volume.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -1008,7 +1055,8 @@ class TestVolumeMigrate(TestVolume):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.volumes_mock.get.assert_called_once_with(self._volume.id)
|
||||
self.volumes_mock.migrate_volume.assert_called_once_with(
|
||||
self._volume.id, "host@backend-name#pool", True)
|
||||
self._volume.id, "host@backend-name#pool", True
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_volume_migrate_without_host(self):
|
||||
@ -1020,12 +1068,16 @@ class TestVolumeMigrate(TestVolume):
|
||||
("volume", self._volume.id),
|
||||
]
|
||||
|
||||
self.assertRaises(tests_utils.ParserException, self.check_parser,
|
||||
self.cmd, arglist, verifylist)
|
||||
self.assertRaises(
|
||||
tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist,
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeSet(TestVolume):
|
||||
|
||||
_volume = volume_fakes.create_one_volume()
|
||||
|
||||
def setUp(self):
|
||||
@ -1055,7 +1107,8 @@ class TestVolumeSet(TestVolume):
|
||||
|
||||
def test_volume_set_name(self):
|
||||
arglist = [
|
||||
'--name', 'qwerty',
|
||||
'--name',
|
||||
'qwerty',
|
||||
self._volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -1073,15 +1126,13 @@ class TestVolumeSet(TestVolume):
|
||||
kwargs = {
|
||||
'display_name': 'qwerty',
|
||||
}
|
||||
self.volumes_mock.update.assert_called_with(
|
||||
self._volume.id,
|
||||
**kwargs
|
||||
)
|
||||
self.volumes_mock.update.assert_called_with(self._volume.id, **kwargs)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_volume_set_description(self):
|
||||
arglist = [
|
||||
'--description', 'new desc',
|
||||
'--description',
|
||||
'new desc',
|
||||
self._volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -1099,15 +1150,13 @@ class TestVolumeSet(TestVolume):
|
||||
kwargs = {
|
||||
'display_description': 'new desc',
|
||||
}
|
||||
self.volumes_mock.update.assert_called_with(
|
||||
self._volume.id,
|
||||
**kwargs
|
||||
)
|
||||
self.volumes_mock.update.assert_called_with(self._volume.id, **kwargs)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_volume_set_size(self):
|
||||
arglist = [
|
||||
'--size', '130',
|
||||
'--size',
|
||||
'130',
|
||||
self._volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -1123,16 +1172,14 @@ class TestVolumeSet(TestVolume):
|
||||
|
||||
# Set expected values
|
||||
size = 130
|
||||
self.volumes_mock.extend.assert_called_with(
|
||||
self._volume.id,
|
||||
size
|
||||
)
|
||||
self.volumes_mock.extend.assert_called_with(self._volume.id, size)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_volume_set_size_smaller(self):
|
||||
self._volume.status = 'available'
|
||||
arglist = [
|
||||
'--size', '1',
|
||||
'--size',
|
||||
'1',
|
||||
self._volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -1144,14 +1191,15 @@ class TestVolumeSet(TestVolume):
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
self.assertRaises(
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
|
||||
def test_volume_set_size_not_available(self):
|
||||
self._volume.status = 'error'
|
||||
arglist = [
|
||||
'--size', '130',
|
||||
'--size',
|
||||
'130',
|
||||
self._volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -1163,14 +1211,15 @@ class TestVolumeSet(TestVolume):
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
self.assertRaises(
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
|
||||
def test_volume_set_property(self):
|
||||
arglist = [
|
||||
'--no-property',
|
||||
'--property', 'myprop=myvalue',
|
||||
'--property',
|
||||
'myprop=myvalue',
|
||||
self._volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -1183,23 +1232,19 @@ class TestVolumeSet(TestVolume):
|
||||
('property', {'myprop': 'myvalue'}),
|
||||
('volume', self._volume.display_name),
|
||||
('bootable', False),
|
||||
('non_bootable', False)
|
||||
('non_bootable', False),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
# Set expected values
|
||||
metadata = {
|
||||
'myprop': 'myvalue'
|
||||
}
|
||||
metadata = {'myprop': 'myvalue'}
|
||||
self.volumes_mock.set_metadata.assert_called_with(
|
||||
self._volume.id,
|
||||
metadata
|
||||
self._volume.id, metadata
|
||||
)
|
||||
self.volumes_mock.delete_metadata.assert_called_with(
|
||||
self._volume.id,
|
||||
self._volume.metadata.keys()
|
||||
self._volume.id, self._volume.metadata.keys()
|
||||
)
|
||||
self.volumes_mock.update_readonly_flag.assert_not_called()
|
||||
self.assertIsNone(result)
|
||||
@ -1207,69 +1252,64 @@ class TestVolumeSet(TestVolume):
|
||||
def test_volume_set_bootable(self):
|
||||
arglist = [
|
||||
['--bootable', self._volume.id],
|
||||
['--non-bootable', self._volume.id]
|
||||
['--non-bootable', self._volume.id],
|
||||
]
|
||||
verifylist = [
|
||||
[
|
||||
('bootable', True),
|
||||
('non_bootable', False),
|
||||
('volume', self._volume.id)
|
||||
('volume', self._volume.id),
|
||||
],
|
||||
[
|
||||
('bootable', False),
|
||||
('non_bootable', True),
|
||||
('volume', self._volume.id)
|
||||
]
|
||||
('volume', self._volume.id),
|
||||
],
|
||||
]
|
||||
for index in range(len(arglist)):
|
||||
parsed_args = self.check_parser(
|
||||
self.cmd, arglist[index], verifylist[index])
|
||||
self.cmd, arglist[index], verifylist[index]
|
||||
)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.volumes_mock.set_bootable.assert_called_with(
|
||||
self._volume.id, verifylist[index][0][1])
|
||||
self._volume.id, verifylist[index][0][1]
|
||||
)
|
||||
|
||||
def test_volume_set_readonly(self):
|
||||
arglist = [
|
||||
'--read-only',
|
||||
self._volume.id
|
||||
]
|
||||
arglist = ['--read-only', self._volume.id]
|
||||
verifylist = [
|
||||
('read_only', True),
|
||||
('read_write', False),
|
||||
('volume', self._volume.id)
|
||||
('volume', self._volume.id),
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.volumes_mock.update_readonly_flag.assert_called_once_with(
|
||||
self._volume.id,
|
||||
True)
|
||||
self._volume.id, True
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_volume_set_read_write(self):
|
||||
arglist = [
|
||||
'--read-write',
|
||||
self._volume.id
|
||||
]
|
||||
arglist = ['--read-write', self._volume.id]
|
||||
verifylist = [
|
||||
('read_only', False),
|
||||
('read_write', True),
|
||||
('volume', self._volume.id)
|
||||
('volume', self._volume.id),
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.volumes_mock.update_readonly_flag.assert_called_once_with(
|
||||
self._volume.id,
|
||||
False)
|
||||
self._volume.id, False
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
||||
class TestVolumeShow(TestVolume):
|
||||
|
||||
columns = (
|
||||
'attachments',
|
||||
'availability_zone',
|
||||
@ -1307,12 +1347,8 @@ class TestVolumeShow(TestVolume):
|
||||
self.cmd = volume.ShowVolume(self.app, None)
|
||||
|
||||
def test_volume_show(self):
|
||||
arglist = [
|
||||
self._volume.id
|
||||
]
|
||||
verifylist = [
|
||||
("volume", self._volume.id)
|
||||
]
|
||||
arglist = [self._volume.id]
|
||||
verifylist = [("volume", self._volume.id)]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
@ -1323,7 +1359,8 @@ class TestVolumeShow(TestVolume):
|
||||
|
||||
def test_volume_show_backward_compatibility(self):
|
||||
arglist = [
|
||||
'-c', 'display_name',
|
||||
'-c',
|
||||
'display_name',
|
||||
self._volume.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -1342,7 +1379,6 @@ class TestVolumeShow(TestVolume):
|
||||
|
||||
|
||||
class TestVolumeUnset(TestVolume):
|
||||
|
||||
_volume = volume_fakes.create_one_volume()
|
||||
|
||||
def setUp(self):
|
||||
@ -1369,7 +1405,8 @@ class TestVolumeUnset(TestVolume):
|
||||
|
||||
def test_volume_unset_property(self):
|
||||
arglist = [
|
||||
'--property', 'myprop',
|
||||
'--property',
|
||||
'myprop',
|
||||
self._volume.display_name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -1387,15 +1424,15 @@ class TestVolumeUnset(TestVolume):
|
||||
|
||||
|
||||
class TestColumns(TestVolume):
|
||||
|
||||
def test_attachments_column_without_server_cache(self):
|
||||
_volume = volume_fakes.create_one_volume()
|
||||
server_id = _volume.attachments[0]['server_id']
|
||||
device = _volume.attachments[0]['device']
|
||||
|
||||
col = volume.AttachmentsColumn(_volume.attachments, {})
|
||||
self.assertEqual('Attached to %s on %s ' % (server_id, device),
|
||||
col.human_readable())
|
||||
self.assertEqual(
|
||||
'Attached to %s on %s ' % (server_id, device), col.human_readable()
|
||||
)
|
||||
self.assertEqual(_volume.attachments, col.machine_readable())
|
||||
|
||||
def test_attachments_column_with_server_cache(self):
|
||||
@ -1410,5 +1447,6 @@ class TestColumns(TestVolume):
|
||||
col = volume.AttachmentsColumn(_volume.attachments, server_cache)
|
||||
self.assertEqual(
|
||||
'Attached to %s on %s ' % ('fake-server-name', device),
|
||||
col.human_readable())
|
||||
col.human_readable(),
|
||||
)
|
||||
self.assertEqual(_volume.attachments, col.machine_readable())
|
||||
|
@ -23,7 +23,6 @@ from openstackclient.volume.v1 import volume_backup
|
||||
|
||||
|
||||
class TestBackup(volume_fakes.TestVolumev1):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -38,7 +37,6 @@ class TestBackup(volume_fakes.TestVolumev1):
|
||||
|
||||
|
||||
class TestBackupCreate(TestBackup):
|
||||
|
||||
volume = volume_fakes.create_one_volume()
|
||||
|
||||
columns = (
|
||||
@ -79,9 +77,12 @@ class TestBackupCreate(TestBackup):
|
||||
|
||||
def test_backup_create(self):
|
||||
arglist = [
|
||||
"--name", self.new_backup.name,
|
||||
"--description", self.new_backup.description,
|
||||
"--container", self.new_backup.container,
|
||||
"--name",
|
||||
self.new_backup.name,
|
||||
"--description",
|
||||
self.new_backup.description,
|
||||
"--container",
|
||||
self.new_backup.container,
|
||||
self.new_backup.volume_id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -105,8 +106,10 @@ class TestBackupCreate(TestBackup):
|
||||
|
||||
def test_backup_create_without_name(self):
|
||||
arglist = [
|
||||
"--description", self.new_backup.description,
|
||||
"--container", self.new_backup.container,
|
||||
"--description",
|
||||
self.new_backup.description,
|
||||
"--container",
|
||||
self.new_backup.container,
|
||||
self.new_backup.volume_id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -129,7 +132,6 @@ class TestBackupCreate(TestBackup):
|
||||
|
||||
|
||||
class TestBackupDelete(TestBackup):
|
||||
|
||||
backups = volume_fakes.create_backups(count=2)
|
||||
|
||||
def setUp(self):
|
||||
@ -142,18 +144,13 @@ class TestBackupDelete(TestBackup):
|
||||
self.cmd = volume_backup.DeleteVolumeBackup(self.app, None)
|
||||
|
||||
def test_backup_delete(self):
|
||||
arglist = [
|
||||
self.backups[0].id
|
||||
]
|
||||
verifylist = [
|
||||
("backups", [self.backups[0].id])
|
||||
]
|
||||
arglist = [self.backups[0].id]
|
||||
verifylist = [("backups", [self.backups[0].id])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.backups_mock.delete.assert_called_with(
|
||||
self.backups[0].id)
|
||||
self.backups_mock.delete.assert_called_with(self.backups[0].id)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_delete_multiple_backups(self):
|
||||
@ -185,14 +182,14 @@ class TestBackupDelete(TestBackup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
find_mock_result = [self.backups[0], exceptions.CommandError]
|
||||
with mock.patch.object(utils, 'find_resource',
|
||||
side_effect=find_mock_result) as find_mock:
|
||||
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 backups failed to delete.',
|
||||
str(e))
|
||||
self.assertEqual('1 of 2 backups failed to delete.', str(e))
|
||||
|
||||
find_mock.assert_any_call(self.backups_mock, self.backups[0].id)
|
||||
find_mock.assert_any_call(self.backups_mock, 'unexist_backup')
|
||||
@ -204,7 +201,6 @@ class TestBackupDelete(TestBackup):
|
||||
|
||||
|
||||
class TestBackupList(TestBackup):
|
||||
|
||||
volume = volume_fakes.create_one_volume()
|
||||
backups = volume_fakes.create_backups(
|
||||
attrs={'volume_id': volume.display_name},
|
||||
@ -226,25 +222,29 @@ class TestBackupList(TestBackup):
|
||||
|
||||
data = []
|
||||
for b in backups:
|
||||
data.append((
|
||||
b.id,
|
||||
b.name,
|
||||
b.description,
|
||||
b.status,
|
||||
b.size,
|
||||
))
|
||||
data.append(
|
||||
(
|
||||
b.id,
|
||||
b.name,
|
||||
b.description,
|
||||
b.status,
|
||||
b.size,
|
||||
)
|
||||
)
|
||||
data_long = []
|
||||
for b in backups:
|
||||
data_long.append((
|
||||
b.id,
|
||||
b.name,
|
||||
b.description,
|
||||
b.status,
|
||||
b.size,
|
||||
b.availability_zone,
|
||||
volume_backup.VolumeIdColumn(b.volume_id),
|
||||
b.container,
|
||||
))
|
||||
data_long.append(
|
||||
(
|
||||
b.id,
|
||||
b.name,
|
||||
b.description,
|
||||
b.status,
|
||||
b.size,
|
||||
b.availability_zone,
|
||||
volume_backup.VolumeIdColumn(b.volume_id),
|
||||
b.container,
|
||||
)
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@ -284,10 +284,13 @@ class TestBackupList(TestBackup):
|
||||
def test_backup_list_with_options(self):
|
||||
arglist = [
|
||||
"--long",
|
||||
"--name", self.backups[0].name,
|
||||
"--status", "error",
|
||||
"--volume", self.volume.id,
|
||||
"--all-projects"
|
||||
"--name",
|
||||
self.backups[0].name,
|
||||
"--status",
|
||||
"error",
|
||||
"--volume",
|
||||
self.volume.id,
|
||||
"--all-projects",
|
||||
]
|
||||
verifylist = [
|
||||
("long", True),
|
||||
@ -315,7 +318,6 @@ class TestBackupList(TestBackup):
|
||||
|
||||
|
||||
class TestBackupRestore(TestBackup):
|
||||
|
||||
volume = volume_fakes.create_one_volume()
|
||||
backup = volume_fakes.create_one_backup(
|
||||
attrs={'volume_id': volume.id},
|
||||
@ -345,8 +347,7 @@ class TestBackupRestore(TestBackup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.restores_mock.restore.assert_called_with(self.backup.id,
|
||||
None)
|
||||
self.restores_mock.restore.assert_called_with(self.backup.id, None)
|
||||
self.assertIsNotNone(result)
|
||||
|
||||
def test_backup_restore_with_existing_volume(self):
|
||||
@ -362,7 +363,8 @@ class TestBackupRestore(TestBackup):
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.restores_mock.restore.assert_called_with(
|
||||
self.backup.id, self.backup.volume_id,
|
||||
self.backup.id,
|
||||
self.backup.volume_id,
|
||||
)
|
||||
self.assertIsNotNone(result)
|
||||
|
||||
@ -377,7 +379,8 @@ class TestBackupRestore(TestBackup):
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
with mock.patch.object(
|
||||
utils, 'find_resource',
|
||||
utils,
|
||||
'find_resource',
|
||||
side_effect=exceptions.CommandError(),
|
||||
):
|
||||
self.assertRaises(
|
||||
@ -388,7 +391,6 @@ class TestBackupRestore(TestBackup):
|
||||
|
||||
|
||||
class TestBackupShow(TestBackup):
|
||||
|
||||
columns = (
|
||||
'availability_zone',
|
||||
'container',
|
||||
@ -422,12 +424,8 @@ class TestBackupShow(TestBackup):
|
||||
self.cmd = volume_backup.ShowVolumeBackup(self.app, None)
|
||||
|
||||
def test_backup_show(self):
|
||||
arglist = [
|
||||
self.backup.id
|
||||
]
|
||||
verifylist = [
|
||||
("backup", self.backup.id)
|
||||
]
|
||||
arglist = [self.backup.id]
|
||||
verifylist = [("backup", self.backup.id)]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
@ -1182,12 +1182,12 @@ class FakeLimits(object):
|
||||
|
||||
@property
|
||||
def absolute(self):
|
||||
for (name, value) in self.absolute_limits_attrs.items():
|
||||
for name, value in self.absolute_limits_attrs.items():
|
||||
yield FakeAbsoluteLimit(name, value)
|
||||
|
||||
def absolute_limits(self):
|
||||
reference_data = []
|
||||
for (name, value) in self.absolute_limits_attrs.items():
|
||||
for name, value in self.absolute_limits_attrs.items():
|
||||
reference_data.append((name, value))
|
||||
return reference_data
|
||||
|
||||
|
@ -17,7 +17,6 @@ from openstackclient.volume.v2 import backup_record
|
||||
|
||||
|
||||
class TestBackupRecord(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -26,7 +25,6 @@ class TestBackupRecord(volume_fakes.TestVolume):
|
||||
|
||||
|
||||
class TestBackupRecordExport(TestBackupRecord):
|
||||
|
||||
new_backup = volume_fakes.create_one_backup(
|
||||
attrs={'volume_id': 'a54708a2-0388-4476-a909-09579f885c25'},
|
||||
)
|
||||
@ -81,7 +79,6 @@ class TestBackupRecordExport(TestBackupRecord):
|
||||
|
||||
|
||||
class TestBackupRecordImport(TestBackupRecord):
|
||||
|
||||
new_backup = volume_fakes.create_one_backup(
|
||||
attrs={'volume_id': 'a54708a2-0388-4476-a909-09579f885c25'},
|
||||
)
|
||||
@ -101,8 +98,10 @@ class TestBackupRecordImport(TestBackupRecord):
|
||||
"fake_backup_record_data",
|
||||
]
|
||||
verifylist = [
|
||||
("backup_service",
|
||||
"cinder.backup.drivers.swift.SwiftBackupDriver"),
|
||||
(
|
||||
"backup_service",
|
||||
"cinder.backup.drivers.swift.SwiftBackupDriver",
|
||||
),
|
||||
("backup_metadata", "fake_backup_record_data"),
|
||||
]
|
||||
|
||||
|
@ -24,21 +24,19 @@ from openstackclient.volume.v2 import consistency_group
|
||||
|
||||
|
||||
class TestConsistencyGroup(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
# Get a shortcut to the TransferManager Mock
|
||||
self.consistencygroups_mock = (
|
||||
self.app.client_manager.volume.consistencygroups)
|
||||
self.app.client_manager.volume.consistencygroups
|
||||
)
|
||||
self.consistencygroups_mock.reset_mock()
|
||||
|
||||
self.cgsnapshots_mock = (
|
||||
self.app.client_manager.volume.cgsnapshots)
|
||||
self.cgsnapshots_mock = self.app.client_manager.volume.cgsnapshots
|
||||
self.cgsnapshots_mock.reset_mock()
|
||||
|
||||
self.volumes_mock = (
|
||||
self.app.client_manager.volume.volumes)
|
||||
self.volumes_mock = self.app.client_manager.volume.volumes
|
||||
self.volumes_mock.reset_mock()
|
||||
|
||||
self.types_mock = self.app.client_manager.volume.volume_types
|
||||
@ -46,17 +44,16 @@ class TestConsistencyGroup(volume_fakes.TestVolume):
|
||||
|
||||
|
||||
class TestConsistencyGroupAddVolume(TestConsistencyGroup):
|
||||
|
||||
_consistency_group = volume_fakes.create_one_consistency_group()
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.consistencygroups_mock.get.return_value = (
|
||||
self._consistency_group)
|
||||
self.consistencygroups_mock.get.return_value = self._consistency_group
|
||||
# Get the command object to test
|
||||
self.cmd = \
|
||||
consistency_group.AddVolumeToConsistencyGroup(self.app, None)
|
||||
self.cmd = consistency_group.AddVolumeToConsistencyGroup(
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_add_one_volume_to_consistency_group(self):
|
||||
volume = volume_fakes.create_one_volume()
|
||||
@ -78,8 +75,7 @@ class TestConsistencyGroupAddVolume(TestConsistencyGroup):
|
||||
'add_volumes': volume.id,
|
||||
}
|
||||
self.consistencygroups_mock.update.assert_called_once_with(
|
||||
self._consistency_group.id,
|
||||
**kwargs
|
||||
self._consistency_group.id, **kwargs
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
@ -104,14 +100,14 @@ class TestConsistencyGroupAddVolume(TestConsistencyGroup):
|
||||
'add_volumes': volumes[0].id + ',' + volumes[1].id,
|
||||
}
|
||||
self.consistencygroups_mock.update.assert_called_once_with(
|
||||
self._consistency_group.id,
|
||||
**kwargs
|
||||
self._consistency_group.id, **kwargs
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
@mock.patch.object(consistency_group.LOG, 'error')
|
||||
def test_add_multiple_volumes_to_consistency_group_with_exception(
|
||||
self, mock_error,
|
||||
self,
|
||||
mock_error,
|
||||
):
|
||||
volume = volume_fakes.create_one_volume()
|
||||
arglist = [
|
||||
@ -126,20 +122,22 @@ class TestConsistencyGroupAddVolume(TestConsistencyGroup):
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
find_mock_result = [volume,
|
||||
exceptions.CommandError,
|
||||
self._consistency_group]
|
||||
with mock.patch.object(utils, 'find_resource',
|
||||
side_effect=find_mock_result) as find_mock:
|
||||
find_mock_result = [
|
||||
volume,
|
||||
exceptions.CommandError,
|
||||
self._consistency_group,
|
||||
]
|
||||
with mock.patch.object(
|
||||
utils, 'find_resource', side_effect=find_mock_result
|
||||
) as find_mock:
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
mock_error.assert_called_with("1 of 2 volumes failed to add.")
|
||||
self.assertIsNone(result)
|
||||
find_mock.assert_any_call(self.consistencygroups_mock,
|
||||
self._consistency_group.id)
|
||||
find_mock.assert_any_call(self.volumes_mock,
|
||||
volume.id)
|
||||
find_mock.assert_any_call(self.volumes_mock,
|
||||
'unexist_volume')
|
||||
find_mock.assert_any_call(
|
||||
self.consistencygroups_mock, self._consistency_group.id
|
||||
)
|
||||
find_mock.assert_any_call(self.volumes_mock, volume.id)
|
||||
find_mock.assert_any_call(self.volumes_mock, 'unexist_volume')
|
||||
self.assertEqual(3, find_mock.call_count)
|
||||
self.consistencygroups_mock.update.assert_called_once_with(
|
||||
self._consistency_group.id, add_volumes=volume.id
|
||||
@ -147,7 +145,6 @@ class TestConsistencyGroupAddVolume(TestConsistencyGroup):
|
||||
|
||||
|
||||
class TestConsistencyGroupCreate(TestConsistencyGroup):
|
||||
|
||||
volume_type = volume_fakes.create_one_volume_type()
|
||||
new_consistency_group = volume_fakes.create_one_consistency_group()
|
||||
consistency_group_snapshot = (
|
||||
@ -176,22 +173,28 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.consistencygroups_mock.create.return_value = (
|
||||
self.new_consistency_group)
|
||||
self.new_consistency_group
|
||||
)
|
||||
self.consistencygroups_mock.create_from_src.return_value = (
|
||||
self.new_consistency_group)
|
||||
self.new_consistency_group
|
||||
)
|
||||
self.consistencygroups_mock.get.return_value = (
|
||||
self.new_consistency_group)
|
||||
self.new_consistency_group
|
||||
)
|
||||
self.types_mock.get.return_value = self.volume_type
|
||||
self.cgsnapshots_mock.get.return_value = (
|
||||
self.consistency_group_snapshot)
|
||||
self.consistency_group_snapshot
|
||||
)
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = consistency_group.CreateConsistencyGroup(self.app, None)
|
||||
|
||||
def test_consistency_group_create(self):
|
||||
arglist = [
|
||||
'--volume-type', self.volume_type.id,
|
||||
'--description', self.new_consistency_group.description,
|
||||
'--volume-type',
|
||||
self.volume_type.id,
|
||||
'--description',
|
||||
self.new_consistency_group.description,
|
||||
'--availability-zone',
|
||||
self.new_consistency_group.availability_zone,
|
||||
self.new_consistency_group.name,
|
||||
@ -199,16 +202,17 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
|
||||
verifylist = [
|
||||
('volume_type', self.volume_type.id),
|
||||
('description', self.new_consistency_group.description),
|
||||
('availability_zone',
|
||||
self.new_consistency_group.availability_zone),
|
||||
(
|
||||
'availability_zone',
|
||||
self.new_consistency_group.availability_zone,
|
||||
),
|
||||
('name', self.new_consistency_group.name),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.types_mock.get.assert_called_once_with(
|
||||
self.volume_type.id)
|
||||
self.types_mock.get.assert_called_once_with(self.volume_type.id)
|
||||
self.consistencygroups_mock.get.assert_not_called()
|
||||
self.consistencygroups_mock.create.assert_called_once_with(
|
||||
self.volume_type.id,
|
||||
@ -222,23 +226,26 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
|
||||
|
||||
def test_consistency_group_create_without_name(self):
|
||||
arglist = [
|
||||
'--volume-type', self.volume_type.id,
|
||||
'--description', self.new_consistency_group.description,
|
||||
'--volume-type',
|
||||
self.volume_type.id,
|
||||
'--description',
|
||||
self.new_consistency_group.description,
|
||||
'--availability-zone',
|
||||
self.new_consistency_group.availability_zone,
|
||||
]
|
||||
verifylist = [
|
||||
('volume_type', self.volume_type.id),
|
||||
('description', self.new_consistency_group.description),
|
||||
('availability_zone',
|
||||
self.new_consistency_group.availability_zone),
|
||||
(
|
||||
'availability_zone',
|
||||
self.new_consistency_group.availability_zone,
|
||||
),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.types_mock.get.assert_called_once_with(
|
||||
self.volume_type.id)
|
||||
self.types_mock.get.assert_called_once_with(self.volume_type.id)
|
||||
self.consistencygroups_mock.get.assert_not_called()
|
||||
self.consistencygroups_mock.create.assert_called_once_with(
|
||||
self.volume_type.id,
|
||||
@ -252,8 +259,10 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
|
||||
|
||||
def test_consistency_group_create_from_source(self):
|
||||
arglist = [
|
||||
'--consistency-group-source', self.new_consistency_group.id,
|
||||
'--description', self.new_consistency_group.description,
|
||||
'--consistency-group-source',
|
||||
self.new_consistency_group.id,
|
||||
'--description',
|
||||
self.new_consistency_group.description,
|
||||
self.new_consistency_group.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -267,7 +276,8 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
|
||||
|
||||
self.types_mock.get.assert_not_called()
|
||||
self.consistencygroups_mock.get.assert_called_once_with(
|
||||
self.new_consistency_group.id)
|
||||
self.new_consistency_group.id
|
||||
)
|
||||
self.consistencygroups_mock.create_from_src.assert_called_with(
|
||||
None,
|
||||
self.new_consistency_group.id,
|
||||
@ -280,8 +290,10 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
|
||||
|
||||
def test_consistency_group_create_from_snapshot(self):
|
||||
arglist = [
|
||||
'--consistency-group-snapshot', self.consistency_group_snapshot.id,
|
||||
'--description', self.new_consistency_group.description,
|
||||
'--consistency-group-snapshot',
|
||||
self.consistency_group_snapshot.id,
|
||||
'--description',
|
||||
self.new_consistency_group.description,
|
||||
self.new_consistency_group.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -295,7 +307,8 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
|
||||
|
||||
self.types_mock.get.assert_not_called()
|
||||
self.cgsnapshots_mock.get.assert_called_once_with(
|
||||
self.consistency_group_snapshot.id)
|
||||
self.consistency_group_snapshot.id
|
||||
)
|
||||
self.consistencygroups_mock.create_from_src.assert_called_with(
|
||||
self.consistency_group_snapshot.id,
|
||||
None,
|
||||
@ -308,9 +321,7 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
|
||||
|
||||
|
||||
class TestConsistencyGroupDelete(TestConsistencyGroup):
|
||||
|
||||
consistency_groups =\
|
||||
volume_fakes.create_consistency_groups(count=2)
|
||||
consistency_groups = volume_fakes.create_consistency_groups(count=2)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@ -324,18 +335,15 @@ class TestConsistencyGroupDelete(TestConsistencyGroup):
|
||||
self.cmd = consistency_group.DeleteConsistencyGroup(self.app, None)
|
||||
|
||||
def test_consistency_group_delete(self):
|
||||
arglist = [
|
||||
self.consistency_groups[0].id
|
||||
]
|
||||
verifylist = [
|
||||
("consistency_groups", [self.consistency_groups[0].id])
|
||||
]
|
||||
arglist = [self.consistency_groups[0].id]
|
||||
verifylist = [("consistency_groups", [self.consistency_groups[0].id])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.consistencygroups_mock.delete.assert_called_with(
|
||||
self.consistency_groups[0].id, False)
|
||||
self.consistency_groups[0].id, False
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_consistency_group_delete_with_force(self):
|
||||
@ -345,14 +353,15 @@ class TestConsistencyGroupDelete(TestConsistencyGroup):
|
||||
]
|
||||
verifylist = [
|
||||
('force', True),
|
||||
("consistency_groups", [self.consistency_groups[0].id])
|
||||
("consistency_groups", [self.consistency_groups[0].id]),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.consistencygroups_mock.delete.assert_called_with(
|
||||
self.consistency_groups[0].id, True)
|
||||
self.consistency_groups[0].id, True
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_delete_multiple_consistency_groups(self):
|
||||
@ -383,21 +392,27 @@ class TestConsistencyGroupDelete(TestConsistencyGroup):
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
find_mock_result = [self.consistency_groups[0],
|
||||
exceptions.CommandError]
|
||||
with mock.patch.object(utils, 'find_resource',
|
||||
side_effect=find_mock_result) as find_mock:
|
||||
find_mock_result = [
|
||||
self.consistency_groups[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 consistency groups failed to delete.',
|
||||
str(e))
|
||||
self.assertEqual(
|
||||
'1 of 2 consistency groups failed to delete.', str(e)
|
||||
)
|
||||
|
||||
find_mock.assert_any_call(self.consistencygroups_mock,
|
||||
self.consistency_groups[0].id)
|
||||
find_mock.assert_any_call(self.consistencygroups_mock,
|
||||
'unexist_consistency_group')
|
||||
find_mock.assert_any_call(
|
||||
self.consistencygroups_mock, self.consistency_groups[0].id
|
||||
)
|
||||
find_mock.assert_any_call(
|
||||
self.consistencygroups_mock, 'unexist_consistency_group'
|
||||
)
|
||||
|
||||
self.assertEqual(2, find_mock.call_count)
|
||||
self.consistencygroups_mock.delete.assert_called_once_with(
|
||||
@ -406,7 +421,6 @@ class TestConsistencyGroupDelete(TestConsistencyGroup):
|
||||
|
||||
|
||||
class TestConsistencyGroupList(TestConsistencyGroup):
|
||||
|
||||
consistency_groups = volume_fakes.create_consistency_groups(count=2)
|
||||
|
||||
columns = [
|
||||
@ -424,21 +438,25 @@ class TestConsistencyGroupList(TestConsistencyGroup):
|
||||
]
|
||||
data = []
|
||||
for c in consistency_groups:
|
||||
data.append((
|
||||
c.id,
|
||||
c.status,
|
||||
c.name,
|
||||
))
|
||||
data.append(
|
||||
(
|
||||
c.id,
|
||||
c.status,
|
||||
c.name,
|
||||
)
|
||||
)
|
||||
data_long = []
|
||||
for c in consistency_groups:
|
||||
data_long.append((
|
||||
c.id,
|
||||
c.status,
|
||||
c.availability_zone,
|
||||
c.name,
|
||||
c.description,
|
||||
format_columns.ListColumn(c.volume_types)
|
||||
))
|
||||
data_long.append(
|
||||
(
|
||||
c.id,
|
||||
c.status,
|
||||
c.availability_zone,
|
||||
c.name,
|
||||
c.description,
|
||||
format_columns.ListColumn(c.volume_types),
|
||||
)
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@ -458,14 +476,13 @@ class TestConsistencyGroupList(TestConsistencyGroup):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.consistencygroups_mock.list.assert_called_once_with(
|
||||
detailed=True, search_opts={'all_tenants': False})
|
||||
detailed=True, search_opts={'all_tenants': False}
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, list(data))
|
||||
|
||||
def test_consistency_group_list_with_all_project(self):
|
||||
arglist = [
|
||||
"--all-projects"
|
||||
]
|
||||
arglist = ["--all-projects"]
|
||||
verifylist = [
|
||||
("all_projects", True),
|
||||
("long", False),
|
||||
@ -475,7 +492,8 @@ class TestConsistencyGroupList(TestConsistencyGroup):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.consistencygroups_mock.list.assert_called_once_with(
|
||||
detailed=True, search_opts={'all_tenants': True})
|
||||
detailed=True, search_opts={'all_tenants': True}
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, list(data))
|
||||
|
||||
@ -492,23 +510,23 @@ class TestConsistencyGroupList(TestConsistencyGroup):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.consistencygroups_mock.list.assert_called_once_with(
|
||||
detailed=True, search_opts={'all_tenants': False})
|
||||
detailed=True, search_opts={'all_tenants': False}
|
||||
)
|
||||
self.assertEqual(self.columns_long, columns)
|
||||
self.assertCountEqual(self.data_long, list(data))
|
||||
|
||||
|
||||
class TestConsistencyGroupRemoveVolume(TestConsistencyGroup):
|
||||
|
||||
_consistency_group = volume_fakes.create_one_consistency_group()
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.consistencygroups_mock.get.return_value = (
|
||||
self._consistency_group)
|
||||
self.consistencygroups_mock.get.return_value = self._consistency_group
|
||||
# Get the command object to test
|
||||
self.cmd = \
|
||||
consistency_group.RemoveVolumeFromConsistencyGroup(self.app, None)
|
||||
self.cmd = consistency_group.RemoveVolumeFromConsistencyGroup(
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_remove_one_volume_from_consistency_group(self):
|
||||
volume = volume_fakes.create_one_volume()
|
||||
@ -530,8 +548,7 @@ class TestConsistencyGroupRemoveVolume(TestConsistencyGroup):
|
||||
'remove_volumes': volume.id,
|
||||
}
|
||||
self.consistencygroups_mock.update.assert_called_once_with(
|
||||
self._consistency_group.id,
|
||||
**kwargs
|
||||
self._consistency_group.id, **kwargs
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
@ -556,8 +573,7 @@ class TestConsistencyGroupRemoveVolume(TestConsistencyGroup):
|
||||
'remove_volumes': volumes[0].id + ',' + volumes[1].id,
|
||||
}
|
||||
self.consistencygroups_mock.update.assert_called_once_with(
|
||||
self._consistency_group.id,
|
||||
**kwargs
|
||||
self._consistency_group.id, **kwargs
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
@ -579,20 +595,22 @@ class TestConsistencyGroupRemoveVolume(TestConsistencyGroup):
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
find_mock_result = [volume,
|
||||
exceptions.CommandError,
|
||||
self._consistency_group]
|
||||
with mock.patch.object(utils, 'find_resource',
|
||||
side_effect=find_mock_result) as find_mock:
|
||||
find_mock_result = [
|
||||
volume,
|
||||
exceptions.CommandError,
|
||||
self._consistency_group,
|
||||
]
|
||||
with mock.patch.object(
|
||||
utils, 'find_resource', side_effect=find_mock_result
|
||||
) as find_mock:
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
mock_error.assert_called_with("1 of 2 volumes failed to remove.")
|
||||
self.assertIsNone(result)
|
||||
find_mock.assert_any_call(self.consistencygroups_mock,
|
||||
self._consistency_group.id)
|
||||
find_mock.assert_any_call(self.volumes_mock,
|
||||
volume.id)
|
||||
find_mock.assert_any_call(self.volumes_mock,
|
||||
'unexist_volume')
|
||||
find_mock.assert_any_call(
|
||||
self.consistencygroups_mock, self._consistency_group.id
|
||||
)
|
||||
find_mock.assert_any_call(self.volumes_mock, volume.id)
|
||||
find_mock.assert_any_call(self.volumes_mock, 'unexist_volume')
|
||||
self.assertEqual(3, find_mock.call_count)
|
||||
self.consistencygroups_mock.update.assert_called_once_with(
|
||||
self._consistency_group.id, remove_volumes=volume.id
|
||||
@ -600,21 +618,20 @@ class TestConsistencyGroupRemoveVolume(TestConsistencyGroup):
|
||||
|
||||
|
||||
class TestConsistencyGroupSet(TestConsistencyGroup):
|
||||
|
||||
consistency_group = volume_fakes.create_one_consistency_group()
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.consistencygroups_mock.get.return_value = (
|
||||
self.consistency_group)
|
||||
self.consistencygroups_mock.get.return_value = self.consistency_group
|
||||
# Get the command object to test
|
||||
self.cmd = consistency_group.SetConsistencyGroup(self.app, None)
|
||||
|
||||
def test_consistency_group_set_name(self):
|
||||
new_name = 'new_name'
|
||||
arglist = [
|
||||
'--name', new_name,
|
||||
'--name',
|
||||
new_name,
|
||||
self.consistency_group.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -631,15 +648,15 @@ class TestConsistencyGroupSet(TestConsistencyGroup):
|
||||
'name': new_name,
|
||||
}
|
||||
self.consistencygroups_mock.update.assert_called_once_with(
|
||||
self.consistency_group.id,
|
||||
**kwargs
|
||||
self.consistency_group.id, **kwargs
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_consistency_group_set_description(self):
|
||||
new_description = 'new_description'
|
||||
arglist = [
|
||||
'--description', new_description,
|
||||
'--description',
|
||||
new_description,
|
||||
self.consistency_group.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -656,8 +673,7 @@ class TestConsistencyGroupSet(TestConsistencyGroup):
|
||||
'description': new_description,
|
||||
}
|
||||
self.consistencygroups_mock.update.assert_called_once_with(
|
||||
self.consistency_group.id,
|
||||
**kwargs
|
||||
self.consistency_group.id, **kwargs
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
@ -690,15 +706,12 @@ class TestConsistencyGroupShow(TestConsistencyGroup):
|
||||
self.cmd = consistency_group.ShowConsistencyGroup(self.app, None)
|
||||
|
||||
def test_consistency_group_show(self):
|
||||
arglist = [
|
||||
self.consistency_group.id
|
||||
]
|
||||
verifylist = [
|
||||
("consistency_group", self.consistency_group.id)
|
||||
]
|
||||
arglist = [self.consistency_group.id]
|
||||
verifylist = [("consistency_group", self.consistency_group.id)]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.consistencygroups_mock.get.assert_called_once_with(
|
||||
self.consistency_group.id)
|
||||
self.consistency_group.id
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
@ -19,21 +19,19 @@ from openstackclient.volume.v2 import consistency_group_snapshot
|
||||
|
||||
|
||||
class TestConsistencyGroupSnapshot(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super(TestConsistencyGroupSnapshot, self).setUp()
|
||||
|
||||
# Get a shortcut to the TransferManager Mock
|
||||
self.cgsnapshots_mock = (
|
||||
self.app.client_manager.volume.cgsnapshots)
|
||||
self.cgsnapshots_mock = self.app.client_manager.volume.cgsnapshots
|
||||
self.cgsnapshots_mock.reset_mock()
|
||||
self.consistencygroups_mock = (
|
||||
self.app.client_manager.volume.consistencygroups)
|
||||
self.app.client_manager.volume.consistencygroups
|
||||
)
|
||||
self.consistencygroups_mock.reset_mock()
|
||||
|
||||
|
||||
class TestConsistencyGroupSnapshotCreate(TestConsistencyGroupSnapshot):
|
||||
|
||||
_consistency_group_snapshot = (
|
||||
volume_fakes.create_one_consistency_group_snapshot()
|
||||
)
|
||||
@ -59,18 +57,21 @@ class TestConsistencyGroupSnapshotCreate(TestConsistencyGroupSnapshot):
|
||||
def setUp(self):
|
||||
super(TestConsistencyGroupSnapshotCreate, self).setUp()
|
||||
self.cgsnapshots_mock.create.return_value = (
|
||||
self._consistency_group_snapshot)
|
||||
self.consistencygroups_mock.get.return_value = (
|
||||
self.consistency_group)
|
||||
self._consistency_group_snapshot
|
||||
)
|
||||
self.consistencygroups_mock.get.return_value = self.consistency_group
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = (consistency_group_snapshot.
|
||||
CreateConsistencyGroupSnapshot(self.app, None))
|
||||
self.cmd = consistency_group_snapshot.CreateConsistencyGroupSnapshot(
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_consistency_group_snapshot_create(self):
|
||||
arglist = [
|
||||
'--consistency-group', self.consistency_group.id,
|
||||
'--description', self._consistency_group_snapshot.description,
|
||||
'--consistency-group',
|
||||
self.consistency_group.id,
|
||||
'--description',
|
||||
self._consistency_group_snapshot.description,
|
||||
self._consistency_group_snapshot.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -83,7 +84,8 @@ class TestConsistencyGroupSnapshotCreate(TestConsistencyGroupSnapshot):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.consistencygroups_mock.get.assert_called_once_with(
|
||||
self.consistency_group.id)
|
||||
self.consistency_group.id
|
||||
)
|
||||
self.cgsnapshots_mock.create.assert_called_once_with(
|
||||
self.consistency_group.id,
|
||||
name=self._consistency_group_snapshot.name,
|
||||
@ -95,7 +97,8 @@ class TestConsistencyGroupSnapshotCreate(TestConsistencyGroupSnapshot):
|
||||
|
||||
def test_consistency_group_snapshot_create_no_consistency_group(self):
|
||||
arglist = [
|
||||
'--description', self._consistency_group_snapshot.description,
|
||||
'--description',
|
||||
self._consistency_group_snapshot.description,
|
||||
self._consistency_group_snapshot.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -107,7 +110,8 @@ class TestConsistencyGroupSnapshotCreate(TestConsistencyGroupSnapshot):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.consistencygroups_mock.get.assert_called_once_with(
|
||||
self._consistency_group_snapshot.name)
|
||||
self._consistency_group_snapshot.name
|
||||
)
|
||||
self.cgsnapshots_mock.create.assert_called_once_with(
|
||||
self.consistency_group.id,
|
||||
name=self._consistency_group_snapshot.name,
|
||||
@ -119,7 +123,6 @@ class TestConsistencyGroupSnapshotCreate(TestConsistencyGroupSnapshot):
|
||||
|
||||
|
||||
class TestConsistencyGroupSnapshotDelete(TestConsistencyGroupSnapshot):
|
||||
|
||||
consistency_group_snapshots = (
|
||||
volume_fakes.create_consistency_group_snapshots(count=2)
|
||||
)
|
||||
@ -135,23 +138,25 @@ class TestConsistencyGroupSnapshotDelete(TestConsistencyGroupSnapshot):
|
||||
self.cgsnapshots_mock.delete.return_value = None
|
||||
|
||||
# Get the command object to mock
|
||||
self.cmd = (consistency_group_snapshot.
|
||||
DeleteConsistencyGroupSnapshot(self.app, None))
|
||||
self.cmd = consistency_group_snapshot.DeleteConsistencyGroupSnapshot(
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_consistency_group_snapshot_delete(self):
|
||||
arglist = [
|
||||
self.consistency_group_snapshots[0].id
|
||||
]
|
||||
arglist = [self.consistency_group_snapshots[0].id]
|
||||
verifylist = [
|
||||
("consistency_group_snapshot",
|
||||
[self.consistency_group_snapshots[0].id])
|
||||
(
|
||||
"consistency_group_snapshot",
|
||||
[self.consistency_group_snapshots[0].id],
|
||||
)
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.cgsnapshots_mock.delete.assert_called_once_with(
|
||||
self.consistency_group_snapshots[0].id)
|
||||
self.consistency_group_snapshots[0].id
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_multiple_consistency_group_snapshots_delete(self):
|
||||
@ -173,7 +178,6 @@ class TestConsistencyGroupSnapshotDelete(TestConsistencyGroupSnapshot):
|
||||
|
||||
|
||||
class TestConsistencyGroupSnapshotList(TestConsistencyGroupSnapshot):
|
||||
|
||||
consistency_group_snapshots = (
|
||||
volume_fakes.create_consistency_group_snapshots(count=2)
|
||||
)
|
||||
@ -194,32 +198,36 @@ class TestConsistencyGroupSnapshotList(TestConsistencyGroupSnapshot):
|
||||
]
|
||||
data = []
|
||||
for c in consistency_group_snapshots:
|
||||
data.append((
|
||||
c.id,
|
||||
c.status,
|
||||
c.name,
|
||||
))
|
||||
data.append(
|
||||
(
|
||||
c.id,
|
||||
c.status,
|
||||
c.name,
|
||||
)
|
||||
)
|
||||
data_long = []
|
||||
for c in consistency_group_snapshots:
|
||||
data_long.append((
|
||||
c.id,
|
||||
c.status,
|
||||
c.consistencygroup_id,
|
||||
c.name,
|
||||
c.description,
|
||||
c.created_at,
|
||||
))
|
||||
data_long.append(
|
||||
(
|
||||
c.id,
|
||||
c.status,
|
||||
c.consistencygroup_id,
|
||||
c.name,
|
||||
c.description,
|
||||
c.created_at,
|
||||
)
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super(TestConsistencyGroupSnapshotList, self).setUp()
|
||||
|
||||
self.cgsnapshots_mock.list.return_value = (
|
||||
self.consistency_group_snapshots)
|
||||
self.consistency_group_snapshots
|
||||
)
|
||||
self.consistencygroups_mock.get.return_value = self.consistency_group
|
||||
# Get the command to test
|
||||
self.cmd = (
|
||||
consistency_group_snapshot.
|
||||
ListConsistencyGroupSnapshot(self.app, None)
|
||||
self.cmd = consistency_group_snapshot.ListConsistencyGroupSnapshot(
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_consistency_group_snapshot_list_without_options(self):
|
||||
@ -240,7 +248,8 @@ class TestConsistencyGroupSnapshotList(TestConsistencyGroupSnapshot):
|
||||
'consistencygroup_id': None,
|
||||
}
|
||||
self.cgsnapshots_mock.list.assert_called_once_with(
|
||||
detailed=True, search_opts=search_opts)
|
||||
detailed=True, search_opts=search_opts
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, list(data))
|
||||
|
||||
@ -264,15 +273,18 @@ class TestConsistencyGroupSnapshotList(TestConsistencyGroupSnapshot):
|
||||
'consistencygroup_id': None,
|
||||
}
|
||||
self.cgsnapshots_mock.list.assert_called_once_with(
|
||||
detailed=True, search_opts=search_opts)
|
||||
detailed=True, search_opts=search_opts
|
||||
)
|
||||
self.assertEqual(self.columns_long, columns)
|
||||
self.assertEqual(self.data_long, list(data))
|
||||
|
||||
def test_consistency_group_snapshot_list_with_options(self):
|
||||
arglist = [
|
||||
"--all-project",
|
||||
"--status", self.consistency_group_snapshots[0].status,
|
||||
"--consistency-group", self.consistency_group.id,
|
||||
"--status",
|
||||
self.consistency_group_snapshots[0].status,
|
||||
"--consistency-group",
|
||||
self.consistency_group.id,
|
||||
]
|
||||
verifylist = [
|
||||
("all_projects", True),
|
||||
@ -290,15 +302,16 @@ class TestConsistencyGroupSnapshotList(TestConsistencyGroupSnapshot):
|
||||
'consistencygroup_id': self.consistency_group.id,
|
||||
}
|
||||
self.consistencygroups_mock.get.assert_called_once_with(
|
||||
self.consistency_group.id)
|
||||
self.consistency_group.id
|
||||
)
|
||||
self.cgsnapshots_mock.list.assert_called_once_with(
|
||||
detailed=True, search_opts=search_opts)
|
||||
detailed=True, search_opts=search_opts
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, list(data))
|
||||
|
||||
|
||||
class TestConsistencyGroupSnapshotShow(TestConsistencyGroupSnapshot):
|
||||
|
||||
_consistency_group_snapshot = (
|
||||
volume_fakes.create_one_consistency_group_snapshot()
|
||||
)
|
||||
@ -324,20 +337,21 @@ class TestConsistencyGroupSnapshotShow(TestConsistencyGroupSnapshot):
|
||||
super(TestConsistencyGroupSnapshotShow, self).setUp()
|
||||
|
||||
self.cgsnapshots_mock.get.return_value = (
|
||||
self._consistency_group_snapshot)
|
||||
self.cmd = (consistency_group_snapshot.
|
||||
ShowConsistencyGroupSnapshot(self.app, None))
|
||||
self._consistency_group_snapshot
|
||||
)
|
||||
self.cmd = consistency_group_snapshot.ShowConsistencyGroupSnapshot(
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_consistency_group_snapshot_show(self):
|
||||
arglist = [
|
||||
self._consistency_group_snapshot.id
|
||||
]
|
||||
arglist = [self._consistency_group_snapshot.id]
|
||||
verifylist = [
|
||||
("consistency_group_snapshot", self._consistency_group_snapshot.id)
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.cgsnapshots_mock.get.assert_called_once_with(
|
||||
self._consistency_group_snapshot.id)
|
||||
self._consistency_group_snapshot.id
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
|
@ -26,7 +26,6 @@ from openstackclient.volume.v2 import qos_specs
|
||||
|
||||
|
||||
class TestQos(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super(TestQos, self).setUp()
|
||||
|
||||
@ -38,7 +37,6 @@ class TestQos(volume_fakes.TestVolume):
|
||||
|
||||
|
||||
class TestQosAssociate(TestQos):
|
||||
|
||||
volume_type = volume_fakes.create_one_volume_type()
|
||||
qos_spec = volume_fakes.create_one_qos()
|
||||
|
||||
@ -51,33 +49,23 @@ class TestQosAssociate(TestQos):
|
||||
self.cmd = qos_specs.AssociateQos(self.app, None)
|
||||
|
||||
def test_qos_associate(self):
|
||||
arglist = [
|
||||
self.qos_spec.id,
|
||||
self.volume_type.id
|
||||
]
|
||||
arglist = [self.qos_spec.id, self.volume_type.id]
|
||||
verifylist = [
|
||||
('qos_spec', self.qos_spec.id),
|
||||
('volume_type', self.volume_type.id)
|
||||
('volume_type', self.volume_type.id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.qos_mock.associate.assert_called_with(
|
||||
self.qos_spec.id,
|
||||
self.volume_type.id
|
||||
self.qos_spec.id, self.volume_type.id
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
||||
class TestQosCreate(TestQos):
|
||||
|
||||
columns = (
|
||||
'consumer',
|
||||
'id',
|
||||
'name',
|
||||
'properties'
|
||||
)
|
||||
columns = ('consumer', 'id', 'name', 'properties')
|
||||
|
||||
def setUp(self):
|
||||
super(TestQosCreate, self).setUp()
|
||||
@ -89,7 +77,7 @@ class TestQosCreate(TestQos):
|
||||
self.new_qos_spec.consumer,
|
||||
self.new_qos_spec.id,
|
||||
self.new_qos_spec.name,
|
||||
format_columns.DictColumn(self.new_qos_spec.specs)
|
||||
format_columns.DictColumn(self.new_qos_spec.specs),
|
||||
)
|
||||
|
||||
# Get the command object to test
|
||||
@ -107,8 +95,7 @@ class TestQosCreate(TestQos):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.qos_mock.create.assert_called_with(
|
||||
self.new_qos_spec.name,
|
||||
{'consumer': 'both'}
|
||||
self.new_qos_spec.name, {'consumer': 'both'}
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
@ -116,7 +103,8 @@ class TestQosCreate(TestQos):
|
||||
|
||||
def test_qos_create_with_consumer(self):
|
||||
arglist = [
|
||||
'--consumer', self.new_qos_spec.consumer,
|
||||
'--consumer',
|
||||
self.new_qos_spec.consumer,
|
||||
self.new_qos_spec.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -128,8 +116,7 @@ class TestQosCreate(TestQos):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.qos_mock.create.assert_called_with(
|
||||
self.new_qos_spec.name,
|
||||
{'consumer': self.new_qos_spec.consumer}
|
||||
self.new_qos_spec.name, {'consumer': self.new_qos_spec.consumer}
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
@ -137,9 +124,12 @@ class TestQosCreate(TestQos):
|
||||
|
||||
def test_qos_create_with_properties(self):
|
||||
arglist = [
|
||||
'--consumer', self.new_qos_spec.consumer,
|
||||
'--property', 'foo=bar',
|
||||
'--property', 'iops=9001',
|
||||
'--consumer',
|
||||
self.new_qos_spec.consumer,
|
||||
'--property',
|
||||
'foo=bar',
|
||||
'--property',
|
||||
'iops=9001',
|
||||
self.new_qos_spec.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -153,9 +143,11 @@ class TestQosCreate(TestQos):
|
||||
|
||||
self.qos_mock.create.assert_called_with(
|
||||
self.new_qos_spec.name,
|
||||
{'consumer': self.new_qos_spec.consumer,
|
||||
'foo': 'bar',
|
||||
'iops': '9001'}
|
||||
{
|
||||
'consumer': self.new_qos_spec.consumer,
|
||||
'foo': 'bar',
|
||||
'iops': '9001',
|
||||
},
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
@ -163,47 +155,33 @@ class TestQosCreate(TestQos):
|
||||
|
||||
|
||||
class TestQosDelete(TestQos):
|
||||
|
||||
qos_specs = volume_fakes.create_qoses(count=2)
|
||||
|
||||
def setUp(self):
|
||||
super(TestQosDelete, self).setUp()
|
||||
|
||||
self.qos_mock.get = (
|
||||
volume_fakes.get_qoses(self.qos_specs))
|
||||
self.qos_mock.get = volume_fakes.get_qoses(self.qos_specs)
|
||||
# Get the command object to test
|
||||
self.cmd = qos_specs.DeleteQos(self.app, None)
|
||||
|
||||
def test_qos_delete(self):
|
||||
arglist = [
|
||||
self.qos_specs[0].id
|
||||
]
|
||||
verifylist = [
|
||||
('qos_specs', [self.qos_specs[0].id])
|
||||
]
|
||||
arglist = [self.qos_specs[0].id]
|
||||
verifylist = [('qos_specs', [self.qos_specs[0].id])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.qos_mock.delete.assert_called_with(
|
||||
self.qos_specs[0].id, False)
|
||||
self.qos_mock.delete.assert_called_with(self.qos_specs[0].id, False)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_qos_delete_with_force(self):
|
||||
arglist = [
|
||||
'--force',
|
||||
self.qos_specs[0].id
|
||||
]
|
||||
verifylist = [
|
||||
('force', True),
|
||||
('qos_specs', [self.qos_specs[0].id])
|
||||
]
|
||||
arglist = ['--force', self.qos_specs[0].id]
|
||||
verifylist = [('force', True), ('qos_specs', [self.qos_specs[0].id])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.qos_mock.delete.assert_called_with(
|
||||
self.qos_specs[0].id, True)
|
||||
self.qos_mock.delete.assert_called_with(self.qos_specs[0].id, True)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_delete_multiple_qoses(self):
|
||||
@ -235,14 +213,16 @@ class TestQosDelete(TestQos):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
find_mock_result = [self.qos_specs[0], exceptions.CommandError]
|
||||
with mock.patch.object(utils, 'find_resource',
|
||||
side_effect=find_mock_result) as find_mock:
|
||||
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 QoS specifications failed to delete.', str(e))
|
||||
'1 of 2 QoS specifications failed to delete.', str(e)
|
||||
)
|
||||
|
||||
find_mock.assert_any_call(self.qos_mock, self.qos_specs[0].id)
|
||||
find_mock.assert_any_call(self.qos_mock, 'unexist_qos')
|
||||
@ -254,7 +234,6 @@ class TestQosDelete(TestQos):
|
||||
|
||||
|
||||
class TestQosDisassociate(TestQos):
|
||||
|
||||
volume_type = volume_fakes.create_one_volume_type()
|
||||
qos_spec = volume_fakes.create_one_qos()
|
||||
|
||||
@ -268,7 +247,8 @@ class TestQosDisassociate(TestQos):
|
||||
|
||||
def test_qos_disassociate_with_volume_type(self):
|
||||
arglist = [
|
||||
'--volume-type', self.volume_type.id,
|
||||
'--volume-type',
|
||||
self.volume_type.id,
|
||||
self.qos_spec.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -280,8 +260,7 @@ class TestQosDisassociate(TestQos):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.qos_mock.disassociate.assert_called_with(
|
||||
self.qos_spec.id,
|
||||
self.volume_type.id
|
||||
self.qos_spec.id, self.volume_type.id
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
@ -290,9 +269,7 @@ class TestQosDisassociate(TestQos):
|
||||
'--all',
|
||||
self.qos_spec.id,
|
||||
]
|
||||
verifylist = [
|
||||
('qos_spec', self.qos_spec.id)
|
||||
]
|
||||
verifylist = [('qos_spec', self.qos_spec.id)]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
@ -302,7 +279,6 @@ class TestQosDisassociate(TestQos):
|
||||
|
||||
|
||||
class TestQosList(TestQos):
|
||||
|
||||
qos_specs = volume_fakes.create_qoses(count=2)
|
||||
qos_association = volume_fakes.create_one_qos_association()
|
||||
|
||||
@ -315,13 +291,15 @@ class TestQosList(TestQos):
|
||||
)
|
||||
data = []
|
||||
for q in qos_specs:
|
||||
data.append((
|
||||
q.id,
|
||||
q.name,
|
||||
q.consumer,
|
||||
format_columns.ListColumn([qos_association.name]),
|
||||
format_columns.DictColumn(q.specs),
|
||||
))
|
||||
data.append(
|
||||
(
|
||||
q.id,
|
||||
q.name,
|
||||
q.consumer,
|
||||
format_columns.ListColumn([qos_association.name]),
|
||||
format_columns.DictColumn(q.specs),
|
||||
)
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super(TestQosList, self).setUp()
|
||||
@ -373,7 +351,6 @@ class TestQosList(TestQos):
|
||||
|
||||
|
||||
class TestQosSet(TestQos):
|
||||
|
||||
qos_spec = volume_fakes.create_one_qos()
|
||||
|
||||
def setUp(self):
|
||||
@ -385,8 +362,10 @@ class TestQosSet(TestQos):
|
||||
|
||||
def test_qos_set_with_properties_with_id(self):
|
||||
arglist = [
|
||||
'--property', 'foo=bar',
|
||||
'--property', 'iops=9001',
|
||||
'--property',
|
||||
'foo=bar',
|
||||
'--property',
|
||||
'iops=9001',
|
||||
self.qos_spec.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -398,24 +377,16 @@ class TestQosSet(TestQos):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.qos_mock.set_keys.assert_called_with(
|
||||
self.qos_spec.id,
|
||||
self.qos_spec.specs
|
||||
self.qos_spec.id, self.qos_spec.specs
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
||||
class TestQosShow(TestQos):
|
||||
|
||||
qos_spec = volume_fakes.create_one_qos()
|
||||
qos_association = volume_fakes.create_one_qos_association()
|
||||
|
||||
columns = (
|
||||
'associations',
|
||||
'consumer',
|
||||
'id',
|
||||
'name',
|
||||
'properties'
|
||||
)
|
||||
columns = ('associations', 'consumer', 'id', 'name', 'properties')
|
||||
data = (
|
||||
format_columns.ListColumn([qos_association.name]),
|
||||
qos_spec.consumer,
|
||||
@ -434,26 +405,19 @@ class TestQosShow(TestQos):
|
||||
self.cmd = qos_specs.ShowQos(self.app, None)
|
||||
|
||||
def test_qos_show(self):
|
||||
arglist = [
|
||||
self.qos_spec.id
|
||||
]
|
||||
verifylist = [
|
||||
('qos_spec', self.qos_spec.id)
|
||||
]
|
||||
arglist = [self.qos_spec.id]
|
||||
verifylist = [('qos_spec', self.qos_spec.id)]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.qos_mock.get.assert_called_with(
|
||||
self.qos_spec.id
|
||||
)
|
||||
self.qos_mock.get.assert_called_with(self.qos_spec.id)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, tuple(data))
|
||||
|
||||
|
||||
class TestQosUnset(TestQos):
|
||||
|
||||
qos_spec = volume_fakes.create_one_qos()
|
||||
|
||||
def setUp(self):
|
||||
@ -465,8 +429,10 @@ class TestQosUnset(TestQos):
|
||||
|
||||
def test_qos_unset_with_properties(self):
|
||||
arglist = [
|
||||
'--property', 'iops',
|
||||
'--property', 'foo',
|
||||
'--property',
|
||||
'iops',
|
||||
'--property',
|
||||
'foo',
|
||||
self.qos_spec.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -478,7 +444,6 @@ class TestQosUnset(TestQos):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.qos_mock.unset_keys.assert_called_with(
|
||||
self.qos_spec.id,
|
||||
['iops', 'foo']
|
||||
self.qos_spec.id, ['iops', 'foo']
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
@ -19,7 +19,6 @@ from openstackclient.volume.v2 import service
|
||||
|
||||
|
||||
class TestService(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -29,7 +28,6 @@ class TestService(volume_fakes.TestVolume):
|
||||
|
||||
|
||||
class TestServiceList(TestService):
|
||||
|
||||
# The service to be listed
|
||||
services = volume_fakes.create_one_service()
|
||||
|
||||
@ -43,8 +41,10 @@ class TestServiceList(TestService):
|
||||
|
||||
def test_service_list(self):
|
||||
arglist = [
|
||||
'--host', self.services.host,
|
||||
'--service', self.services.binary,
|
||||
'--host',
|
||||
self.services.host,
|
||||
'--service',
|
||||
self.services.binary,
|
||||
]
|
||||
verifylist = [
|
||||
('host', self.services.host),
|
||||
@ -69,14 +69,16 @@ class TestServiceList(TestService):
|
||||
# confirming if all expected columns are present in the result.
|
||||
self.assertEqual(expected_columns, columns)
|
||||
|
||||
datalist = ((
|
||||
self.services.binary,
|
||||
self.services.host,
|
||||
self.services.zone,
|
||||
self.services.status,
|
||||
self.services.state,
|
||||
self.services.updated_at,
|
||||
), )
|
||||
datalist = (
|
||||
(
|
||||
self.services.binary,
|
||||
self.services.host,
|
||||
self.services.zone,
|
||||
self.services.status,
|
||||
self.services.state,
|
||||
self.services.updated_at,
|
||||
),
|
||||
)
|
||||
|
||||
# confirming if all expected values are present in the result.
|
||||
self.assertEqual(datalist, tuple(data))
|
||||
@ -89,19 +91,20 @@ class TestServiceList(TestService):
|
||||
|
||||
# checking if prohibited columns are present in output
|
||||
self.assertNotIn("Disabled Reason", columns)
|
||||
self.assertNotIn(self.services.disabled_reason,
|
||||
tuple(data))
|
||||
self.assertNotIn(self.services.disabled_reason, tuple(data))
|
||||
|
||||
def test_service_list_with_long_option(self):
|
||||
arglist = [
|
||||
'--host', self.services.host,
|
||||
'--service', self.services.binary,
|
||||
'--long'
|
||||
'--host',
|
||||
self.services.host,
|
||||
'--service',
|
||||
self.services.binary,
|
||||
'--long',
|
||||
]
|
||||
verifylist = [
|
||||
('host', self.services.host),
|
||||
('service', self.services.binary),
|
||||
('long', True)
|
||||
('long', True),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
@ -117,21 +120,23 @@ class TestServiceList(TestService):
|
||||
'Status',
|
||||
'State',
|
||||
'Updated At',
|
||||
'Disabled Reason'
|
||||
'Disabled Reason',
|
||||
]
|
||||
|
||||
# confirming if all expected columns are present in the result.
|
||||
self.assertEqual(expected_columns, columns)
|
||||
|
||||
datalist = ((
|
||||
self.services.binary,
|
||||
self.services.host,
|
||||
self.services.zone,
|
||||
self.services.status,
|
||||
self.services.state,
|
||||
self.services.updated_at,
|
||||
self.services.disabled_reason,
|
||||
), )
|
||||
datalist = (
|
||||
(
|
||||
self.services.binary,
|
||||
self.services.host,
|
||||
self.services.zone,
|
||||
self.services.status,
|
||||
self.services.state,
|
||||
self.services.updated_at,
|
||||
self.services.disabled_reason,
|
||||
),
|
||||
)
|
||||
|
||||
# confirming if all expected values are present in the result.
|
||||
self.assertEqual(datalist, tuple(data))
|
||||
@ -143,7 +148,6 @@ class TestServiceList(TestService):
|
||||
|
||||
|
||||
class TestServiceSet(TestService):
|
||||
|
||||
service = volume_fakes.create_one_service()
|
||||
|
||||
def setUp(self):
|
||||
@ -188,8 +192,7 @@ class TestServiceSet(TestService):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.service_mock.enable.assert_called_with(
|
||||
self.service.host,
|
||||
self.service.binary
|
||||
self.service.host, self.service.binary
|
||||
)
|
||||
self.service_mock.disable.assert_not_called()
|
||||
self.service_mock.disable_log_reason.assert_not_called()
|
||||
@ -211,8 +214,7 @@ class TestServiceSet(TestService):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.service_mock.disable.assert_called_with(
|
||||
self.service.host,
|
||||
self.service.binary
|
||||
self.service.host, self.service.binary
|
||||
)
|
||||
self.service_mock.enable.assert_not_called()
|
||||
self.service_mock.disable_log_reason.assert_not_called()
|
||||
@ -222,7 +224,8 @@ class TestServiceSet(TestService):
|
||||
reason = 'earthquake'
|
||||
arglist = [
|
||||
'--disable',
|
||||
'--disable-reason', reason,
|
||||
'--disable-reason',
|
||||
reason,
|
||||
self.service.host,
|
||||
self.service.binary,
|
||||
]
|
||||
@ -237,16 +240,15 @@ class TestServiceSet(TestService):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.service_mock.disable_log_reason.assert_called_with(
|
||||
self.service.host,
|
||||
self.service.binary,
|
||||
reason
|
||||
self.service.host, self.service.binary, reason
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_service_set_only_with_disable_reason(self):
|
||||
reason = 'earthquake'
|
||||
arglist = [
|
||||
'--disable-reason', reason,
|
||||
'--disable-reason',
|
||||
reason,
|
||||
self.service.host,
|
||||
self.service.binary,
|
||||
]
|
||||
@ -260,14 +262,18 @@ class TestServiceSet(TestService):
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.fail("CommandError should be raised.")
|
||||
except exceptions.CommandError as e:
|
||||
self.assertEqual("Cannot specify option --disable-reason without "
|
||||
"--disable specified.", str(e))
|
||||
self.assertEqual(
|
||||
"Cannot specify option --disable-reason without "
|
||||
"--disable specified.",
|
||||
str(e),
|
||||
)
|
||||
|
||||
def test_service_set_enable_with_disable_reason(self):
|
||||
reason = 'earthquake'
|
||||
arglist = [
|
||||
'--enable',
|
||||
'--disable-reason', reason,
|
||||
'--disable-reason',
|
||||
reason,
|
||||
self.service.host,
|
||||
self.service.binary,
|
||||
]
|
||||
@ -282,5 +288,8 @@ class TestServiceSet(TestService):
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.fail("CommandError should be raised.")
|
||||
except exceptions.CommandError as e:
|
||||
self.assertEqual("Cannot specify option --disable-reason without "
|
||||
"--disable specified.", str(e))
|
||||
self.assertEqual(
|
||||
"Cannot specify option --disable-reason without "
|
||||
"--disable specified.",
|
||||
str(e),
|
||||
)
|
||||
|
@ -26,7 +26,6 @@ from openstackclient.volume.v2 import volume_type
|
||||
|
||||
|
||||
class TestType(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -34,11 +33,13 @@ class TestType(volume_fakes.TestVolume):
|
||||
self.types_mock.reset_mock()
|
||||
|
||||
self.types_access_mock = (
|
||||
self.app.client_manager.volume.volume_type_access)
|
||||
self.app.client_manager.volume.volume_type_access
|
||||
)
|
||||
self.types_access_mock.reset_mock()
|
||||
|
||||
self.encryption_types_mock = (
|
||||
self.app.client_manager.volume.volume_encryption_types)
|
||||
self.app.client_manager.volume.volume_encryption_types
|
||||
)
|
||||
self.encryption_types_mock.reset_mock()
|
||||
|
||||
self.projects_mock = self.app.client_manager.identity.projects
|
||||
@ -46,7 +47,6 @@ class TestType(volume_fakes.TestVolume):
|
||||
|
||||
|
||||
class TestTypeCreate(TestType):
|
||||
|
||||
project = identity_fakes.FakeProject.create_one_project()
|
||||
columns = (
|
||||
'description',
|
||||
@ -73,7 +73,8 @@ class TestTypeCreate(TestType):
|
||||
|
||||
def test_type_create_public(self):
|
||||
arglist = [
|
||||
"--description", self.new_volume_type.description,
|
||||
"--description",
|
||||
self.new_volume_type.description,
|
||||
"--public",
|
||||
self.new_volume_type.name,
|
||||
]
|
||||
@ -97,9 +98,11 @@ class TestTypeCreate(TestType):
|
||||
|
||||
def test_type_create_private(self):
|
||||
arglist = [
|
||||
"--description", self.new_volume_type.description,
|
||||
"--description",
|
||||
self.new_volume_type.description,
|
||||
"--private",
|
||||
"--project", self.project.id,
|
||||
"--project",
|
||||
self.project.id,
|
||||
self.new_volume_type.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -123,7 +126,8 @@ class TestTypeCreate(TestType):
|
||||
|
||||
def test_public_type_create_with_project(self):
|
||||
arglist = [
|
||||
'--project', self.project.id,
|
||||
'--project',
|
||||
self.project.id,
|
||||
self.new_volume_type.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -132,9 +136,9 @@ class TestTypeCreate(TestType):
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
self.assertRaises(
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
|
||||
def test_type_create_with_encryption(self):
|
||||
encryption_info = {
|
||||
@ -166,10 +170,14 @@ class TestTypeCreate(TestType):
|
||||
self.new_volume_type.name,
|
||||
)
|
||||
arglist = [
|
||||
'--encryption-provider', 'LuksEncryptor',
|
||||
'--encryption-cipher', 'aes-xts-plain64',
|
||||
'--encryption-key-size', '128',
|
||||
'--encryption-control-location', 'front-end',
|
||||
'--encryption-provider',
|
||||
'LuksEncryptor',
|
||||
'--encryption-cipher',
|
||||
'aes-xts-plain64',
|
||||
'--encryption-key-size',
|
||||
'128',
|
||||
'--encryption-control-location',
|
||||
'front-end',
|
||||
self.new_volume_type.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -201,7 +209,6 @@ class TestTypeCreate(TestType):
|
||||
|
||||
|
||||
class TestTypeDelete(TestType):
|
||||
|
||||
volume_types = volume_fakes.create_volume_types(count=2)
|
||||
|
||||
def setUp(self):
|
||||
@ -216,12 +223,8 @@ class TestTypeDelete(TestType):
|
||||
self.cmd = volume_type.DeleteVolumeType(self.app, None)
|
||||
|
||||
def test_type_delete(self):
|
||||
arglist = [
|
||||
self.volume_types[0].id
|
||||
]
|
||||
verifylist = [
|
||||
("volume_types", [self.volume_types[0].id])
|
||||
]
|
||||
arglist = [self.volume_types[0].id]
|
||||
verifylist = [("volume_types", [self.volume_types[0].id])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
@ -258,16 +261,17 @@ class TestTypeDelete(TestType):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
find_mock_result = [self.volume_types[0], exceptions.CommandError]
|
||||
with mock.patch.object(utils, 'find_resource',
|
||||
side_effect=find_mock_result) as find_mock:
|
||||
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 volume types failed to delete.',
|
||||
str(e))
|
||||
find_mock.assert_any_call(
|
||||
self.types_mock, self.volume_types[0].id)
|
||||
self.assertEqual(
|
||||
'1 of 2 volume types failed to delete.', str(e)
|
||||
)
|
||||
find_mock.assert_any_call(self.types_mock, self.volume_types[0].id)
|
||||
find_mock.assert_any_call(self.types_mock, 'unexist_type')
|
||||
|
||||
self.assertEqual(2, find_mock.call_count)
|
||||
@ -277,7 +281,6 @@ class TestTypeDelete(TestType):
|
||||
|
||||
|
||||
class TestTypeList(TestType):
|
||||
|
||||
volume_types = volume_fakes.create_volume_types()
|
||||
|
||||
columns = [
|
||||
@ -285,31 +288,28 @@ class TestTypeList(TestType):
|
||||
"Name",
|
||||
"Is Public",
|
||||
]
|
||||
columns_long = columns + [
|
||||
"Description",
|
||||
"Properties"
|
||||
]
|
||||
data_with_default_type = [(
|
||||
volume_types[0].id,
|
||||
volume_types[0].name,
|
||||
True
|
||||
)]
|
||||
columns_long = columns + ["Description", "Properties"]
|
||||
data_with_default_type = [(volume_types[0].id, volume_types[0].name, True)]
|
||||
data = []
|
||||
for t in volume_types:
|
||||
data.append((
|
||||
t.id,
|
||||
t.name,
|
||||
t.is_public,
|
||||
))
|
||||
data.append(
|
||||
(
|
||||
t.id,
|
||||
t.name,
|
||||
t.is_public,
|
||||
)
|
||||
)
|
||||
data_long = []
|
||||
for t in volume_types:
|
||||
data_long.append((
|
||||
t.id,
|
||||
t.name,
|
||||
t.is_public,
|
||||
t.description,
|
||||
format_columns.DictColumn(t.extra_specs),
|
||||
))
|
||||
data_long.append(
|
||||
(
|
||||
t.id,
|
||||
t.name,
|
||||
t.is_public,
|
||||
t.description,
|
||||
format_columns.DictColumn(t.extra_specs),
|
||||
)
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@ -401,21 +401,25 @@ class TestTypeList(TestType):
|
||||
"Encryption",
|
||||
]
|
||||
encryption_data = []
|
||||
encryption_data.append((
|
||||
self.volume_types[0].id,
|
||||
self.volume_types[0].name,
|
||||
self.volume_types[0].is_public,
|
||||
volume_type.EncryptionInfoColumn(
|
||||
encryption_data.append(
|
||||
(
|
||||
self.volume_types[0].id,
|
||||
{self.volume_types[0].id: encryption_info}),
|
||||
))
|
||||
encryption_data.append((
|
||||
self.volume_types[1].id,
|
||||
self.volume_types[1].name,
|
||||
self.volume_types[1].is_public,
|
||||
volume_type.EncryptionInfoColumn(
|
||||
self.volume_types[1].id, {}),
|
||||
))
|
||||
self.volume_types[0].name,
|
||||
self.volume_types[0].is_public,
|
||||
volume_type.EncryptionInfoColumn(
|
||||
self.volume_types[0].id,
|
||||
{self.volume_types[0].id: encryption_info},
|
||||
),
|
||||
)
|
||||
)
|
||||
encryption_data.append(
|
||||
(
|
||||
self.volume_types[1].id,
|
||||
self.volume_types[1].name,
|
||||
self.volume_types[1].is_public,
|
||||
volume_type.EncryptionInfoColumn(self.volume_types[1].id, {}),
|
||||
)
|
||||
)
|
||||
|
||||
self.encryption_types_mock.list.return_value = [encryption_type]
|
||||
arglist = [
|
||||
@ -434,7 +438,6 @@ class TestTypeList(TestType):
|
||||
|
||||
|
||||
class TestTypeSet(TestType):
|
||||
|
||||
project = identity_fakes.FakeProject.create_one_project()
|
||||
volume_type = volume_fakes.create_one_volume_type(
|
||||
methods={'set_keys': None},
|
||||
@ -455,7 +458,8 @@ class TestTypeSet(TestType):
|
||||
def test_type_set_name(self):
|
||||
new_name = 'new_name'
|
||||
arglist = [
|
||||
'--name', new_name,
|
||||
'--name',
|
||||
new_name,
|
||||
self.volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -473,15 +477,15 @@ class TestTypeSet(TestType):
|
||||
'name': new_name,
|
||||
}
|
||||
self.types_mock.update.assert_called_with(
|
||||
self.volume_type.id,
|
||||
**kwargs
|
||||
self.volume_type.id, **kwargs
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_type_set_description(self):
|
||||
new_desc = 'new_desc'
|
||||
arglist = [
|
||||
'--description', new_desc,
|
||||
'--description',
|
||||
new_desc,
|
||||
self.volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -499,14 +503,14 @@ class TestTypeSet(TestType):
|
||||
'description': new_desc,
|
||||
}
|
||||
self.types_mock.update.assert_called_with(
|
||||
self.volume_type.id,
|
||||
**kwargs
|
||||
self.volume_type.id, **kwargs
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_type_set_property(self):
|
||||
arglist = [
|
||||
'--property', 'myprop=myvalue',
|
||||
'--property',
|
||||
'myprop=myvalue',
|
||||
self.volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -519,12 +523,14 @@ class TestTypeSet(TestType):
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.volume_type.set_keys.assert_called_once_with(
|
||||
{'myprop': 'myvalue'})
|
||||
{'myprop': 'myvalue'}
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_type_set_not_called_without_project_argument(self):
|
||||
arglist = [
|
||||
'--project', '',
|
||||
'--project',
|
||||
'',
|
||||
self.volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -541,21 +547,25 @@ class TestTypeSet(TestType):
|
||||
|
||||
def test_type_set_failed_with_missing_volume_type_argument(self):
|
||||
arglist = [
|
||||
'--project', 'identity_fakes.project_id',
|
||||
'--project',
|
||||
'identity_fakes.project_id',
|
||||
]
|
||||
verifylist = [
|
||||
('project', 'identity_fakes.project_id'),
|
||||
]
|
||||
|
||||
self.assertRaises(tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist)
|
||||
self.assertRaises(
|
||||
tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist,
|
||||
)
|
||||
|
||||
def test_type_set_project_access(self):
|
||||
arglist = [
|
||||
'--project', self.project.id,
|
||||
'--project',
|
||||
self.project.id,
|
||||
self.volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -573,13 +583,18 @@ class TestTypeSet(TestType):
|
||||
)
|
||||
|
||||
def test_type_set_new_encryption(self):
|
||||
self.encryption_types_mock.update.side_effect = (
|
||||
exceptions.NotFound('NotFound'))
|
||||
self.encryption_types_mock.update.side_effect = exceptions.NotFound(
|
||||
'NotFound'
|
||||
)
|
||||
arglist = [
|
||||
'--encryption-provider', 'LuksEncryptor',
|
||||
'--encryption-cipher', 'aes-xts-plain64',
|
||||
'--encryption-key-size', '128',
|
||||
'--encryption-control-location', 'front-end',
|
||||
'--encryption-provider',
|
||||
'LuksEncryptor',
|
||||
'--encryption-cipher',
|
||||
'aes-xts-plain64',
|
||||
'--encryption-key-size',
|
||||
'128',
|
||||
'--encryption-control-location',
|
||||
'front-end',
|
||||
self.volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -610,12 +625,14 @@ class TestTypeSet(TestType):
|
||||
|
||||
@mock.patch.object(utils, 'find_resource')
|
||||
def test_type_set_existing_encryption(self, mock_find):
|
||||
mock_find.side_effect = [self.volume_type,
|
||||
"existing_encryption_type"]
|
||||
mock_find.side_effect = [self.volume_type, "existing_encryption_type"]
|
||||
arglist = [
|
||||
'--encryption-provider', 'LuksEncryptor',
|
||||
'--encryption-cipher', 'aes-xts-plain64',
|
||||
'--encryption-control-location', 'front-end',
|
||||
'--encryption-provider',
|
||||
'LuksEncryptor',
|
||||
'--encryption-cipher',
|
||||
'aes-xts-plain64',
|
||||
'--encryption-control-location',
|
||||
'front-end',
|
||||
self.volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -640,12 +657,16 @@ class TestTypeSet(TestType):
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_type_set_new_encryption_without_provider(self):
|
||||
self.encryption_types_mock.update.side_effect = (
|
||||
exceptions.NotFound('NotFound'))
|
||||
self.encryption_types_mock.update.side_effect = exceptions.NotFound(
|
||||
'NotFound'
|
||||
)
|
||||
arglist = [
|
||||
'--encryption-cipher', 'aes-xts-plain64',
|
||||
'--encryption-key-size', '128',
|
||||
'--encryption-control-location', 'front-end',
|
||||
'--encryption-cipher',
|
||||
'aes-xts-plain64',
|
||||
'--encryption-key-size',
|
||||
'128',
|
||||
'--encryption-control-location',
|
||||
'front-end',
|
||||
self.volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -659,9 +680,10 @@ class TestTypeSet(TestType):
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.fail('CommandError should be raised.')
|
||||
except exceptions.CommandError as e:
|
||||
self.assertEqual("Command Failed: One or more of"
|
||||
" the operations failed",
|
||||
str(e))
|
||||
self.assertEqual(
|
||||
"Command Failed: One or more of" " the operations failed",
|
||||
str(e),
|
||||
)
|
||||
body = {
|
||||
'cipher': 'aes-xts-plain64',
|
||||
'key_size': 128,
|
||||
@ -675,7 +697,6 @@ class TestTypeSet(TestType):
|
||||
|
||||
|
||||
class TestTypeShow(TestType):
|
||||
|
||||
columns = (
|
||||
'access_project_ids',
|
||||
'description',
|
||||
@ -695,7 +716,7 @@ class TestTypeShow(TestType):
|
||||
self.volume_type.id,
|
||||
True,
|
||||
self.volume_type.name,
|
||||
format_columns.DictColumn(self.volume_type.extra_specs)
|
||||
format_columns.DictColumn(self.volume_type.extra_specs),
|
||||
)
|
||||
|
||||
self.types_mock.get.return_value = self.volume_type
|
||||
@ -704,12 +725,10 @@ class TestTypeShow(TestType):
|
||||
self.cmd = volume_type.ShowVolumeType(self.app, None)
|
||||
|
||||
def test_type_show(self):
|
||||
arglist = [
|
||||
self.volume_type.id
|
||||
]
|
||||
arglist = [self.volume_type.id]
|
||||
verifylist = [
|
||||
("encryption_type", False),
|
||||
("volume_type", self.volume_type.id)
|
||||
("volume_type", self.volume_type.id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
@ -720,12 +739,8 @@ class TestTypeShow(TestType):
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_type_show_with_access(self):
|
||||
arglist = [
|
||||
self.volume_type.id
|
||||
]
|
||||
verifylist = [
|
||||
("volume_type", self.volume_type.id)
|
||||
]
|
||||
arglist = [self.volume_type.id]
|
||||
verifylist = [("volume_type", self.volume_type.id)]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
private_type = volume_fakes.create_one_volume_type(
|
||||
@ -744,9 +759,11 @@ class TestTypeShow(TestType):
|
||||
):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.types_mock.get.assert_called_once_with(
|
||||
self.volume_type.id)
|
||||
self.volume_type.id
|
||||
)
|
||||
self.types_access_mock.list.assert_called_once_with(
|
||||
private_type.id)
|
||||
private_type.id
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
private_type_data = (
|
||||
@ -755,31 +772,31 @@ class TestTypeShow(TestType):
|
||||
private_type.id,
|
||||
private_type.is_public,
|
||||
private_type.name,
|
||||
format_columns.DictColumn(private_type.extra_specs)
|
||||
format_columns.DictColumn(private_type.extra_specs),
|
||||
)
|
||||
self.assertCountEqual(private_type_data, data)
|
||||
|
||||
def test_type_show_with_list_access_exec(self):
|
||||
arglist = [
|
||||
self.volume_type.id
|
||||
]
|
||||
verifylist = [
|
||||
("volume_type", self.volume_type.id)
|
||||
]
|
||||
arglist = [self.volume_type.id]
|
||||
verifylist = [("volume_type", self.volume_type.id)]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
private_type = volume_fakes.create_one_volume_type(
|
||||
attrs={'is_public': False},
|
||||
)
|
||||
with mock.patch.object(self.types_mock, 'get',
|
||||
return_value=private_type):
|
||||
with mock.patch.object(self.types_access_mock, 'list',
|
||||
side_effect=Exception()):
|
||||
with mock.patch.object(
|
||||
self.types_mock, 'get', return_value=private_type
|
||||
):
|
||||
with mock.patch.object(
|
||||
self.types_access_mock, 'list', side_effect=Exception()
|
||||
):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.types_mock.get.assert_called_once_with(
|
||||
self.volume_type.id)
|
||||
self.volume_type.id
|
||||
)
|
||||
self.types_access_mock.list.assert_called_once_with(
|
||||
private_type.id)
|
||||
private_type.id
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
private_type_data = (
|
||||
@ -788,7 +805,7 @@ class TestTypeShow(TestType):
|
||||
private_type.id,
|
||||
private_type.is_public,
|
||||
private_type.name,
|
||||
format_columns.DictColumn(private_type.extra_specs)
|
||||
format_columns.DictColumn(private_type.extra_specs),
|
||||
)
|
||||
self.assertCountEqual(private_type_data, data)
|
||||
|
||||
@ -821,15 +838,12 @@ class TestTypeShow(TestType):
|
||||
self.volume_type.id,
|
||||
True,
|
||||
self.volume_type.name,
|
||||
format_columns.DictColumn(self.volume_type.extra_specs)
|
||||
format_columns.DictColumn(self.volume_type.extra_specs),
|
||||
)
|
||||
arglist = [
|
||||
'--encryption-type',
|
||||
self.volume_type.id
|
||||
]
|
||||
arglist = ['--encryption-type', self.volume_type.id]
|
||||
verifylist = [
|
||||
('encryption_type', True),
|
||||
("volume_type", self.volume_type.id)
|
||||
("volume_type", self.volume_type.id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
@ -841,7 +855,6 @@ class TestTypeShow(TestType):
|
||||
|
||||
|
||||
class TestTypeUnset(TestType):
|
||||
|
||||
project = identity_fakes.FakeProject.create_one_project()
|
||||
volume_type = volume_fakes.create_one_volume_type(
|
||||
methods={'unset_keys': None},
|
||||
@ -860,8 +873,10 @@ class TestTypeUnset(TestType):
|
||||
|
||||
def test_type_unset(self):
|
||||
arglist = [
|
||||
'--property', 'property',
|
||||
'--property', 'multi_property',
|
||||
'--property',
|
||||
'property',
|
||||
'--property',
|
||||
'multi_property',
|
||||
self.volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -873,12 +888,14 @@ class TestTypeUnset(TestType):
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.volume_type.unset_keys.assert_called_once_with(
|
||||
['property', 'multi_property'])
|
||||
['property', 'multi_property']
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_type_unset_project_access(self):
|
||||
arglist = [
|
||||
'--project', self.project.id,
|
||||
'--project',
|
||||
self.project.id,
|
||||
self.volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -897,7 +914,8 @@ class TestTypeUnset(TestType):
|
||||
|
||||
def test_type_unset_not_called_without_project_argument(self):
|
||||
arglist = [
|
||||
'--project', '',
|
||||
'--project',
|
||||
'',
|
||||
self.volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -915,17 +933,20 @@ class TestTypeUnset(TestType):
|
||||
|
||||
def test_type_unset_failed_with_missing_volume_type_argument(self):
|
||||
arglist = [
|
||||
'--project', 'identity_fakes.project_id',
|
||||
'--project',
|
||||
'identity_fakes.project_id',
|
||||
]
|
||||
verifylist = [
|
||||
('project', 'identity_fakes.project_id'),
|
||||
]
|
||||
|
||||
self.assertRaises(tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist)
|
||||
self.assertRaises(
|
||||
tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist,
|
||||
)
|
||||
|
||||
def test_type_unset_encryption_type(self):
|
||||
arglist = [
|
||||
@ -944,7 +965,6 @@ class TestTypeUnset(TestType):
|
||||
|
||||
|
||||
class TestColumns(TestType):
|
||||
|
||||
def test_encryption_info_column_with_info(self):
|
||||
fake_volume_type = volume_fakes.create_one_volume_type()
|
||||
type_id = fake_volume_type.id
|
||||
@ -955,10 +975,12 @@ class TestColumns(TestType):
|
||||
'key_size': None,
|
||||
'control_location': 'front-end',
|
||||
}
|
||||
col = volume_type.EncryptionInfoColumn(type_id,
|
||||
{type_id: encryption_info})
|
||||
self.assertEqual(utils.format_dict(encryption_info),
|
||||
col.human_readable())
|
||||
col = volume_type.EncryptionInfoColumn(
|
||||
type_id, {type_id: encryption_info}
|
||||
)
|
||||
self.assertEqual(
|
||||
utils.format_dict(encryption_info), col.human_readable()
|
||||
)
|
||||
self.assertEqual(encryption_info, col.machine_readable())
|
||||
|
||||
def test_encryption_info_column_without_info(self):
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -105,9 +105,7 @@ class TestListVolumePool(volume_fakes.TestVolume):
|
||||
# confirming if all expected columns are present in the result.
|
||||
self.assertEqual(expected_columns, columns)
|
||||
|
||||
datalist = ((
|
||||
self.pools.name,
|
||||
), )
|
||||
datalist = ((self.pools.name,),)
|
||||
|
||||
# confirming if all expected values are present in the result.
|
||||
self.assertEqual(datalist, tuple(data))
|
||||
@ -122,12 +120,8 @@ class TestListVolumePool(volume_fakes.TestVolume):
|
||||
self.assertNotIn("storage_protocol", columns)
|
||||
|
||||
def test_service_list_with_long_option(self):
|
||||
arglist = [
|
||||
'--long'
|
||||
]
|
||||
verifylist = [
|
||||
('long', True)
|
||||
]
|
||||
arglist = ['--long']
|
||||
verifylist = [('long', True)]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
# In base command class Lister in cliff, abstract method take_action()
|
||||
@ -149,16 +143,18 @@ class TestListVolumePool(volume_fakes.TestVolume):
|
||||
# confirming if all expected columns are present in the result.
|
||||
self.assertEqual(expected_columns, columns)
|
||||
|
||||
datalist = ((
|
||||
self.pools.name,
|
||||
self.pools.storage_protocol,
|
||||
self.pools.thick_provisioning_support,
|
||||
self.pools.thin_provisioning_support,
|
||||
self.pools.total_volumes,
|
||||
self.pools.total_capacity_gb,
|
||||
self.pools.allocated_capacity_gb,
|
||||
self.pools.max_over_subscription_ratio,
|
||||
), )
|
||||
datalist = (
|
||||
(
|
||||
self.pools.name,
|
||||
self.pools.storage_protocol,
|
||||
self.pools.thick_provisioning_support,
|
||||
self.pools.thin_provisioning_support,
|
||||
self.pools.total_volumes,
|
||||
self.pools.total_capacity_gb,
|
||||
self.pools.allocated_capacity_gb,
|
||||
self.pools.max_over_subscription_ratio,
|
||||
),
|
||||
)
|
||||
|
||||
# confirming if all expected values are present in the result.
|
||||
self.assertEqual(datalist, tuple(data))
|
||||
|
@ -24,7 +24,6 @@ from openstackclient.volume.v2 import volume_backup
|
||||
|
||||
|
||||
class TestBackup(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -39,11 +38,11 @@ class TestBackup(volume_fakes.TestVolume):
|
||||
|
||||
|
||||
class TestBackupCreate(TestBackup):
|
||||
|
||||
volume = volume_fakes.create_one_volume()
|
||||
snapshot = volume_fakes.create_one_snapshot()
|
||||
new_backup = volume_fakes.create_one_backup(
|
||||
attrs={'volume_id': volume.id, 'snapshot_id': snapshot.id})
|
||||
attrs={'volume_id': volume.id, 'snapshot_id': snapshot.id}
|
||||
)
|
||||
|
||||
columns = (
|
||||
'availability_zone',
|
||||
@ -82,12 +81,16 @@ class TestBackupCreate(TestBackup):
|
||||
|
||||
def test_backup_create(self):
|
||||
arglist = [
|
||||
"--name", self.new_backup.name,
|
||||
"--description", self.new_backup.description,
|
||||
"--container", self.new_backup.container,
|
||||
"--name",
|
||||
self.new_backup.name,
|
||||
"--description",
|
||||
self.new_backup.description,
|
||||
"--container",
|
||||
self.new_backup.container,
|
||||
"--force",
|
||||
"--incremental",
|
||||
"--snapshot", self.new_backup.snapshot_id,
|
||||
"--snapshot",
|
||||
self.new_backup.snapshot_id,
|
||||
self.new_backup.volume_id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -116,12 +119,15 @@ class TestBackupCreate(TestBackup):
|
||||
self.assertEqual(self.data, data)
|
||||
|
||||
def test_backup_create_with_properties(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.43')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.43'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
"--property", "foo=bar",
|
||||
"--property", "wow=much-cool",
|
||||
"--property",
|
||||
"foo=bar",
|
||||
"--property",
|
||||
"wow=much-cool",
|
||||
self.new_backup.volume_id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -145,12 +151,15 @@ class TestBackupCreate(TestBackup):
|
||||
self.assertEqual(self.data, data)
|
||||
|
||||
def test_backup_create_with_properties_pre_v343(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.42')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.42'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
"--property", "foo=bar",
|
||||
"--property", "wow=much-cool",
|
||||
"--property",
|
||||
"foo=bar",
|
||||
"--property",
|
||||
"wow=much-cool",
|
||||
self.new_backup.volume_id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -160,17 +169,18 @@ class TestBackupCreate(TestBackup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn("--os-volume-api-version 3.43 or greater", str(exc))
|
||||
|
||||
def test_backup_create_with_availability_zone(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.51')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.51'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
"--availability-zone", "my-az",
|
||||
"--availability-zone",
|
||||
"my-az",
|
||||
self.new_backup.volume_id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -194,11 +204,13 @@ class TestBackupCreate(TestBackup):
|
||||
self.assertEqual(self.data, data)
|
||||
|
||||
def test_backup_create_with_availability_zone_pre_v351(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.50')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.50'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
"--availability-zone", "my-az",
|
||||
"--availability-zone",
|
||||
"my-az",
|
||||
self.new_backup.volume_id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -208,15 +220,16 @@ class TestBackupCreate(TestBackup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn("--os-volume-api-version 3.51 or greater", str(exc))
|
||||
|
||||
def test_backup_create_without_name(self):
|
||||
arglist = [
|
||||
"--description", self.new_backup.description,
|
||||
"--container", self.new_backup.container,
|
||||
"--description",
|
||||
self.new_backup.description,
|
||||
"--container",
|
||||
self.new_backup.container,
|
||||
self.new_backup.volume_id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -241,32 +254,25 @@ class TestBackupCreate(TestBackup):
|
||||
|
||||
|
||||
class TestBackupDelete(TestBackup):
|
||||
|
||||
backups = volume_fakes.create_backups(count=2)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.backups_mock.get = (
|
||||
volume_fakes.get_backups(self.backups))
|
||||
self.backups_mock.get = volume_fakes.get_backups(self.backups)
|
||||
self.backups_mock.delete.return_value = None
|
||||
|
||||
# Get the command object to mock
|
||||
self.cmd = volume_backup.DeleteVolumeBackup(self.app, None)
|
||||
|
||||
def test_backup_delete(self):
|
||||
arglist = [
|
||||
self.backups[0].id
|
||||
]
|
||||
verifylist = [
|
||||
("backups", [self.backups[0].id])
|
||||
]
|
||||
arglist = [self.backups[0].id]
|
||||
verifylist = [("backups", [self.backups[0].id])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.backups_mock.delete.assert_called_with(
|
||||
self.backups[0].id, False)
|
||||
self.backups_mock.delete.assert_called_with(self.backups[0].id, False)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_backup_delete_with_force(self):
|
||||
@ -274,10 +280,7 @@ class TestBackupDelete(TestBackup):
|
||||
'--force',
|
||||
self.backups[0].id,
|
||||
]
|
||||
verifylist = [
|
||||
('force', True),
|
||||
("backups", [self.backups[0].id])
|
||||
]
|
||||
verifylist = [('force', True), ("backups", [self.backups[0].id])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
@ -314,14 +317,14 @@ class TestBackupDelete(TestBackup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
find_mock_result = [self.backups[0], exceptions.CommandError]
|
||||
with mock.patch.object(utils, 'find_resource',
|
||||
side_effect=find_mock_result) as find_mock:
|
||||
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 backups failed to delete.',
|
||||
str(e))
|
||||
self.assertEqual('1 of 2 backups failed to delete.', str(e))
|
||||
|
||||
find_mock.assert_any_call(self.backups_mock, self.backups[0].id)
|
||||
find_mock.assert_any_call(self.backups_mock, 'unexist_backup')
|
||||
@ -333,10 +336,10 @@ class TestBackupDelete(TestBackup):
|
||||
|
||||
|
||||
class TestBackupList(TestBackup):
|
||||
|
||||
volume = volume_fakes.create_one_volume()
|
||||
backups = volume_fakes.create_backups(
|
||||
attrs={'volume_id': volume.name}, count=3)
|
||||
attrs={'volume_id': volume.name}, count=3
|
||||
)
|
||||
|
||||
columns = (
|
||||
'ID',
|
||||
@ -353,25 +356,29 @@ class TestBackupList(TestBackup):
|
||||
|
||||
data = []
|
||||
for b in backups:
|
||||
data.append((
|
||||
b.id,
|
||||
b.name,
|
||||
b.description,
|
||||
b.status,
|
||||
b.size,
|
||||
))
|
||||
data.append(
|
||||
(
|
||||
b.id,
|
||||
b.name,
|
||||
b.description,
|
||||
b.status,
|
||||
b.size,
|
||||
)
|
||||
)
|
||||
data_long = []
|
||||
for b in backups:
|
||||
data_long.append((
|
||||
b.id,
|
||||
b.name,
|
||||
b.description,
|
||||
b.status,
|
||||
b.size,
|
||||
b.availability_zone,
|
||||
volume_backup.VolumeIdColumn(b.volume_id),
|
||||
b.container,
|
||||
))
|
||||
data_long.append(
|
||||
(
|
||||
b.id,
|
||||
b.name,
|
||||
b.description,
|
||||
b.status,
|
||||
b.size,
|
||||
b.availability_zone,
|
||||
volume_backup.VolumeIdColumn(b.volume_id),
|
||||
b.container,
|
||||
)
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@ -417,12 +424,17 @@ class TestBackupList(TestBackup):
|
||||
def test_backup_list_with_options(self):
|
||||
arglist = [
|
||||
"--long",
|
||||
"--name", self.backups[0].name,
|
||||
"--status", "error",
|
||||
"--volume", self.volume.id,
|
||||
"--marker", self.backups[0].id,
|
||||
"--name",
|
||||
self.backups[0].name,
|
||||
"--status",
|
||||
"error",
|
||||
"--volume",
|
||||
self.volume.id,
|
||||
"--marker",
|
||||
self.backups[0].id,
|
||||
"--all-projects",
|
||||
"--limit", "3",
|
||||
"--limit",
|
||||
"3",
|
||||
]
|
||||
verifylist = [
|
||||
("long", True),
|
||||
@ -455,7 +467,6 @@ class TestBackupList(TestBackup):
|
||||
|
||||
|
||||
class TestBackupRestore(TestBackup):
|
||||
|
||||
volume = volume_fakes.create_one_volume()
|
||||
backup = volume_fakes.create_one_backup(
|
||||
attrs={'volume_id': volume.id},
|
||||
@ -477,9 +488,7 @@ class TestBackupRestore(TestBackup):
|
||||
def test_backup_restore(self):
|
||||
self.volumes_mock.get.side_effect = exceptions.CommandError()
|
||||
self.volumes_mock.find.side_effect = exceptions.CommandError()
|
||||
arglist = [
|
||||
self.backup.id
|
||||
]
|
||||
arglist = [self.backup.id]
|
||||
verifylist = [
|
||||
("backup", self.backup.id),
|
||||
("volume", None),
|
||||
@ -488,7 +497,9 @@ class TestBackupRestore(TestBackup):
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.restores_mock.restore.assert_called_with(
|
||||
self.backup.id, None, None,
|
||||
self.backup.id,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
self.assertIsNotNone(result)
|
||||
|
||||
@ -507,7 +518,9 @@ class TestBackupRestore(TestBackup):
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.restores_mock.restore.assert_called_with(
|
||||
self.backup.id, None, self.backup.volume_id,
|
||||
self.backup.id,
|
||||
None,
|
||||
self.backup.volume_id,
|
||||
)
|
||||
self.assertIsNotNone(result)
|
||||
|
||||
@ -526,7 +539,9 @@ class TestBackupRestore(TestBackup):
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.restores_mock.restore.assert_called_with(
|
||||
self.backup.id, self.volume.id, None,
|
||||
self.backup.id,
|
||||
self.volume.id,
|
||||
None,
|
||||
)
|
||||
self.assertIsNotNone(result)
|
||||
|
||||
@ -549,7 +564,6 @@ class TestBackupRestore(TestBackup):
|
||||
|
||||
|
||||
class TestBackupSet(TestBackup):
|
||||
|
||||
backup = volume_fakes.create_one_backup(
|
||||
attrs={'metadata': {'wow': 'cool'}},
|
||||
)
|
||||
@ -563,11 +577,13 @@ class TestBackupSet(TestBackup):
|
||||
self.cmd = volume_backup.SetVolumeBackup(self.app, None)
|
||||
|
||||
def test_backup_set_name(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.9')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.9'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--name', 'new_name',
|
||||
'--name',
|
||||
'new_name',
|
||||
self.backup.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -580,15 +596,18 @@ class TestBackupSet(TestBackup):
|
||||
# returns nothing
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.backups_mock.update.assert_called_once_with(
|
||||
self.backup.id, **{'name': 'new_name'})
|
||||
self.backup.id, **{'name': 'new_name'}
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_backup_set_name_pre_v39(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.8')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.8'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--name', 'new_name',
|
||||
'--name',
|
||||
'new_name',
|
||||
self.backup.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -598,17 +617,18 @@ class TestBackupSet(TestBackup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn("--os-volume-api-version 3.9 or greater", str(exc))
|
||||
|
||||
def test_backup_set_description(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.9')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.9'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--description', 'new_description',
|
||||
'--description',
|
||||
'new_description',
|
||||
self.backup.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -621,21 +641,20 @@ class TestBackupSet(TestBackup):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
# Set expected values
|
||||
kwargs = {
|
||||
'description': 'new_description'
|
||||
}
|
||||
kwargs = {'description': 'new_description'}
|
||||
self.backups_mock.update.assert_called_once_with(
|
||||
self.backup.id,
|
||||
**kwargs
|
||||
self.backup.id, **kwargs
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_backup_set_description_pre_v39(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.8')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.8'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--description', 'new_description',
|
||||
'--description',
|
||||
'new_description',
|
||||
self.backup.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -646,52 +665,43 @@ class TestBackupSet(TestBackup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn("--os-volume-api-version 3.9 or greater", str(exc))
|
||||
|
||||
def test_backup_set_state(self):
|
||||
arglist = [
|
||||
'--state', 'error',
|
||||
self.backup.id
|
||||
]
|
||||
verifylist = [
|
||||
('state', 'error'),
|
||||
('backup', self.backup.id)
|
||||
]
|
||||
arglist = ['--state', 'error', self.backup.id]
|
||||
verifylist = [('state', 'error'), ('backup', self.backup.id)]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.backups_mock.reset_state.assert_called_once_with(
|
||||
self.backup.id, 'error')
|
||||
self.backup.id, 'error'
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_backup_set_state_failed(self):
|
||||
self.backups_mock.reset_state.side_effect = exceptions.CommandError()
|
||||
arglist = [
|
||||
'--state', 'error',
|
||||
self.backup.id
|
||||
]
|
||||
verifylist = [
|
||||
('state', 'error'),
|
||||
('backup', self.backup.id)
|
||||
]
|
||||
arglist = ['--state', 'error', self.backup.id]
|
||||
verifylist = [('state', 'error'), ('backup', self.backup.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.assertEqual(
|
||||
'One or more of the set operations failed', str(e)
|
||||
)
|
||||
self.backups_mock.reset_state.assert_called_with(
|
||||
self.backup.id, 'error')
|
||||
self.backup.id, 'error'
|
||||
)
|
||||
|
||||
def test_backup_set_no_property(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.43')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.43'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--no-property',
|
||||
@ -710,14 +720,14 @@ class TestBackupSet(TestBackup):
|
||||
'metadata': {},
|
||||
}
|
||||
self.backups_mock.update.assert_called_once_with(
|
||||
self.backup.id,
|
||||
**kwargs
|
||||
self.backup.id, **kwargs
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_backup_set_no_property_pre_v343(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.42')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.42'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--no-property',
|
||||
@ -730,17 +740,18 @@ class TestBackupSet(TestBackup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn("--os-volume-api-version 3.43 or greater", str(exc))
|
||||
|
||||
def test_backup_set_property(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.43')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.43'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--property', 'foo=bar',
|
||||
'--property',
|
||||
'foo=bar',
|
||||
self.backup.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -756,17 +767,18 @@ class TestBackupSet(TestBackup):
|
||||
'metadata': {'wow': 'cool', 'foo': 'bar'},
|
||||
}
|
||||
self.backups_mock.update.assert_called_once_with(
|
||||
self.backup.id,
|
||||
**kwargs
|
||||
self.backup.id, **kwargs
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_backup_set_property_pre_v343(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.42')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.42'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--property', 'foo=bar',
|
||||
'--property',
|
||||
'foo=bar',
|
||||
self.backup.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -776,14 +788,12 @@ class TestBackupSet(TestBackup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn("--os-volume-api-version 3.43 or greater", str(exc))
|
||||
|
||||
|
||||
class TestBackupUnset(TestBackup):
|
||||
|
||||
backup = volume_fakes.create_one_backup(
|
||||
attrs={'metadata': {'foo': 'bar'}},
|
||||
)
|
||||
@ -797,11 +807,13 @@ class TestBackupUnset(TestBackup):
|
||||
self.cmd = volume_backup.UnsetVolumeBackup(self.app, None)
|
||||
|
||||
def test_backup_unset_property(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.43')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.43'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--property', 'foo',
|
||||
'--property',
|
||||
'foo',
|
||||
self.backup.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -817,17 +829,18 @@ class TestBackupUnset(TestBackup):
|
||||
'metadata': {},
|
||||
}
|
||||
self.backups_mock.update.assert_called_once_with(
|
||||
self.backup.id,
|
||||
**kwargs
|
||||
self.backup.id, **kwargs
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_backup_unset_property_pre_v343(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.42')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.42'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--property', 'foo',
|
||||
'--property',
|
||||
'foo',
|
||||
self.backup.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -837,14 +850,12 @@ class TestBackupUnset(TestBackup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn("--os-volume-api-version 3.43 or greater", str(exc))
|
||||
|
||||
|
||||
class TestBackupShow(TestBackup):
|
||||
|
||||
backup = volume_fakes.create_one_backup()
|
||||
|
||||
columns = (
|
||||
@ -880,12 +891,8 @@ class TestBackupShow(TestBackup):
|
||||
self.cmd = volume_backup.ShowVolumeBackup(self.app, None)
|
||||
|
||||
def test_backup_show(self):
|
||||
arglist = [
|
||||
self.backup.id
|
||||
]
|
||||
verifylist = [
|
||||
("backup", self.backup.id)
|
||||
]
|
||||
arglist = [self.backup.id]
|
||||
verifylist = [("backup", self.backup.id)]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
@ -17,7 +17,6 @@ from openstackclient.volume.v2 import volume_host
|
||||
|
||||
|
||||
class TestVolumeHost(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -26,7 +25,6 @@ class TestVolumeHost(volume_fakes.TestVolume):
|
||||
|
||||
|
||||
class TestVolumeHostSet(TestVolumeHost):
|
||||
|
||||
service = volume_fakes.create_one_service()
|
||||
|
||||
def setUp(self):
|
||||
@ -88,7 +86,6 @@ class TestVolumeHostSet(TestVolumeHost):
|
||||
|
||||
|
||||
class TestVolumeHostFailover(TestVolumeHost):
|
||||
|
||||
service = volume_fakes.create_one_service()
|
||||
|
||||
def setUp(self):
|
||||
@ -101,7 +98,8 @@ class TestVolumeHostFailover(TestVolumeHost):
|
||||
|
||||
def test_volume_host_failover(self):
|
||||
arglist = [
|
||||
'--volume-backend', 'backend_test',
|
||||
'--volume-backend',
|
||||
'backend_test',
|
||||
self.service.host,
|
||||
]
|
||||
verifylist = [
|
||||
@ -113,5 +111,6 @@ class TestVolumeHostFailover(TestVolumeHost):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.host_mock.failover_host.assert_called_with(
|
||||
self.service.host, 'backend_test')
|
||||
self.service.host, 'backend_test'
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
@ -26,7 +26,6 @@ from openstackclient.volume.v2 import volume_snapshot
|
||||
|
||||
|
||||
class TestVolumeSnapshot(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -39,7 +38,6 @@ class TestVolumeSnapshot(volume_fakes.TestVolume):
|
||||
|
||||
|
||||
class TestVolumeSnapshotCreate(TestVolumeSnapshot):
|
||||
|
||||
columns = (
|
||||
'created_at',
|
||||
'description',
|
||||
@ -56,7 +54,8 @@ class TestVolumeSnapshotCreate(TestVolumeSnapshot):
|
||||
|
||||
self.volume = volume_fakes.create_one_volume()
|
||||
self.new_snapshot = volume_fakes.create_one_snapshot(
|
||||
attrs={'volume_id': self.volume.id})
|
||||
attrs={'volume_id': self.volume.id}
|
||||
)
|
||||
|
||||
self.data = (
|
||||
self.new_snapshot.created_at,
|
||||
@ -77,11 +76,15 @@ class TestVolumeSnapshotCreate(TestVolumeSnapshot):
|
||||
|
||||
def test_snapshot_create(self):
|
||||
arglist = [
|
||||
"--volume", self.new_snapshot.volume_id,
|
||||
"--description", self.new_snapshot.description,
|
||||
"--volume",
|
||||
self.new_snapshot.volume_id,
|
||||
"--description",
|
||||
self.new_snapshot.description,
|
||||
"--force",
|
||||
'--property', 'Alpha=a',
|
||||
'--property', 'Beta=b',
|
||||
'--property',
|
||||
'Alpha=a',
|
||||
'--property',
|
||||
'Beta=b',
|
||||
self.new_snapshot.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -107,7 +110,8 @@ class TestVolumeSnapshotCreate(TestVolumeSnapshot):
|
||||
|
||||
def test_snapshot_create_without_name(self):
|
||||
arglist = [
|
||||
"--volume", self.new_snapshot.volume_id,
|
||||
"--volume",
|
||||
self.new_snapshot.volume_id,
|
||||
]
|
||||
verifylist = [
|
||||
("volume", self.new_snapshot.volume_id),
|
||||
@ -122,21 +126,21 @@ class TestVolumeSnapshotCreate(TestVolumeSnapshot):
|
||||
|
||||
def test_snapshot_create_without_volume(self):
|
||||
arglist = [
|
||||
"--description", self.new_snapshot.description,
|
||||
"--description",
|
||||
self.new_snapshot.description,
|
||||
"--force",
|
||||
self.new_snapshot.name
|
||||
self.new_snapshot.name,
|
||||
]
|
||||
verifylist = [
|
||||
("description", self.new_snapshot.description),
|
||||
("force", True),
|
||||
("snapshot_name", self.new_snapshot.name)
|
||||
("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.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,
|
||||
@ -149,13 +153,18 @@ class TestVolumeSnapshotCreate(TestVolumeSnapshot):
|
||||
|
||||
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,
|
||||
'--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'}
|
||||
ref_dict = {
|
||||
'source-name': 'test_source_name',
|
||||
'source-id': 'test_source_id',
|
||||
}
|
||||
verifylist = [
|
||||
('remote_source', ref_dict),
|
||||
('volume', self.new_snapshot.volume_id),
|
||||
@ -178,49 +187,39 @@ class TestVolumeSnapshotCreate(TestVolumeSnapshot):
|
||||
|
||||
|
||||
class TestVolumeSnapshotDelete(TestVolumeSnapshot):
|
||||
|
||||
snapshots = volume_fakes.create_snapshots(count=2)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.snapshots_mock.get = (
|
||||
volume_fakes.get_snapshots(self.snapshots))
|
||||
self.snapshots_mock.get = volume_fakes.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])
|
||||
]
|
||||
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.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])
|
||||
]
|
||||
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.snapshots[0].id, True
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_delete_multiple_snapshots(self):
|
||||
@ -252,17 +251,18 @@ class TestVolumeSnapshotDelete(TestVolumeSnapshot):
|
||||
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:
|
||||
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))
|
||||
self.assertEqual('1 of 2 snapshots failed to delete.', str(e))
|
||||
|
||||
find_mock.assert_any_call(
|
||||
self.snapshots_mock, self.snapshots[0].id)
|
||||
self.snapshots_mock, self.snapshots[0].id
|
||||
)
|
||||
find_mock.assert_any_call(self.snapshots_mock, 'unexist_snapshot')
|
||||
|
||||
self.assertEqual(2, find_mock.call_count)
|
||||
@ -272,47 +272,42 @@ class TestVolumeSnapshotDelete(TestVolumeSnapshot):
|
||||
|
||||
|
||||
class TestVolumeSnapshotList(TestVolumeSnapshot):
|
||||
|
||||
volume = volume_fakes.create_one_volume()
|
||||
project = project_fakes.FakeProject.create_one_project()
|
||||
snapshots = volume_fakes.create_snapshots(
|
||||
attrs={'volume_id': volume.name}, count=3)
|
||||
attrs={'volume_id': volume.name}, count=3
|
||||
)
|
||||
|
||||
columns = [
|
||||
"ID",
|
||||
"Name",
|
||||
"Description",
|
||||
"Status",
|
||||
"Size"
|
||||
]
|
||||
columns_long = columns + [
|
||||
"Created At",
|
||||
"Volume",
|
||||
"Properties"
|
||||
]
|
||||
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.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,
|
||||
volume_snapshot.VolumeIdColumn(
|
||||
s.volume_id, volume_cache={volume.id: volume}),
|
||||
format_columns.DictColumn(s.metadata),
|
||||
))
|
||||
data_long.append(
|
||||
(
|
||||
s.id,
|
||||
s.name,
|
||||
s.description,
|
||||
s.status,
|
||||
s.size,
|
||||
s.created_at,
|
||||
volume_snapshot.VolumeIdColumn(
|
||||
s.volume_id, volume_cache={volume.id: volume}
|
||||
),
|
||||
format_columns.DictColumn(s.metadata),
|
||||
)
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@ -326,23 +321,21 @@ class TestVolumeSnapshotList(TestVolumeSnapshot):
|
||||
|
||||
def test_snapshot_list_without_options(self):
|
||||
arglist = []
|
||||
verifylist = [
|
||||
('all_projects', False),
|
||||
('long', False)
|
||||
]
|
||||
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,
|
||||
limit=None,
|
||||
marker=None,
|
||||
search_opts={
|
||||
'all_tenants': False,
|
||||
'name': None,
|
||||
'status': None,
|
||||
'project_id': None,
|
||||
'volume_id': None
|
||||
}
|
||||
'volume_id': None,
|
||||
},
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, list(data))
|
||||
@ -350,9 +343,12 @@ class TestVolumeSnapshotList(TestVolumeSnapshot):
|
||||
def test_snapshot_list_with_options(self):
|
||||
arglist = [
|
||||
"--long",
|
||||
"--limit", "2",
|
||||
"--project", self.project.id,
|
||||
"--marker", self.snapshots[0].id,
|
||||
"--limit",
|
||||
"2",
|
||||
"--project",
|
||||
self.project.id,
|
||||
"--marker",
|
||||
self.snapshots[0].id,
|
||||
]
|
||||
verifylist = [
|
||||
("long", True),
|
||||
@ -373,8 +369,8 @@ class TestVolumeSnapshotList(TestVolumeSnapshot):
|
||||
'project_id': self.project.id,
|
||||
'name': None,
|
||||
'status': None,
|
||||
'volume_id': None
|
||||
}
|
||||
'volume_id': None,
|
||||
},
|
||||
)
|
||||
self.assertEqual(self.columns_long, columns)
|
||||
self.assertEqual(self.data_long, list(data))
|
||||
@ -383,30 +379,29 @@ class TestVolumeSnapshotList(TestVolumeSnapshot):
|
||||
arglist = [
|
||||
'--all-projects',
|
||||
]
|
||||
verifylist = [
|
||||
('long', False),
|
||||
('all_projects', True)
|
||||
]
|
||||
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,
|
||||
limit=None,
|
||||
marker=None,
|
||||
search_opts={
|
||||
'all_tenants': True,
|
||||
'name': None,
|
||||
'status': None,
|
||||
'project_id': None,
|
||||
'volume_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,
|
||||
'--name',
|
||||
self.snapshots[0].name,
|
||||
]
|
||||
verifylist = [
|
||||
('all_projects', False),
|
||||
@ -418,21 +413,23 @@ class TestVolumeSnapshotList(TestVolumeSnapshot):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.snapshots_mock.list.assert_called_once_with(
|
||||
limit=None, marker=None,
|
||||
limit=None,
|
||||
marker=None,
|
||||
search_opts={
|
||||
'all_tenants': False,
|
||||
'name': self.snapshots[0].name,
|
||||
'status': None,
|
||||
'project_id': None,
|
||||
'volume_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,
|
||||
'--status',
|
||||
self.snapshots[0].status,
|
||||
]
|
||||
verifylist = [
|
||||
('all_projects', False),
|
||||
@ -444,21 +441,23 @@ class TestVolumeSnapshotList(TestVolumeSnapshot):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.snapshots_mock.list.assert_called_once_with(
|
||||
limit=None, marker=None,
|
||||
limit=None,
|
||||
marker=None,
|
||||
search_opts={
|
||||
'all_tenants': False,
|
||||
'name': None,
|
||||
'status': self.snapshots[0].status,
|
||||
'project_id': None,
|
||||
'volume_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,
|
||||
'--volume',
|
||||
self.volume.id,
|
||||
]
|
||||
verifylist = [
|
||||
('all_projects', False),
|
||||
@ -470,31 +469,37 @@ class TestVolumeSnapshotList(TestVolumeSnapshot):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.snapshots_mock.list.assert_called_once_with(
|
||||
limit=None, marker=None,
|
||||
limit=None,
|
||||
marker=None,
|
||||
search_opts={
|
||||
'all_tenants': False,
|
||||
'name': None,
|
||||
'status': None,
|
||||
'project_id': None,
|
||||
'volume_id': self.volume.id
|
||||
}
|
||||
'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",
|
||||
"--limit",
|
||||
"-2",
|
||||
]
|
||||
verifylist = [
|
||||
("limit", -2),
|
||||
]
|
||||
self.assertRaises(argparse.ArgumentTypeError, self.check_parser,
|
||||
self.cmd, arglist, verifylist)
|
||||
self.assertRaises(
|
||||
argparse.ArgumentTypeError,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist,
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeSnapshotSet(TestVolumeSnapshot):
|
||||
|
||||
snapshot = volume_fakes.create_one_snapshot()
|
||||
|
||||
def setUp(self):
|
||||
@ -524,9 +529,12 @@ class TestVolumeSnapshotSet(TestVolumeSnapshot):
|
||||
|
||||
def test_snapshot_set_name_and_property(self):
|
||||
arglist = [
|
||||
"--name", "new_snapshot",
|
||||
"--property", "x=y",
|
||||
"--property", "foo=foo",
|
||||
"--name",
|
||||
"new_snapshot",
|
||||
"--property",
|
||||
"x=y",
|
||||
"--property",
|
||||
"foo=foo",
|
||||
self.snapshot.id,
|
||||
]
|
||||
new_property = {"x": "y", "foo": "foo"}
|
||||
@ -543,7 +551,8 @@ class TestVolumeSnapshotSet(TestVolumeSnapshot):
|
||||
"name": "new_snapshot",
|
||||
}
|
||||
self.snapshots_mock.update.assert_called_with(
|
||||
self.snapshot.id, **kwargs)
|
||||
self.snapshot.id, **kwargs
|
||||
)
|
||||
self.snapshots_mock.set_metadata.assert_called_with(
|
||||
self.snapshot.id, new_property
|
||||
)
|
||||
@ -573,7 +582,8 @@ class TestVolumeSnapshotSet(TestVolumeSnapshot):
|
||||
def test_snapshot_set_with_no_property_and_property(self):
|
||||
arglist = [
|
||||
"--no-property",
|
||||
"--property", "foo_1=bar_1",
|
||||
"--property",
|
||||
"foo_1=bar_1",
|
||||
self.snapshot.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -591,58 +601,52 @@ class TestVolumeSnapshotSet(TestVolumeSnapshot):
|
||||
self.snapshot.id, ["foo"]
|
||||
)
|
||||
self.snapshots_mock.set_metadata.assert_called_once_with(
|
||||
self.snapshot.id, {"foo_1": "bar_1"})
|
||||
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)
|
||||
]
|
||||
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.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)
|
||||
]
|
||||
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.assertEqual(
|
||||
'One or more of the set operations failed', str(e)
|
||||
)
|
||||
self.snapshots_mock.reset_state.assert_called_once_with(
|
||||
self.snapshot.id, 'error')
|
||||
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
|
||||
'--state',
|
||||
'error',
|
||||
"--name",
|
||||
"new_snapshot",
|
||||
self.snapshot.id,
|
||||
]
|
||||
verifylist = [
|
||||
('state', 'error'),
|
||||
("name", "new_snapshot"),
|
||||
('snapshot', self.snapshot.id)
|
||||
('snapshot', self.snapshot.id),
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
@ -650,19 +654,21 @@ class TestVolumeSnapshotSet(TestVolumeSnapshot):
|
||||
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.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.snapshot.id, **kwargs
|
||||
)
|
||||
self.snapshots_mock.reset_state.assert_called_once_with(
|
||||
self.snapshot.id, 'error')
|
||||
self.snapshot.id, 'error'
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeSnapshotShow(TestVolumeSnapshot):
|
||||
|
||||
columns = (
|
||||
'created_at',
|
||||
'description',
|
||||
@ -695,12 +701,8 @@ class TestVolumeSnapshotShow(TestVolumeSnapshot):
|
||||
self.cmd = volume_snapshot.ShowVolumeSnapshot(self.app, None)
|
||||
|
||||
def test_snapshot_show(self):
|
||||
arglist = [
|
||||
self.snapshot.id
|
||||
]
|
||||
verifylist = [
|
||||
("snapshot", self.snapshot.id)
|
||||
]
|
||||
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)
|
||||
@ -711,7 +713,6 @@ class TestVolumeSnapshotShow(TestVolumeSnapshot):
|
||||
|
||||
|
||||
class TestVolumeSnapshotUnset(TestVolumeSnapshot):
|
||||
|
||||
snapshot = volume_fakes.create_one_snapshot()
|
||||
|
||||
def setUp(self):
|
||||
@ -724,7 +725,8 @@ class TestVolumeSnapshotUnset(TestVolumeSnapshot):
|
||||
|
||||
def test_snapshot_unset(self):
|
||||
arglist = [
|
||||
"--property", "foo",
|
||||
"--property",
|
||||
"foo",
|
||||
self.snapshot.id,
|
||||
]
|
||||
verifylist = [
|
||||
|
@ -25,7 +25,6 @@ from openstackclient.volume.v2 import volume_transfer_request
|
||||
|
||||
|
||||
class TestTransfer(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -39,7 +38,6 @@ class TestTransfer(volume_fakes.TestVolume):
|
||||
|
||||
|
||||
class TestTransferAccept(TestTransfer):
|
||||
|
||||
columns = (
|
||||
'id',
|
||||
'name',
|
||||
@ -61,11 +59,13 @@ class TestTransferAccept(TestTransfer):
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = volume_transfer_request.AcceptTransferRequest(
|
||||
self.app, None)
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_transfer_accept(self):
|
||||
arglist = [
|
||||
'--auth-key', 'key_value',
|
||||
'--auth-key',
|
||||
'key_value',
|
||||
self.volume_transfer.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -104,7 +104,6 @@ class TestTransferAccept(TestTransfer):
|
||||
|
||||
|
||||
class TestTransferCreate(TestTransfer):
|
||||
|
||||
volume = volume_fakes.create_one_volume()
|
||||
|
||||
columns = (
|
||||
@ -138,7 +137,8 @@ class TestTransferCreate(TestTransfer):
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = volume_transfer_request.CreateTransferRequest(
|
||||
self.app, None)
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_transfer_create_without_name(self):
|
||||
arglist = [
|
||||
@ -151,14 +151,14 @@ class TestTransferCreate(TestTransfer):
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.transfer_mock.create.assert_called_once_with(
|
||||
self.volume.id, None)
|
||||
self.transfer_mock.create.assert_called_once_with(self.volume.id, None)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
|
||||
def test_transfer_create_with_name(self):
|
||||
arglist = [
|
||||
'--name', self.volume_transfer.name,
|
||||
'--name',
|
||||
self.volume_transfer.name,
|
||||
self.volume.id,
|
||||
]
|
||||
verifylist = [
|
||||
@ -170,13 +170,16 @@ class TestTransferCreate(TestTransfer):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.transfer_mock.create.assert_called_once_with(
|
||||
self.volume.id, self.volume_transfer.name,)
|
||||
self.volume.id,
|
||||
self.volume_transfer.name,
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
|
||||
def test_transfer_create_with_no_snapshots(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.55')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.55'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--no-snapshots',
|
||||
@ -192,13 +195,15 @@ class TestTransferCreate(TestTransfer):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.transfer_mock.create.assert_called_once_with(
|
||||
self.volume.id, None, no_snapshots=True)
|
||||
self.volume.id, None, no_snapshots=True
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
|
||||
def test_transfer_create_pre_v355(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.54')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.54'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--no-snapshots',
|
||||
@ -212,16 +217,14 @@ class TestTransferCreate(TestTransfer):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.55 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.55 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestTransferDelete(TestTransfer):
|
||||
|
||||
volume_transfers = volume_fakes.create_transfers(count=2)
|
||||
|
||||
def setUp(self):
|
||||
@ -234,21 +237,19 @@ class TestTransferDelete(TestTransfer):
|
||||
|
||||
# Get the command object to mock
|
||||
self.cmd = volume_transfer_request.DeleteTransferRequest(
|
||||
self.app, None)
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_transfer_delete(self):
|
||||
arglist = [
|
||||
self.volume_transfers[0].id
|
||||
]
|
||||
verifylist = [
|
||||
("transfer_request", [self.volume_transfers[0].id])
|
||||
]
|
||||
arglist = [self.volume_transfers[0].id]
|
||||
verifylist = [("transfer_request", [self.volume_transfers[0].id])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.transfer_mock.delete.assert_called_with(
|
||||
self.volume_transfers[0].id)
|
||||
self.volume_transfers[0].id
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_delete_multiple_transfers(self):
|
||||
@ -280,17 +281,21 @@ class TestTransferDelete(TestTransfer):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
find_mock_result = [self.volume_transfers[0], exceptions.CommandError]
|
||||
with mock.patch.object(utils, 'find_resource',
|
||||
side_effect=find_mock_result) as find_mock:
|
||||
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 volume transfer requests failed '
|
||||
'to delete', str(e))
|
||||
self.assertEqual(
|
||||
'1 of 2 volume transfer requests failed ' 'to delete',
|
||||
str(e),
|
||||
)
|
||||
|
||||
find_mock.assert_any_call(
|
||||
self.transfer_mock, self.volume_transfers[0].id)
|
||||
self.transfer_mock, self.volume_transfers[0].id
|
||||
)
|
||||
find_mock.assert_any_call(self.transfer_mock, 'unexist_transfer')
|
||||
|
||||
self.assertEqual(2, find_mock.call_count)
|
||||
@ -300,7 +305,6 @@ class TestTransferDelete(TestTransfer):
|
||||
|
||||
|
||||
class TestTransferList(TestTransfer):
|
||||
|
||||
# The Transfers to be listed
|
||||
volume_transfers = volume_fakes.create_one_transfer()
|
||||
|
||||
@ -331,28 +335,25 @@ class TestTransferList(TestTransfer):
|
||||
# confirming if all expected columns are present in the result.
|
||||
self.assertEqual(expected_columns, columns)
|
||||
|
||||
datalist = ((
|
||||
self.volume_transfers.id,
|
||||
self.volume_transfers.name,
|
||||
self.volume_transfers.volume_id,
|
||||
), )
|
||||
datalist = (
|
||||
(
|
||||
self.volume_transfers.id,
|
||||
self.volume_transfers.name,
|
||||
self.volume_transfers.volume_id,
|
||||
),
|
||||
)
|
||||
|
||||
# confirming if all expected values are present in the result.
|
||||
self.assertEqual(datalist, tuple(data))
|
||||
|
||||
# checking if proper call was made to list volume_transfers
|
||||
self.transfer_mock.list.assert_called_with(
|
||||
detailed=True,
|
||||
search_opts={'all_tenants': 0}
|
||||
detailed=True, search_opts={'all_tenants': 0}
|
||||
)
|
||||
|
||||
def test_transfer_list_with_argument(self):
|
||||
arglist = [
|
||||
"--all-projects"
|
||||
]
|
||||
verifylist = [
|
||||
("all_projects", True)
|
||||
]
|
||||
arglist = ["--all-projects"]
|
||||
verifylist = [("all_projects", True)]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
@ -370,24 +371,24 @@ class TestTransferList(TestTransfer):
|
||||
# confirming if all expected columns are present in the result.
|
||||
self.assertEqual(expected_columns, columns)
|
||||
|
||||
datalist = ((
|
||||
self.volume_transfers.id,
|
||||
self.volume_transfers.name,
|
||||
self.volume_transfers.volume_id,
|
||||
), )
|
||||
datalist = (
|
||||
(
|
||||
self.volume_transfers.id,
|
||||
self.volume_transfers.name,
|
||||
self.volume_transfers.volume_id,
|
||||
),
|
||||
)
|
||||
|
||||
# confirming if all expected values are present in the result.
|
||||
self.assertEqual(datalist, tuple(data))
|
||||
|
||||
# checking if proper call was made to list volume_transfers
|
||||
self.transfer_mock.list.assert_called_with(
|
||||
detailed=True,
|
||||
search_opts={'all_tenants': 1}
|
||||
detailed=True, search_opts={'all_tenants': 1}
|
||||
)
|
||||
|
||||
|
||||
class TestTransferShow(TestTransfer):
|
||||
|
||||
columns = (
|
||||
'created_at',
|
||||
'id',
|
||||
@ -411,8 +412,7 @@ class TestTransferShow(TestTransfer):
|
||||
self.transfer_mock.get.return_value = self.volume_transfer
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = volume_transfer_request.ShowTransferRequest(
|
||||
self.app, None)
|
||||
self.cmd = volume_transfer_request.ShowTransferRequest(self.app, None)
|
||||
|
||||
def test_transfer_show(self):
|
||||
arglist = [
|
||||
@ -425,7 +425,6 @@ class TestTransferShow(TestTransfer):
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.transfer_mock.get.assert_called_once_with(
|
||||
self.volume_transfer.id)
|
||||
self.transfer_mock.get.assert_called_once_with(self.volume_transfer.id)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
|
@ -455,7 +455,8 @@ def create_service_log_level_entry(attrs=None):
|
||||
service_log_level_info.update(attrs)
|
||||
|
||||
service_log_level = fakes.FakeResource(
|
||||
None, service_log_level_info, loaded=True)
|
||||
None, service_log_level_info, loaded=True
|
||||
)
|
||||
return service_log_level
|
||||
|
||||
|
||||
@ -481,10 +482,13 @@ def create_cleanup_records():
|
||||
cleaning_records.append(cleaning_work_info)
|
||||
unavailable_records.append(unavailable_work_info)
|
||||
|
||||
cleaning = [fakes.FakeResource(
|
||||
None, obj, loaded=True) for obj in cleaning_records]
|
||||
unavailable = [fakes.FakeResource(
|
||||
None, obj, loaded=True) for obj in unavailable_records]
|
||||
cleaning = [
|
||||
fakes.FakeResource(None, obj, loaded=True) for obj in cleaning_records
|
||||
]
|
||||
unavailable = [
|
||||
fakes.FakeResource(None, obj, loaded=True)
|
||||
for obj in unavailable_records
|
||||
]
|
||||
|
||||
return cleaning, unavailable
|
||||
|
||||
@ -513,7 +517,8 @@ def create_volume_manage_list_records(count=2):
|
||||
volume_manage_list = []
|
||||
for i in range(count):
|
||||
volume_manage_list.append(
|
||||
create_one_manage_record({'size': str(i + 1)}))
|
||||
create_one_manage_record({'size': str(i + 1)})
|
||||
)
|
||||
|
||||
return volume_manage_list
|
||||
|
||||
@ -522,6 +527,7 @@ def create_snapshot_manage_list_records(count=2):
|
||||
snapshot_manage_list = []
|
||||
for i in range(count):
|
||||
snapshot_manage_list.append(
|
||||
create_one_manage_record({'size': str(i + 1)}, snapshot=True))
|
||||
create_one_manage_record({'size': str(i + 1)}, snapshot=True)
|
||||
)
|
||||
|
||||
return snapshot_manage_list
|
||||
|
@ -20,7 +20,6 @@ from openstackclient.volume.v3 import block_storage_cleanup
|
||||
|
||||
|
||||
class TestBlockStorage(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -30,7 +29,6 @@ class TestBlockStorage(volume_fakes.TestVolume):
|
||||
|
||||
|
||||
class TestBlockStorageCleanup(TestBlockStorage):
|
||||
|
||||
cleaning, unavailable = volume_fakes.create_cleanup_records()
|
||||
|
||||
def setUp(self):
|
||||
@ -39,15 +37,14 @@ class TestBlockStorageCleanup(TestBlockStorage):
|
||||
self.worker_mock.clean.return_value = (self.cleaning, self.unavailable)
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = \
|
||||
block_storage_cleanup.BlockStorageCleanup(self.app, None)
|
||||
self.cmd = block_storage_cleanup.BlockStorageCleanup(self.app, None)
|
||||
|
||||
def test_cleanup(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.24')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.24'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
]
|
||||
arglist = []
|
||||
verifylist = [
|
||||
('cluster', None),
|
||||
('host', None),
|
||||
@ -62,22 +59,12 @@ class TestBlockStorageCleanup(TestBlockStorage):
|
||||
|
||||
expected_columns = ('ID', 'Cluster Name', 'Host', 'Binary', 'Status')
|
||||
cleaning_data = tuple(
|
||||
(
|
||||
obj.id,
|
||||
obj.cluster_name,
|
||||
obj.host,
|
||||
obj.binary,
|
||||
'Cleaning'
|
||||
) for obj in self.cleaning
|
||||
(obj.id, obj.cluster_name, obj.host, obj.binary, 'Cleaning')
|
||||
for obj in self.cleaning
|
||||
)
|
||||
unavailable_data = tuple(
|
||||
(
|
||||
obj.id,
|
||||
obj.cluster_name,
|
||||
obj.host,
|
||||
obj.binary,
|
||||
'Unavailable'
|
||||
) for obj in self.unavailable
|
||||
(obj.id, obj.cluster_name, obj.host, obj.binary, 'Unavailable')
|
||||
for obj in self.unavailable
|
||||
)
|
||||
expected_data = cleaning_data + unavailable_data
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
@ -91,8 +78,7 @@ class TestBlockStorageCleanup(TestBlockStorage):
|
||||
self.worker_mock.clean.assert_called_once_with()
|
||||
|
||||
def test_block_storage_cleanup_pre_324(self):
|
||||
arglist = [
|
||||
]
|
||||
arglist = []
|
||||
verifylist = [
|
||||
('cluster', None),
|
||||
('host', None),
|
||||
@ -104,14 +90,17 @@ class TestBlockStorageCleanup(TestBlockStorage):
|
||||
('service_id', None),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
exc = self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
||||
parsed_args)
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.24 or greater is required', str(exc))
|
||||
'--os-volume-api-version 3.24 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
def test_cleanup_with_args(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.24')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.24'
|
||||
)
|
||||
|
||||
fake_cluster = 'fake-cluster'
|
||||
fake_host = 'fake-host'
|
||||
@ -120,14 +109,20 @@ class TestBlockStorageCleanup(TestBlockStorage):
|
||||
fake_resource_type = 'Volume'
|
||||
fake_service_id = 1
|
||||
arglist = [
|
||||
'--cluster', fake_cluster,
|
||||
'--host', fake_host,
|
||||
'--binary', fake_binary,
|
||||
'--cluster',
|
||||
fake_cluster,
|
||||
'--host',
|
||||
fake_host,
|
||||
'--binary',
|
||||
fake_binary,
|
||||
'--down',
|
||||
'--enabled',
|
||||
'--resource-id', fake_resource_id,
|
||||
'--resource-type', fake_resource_type,
|
||||
'--service-id', str(fake_service_id),
|
||||
'--resource-id',
|
||||
fake_resource_id,
|
||||
'--resource-type',
|
||||
fake_resource_type,
|
||||
'--service-id',
|
||||
str(fake_service_id),
|
||||
]
|
||||
verifylist = [
|
||||
('cluster', fake_cluster),
|
||||
@ -143,22 +138,12 @@ class TestBlockStorageCleanup(TestBlockStorage):
|
||||
|
||||
expected_columns = ('ID', 'Cluster Name', 'Host', 'Binary', 'Status')
|
||||
cleaning_data = tuple(
|
||||
(
|
||||
obj.id,
|
||||
obj.cluster_name,
|
||||
obj.host,
|
||||
obj.binary,
|
||||
'Cleaning'
|
||||
) for obj in self.cleaning
|
||||
(obj.id, obj.cluster_name, obj.host, obj.binary, 'Cleaning')
|
||||
for obj in self.cleaning
|
||||
)
|
||||
unavailable_data = tuple(
|
||||
(
|
||||
obj.id,
|
||||
obj.cluster_name,
|
||||
obj.host,
|
||||
obj.binary,
|
||||
'Unavailable'
|
||||
) for obj in self.unavailable
|
||||
(obj.id, obj.cluster_name, obj.host, obj.binary, 'Unavailable')
|
||||
for obj in self.unavailable
|
||||
)
|
||||
expected_data = cleaning_data + unavailable_data
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
@ -175,4 +160,5 @@ class TestBlockStorageCleanup(TestBlockStorage):
|
||||
disabled=False,
|
||||
resource_id=fake_resource_id,
|
||||
resource_type=fake_resource_type,
|
||||
service_id=fake_service_id)
|
||||
service_id=fake_service_id,
|
||||
)
|
||||
|
@ -18,7 +18,6 @@ from openstackclient.volume.v3 import block_storage_cluster
|
||||
|
||||
|
||||
class TestBlockStorageCluster(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -28,7 +27,6 @@ class TestBlockStorageCluster(volume_fakes.TestVolume):
|
||||
|
||||
|
||||
class TestBlockStorageClusterList(TestBlockStorageCluster):
|
||||
|
||||
# The cluster to be listed
|
||||
fake_clusters = volume_fakes.create_clusters()
|
||||
|
||||
@ -38,15 +36,16 @@ class TestBlockStorageClusterList(TestBlockStorageCluster):
|
||||
self.cluster_mock.list.return_value = self.fake_clusters
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = \
|
||||
block_storage_cluster.ListBlockStorageCluster(self.app, None)
|
||||
self.cmd = block_storage_cluster.ListBlockStorageCluster(
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_cluster_list(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.7')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.7'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
]
|
||||
arglist = []
|
||||
verifylist = [
|
||||
('cluster', None),
|
||||
('binary', None),
|
||||
@ -65,7 +64,8 @@ class TestBlockStorageClusterList(TestBlockStorageCluster):
|
||||
cluster.binary,
|
||||
cluster.state,
|
||||
cluster.status,
|
||||
) for cluster in self.fake_clusters
|
||||
)
|
||||
for cluster in self.fake_clusters
|
||||
)
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
@ -84,16 +84,21 @@ class TestBlockStorageClusterList(TestBlockStorageCluster):
|
||||
)
|
||||
|
||||
def test_cluster_list_with_full_options(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.7')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.7'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--cluster', 'foo',
|
||||
'--binary', 'bar',
|
||||
'--cluster',
|
||||
'foo',
|
||||
'--binary',
|
||||
'bar',
|
||||
'--up',
|
||||
'--disabled',
|
||||
'--num-hosts', '5',
|
||||
'--num-down-hosts', '0',
|
||||
'--num-hosts',
|
||||
'5',
|
||||
'--num-down-hosts',
|
||||
'0',
|
||||
'--long',
|
||||
]
|
||||
verifylist = [
|
||||
@ -131,7 +136,8 @@ class TestBlockStorageClusterList(TestBlockStorageCluster):
|
||||
cluster.disabled_reason,
|
||||
cluster.created_at,
|
||||
cluster.updated_at,
|
||||
) for cluster in self.fake_clusters
|
||||
)
|
||||
for cluster in self.fake_clusters
|
||||
)
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
@ -150,11 +156,11 @@ class TestBlockStorageClusterList(TestBlockStorageCluster):
|
||||
)
|
||||
|
||||
def test_cluster_list_pre_v37(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.6')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.6'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
]
|
||||
arglist = []
|
||||
verifylist = [
|
||||
('cluster', None),
|
||||
('binary', None),
|
||||
@ -167,15 +173,14 @@ class TestBlockStorageClusterList(TestBlockStorageCluster):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.7 or greater is required', str(exc))
|
||||
'--os-volume-api-version 3.7 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestBlockStorageClusterSet(TestBlockStorageCluster):
|
||||
|
||||
cluster = volume_fakes.create_one_cluster()
|
||||
columns = (
|
||||
'Name',
|
||||
@ -213,12 +218,12 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
|
||||
|
||||
self.cluster_mock.update.return_value = self.cluster
|
||||
|
||||
self.cmd = \
|
||||
block_storage_cluster.SetBlockStorageCluster(self.app, None)
|
||||
self.cmd = block_storage_cluster.SetBlockStorageCluster(self.app, None)
|
||||
|
||||
def test_cluster_set(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.7')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.7'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--enable',
|
||||
@ -245,13 +250,16 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
|
||||
)
|
||||
|
||||
def test_cluster_set_disable_with_reason(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.7')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.7'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--binary', self.cluster.binary,
|
||||
'--binary',
|
||||
self.cluster.binary,
|
||||
'--disable',
|
||||
'--disable-reason', 'foo',
|
||||
'--disable-reason',
|
||||
'foo',
|
||||
self.cluster.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -274,11 +282,13 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
|
||||
)
|
||||
|
||||
def test_cluster_set_only_with_disable_reason(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.7')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.7'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--disable-reason', 'foo',
|
||||
'--disable-reason',
|
||||
'foo',
|
||||
self.cluster.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -290,19 +300,21 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
"Cannot specify --disable-reason without --disable", str(exc))
|
||||
"Cannot specify --disable-reason without --disable", str(exc)
|
||||
)
|
||||
|
||||
def test_cluster_set_enable_with_disable_reason(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.7')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.7'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--enable',
|
||||
'--disable-reason', 'foo',
|
||||
'--disable-reason',
|
||||
'foo',
|
||||
self.cluster.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -314,15 +326,16 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
"Cannot specify --disable-reason without --disable", str(exc))
|
||||
"Cannot specify --disable-reason without --disable", str(exc)
|
||||
)
|
||||
|
||||
def test_cluster_set_pre_v37(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.6')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.6'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--enable',
|
||||
@ -338,15 +351,14 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.7 or greater is required', str(exc))
|
||||
'--os-volume-api-version 3.7 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestBlockStorageClusterShow(TestBlockStorageCluster):
|
||||
|
||||
cluster = volume_fakes.create_one_cluster()
|
||||
columns = (
|
||||
'Name',
|
||||
@ -384,15 +396,18 @@ class TestBlockStorageClusterShow(TestBlockStorageCluster):
|
||||
|
||||
self.cluster_mock.show.return_value = self.cluster
|
||||
|
||||
self.cmd = \
|
||||
block_storage_cluster.ShowBlockStorageCluster(self.app, None)
|
||||
self.cmd = block_storage_cluster.ShowBlockStorageCluster(
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_cluster_show(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.7')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.7'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--binary', self.cluster.binary,
|
||||
'--binary',
|
||||
self.cluster.binary,
|
||||
self.cluster.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -412,11 +427,13 @@ class TestBlockStorageClusterShow(TestBlockStorageCluster):
|
||||
)
|
||||
|
||||
def test_cluster_show_pre_v37(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.6')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.6'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--binary', self.cluster.binary,
|
||||
'--binary',
|
||||
self.cluster.binary,
|
||||
self.cluster.name,
|
||||
]
|
||||
verifylist = [
|
||||
@ -427,8 +444,8 @@ class TestBlockStorageClusterShow(TestBlockStorageCluster):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.7 or greater is required', str(exc))
|
||||
'--os-volume-api-version 3.7 or greater is required', str(exc)
|
||||
)
|
||||
|
@ -22,7 +22,6 @@ from openstackclient.volume.v3 import block_storage_log_level as service
|
||||
|
||||
|
||||
class TestService(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -32,7 +31,6 @@ class TestService(volume_fakes.TestVolume):
|
||||
|
||||
|
||||
class TestBlockStorageLogLevelList(TestService):
|
||||
|
||||
service_log = volume_fakes.create_service_log_level_entry()
|
||||
|
||||
def setUp(self):
|
||||
@ -44,12 +42,16 @@ class TestBlockStorageLogLevelList(TestService):
|
||||
self.cmd = service.BlockStorageLogLevelList(self.app, None)
|
||||
|
||||
def test_block_storage_log_level_list(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.32')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.32'
|
||||
)
|
||||
arglist = [
|
||||
'--host', self.service_log.host,
|
||||
'--service', self.service_log.binary,
|
||||
'--log-prefix', self.service_log.prefix,
|
||||
'--host',
|
||||
self.service_log.host,
|
||||
'--service',
|
||||
self.service_log.binary,
|
||||
'--log-prefix',
|
||||
self.service_log.prefix,
|
||||
]
|
||||
verifylist = [
|
||||
('host', self.service_log.host),
|
||||
@ -70,12 +72,14 @@ class TestBlockStorageLogLevelList(TestService):
|
||||
# confirming if all expected columns are present in the result.
|
||||
self.assertEqual(expected_columns, columns)
|
||||
|
||||
datalist = ((
|
||||
self.service_log.binary,
|
||||
self.service_log.host,
|
||||
self.service_log.prefix,
|
||||
self.service_log.level,
|
||||
), )
|
||||
datalist = (
|
||||
(
|
||||
self.service_log.binary,
|
||||
self.service_log.host,
|
||||
self.service_log.prefix,
|
||||
self.service_log.level,
|
||||
),
|
||||
)
|
||||
|
||||
# confirming if all expected values are present in the result.
|
||||
self.assertEqual(datalist, tuple(data))
|
||||
@ -89,9 +93,12 @@ class TestBlockStorageLogLevelList(TestService):
|
||||
|
||||
def test_block_storage_log_level_list_pre_332(self):
|
||||
arglist = [
|
||||
'--host', self.service_log.host,
|
||||
'--service', 'cinder-api',
|
||||
'--log-prefix', 'cinder_test.api.common',
|
||||
'--host',
|
||||
self.service_log.host,
|
||||
'--service',
|
||||
'cinder-api',
|
||||
'--log-prefix',
|
||||
'cinder_test.api.common',
|
||||
]
|
||||
verifylist = [
|
||||
('host', self.service_log.host),
|
||||
@ -100,18 +107,24 @@ class TestBlockStorageLogLevelList(TestService):
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
||||
parsed_args)
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.32 or greater is required', str(exc))
|
||||
'--os-volume-api-version 3.32 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
def test_block_storage_log_level_list_invalid_service_name(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.32')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.32'
|
||||
)
|
||||
arglist = [
|
||||
'--host', self.service_log.host,
|
||||
'--service', 'nova-api',
|
||||
'--log-prefix', 'cinder_test.api.common',
|
||||
'--host',
|
||||
self.service_log.host,
|
||||
'--service',
|
||||
'nova-api',
|
||||
'--log-prefix',
|
||||
'cinder_test.api.common',
|
||||
]
|
||||
verifylist = [
|
||||
('host', self.service_log.host),
|
||||
@ -119,13 +132,17 @@ class TestBlockStorageLogLevelList(TestService):
|
||||
('log_prefix', 'cinder_test.api.common'),
|
||||
]
|
||||
|
||||
self.assertRaises(tests_utils.ParserException, self.check_parser,
|
||||
self.cmd, arglist, verifylist)
|
||||
self.assertRaises(
|
||||
tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist,
|
||||
)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestBlockStorageLogLevelSet(TestService):
|
||||
|
||||
service_log = volume_fakes.create_service_log_level_entry()
|
||||
|
||||
def setUp(self):
|
||||
@ -135,13 +152,17 @@ class TestBlockStorageLogLevelSet(TestService):
|
||||
self.cmd = service.BlockStorageLogLevelSet(self.app, None)
|
||||
|
||||
def test_block_storage_log_level_set(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.32')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.32'
|
||||
)
|
||||
arglist = [
|
||||
'ERROR',
|
||||
'--host', self.service_log.host,
|
||||
'--service', self.service_log.binary,
|
||||
'--log-prefix', self.service_log.prefix,
|
||||
'--host',
|
||||
self.service_log.host,
|
||||
'--service',
|
||||
self.service_log.binary,
|
||||
'--log-prefix',
|
||||
self.service_log.prefix,
|
||||
]
|
||||
verifylist = [
|
||||
('level', 'ERROR'),
|
||||
@ -164,9 +185,12 @@ class TestBlockStorageLogLevelSet(TestService):
|
||||
def test_block_storage_log_level_set_pre_332(self):
|
||||
arglist = [
|
||||
'ERROR',
|
||||
'--host', self.service_log.host,
|
||||
'--service', 'cinder-api',
|
||||
'--log-prefix', 'cinder_test.api.common',
|
||||
'--host',
|
||||
self.service_log.host,
|
||||
'--service',
|
||||
'cinder-api',
|
||||
'--log-prefix',
|
||||
'cinder_test.api.common',
|
||||
]
|
||||
verifylist = [
|
||||
('level', 'ERROR'),
|
||||
@ -176,19 +200,25 @@ class TestBlockStorageLogLevelSet(TestService):
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
||||
parsed_args)
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.32 or greater is required', str(exc))
|
||||
'--os-volume-api-version 3.32 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
def test_block_storage_log_level_set_invalid_service_name(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.32')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.32'
|
||||
)
|
||||
arglist = [
|
||||
'ERROR',
|
||||
'--host', self.service_log.host,
|
||||
'--service', 'nova-api',
|
||||
'--log-prefix', 'cinder.api.common',
|
||||
'--host',
|
||||
self.service_log.host,
|
||||
'--service',
|
||||
'nova-api',
|
||||
'--log-prefix',
|
||||
'cinder.api.common',
|
||||
]
|
||||
verifylist = [
|
||||
('level', 'ERROR'),
|
||||
@ -197,18 +227,27 @@ class TestBlockStorageLogLevelSet(TestService):
|
||||
('log_prefix', 'cinder.api.common'),
|
||||
]
|
||||
|
||||
self.assertRaises(tests_utils.ParserException, self.check_parser,
|
||||
self.cmd, arglist, verifylist)
|
||||
self.assertRaises(
|
||||
tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist,
|
||||
)
|
||||
|
||||
@ddt.data('WARNING', 'info', 'Error', 'debuG', 'fake-log-level')
|
||||
def test_block_storage_log_level_set_log_level(self, log_level):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.32')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.32'
|
||||
)
|
||||
arglist = [
|
||||
log_level,
|
||||
'--host', self.service_log.host,
|
||||
'--service', 'cinder-api',
|
||||
'--log-prefix', 'cinder.api.common',
|
||||
'--host',
|
||||
self.service_log.host,
|
||||
'--service',
|
||||
'cinder-api',
|
||||
'--log-prefix',
|
||||
'cinder.api.common',
|
||||
]
|
||||
verifylist = [
|
||||
('level', log_level.upper()),
|
||||
@ -218,8 +257,13 @@ class TestBlockStorageLogLevelSet(TestService):
|
||||
]
|
||||
|
||||
if log_level == 'fake-log-level':
|
||||
self.assertRaises(tests_utils.ParserException, self.check_parser,
|
||||
self.cmd, arglist, verifylist)
|
||||
self.assertRaises(
|
||||
tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist,
|
||||
)
|
||||
else:
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
@ -230,4 +274,5 @@ class TestBlockStorageLogLevelSet(TestService):
|
||||
level=log_level.upper(),
|
||||
server=self.service_log.host,
|
||||
binary=self.service_log.binary,
|
||||
prefix=self.service_log.prefix)
|
||||
prefix=self.service_log.prefix,
|
||||
)
|
||||
|
@ -21,7 +21,6 @@ from openstackclient.volume.v3 import block_storage_manage
|
||||
|
||||
|
||||
class TestBlockStorageManage(v2_volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -32,22 +31,24 @@ class TestBlockStorageManage(v2_volume_fakes.TestVolume):
|
||||
|
||||
|
||||
class TestBlockStorageVolumeManage(TestBlockStorageManage):
|
||||
|
||||
volume_manage_list = volume_fakes.create_volume_manage_list_records()
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.volumes_mock.list_manageable.return_value = (
|
||||
self.volume_manage_list)
|
||||
self.volume_manage_list
|
||||
)
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = block_storage_manage.BlockStorageManageVolumes(
|
||||
self.app, None)
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_block_storage_volume_manage_list(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.8')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.8'
|
||||
)
|
||||
host = 'fake_host'
|
||||
arglist = [
|
||||
host,
|
||||
@ -108,51 +109,65 @@ class TestBlockStorageVolumeManage(TestBlockStorageManage):
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
||||
parsed_args)
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.8 or greater is required', str(exc))
|
||||
'--os-volume-api-version 3.8 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
def test_block_storage_volume_manage_pre_317(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.16')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.16'
|
||||
)
|
||||
cluster = 'fake_cluster'
|
||||
arglist = [
|
||||
'--cluster', cluster,
|
||||
'--cluster',
|
||||
cluster,
|
||||
]
|
||||
verifylist = [
|
||||
('cluster', cluster),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
||||
parsed_args)
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.17 or greater is required', str(exc))
|
||||
'--os-volume-api-version 3.17 or greater is required', str(exc)
|
||||
)
|
||||
self.assertIn('--cluster', str(exc))
|
||||
|
||||
def test_block_storage_volume_manage_host_and_cluster(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.17')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.17'
|
||||
)
|
||||
host = 'fake_host'
|
||||
cluster = 'fake_cluster'
|
||||
arglist = [
|
||||
host,
|
||||
'--cluster', cluster,
|
||||
'--cluster',
|
||||
cluster,
|
||||
]
|
||||
verifylist = [
|
||||
('host', host),
|
||||
('cluster', cluster),
|
||||
]
|
||||
exc = self.assertRaises(tests_utils.ParserException,
|
||||
self.check_parser, self.cmd,
|
||||
arglist, verifylist)
|
||||
exc = self.assertRaises(
|
||||
tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist,
|
||||
)
|
||||
self.assertIn(
|
||||
'argument --cluster: not allowed with argument <host>', str(exc))
|
||||
'argument --cluster: not allowed with argument <host>', str(exc)
|
||||
)
|
||||
|
||||
def test_block_storage_volume_manage_list_all_args(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.8')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.8'
|
||||
)
|
||||
host = 'fake_host'
|
||||
detailed = True
|
||||
marker = 'fake_marker'
|
||||
@ -161,11 +176,16 @@ class TestBlockStorageVolumeManage(TestBlockStorageManage):
|
||||
sort = 'size:asc'
|
||||
arglist = [
|
||||
host,
|
||||
'--detailed', str(detailed),
|
||||
'--marker', marker,
|
||||
'--limit', limit,
|
||||
'--offset', offset,
|
||||
'--sort', sort,
|
||||
'--detailed',
|
||||
str(detailed),
|
||||
'--marker',
|
||||
marker,
|
||||
'--limit',
|
||||
limit,
|
||||
'--offset',
|
||||
offset,
|
||||
'--sort',
|
||||
sort,
|
||||
]
|
||||
verifylist = [
|
||||
('host', host),
|
||||
@ -220,22 +240,24 @@ class TestBlockStorageVolumeManage(TestBlockStorageManage):
|
||||
|
||||
|
||||
class TestBlockStorageSnapshotManage(TestBlockStorageManage):
|
||||
|
||||
snapshot_manage_list = volume_fakes.create_snapshot_manage_list_records()
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.snapshots_mock.list_manageable.return_value = (
|
||||
self.snapshot_manage_list)
|
||||
self.snapshot_manage_list
|
||||
)
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = block_storage_manage.BlockStorageManageSnapshots(
|
||||
self.app, None)
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_block_storage_snapshot_manage_list(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.8')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.8'
|
||||
)
|
||||
host = 'fake_host'
|
||||
arglist = [
|
||||
host,
|
||||
@ -298,51 +320,65 @@ class TestBlockStorageSnapshotManage(TestBlockStorageManage):
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
||||
parsed_args)
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.8 or greater is required', str(exc))
|
||||
'--os-volume-api-version 3.8 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
def test_block_storage_volume_manage_pre_317(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.16')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.16'
|
||||
)
|
||||
cluster = 'fake_cluster'
|
||||
arglist = [
|
||||
'--cluster', cluster,
|
||||
'--cluster',
|
||||
cluster,
|
||||
]
|
||||
verifylist = [
|
||||
('cluster', cluster),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
||||
parsed_args)
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.17 or greater is required', str(exc))
|
||||
'--os-volume-api-version 3.17 or greater is required', str(exc)
|
||||
)
|
||||
self.assertIn('--cluster', str(exc))
|
||||
|
||||
def test_block_storage_volume_manage_host_and_cluster(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.17')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.17'
|
||||
)
|
||||
host = 'fake_host'
|
||||
cluster = 'fake_cluster'
|
||||
arglist = [
|
||||
host,
|
||||
'--cluster', cluster,
|
||||
'--cluster',
|
||||
cluster,
|
||||
]
|
||||
verifylist = [
|
||||
('host', host),
|
||||
('cluster', cluster),
|
||||
]
|
||||
exc = self.assertRaises(tests_utils.ParserException,
|
||||
self.check_parser, self.cmd,
|
||||
arglist, verifylist)
|
||||
exc = self.assertRaises(
|
||||
tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist,
|
||||
)
|
||||
self.assertIn(
|
||||
'argument --cluster: not allowed with argument <host>', str(exc))
|
||||
'argument --cluster: not allowed with argument <host>', str(exc)
|
||||
)
|
||||
|
||||
def test_block_storage_volume_manage_list_all_args(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.8')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.8'
|
||||
)
|
||||
host = 'fake_host'
|
||||
detailed = True
|
||||
marker = 'fake_marker'
|
||||
@ -351,11 +387,16 @@ class TestBlockStorageSnapshotManage(TestBlockStorageManage):
|
||||
sort = 'size:asc'
|
||||
arglist = [
|
||||
host,
|
||||
'--detailed', str(detailed),
|
||||
'--marker', marker,
|
||||
'--limit', limit,
|
||||
'--offset', offset,
|
||||
'--sort', sort,
|
||||
'--detailed',
|
||||
str(detailed),
|
||||
'--marker',
|
||||
marker,
|
||||
'--limit',
|
||||
limit,
|
||||
'--offset',
|
||||
offset,
|
||||
'--sort',
|
||||
sort,
|
||||
]
|
||||
verifylist = [
|
||||
('host', host),
|
||||
|
@ -18,34 +18,38 @@ from openstackclient.volume.v3 import block_storage_resource_filter
|
||||
|
||||
|
||||
class TestBlockStorageResourceFilter(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
# Get a shortcut to the ResourceFilterManager Mock
|
||||
self.resource_filter_mock = \
|
||||
self.resource_filter_mock = (
|
||||
self.app.client_manager.volume.resource_filters
|
||||
)
|
||||
self.resource_filter_mock.reset_mock()
|
||||
|
||||
|
||||
class TestBlockStorageResourceFilterList(TestBlockStorageResourceFilter):
|
||||
|
||||
# The resource filters to be listed
|
||||
fake_resource_filters = volume_fakes.create_resource_filters()
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.resource_filter_mock.list.return_value = \
|
||||
self.resource_filter_mock.list.return_value = (
|
||||
self.fake_resource_filters
|
||||
)
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = block_storage_resource_filter\
|
||||
.ListBlockStorageResourceFilter(self.app, None)
|
||||
self.cmd = (
|
||||
block_storage_resource_filter.ListBlockStorageResourceFilter(
|
||||
self.app, None
|
||||
)
|
||||
)
|
||||
|
||||
def test_resource_filter_list(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.33')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.33'
|
||||
)
|
||||
|
||||
arglist = []
|
||||
verifylist = []
|
||||
@ -56,7 +60,8 @@ class TestBlockStorageResourceFilterList(TestBlockStorageResourceFilter):
|
||||
(
|
||||
resource_filter.resource,
|
||||
resource_filter.filters,
|
||||
) for resource_filter in self.fake_resource_filters
|
||||
)
|
||||
for resource_filter in self.fake_resource_filters
|
||||
)
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
@ -67,39 +72,44 @@ class TestBlockStorageResourceFilterList(TestBlockStorageResourceFilter):
|
||||
self.resource_filter_mock.list.assert_called_with()
|
||||
|
||||
def test_resource_filter_list_pre_v333(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.32')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.32'
|
||||
)
|
||||
|
||||
arglist = []
|
||||
verifylist = []
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.33 or greater is required', str(exc))
|
||||
'--os-volume-api-version 3.33 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestBlockStorageResourceFilterShow(TestBlockStorageResourceFilter):
|
||||
|
||||
# The resource filters to be listed
|
||||
fake_resource_filter = volume_fakes.create_one_resource_filter()
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.resource_filter_mock.list.return_value = \
|
||||
iter([self.fake_resource_filter])
|
||||
self.resource_filter_mock.list.return_value = iter(
|
||||
[self.fake_resource_filter]
|
||||
)
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = block_storage_resource_filter\
|
||||
.ShowBlockStorageResourceFilter(self.app, None)
|
||||
self.cmd = (
|
||||
block_storage_resource_filter.ShowBlockStorageResourceFilter(
|
||||
self.app, None
|
||||
)
|
||||
)
|
||||
|
||||
def test_resource_filter_show(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.33')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.33'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_resource_filter.resource,
|
||||
@ -123,8 +133,9 @@ class TestBlockStorageResourceFilterShow(TestBlockStorageResourceFilter):
|
||||
self.resource_filter_mock.list.assert_called_with(resource='volume')
|
||||
|
||||
def test_resource_filter_show_pre_v333(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.32')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.32'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_resource_filter.resource,
|
||||
@ -135,8 +146,8 @@ class TestBlockStorageResourceFilterShow(TestBlockStorageResourceFilter):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.33 or greater is required', str(exc))
|
||||
'--os-volume-api-version 3.33 or greater is required', str(exc)
|
||||
)
|
||||
|
@ -25,7 +25,6 @@ from openstackclient.volume.v3 import volume
|
||||
|
||||
|
||||
class TestVolumeSummary(volume_fakes.TestVolume):
|
||||
|
||||
columns = [
|
||||
'Total Count',
|
||||
'Total Size',
|
||||
@ -41,15 +40,18 @@ class TestVolumeSummary(volume_fakes.TestVolume):
|
||||
self.return_dict = {
|
||||
'volume-summary': {
|
||||
'total_count': 2,
|
||||
'total_size': self.mock_vol_1.size + self.mock_vol_2.size}}
|
||||
'total_size': self.mock_vol_1.size + self.mock_vol_2.size,
|
||||
}
|
||||
}
|
||||
self.volumes_mock.summary.return_value = self.return_dict
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = volume.VolumeSummary(self.app, None)
|
||||
|
||||
def test_volume_summary(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.12')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.12'
|
||||
)
|
||||
arglist = [
|
||||
'--all-projects',
|
||||
]
|
||||
@ -66,9 +68,7 @@ class TestVolumeSummary(volume_fakes.TestVolume):
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
|
||||
datalist = (
|
||||
2,
|
||||
self.mock_vol_1.size + self.mock_vol_2.size)
|
||||
datalist = (2, self.mock_vol_1.size + self.mock_vol_2.size)
|
||||
self.assertCountEqual(datalist, tuple(data))
|
||||
|
||||
def test_volume_summary_pre_312(self):
|
||||
@ -81,16 +81,16 @@ class TestVolumeSummary(volume_fakes.TestVolume):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.12 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.12 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
def test_volume_summary_with_metadata(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.36')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.36'
|
||||
)
|
||||
|
||||
combine_meta = {**self.mock_vol_1.metadata, **self.mock_vol_2.metadata}
|
||||
meta_dict = copy.deepcopy(self.return_dict)
|
||||
@ -119,12 +119,12 @@ class TestVolumeSummary(volume_fakes.TestVolume):
|
||||
datalist = (
|
||||
2,
|
||||
self.mock_vol_1.size + self.mock_vol_2.size,
|
||||
format_columns.DictColumn(combine_meta))
|
||||
format_columns.DictColumn(combine_meta),
|
||||
)
|
||||
self.assertCountEqual(datalist, tuple(data))
|
||||
|
||||
|
||||
class TestVolumeRevertToSnapshot(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -134,7 +134,8 @@ class TestVolumeRevertToSnapshot(volume_fakes.TestVolume):
|
||||
self.snapshots_mock.reset_mock()
|
||||
self.mock_volume = volume_fakes.create_one_volume()
|
||||
self.mock_snapshot = volume_fakes.create_one_snapshot(
|
||||
attrs={'volume_id': self.volumes_mock.id})
|
||||
attrs={'volume_id': self.volumes_mock.id}
|
||||
)
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = volume.VolumeRevertToSnapshot(self.app, None)
|
||||
@ -149,16 +150,16 @@ class TestVolumeRevertToSnapshot(volume_fakes.TestVolume):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.40 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.40 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
def test_volume_revert_to_snapshot(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.40')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.40'
|
||||
)
|
||||
arglist = [
|
||||
self.mock_snapshot.id,
|
||||
]
|
||||
@ -168,8 +169,9 @@ class TestVolumeRevertToSnapshot(volume_fakes.TestVolume):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
find_mock_result = [self.mock_snapshot, self.mock_volume]
|
||||
with mock.patch.object(utils, 'find_resource',
|
||||
side_effect=find_mock_result) as find_mock:
|
||||
with mock.patch.object(
|
||||
utils, 'find_resource', side_effect=find_mock_result
|
||||
) as find_mock:
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volumes_mock.revert_to_snapshot.assert_called_once_with(
|
||||
|
@ -21,15 +21,15 @@ from openstackclient.volume.v3 import volume_attachment
|
||||
|
||||
|
||||
class TestVolumeAttachment(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.volumes_mock = self.app.client_manager.volume.volumes
|
||||
self.volumes_mock.reset_mock()
|
||||
|
||||
self.volume_attachments_mock = \
|
||||
self.volume_attachments_mock = (
|
||||
self.app.client_manager.volume.attachments
|
||||
)
|
||||
self.volume_attachments_mock.reset_mock()
|
||||
|
||||
self.projects_mock = self.app.client_manager.identity.projects
|
||||
@ -40,7 +40,6 @@ class TestVolumeAttachment(volume_fakes.TestVolume):
|
||||
|
||||
|
||||
class TestVolumeAttachmentCreate(TestVolumeAttachment):
|
||||
|
||||
volume = volume_fakes.create_one_volume()
|
||||
server = compute_fakes.FakeServer.create_one_server()
|
||||
volume_attachment = volume_fakes.create_one_volume_attachment(
|
||||
@ -74,14 +73,16 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
|
||||
self.volumes_mock.get.return_value = self.volume
|
||||
self.servers_mock.get.return_value = self.server
|
||||
# VolumeAttachmentManager.create returns a dict
|
||||
self.volume_attachments_mock.create.return_value = \
|
||||
self.volume_attachments_mock.create.return_value = (
|
||||
self.volume_attachment.to_dict()
|
||||
)
|
||||
|
||||
self.cmd = volume_attachment.CreateVolumeAttachment(self.app, None)
|
||||
|
||||
def test_volume_attachment_create(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.27')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.27'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.volume.id,
|
||||
@ -107,27 +108,38 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
|
||||
self.volumes_mock.get.assert_called_once_with(self.volume.id)
|
||||
self.servers_mock.get.assert_called_once_with(self.server.id)
|
||||
self.volume_attachments_mock.create.assert_called_once_with(
|
||||
self.volume.id, {}, self.server.id, None,
|
||||
self.volume.id,
|
||||
{},
|
||||
self.server.id,
|
||||
None,
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_attachment_create_with_connect(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.54')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.54'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.volume.id,
|
||||
self.server.id,
|
||||
'--connect',
|
||||
'--initiator', 'iqn.1993-08.org.debian:01:cad181614cec',
|
||||
'--ip', '192.168.1.20',
|
||||
'--host', 'my-host',
|
||||
'--platform', 'x86_64',
|
||||
'--os-type', 'linux2',
|
||||
'--initiator',
|
||||
'iqn.1993-08.org.debian:01:cad181614cec',
|
||||
'--ip',
|
||||
'192.168.1.20',
|
||||
'--host',
|
||||
'my-host',
|
||||
'--platform',
|
||||
'x86_64',
|
||||
'--os-type',
|
||||
'linux2',
|
||||
'--multipath',
|
||||
'--mountpoint', '/dev/vdb',
|
||||
'--mode', 'null',
|
||||
'--mountpoint',
|
||||
'/dev/vdb',
|
||||
'--mode',
|
||||
'null',
|
||||
]
|
||||
verifylist = [
|
||||
('volume', self.volume.id),
|
||||
@ -146,27 +158,33 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
connect_info = dict([
|
||||
('initiator', 'iqn.1993-08.org.debian:01:cad181614cec'),
|
||||
('ip', '192.168.1.20'),
|
||||
('host', 'my-host'),
|
||||
('platform', 'x86_64'),
|
||||
('os_type', 'linux2'),
|
||||
('multipath', True),
|
||||
('mountpoint', '/dev/vdb'),
|
||||
])
|
||||
connect_info = dict(
|
||||
[
|
||||
('initiator', 'iqn.1993-08.org.debian:01:cad181614cec'),
|
||||
('ip', '192.168.1.20'),
|
||||
('host', 'my-host'),
|
||||
('platform', 'x86_64'),
|
||||
('os_type', 'linux2'),
|
||||
('multipath', True),
|
||||
('mountpoint', '/dev/vdb'),
|
||||
]
|
||||
)
|
||||
|
||||
self.volumes_mock.get.assert_called_once_with(self.volume.id)
|
||||
self.servers_mock.get.assert_called_once_with(self.server.id)
|
||||
self.volume_attachments_mock.create.assert_called_once_with(
|
||||
self.volume.id, connect_info, self.server.id, 'null',
|
||||
self.volume.id,
|
||||
connect_info,
|
||||
self.server.id,
|
||||
'null',
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_attachment_create_pre_v327(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.26')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.26'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.volume.id,
|
||||
@ -179,21 +197,22 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.27 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.27 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
def test_volume_attachment_create_with_mode_pre_v354(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.53')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.53'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.volume.id,
|
||||
self.server.id,
|
||||
'--mode', 'rw',
|
||||
'--mode',
|
||||
'rw',
|
||||
]
|
||||
verifylist = [
|
||||
('volume', self.volume.id),
|
||||
@ -203,21 +222,22 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.54 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.54 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
def test_volume_attachment_create_with_connect_missing_arg(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.54')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.54'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.volume.id,
|
||||
self.server.id,
|
||||
'--initiator', 'iqn.1993-08.org.debian:01:cad181614cec',
|
||||
'--initiator',
|
||||
'iqn.1993-08.org.debian:01:cad181614cec',
|
||||
]
|
||||
verifylist = [
|
||||
('volume', self.volume.id),
|
||||
@ -228,16 +248,14 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'You must specify the --connect option for any',
|
||||
str(exc))
|
||||
'You must specify the --connect option for any', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeAttachmentDelete(TestVolumeAttachment):
|
||||
|
||||
volume_attachment = volume_fakes.create_one_volume_attachment()
|
||||
|
||||
def setUp(self):
|
||||
@ -248,8 +266,9 @@ class TestVolumeAttachmentDelete(TestVolumeAttachment):
|
||||
self.cmd = volume_attachment.DeleteVolumeAttachment(self.app, None)
|
||||
|
||||
def test_volume_attachment_delete(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.27')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.27'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.volume_attachment.id,
|
||||
@ -267,8 +286,9 @@ class TestVolumeAttachmentDelete(TestVolumeAttachment):
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_volume_attachment_delete_pre_v327(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.26')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.26'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.volume_attachment.id,
|
||||
@ -279,16 +299,14 @@ class TestVolumeAttachmentDelete(TestVolumeAttachment):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.27 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.27 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeAttachmentSet(TestVolumeAttachment):
|
||||
|
||||
volume_attachment = volume_fakes.create_one_volume_attachment()
|
||||
|
||||
columns = (
|
||||
@ -315,24 +333,32 @@ class TestVolumeAttachmentSet(TestVolumeAttachment):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.volume_attachments_mock.update.return_value = \
|
||||
self.volume_attachments_mock.update.return_value = (
|
||||
self.volume_attachment
|
||||
)
|
||||
|
||||
self.cmd = volume_attachment.SetVolumeAttachment(self.app, None)
|
||||
|
||||
def test_volume_attachment_set(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.27')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.27'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.volume_attachment.id,
|
||||
'--initiator', 'iqn.1993-08.org.debian:01:cad181614cec',
|
||||
'--ip', '192.168.1.20',
|
||||
'--host', 'my-host',
|
||||
'--platform', 'x86_64',
|
||||
'--os-type', 'linux2',
|
||||
'--initiator',
|
||||
'iqn.1993-08.org.debian:01:cad181614cec',
|
||||
'--ip',
|
||||
'192.168.1.20',
|
||||
'--host',
|
||||
'my-host',
|
||||
'--platform',
|
||||
'x86_64',
|
||||
'--os-type',
|
||||
'linux2',
|
||||
'--multipath',
|
||||
'--mountpoint', '/dev/vdb',
|
||||
'--mountpoint',
|
||||
'/dev/vdb',
|
||||
]
|
||||
verifylist = [
|
||||
('attachment', self.volume_attachment.id),
|
||||
@ -348,29 +374,34 @@ class TestVolumeAttachmentSet(TestVolumeAttachment):
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
connect_info = dict([
|
||||
('initiator', 'iqn.1993-08.org.debian:01:cad181614cec'),
|
||||
('ip', '192.168.1.20'),
|
||||
('host', 'my-host'),
|
||||
('platform', 'x86_64'),
|
||||
('os_type', 'linux2'),
|
||||
('multipath', True),
|
||||
('mountpoint', '/dev/vdb'),
|
||||
])
|
||||
connect_info = dict(
|
||||
[
|
||||
('initiator', 'iqn.1993-08.org.debian:01:cad181614cec'),
|
||||
('ip', '192.168.1.20'),
|
||||
('host', 'my-host'),
|
||||
('platform', 'x86_64'),
|
||||
('os_type', 'linux2'),
|
||||
('multipath', True),
|
||||
('mountpoint', '/dev/vdb'),
|
||||
]
|
||||
)
|
||||
|
||||
self.volume_attachments_mock.update.assert_called_once_with(
|
||||
self.volume_attachment.id, connect_info,
|
||||
self.volume_attachment.id,
|
||||
connect_info,
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_attachment_set_pre_v327(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.26')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.26'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.volume_attachment.id,
|
||||
'--initiator', 'iqn.1993-08.org.debian:01:cad181614cec',
|
||||
'--initiator',
|
||||
'iqn.1993-08.org.debian:01:cad181614cec',
|
||||
]
|
||||
verifylist = [
|
||||
('attachment', self.volume_attachment.id),
|
||||
@ -379,16 +410,14 @@ class TestVolumeAttachmentSet(TestVolumeAttachment):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.27 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.27 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeAttachmentComplete(TestVolumeAttachment):
|
||||
|
||||
volume_attachment = volume_fakes.create_one_volume_attachment()
|
||||
|
||||
def setUp(self):
|
||||
@ -399,8 +428,9 @@ class TestVolumeAttachmentComplete(TestVolumeAttachment):
|
||||
self.cmd = volume_attachment.CompleteVolumeAttachment(self.app, None)
|
||||
|
||||
def test_volume_attachment_complete(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.44')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.44'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.volume_attachment.id,
|
||||
@ -418,8 +448,9 @@ class TestVolumeAttachmentComplete(TestVolumeAttachment):
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_volume_attachment_complete_pre_v344(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.43')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.43'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.volume_attachment.id,
|
||||
@ -430,16 +461,14 @@ class TestVolumeAttachmentComplete(TestVolumeAttachment):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.44 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.44 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeAttachmentList(TestVolumeAttachment):
|
||||
|
||||
project = identity_fakes.FakeProject.create_one_project()
|
||||
volume_attachments = volume_fakes.create_volume_attachments()
|
||||
|
||||
@ -455,21 +484,24 @@ class TestVolumeAttachmentList(TestVolumeAttachment):
|
||||
volume_attachment.volume_id,
|
||||
volume_attachment.instance,
|
||||
volume_attachment.status,
|
||||
) for volume_attachment in volume_attachments
|
||||
)
|
||||
for volume_attachment in volume_attachments
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.projects_mock.get.return_value = self.project
|
||||
self.volume_attachments_mock.list.return_value = \
|
||||
self.volume_attachments_mock.list.return_value = (
|
||||
self.volume_attachments
|
||||
)
|
||||
|
||||
self.cmd = volume_attachment.ListVolumeAttachment(self.app, None)
|
||||
|
||||
def test_volume_attachment_list(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.27')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.27'
|
||||
)
|
||||
|
||||
arglist = []
|
||||
verifylist = [
|
||||
@ -498,15 +530,21 @@ class TestVolumeAttachmentList(TestVolumeAttachment):
|
||||
self.assertCountEqual(tuple(self.data), data)
|
||||
|
||||
def test_volume_attachment_list_with_options(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.27')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.27'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--project', self.project.name,
|
||||
'--volume-id', 'volume-id',
|
||||
'--status', 'attached',
|
||||
'--marker', 'volume-attachment-id',
|
||||
'--limit', '2',
|
||||
'--project',
|
||||
self.project.name,
|
||||
'--volume-id',
|
||||
'volume-id',
|
||||
'--status',
|
||||
'attached',
|
||||
'--marker',
|
||||
'volume-attachment-id',
|
||||
'--limit',
|
||||
'2',
|
||||
]
|
||||
verifylist = [
|
||||
('project', self.project.name),
|
||||
@ -534,8 +572,9 @@ class TestVolumeAttachmentList(TestVolumeAttachment):
|
||||
self.assertCountEqual(tuple(self.data), data)
|
||||
|
||||
def test_volume_attachment_list_pre_v327(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.26')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.26'
|
||||
)
|
||||
|
||||
arglist = []
|
||||
verifylist = [
|
||||
@ -549,9 +588,8 @@ class TestVolumeAttachmentList(TestVolumeAttachment):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.27 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.27 or greater is required', str(exc)
|
||||
)
|
||||
|
@ -21,27 +21,27 @@ from openstackclient.volume.v3 import volume_group
|
||||
|
||||
|
||||
class TestVolumeGroup(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.volume_groups_mock = self.app.client_manager.volume.groups
|
||||
self.volume_groups_mock.reset_mock()
|
||||
|
||||
self.volume_group_types_mock = \
|
||||
self.volume_group_types_mock = (
|
||||
self.app.client_manager.volume.group_types
|
||||
)
|
||||
self.volume_group_types_mock.reset_mock()
|
||||
|
||||
self.volume_types_mock = self.app.client_manager.volume.volume_types
|
||||
self.volume_types_mock.reset_mock()
|
||||
|
||||
self.volume_group_snapshots_mock = \
|
||||
self.volume_group_snapshots_mock = (
|
||||
self.app.client_manager.volume.group_snapshots
|
||||
)
|
||||
self.volume_group_snapshots_mock.reset_mock()
|
||||
|
||||
|
||||
class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
|
||||
fake_volume_type = volume_fakes.create_one_volume_type()
|
||||
fake_volume_group_type = volume_fakes.create_one_volume_group_type()
|
||||
fake_volume_group = volume_fakes.create_one_volume_group(
|
||||
@ -50,8 +50,9 @@ class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
'volume_types': [fake_volume_type.id],
|
||||
},
|
||||
)
|
||||
fake_volume_group_snapshot = \
|
||||
fake_volume_group_snapshot = (
|
||||
volume_fakes.create_one_volume_group_snapshot()
|
||||
)
|
||||
|
||||
columns = (
|
||||
'ID',
|
||||
@ -84,24 +85,30 @@ class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
super().setUp()
|
||||
|
||||
self.volume_types_mock.get.return_value = self.fake_volume_type
|
||||
self.volume_group_types_mock.get.return_value = \
|
||||
self.volume_group_types_mock.get.return_value = (
|
||||
self.fake_volume_group_type
|
||||
)
|
||||
self.volume_groups_mock.create.return_value = self.fake_volume_group
|
||||
self.volume_groups_mock.get.return_value = self.fake_volume_group
|
||||
self.volume_groups_mock.create_from_src.return_value = \
|
||||
self.volume_groups_mock.create_from_src.return_value = (
|
||||
self.fake_volume_group
|
||||
self.volume_group_snapshots_mock.get.return_value = \
|
||||
)
|
||||
self.volume_group_snapshots_mock.get.return_value = (
|
||||
self.fake_volume_group_snapshot
|
||||
)
|
||||
|
||||
self.cmd = volume_group.CreateVolumeGroup(self.app, None)
|
||||
|
||||
def test_volume_group_create(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.13')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.13'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--volume-group-type', self.fake_volume_group_type.id,
|
||||
'--volume-type', self.fake_volume_type.id,
|
||||
'--volume-group-type',
|
||||
self.fake_volume_group_type.id,
|
||||
'--volume-type',
|
||||
self.fake_volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
('volume_group_type', self.fake_volume_group_type.id),
|
||||
@ -115,9 +122,11 @@ class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volume_group_types_mock.get.assert_called_once_with(
|
||||
self.fake_volume_group_type.id)
|
||||
self.fake_volume_group_type.id
|
||||
)
|
||||
self.volume_types_mock.get.assert_called_once_with(
|
||||
self.fake_volume_type.id)
|
||||
self.fake_volume_type.id
|
||||
)
|
||||
self.volume_groups_mock.create.assert_called_once_with(
|
||||
self.fake_volume_group_type.id,
|
||||
self.fake_volume_type.id,
|
||||
@ -129,8 +138,9 @@ class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_group_create__legacy(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.13')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.13'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group_type.id,
|
||||
@ -149,9 +159,11 @@ class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volume_group_types_mock.get.assert_called_once_with(
|
||||
self.fake_volume_group_type.id)
|
||||
self.fake_volume_group_type.id
|
||||
)
|
||||
self.volume_types_mock.get.assert_called_once_with(
|
||||
self.fake_volume_type.id)
|
||||
self.fake_volume_type.id
|
||||
)
|
||||
self.volume_groups_mock.create.assert_called_once_with(
|
||||
self.fake_volume_group_type.id,
|
||||
self.fake_volume_type.id,
|
||||
@ -168,11 +180,13 @@ class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
)
|
||||
|
||||
def test_volume_group_create_no_volume_type(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.13')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.13'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--volume-group-type', self.fake_volume_group_type.id,
|
||||
'--volume-group-type',
|
||||
self.fake_volume_group_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
('volume_group_type', self.fake_volume_group_type.id),
|
||||
@ -183,23 +197,28 @@ class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--volume-types is a required argument when creating ',
|
||||
str(exc))
|
||||
'--volume-types is a required argument when creating ', str(exc)
|
||||
)
|
||||
|
||||
def test_volume_group_create_with_options(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.13')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.13'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--volume-group-type', self.fake_volume_group_type.id,
|
||||
'--volume-type', self.fake_volume_type.id,
|
||||
'--name', 'foo',
|
||||
'--description', 'hello, world',
|
||||
'--availability-zone', 'bar',
|
||||
'--volume-group-type',
|
||||
self.fake_volume_group_type.id,
|
||||
'--volume-type',
|
||||
self.fake_volume_type.id,
|
||||
'--name',
|
||||
'foo',
|
||||
'--description',
|
||||
'hello, world',
|
||||
'--availability-zone',
|
||||
'bar',
|
||||
]
|
||||
verifylist = [
|
||||
('volume_group_type', self.fake_volume_group_type.id),
|
||||
@ -213,9 +232,11 @@ class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volume_group_types_mock.get.assert_called_once_with(
|
||||
self.fake_volume_group_type.id)
|
||||
self.fake_volume_group_type.id
|
||||
)
|
||||
self.volume_types_mock.get.assert_called_once_with(
|
||||
self.fake_volume_type.id)
|
||||
self.fake_volume_type.id
|
||||
)
|
||||
self.volume_groups_mock.create.assert_called_once_with(
|
||||
self.fake_volume_group_type.id,
|
||||
self.fake_volume_type.id,
|
||||
@ -227,12 +248,15 @@ class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_group_create_pre_v313(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.12')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.12'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--volume-group-type', self.fake_volume_group_type.id,
|
||||
'--volume-type', self.fake_volume_type.id,
|
||||
'--volume-group-type',
|
||||
self.fake_volume_group_type.id,
|
||||
'--volume-type',
|
||||
self.fake_volume_type.id,
|
||||
]
|
||||
verifylist = [
|
||||
('volume_group_type', self.fake_volume_group_type.id),
|
||||
@ -244,19 +268,20 @@ class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.13 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.13 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
def test_volume_group_create_from_source_group(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.14')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.14'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--source-group', self.fake_volume_group.id,
|
||||
'--source-group',
|
||||
self.fake_volume_group.id,
|
||||
]
|
||||
verifylist = [
|
||||
('source_group', self.fake_volume_group.id),
|
||||
@ -266,8 +291,11 @@ class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volume_groups_mock.get.assert_has_calls(
|
||||
[mock.call(self.fake_volume_group.id),
|
||||
mock.call(self.fake_volume_group.id)])
|
||||
[
|
||||
mock.call(self.fake_volume_group.id),
|
||||
mock.call(self.fake_volume_group.id),
|
||||
]
|
||||
)
|
||||
self.volume_groups_mock.create_from_src.assert_called_once_with(
|
||||
None,
|
||||
self.fake_volume_group.id,
|
||||
@ -278,11 +306,13 @@ class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_group_create_from_group_snapshot(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.14')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.14'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--group-snapshot', self.fake_volume_group_snapshot.id,
|
||||
'--group-snapshot',
|
||||
self.fake_volume_group_snapshot.id,
|
||||
]
|
||||
verifylist = [
|
||||
('group_snapshot', self.fake_volume_group_snapshot.id),
|
||||
@ -292,9 +322,11 @@ class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volume_group_snapshots_mock.get.assert_called_once_with(
|
||||
self.fake_volume_group_snapshot.id)
|
||||
self.fake_volume_group_snapshot.id
|
||||
)
|
||||
self.volume_groups_mock.get.assert_called_once_with(
|
||||
self.fake_volume_group.id)
|
||||
self.fake_volume_group.id
|
||||
)
|
||||
self.volume_groups_mock.create_from_src.assert_called_once_with(
|
||||
self.fake_volume_group_snapshot.id,
|
||||
None,
|
||||
@ -305,11 +337,13 @@ class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_group_create_from_src_pre_v314(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.13')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.13'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--source-group', self.fake_volume_group.id,
|
||||
'--source-group',
|
||||
self.fake_volume_group.id,
|
||||
]
|
||||
verifylist = [
|
||||
('source_group', self.fake_volume_group.id),
|
||||
@ -317,38 +351,42 @@ class TestVolumeGroupCreate(TestVolumeGroup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.14 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.14 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
def test_volume_group_create_from_src_source_group_group_snapshot(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.14')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.14'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--source-group', self.fake_volume_group.id,
|
||||
'--group-snapshot', self.fake_volume_group_snapshot.id,
|
||||
'--source-group',
|
||||
self.fake_volume_group.id,
|
||||
'--group-snapshot',
|
||||
self.fake_volume_group_snapshot.id,
|
||||
]
|
||||
verifylist = [
|
||||
('source_group', self.fake_volume_group.id),
|
||||
('group_snapshot', self.fake_volume_group_snapshot.id),
|
||||
]
|
||||
|
||||
exc = self.assertRaises(tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist)
|
||||
exc = self.assertRaises(
|
||||
tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist,
|
||||
)
|
||||
self.assertIn(
|
||||
'--group-snapshot: not allowed with argument --source-group',
|
||||
str(exc))
|
||||
str(exc),
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeGroupDelete(TestVolumeGroup):
|
||||
|
||||
fake_volume_group = volume_fakes.create_one_volume_group()
|
||||
|
||||
def setUp(self):
|
||||
@ -360,8 +398,9 @@ class TestVolumeGroupDelete(TestVolumeGroup):
|
||||
self.cmd = volume_group.DeleteVolumeGroup(self.app, None)
|
||||
|
||||
def test_volume_group_delete(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.13')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.13'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group.id,
|
||||
@ -376,13 +415,15 @@ class TestVolumeGroupDelete(TestVolumeGroup):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volume_groups_mock.delete.assert_called_once_with(
|
||||
self.fake_volume_group.id, delete_volumes=True,
|
||||
self.fake_volume_group.id,
|
||||
delete_volumes=True,
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_volume_group_delete_pre_v313(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.12')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.12'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group.id,
|
||||
@ -394,16 +435,14 @@ class TestVolumeGroupDelete(TestVolumeGroup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.13 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.13 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeGroupSet(TestVolumeGroup):
|
||||
|
||||
fake_volume_group = volume_fakes.create_one_volume_group()
|
||||
|
||||
columns = (
|
||||
@ -442,13 +481,16 @@ class TestVolumeGroupSet(TestVolumeGroup):
|
||||
self.cmd = volume_group.SetVolumeGroup(self.app, None)
|
||||
|
||||
def test_volume_group_set(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.13')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.13'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group.id,
|
||||
'--name', 'foo',
|
||||
'--description', 'hello, world',
|
||||
'--name',
|
||||
'foo',
|
||||
'--description',
|
||||
'hello, world',
|
||||
]
|
||||
verifylist = [
|
||||
('group', self.fake_volume_group.id),
|
||||
@ -460,14 +502,17 @@ class TestVolumeGroupSet(TestVolumeGroup):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volume_groups_mock.update.assert_called_once_with(
|
||||
self.fake_volume_group.id, name='foo', description='hello, world',
|
||||
self.fake_volume_group.id,
|
||||
name='foo',
|
||||
description='hello, world',
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_group_with_enable_replication_option(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.38')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.38'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group.id,
|
||||
@ -482,18 +527,22 @@ class TestVolumeGroupSet(TestVolumeGroup):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volume_groups_mock.enable_replication.assert_called_once_with(
|
||||
self.fake_volume_group.id)
|
||||
self.fake_volume_group.id
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_group_set_pre_v313(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.12')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.12'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group.id,
|
||||
'--name', 'foo',
|
||||
'--description', 'hello, world',
|
||||
'--name',
|
||||
'foo',
|
||||
'--description',
|
||||
'hello, world',
|
||||
]
|
||||
verifylist = [
|
||||
('group', self.fake_volume_group.id),
|
||||
@ -503,16 +552,16 @@ class TestVolumeGroupSet(TestVolumeGroup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.13 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.13 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
def test_volume_group_with_enable_replication_option_pre_v338(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.37')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.37'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group.id,
|
||||
@ -525,16 +574,14 @@ class TestVolumeGroupSet(TestVolumeGroup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.38 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.38 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeGroupList(TestVolumeGroup):
|
||||
|
||||
fake_volume_groups = volume_fakes.create_volume_groups()
|
||||
|
||||
columns = (
|
||||
@ -547,7 +594,8 @@ class TestVolumeGroupList(TestVolumeGroup):
|
||||
fake_volume_group.id,
|
||||
fake_volume_group.status,
|
||||
fake_volume_group.name,
|
||||
) for fake_volume_group in fake_volume_groups
|
||||
)
|
||||
for fake_volume_group in fake_volume_groups
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
@ -558,8 +606,9 @@ class TestVolumeGroupList(TestVolumeGroup):
|
||||
self.cmd = volume_group.ListVolumeGroup(self.app, None)
|
||||
|
||||
def test_volume_group_list(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.13')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.13'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--all-projects',
|
||||
@ -580,8 +629,9 @@ class TestVolumeGroupList(TestVolumeGroup):
|
||||
self.assertCountEqual(tuple(self.data), data)
|
||||
|
||||
def test_volume_group_list_pre_v313(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.12')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.12'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--all-projects',
|
||||
@ -592,16 +642,14 @@ class TestVolumeGroupList(TestVolumeGroup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.13 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.13 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeGroupFailover(TestVolumeGroup):
|
||||
|
||||
fake_volume_group = volume_fakes.create_one_volume_group()
|
||||
|
||||
def setUp(self):
|
||||
@ -613,13 +661,15 @@ class TestVolumeGroupFailover(TestVolumeGroup):
|
||||
self.cmd = volume_group.FailoverVolumeGroup(self.app, None)
|
||||
|
||||
def test_volume_group_failover(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.38')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.38'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group.id,
|
||||
'--allow-attached-volume',
|
||||
'--secondary-backend-id', 'foo',
|
||||
'--secondary-backend-id',
|
||||
'foo',
|
||||
]
|
||||
verifylist = [
|
||||
('group', self.fake_volume_group.id),
|
||||
@ -638,13 +688,15 @@ class TestVolumeGroupFailover(TestVolumeGroup):
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_volume_group_failover_pre_v338(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.37')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.37'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group.id,
|
||||
'--allow-attached-volume',
|
||||
'--secondary-backend-id', 'foo',
|
||||
'--secondary-backend-id',
|
||||
'foo',
|
||||
]
|
||||
verifylist = [
|
||||
('group', self.fake_volume_group.id),
|
||||
@ -654,9 +706,8 @@ class TestVolumeGroupFailover(TestVolumeGroup):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.38 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.38 or greater is required', str(exc)
|
||||
)
|
||||
|
@ -18,23 +18,23 @@ from openstackclient.volume.v3 import volume_group_snapshot
|
||||
|
||||
|
||||
class TestVolumeGroupSnapshot(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.volume_groups_mock = self.app.client_manager.volume.groups
|
||||
self.volume_groups_mock.reset_mock()
|
||||
|
||||
self.volume_group_snapshots_mock = \
|
||||
self.volume_group_snapshots_mock = (
|
||||
self.app.client_manager.volume.group_snapshots
|
||||
)
|
||||
self.volume_group_snapshots_mock.reset_mock()
|
||||
|
||||
|
||||
class TestVolumeGroupSnapshotCreate(TestVolumeGroupSnapshot):
|
||||
|
||||
fake_volume_group = volume_fakes.create_one_volume_group()
|
||||
fake_volume_group_snapshot = \
|
||||
fake_volume_group_snapshot = (
|
||||
volume_fakes.create_one_volume_group_snapshot()
|
||||
)
|
||||
|
||||
columns = (
|
||||
'ID',
|
||||
@ -57,17 +57,21 @@ class TestVolumeGroupSnapshotCreate(TestVolumeGroupSnapshot):
|
||||
super().setUp()
|
||||
|
||||
self.volume_groups_mock.get.return_value = self.fake_volume_group
|
||||
self.volume_group_snapshots_mock.create.return_value = \
|
||||
self.volume_group_snapshots_mock.create.return_value = (
|
||||
self.fake_volume_group_snapshot
|
||||
self.volume_group_snapshots_mock.get.return_value = \
|
||||
)
|
||||
self.volume_group_snapshots_mock.get.return_value = (
|
||||
self.fake_volume_group_snapshot
|
||||
)
|
||||
|
||||
self.cmd = volume_group_snapshot.CreateVolumeGroupSnapshot(
|
||||
self.app, None)
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_volume_group_snapshot_create(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.14')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.14'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group.id,
|
||||
@ -82,21 +86,27 @@ class TestVolumeGroupSnapshotCreate(TestVolumeGroupSnapshot):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volume_groups_mock.get.assert_called_once_with(
|
||||
self.fake_volume_group.id)
|
||||
self.fake_volume_group.id
|
||||
)
|
||||
self.volume_group_snapshots_mock.create.assert_called_once_with(
|
||||
self.fake_volume_group.id, None, None,
|
||||
self.fake_volume_group.id,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_group_snapshot_create_with_options(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.14')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.14'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group.id,
|
||||
'--name', 'foo',
|
||||
'--description', 'hello, world',
|
||||
'--name',
|
||||
'foo',
|
||||
'--description',
|
||||
'hello, world',
|
||||
]
|
||||
verifylist = [
|
||||
('volume_group', self.fake_volume_group.id),
|
||||
@ -108,16 +118,20 @@ class TestVolumeGroupSnapshotCreate(TestVolumeGroupSnapshot):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volume_groups_mock.get.assert_called_once_with(
|
||||
self.fake_volume_group.id)
|
||||
self.fake_volume_group.id
|
||||
)
|
||||
self.volume_group_snapshots_mock.create.assert_called_once_with(
|
||||
self.fake_volume_group.id, 'foo', 'hello, world',
|
||||
self.fake_volume_group.id,
|
||||
'foo',
|
||||
'hello, world',
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_group_snapshot_create_pre_v314(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.13')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.13'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group.id,
|
||||
@ -130,32 +144,34 @@ class TestVolumeGroupSnapshotCreate(TestVolumeGroupSnapshot):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.14 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.14 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeGroupSnapshotDelete(TestVolumeGroupSnapshot):
|
||||
|
||||
fake_volume_group_snapshot = \
|
||||
fake_volume_group_snapshot = (
|
||||
volume_fakes.create_one_volume_group_snapshot()
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.volume_group_snapshots_mock.get.return_value = \
|
||||
self.volume_group_snapshots_mock.get.return_value = (
|
||||
self.fake_volume_group_snapshot
|
||||
)
|
||||
self.volume_group_snapshots_mock.delete.return_value = None
|
||||
|
||||
self.cmd = volume_group_snapshot.DeleteVolumeGroupSnapshot(
|
||||
self.app, None)
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_volume_group_snapshot_delete(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.14')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.14'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group_snapshot.id,
|
||||
@ -173,8 +189,9 @@ class TestVolumeGroupSnapshotDelete(TestVolumeGroupSnapshot):
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_volume_group_snapshot_delete_pre_v314(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.13')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.13'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group_snapshot.id,
|
||||
@ -185,16 +202,14 @@ class TestVolumeGroupSnapshotDelete(TestVolumeGroupSnapshot):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.14 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.14 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeGroupSnapshotList(TestVolumeGroupSnapshot):
|
||||
|
||||
fake_volume_group_snapshots = volume_fakes.create_volume_group_snapshots()
|
||||
|
||||
columns = (
|
||||
@ -207,21 +222,25 @@ class TestVolumeGroupSnapshotList(TestVolumeGroupSnapshot):
|
||||
fake_volume_group_snapshot.id,
|
||||
fake_volume_group_snapshot.status,
|
||||
fake_volume_group_snapshot.name,
|
||||
) for fake_volume_group_snapshot in fake_volume_group_snapshots
|
||||
)
|
||||
for fake_volume_group_snapshot in fake_volume_group_snapshots
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.volume_group_snapshots_mock.list.return_value = \
|
||||
self.volume_group_snapshots_mock.list.return_value = (
|
||||
self.fake_volume_group_snapshots
|
||||
)
|
||||
|
||||
self.cmd = volume_group_snapshot.ListVolumeGroupSnapshot(
|
||||
self.app, None)
|
||||
self.app, None
|
||||
)
|
||||
|
||||
def test_volume_group_snapshot_list(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.14')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.14'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--all-projects',
|
||||
@ -242,20 +261,19 @@ class TestVolumeGroupSnapshotList(TestVolumeGroupSnapshot):
|
||||
self.assertCountEqual(tuple(self.data), data)
|
||||
|
||||
def test_volume_group_snapshot_list_pre_v314(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.13')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.13'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
]
|
||||
arglist = []
|
||||
verifylist = [
|
||||
('all_projects', False),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.14 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.14 or greater is required', str(exc)
|
||||
)
|
||||
|
@ -21,17 +21,16 @@ from openstackclient.volume.v3 import volume_group_type
|
||||
|
||||
|
||||
class TestVolumeGroupType(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.volume_group_types_mock = \
|
||||
self.volume_group_types_mock = (
|
||||
self.app.client_manager.volume.group_types
|
||||
)
|
||||
self.volume_group_types_mock.reset_mock()
|
||||
|
||||
|
||||
class TestVolumeGroupTypeCreate(TestVolumeGroupType):
|
||||
|
||||
maxDiff = 2000
|
||||
|
||||
fake_volume_group_type = volume_fakes.create_one_volume_group_type()
|
||||
@ -54,14 +53,16 @@ class TestVolumeGroupTypeCreate(TestVolumeGroupType):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.volume_group_types_mock.create.return_value = \
|
||||
self.volume_group_types_mock.create.return_value = (
|
||||
self.fake_volume_group_type
|
||||
)
|
||||
|
||||
self.cmd = volume_group_type.CreateVolumeGroupType(self.app, None)
|
||||
|
||||
def test_volume_group_type_create(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.11')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.11'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group_type.name,
|
||||
@ -76,19 +77,20 @@ class TestVolumeGroupTypeCreate(TestVolumeGroupType):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volume_group_types_mock.create.assert_called_once_with(
|
||||
self.fake_volume_group_type.name,
|
||||
None,
|
||||
True)
|
||||
self.fake_volume_group_type.name, None, True
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_group_type_create_with_options(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.11')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.11'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group_type.name,
|
||||
'--description', 'foo',
|
||||
'--description',
|
||||
'foo',
|
||||
'--private',
|
||||
]
|
||||
verifylist = [
|
||||
@ -101,15 +103,15 @@ class TestVolumeGroupTypeCreate(TestVolumeGroupType):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volume_group_types_mock.create.assert_called_once_with(
|
||||
self.fake_volume_group_type.name,
|
||||
'foo',
|
||||
False)
|
||||
self.fake_volume_group_type.name, 'foo', False
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_group_type_create_pre_v311(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.10')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.10'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group_type.name,
|
||||
@ -122,30 +124,30 @@ class TestVolumeGroupTypeCreate(TestVolumeGroupType):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.11 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.11 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeGroupTypeDelete(TestVolumeGroupType):
|
||||
|
||||
fake_volume_group_type = volume_fakes.create_one_volume_group_type()
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.volume_group_types_mock.get.return_value = \
|
||||
self.volume_group_types_mock.get.return_value = (
|
||||
self.fake_volume_group_type
|
||||
)
|
||||
self.volume_group_types_mock.delete.return_value = None
|
||||
|
||||
self.cmd = volume_group_type.DeleteVolumeGroupType(self.app, None)
|
||||
|
||||
def test_volume_group_type_delete(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.11')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.11'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group_type.id,
|
||||
@ -163,8 +165,9 @@ class TestVolumeGroupTypeDelete(TestVolumeGroupType):
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_volume_group_type_delete_pre_v311(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.10')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.10'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group_type.id,
|
||||
@ -175,16 +178,14 @@ class TestVolumeGroupTypeDelete(TestVolumeGroupType):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.11 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.11 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeGroupTypeSet(TestVolumeGroupType):
|
||||
|
||||
fake_volume_group_type = volume_fakes.create_one_volume_group_type(
|
||||
methods={
|
||||
'get_keys': {'foo': 'bar'},
|
||||
@ -211,25 +212,31 @@ class TestVolumeGroupTypeSet(TestVolumeGroupType):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.volume_group_types_mock.get.return_value = \
|
||||
self.volume_group_types_mock.get.return_value = (
|
||||
self.fake_volume_group_type
|
||||
self.volume_group_types_mock.update.return_value = \
|
||||
)
|
||||
self.volume_group_types_mock.update.return_value = (
|
||||
self.fake_volume_group_type
|
||||
)
|
||||
|
||||
self.cmd = volume_group_type.SetVolumeGroupType(self.app, None)
|
||||
|
||||
def test_volume_group_type_set(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.11')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.11'
|
||||
)
|
||||
|
||||
self.fake_volume_group_type.set_keys.return_value = None
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group_type.id,
|
||||
'--name', 'foo',
|
||||
'--description', 'hello, world',
|
||||
'--name',
|
||||
'foo',
|
||||
'--description',
|
||||
'hello, world',
|
||||
'--public',
|
||||
'--property', 'fizz=buzz',
|
||||
'--property',
|
||||
'fizz=buzz',
|
||||
]
|
||||
verifylist = [
|
||||
('group_type', self.fake_volume_group_type.id),
|
||||
@ -256,13 +263,15 @@ class TestVolumeGroupTypeSet(TestVolumeGroupType):
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_group_type_with_no_property_option(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.11')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.11'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group_type.id,
|
||||
'--no-property',
|
||||
'--property', 'fizz=buzz',
|
||||
'--property',
|
||||
'fizz=buzz',
|
||||
]
|
||||
verifylist = [
|
||||
('group_type', self.fake_volume_group_type.id),
|
||||
@ -277,21 +286,26 @@ class TestVolumeGroupTypeSet(TestVolumeGroupType):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volume_group_types_mock.get.assert_called_once_with(
|
||||
self.fake_volume_group_type.id)
|
||||
self.fake_volume_group_type.id
|
||||
)
|
||||
self.fake_volume_group_type.get_keys.assert_called_once_with()
|
||||
self.fake_volume_group_type.unset_keys.assert_called_once_with(
|
||||
{'foo': 'bar'}.keys())
|
||||
{'foo': 'bar'}.keys()
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_group_type_set_pre_v311(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.10')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.10'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group_type.id,
|
||||
'--name', 'foo',
|
||||
'--description', 'hello, world',
|
||||
'--name',
|
||||
'foo',
|
||||
'--description',
|
||||
'hello, world',
|
||||
]
|
||||
verifylist = [
|
||||
('group_type', self.fake_volume_group_type.id),
|
||||
@ -304,16 +318,14 @@ class TestVolumeGroupTypeSet(TestVolumeGroupType):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.11 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.11 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeGroupTypeUnset(TestVolumeGroupType):
|
||||
|
||||
fake_volume_group_type = volume_fakes.create_one_volume_group_type(
|
||||
methods={'unset_keys': None},
|
||||
)
|
||||
@ -336,18 +348,21 @@ class TestVolumeGroupTypeUnset(TestVolumeGroupType):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.volume_group_types_mock.get.return_value = \
|
||||
self.volume_group_types_mock.get.return_value = (
|
||||
self.fake_volume_group_type
|
||||
)
|
||||
|
||||
self.cmd = volume_group_type.UnsetVolumeGroupType(self.app, None)
|
||||
|
||||
def test_volume_group_type_unset(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.11')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.11'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group_type.id,
|
||||
'--property', 'fizz',
|
||||
'--property',
|
||||
'fizz',
|
||||
]
|
||||
verifylist = [
|
||||
('group_type', self.fake_volume_group_type.id),
|
||||
@ -357,22 +372,27 @@ class TestVolumeGroupTypeUnset(TestVolumeGroupType):
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volume_group_types_mock.get.assert_has_calls([
|
||||
mock.call(self.fake_volume_group_type.id),
|
||||
mock.call(self.fake_volume_group_type.id),
|
||||
])
|
||||
self.volume_group_types_mock.get.assert_has_calls(
|
||||
[
|
||||
mock.call(self.fake_volume_group_type.id),
|
||||
mock.call(self.fake_volume_group_type.id),
|
||||
]
|
||||
)
|
||||
self.fake_volume_group_type.unset_keys.assert_called_once_with(
|
||||
['fizz'])
|
||||
['fizz']
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_volume_group_type_unset_pre_v311(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.10')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.10'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_volume_group_type.id,
|
||||
'--property', 'fizz',
|
||||
'--property',
|
||||
'fizz',
|
||||
]
|
||||
verifylist = [
|
||||
('group_type', self.fake_volume_group_type.id),
|
||||
@ -381,16 +401,14 @@ class TestVolumeGroupTypeUnset(TestVolumeGroupType):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.11 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.11 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeGroupTypeList(TestVolumeGroupType):
|
||||
|
||||
fake_volume_group_types = volume_fakes.create_volume_group_types()
|
||||
|
||||
columns = (
|
||||
@ -405,25 +423,28 @@ class TestVolumeGroupTypeList(TestVolumeGroupType):
|
||||
fake_volume_group_type.name,
|
||||
fake_volume_group_type.is_public,
|
||||
fake_volume_group_type.group_specs,
|
||||
) for fake_volume_group_type in fake_volume_group_types
|
||||
)
|
||||
for fake_volume_group_type in fake_volume_group_types
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.volume_group_types_mock.list.return_value = \
|
||||
self.volume_group_types_mock.list.return_value = (
|
||||
self.fake_volume_group_types
|
||||
self.volume_group_types_mock.default.return_value = \
|
||||
)
|
||||
self.volume_group_types_mock.default.return_value = (
|
||||
self.fake_volume_group_types[0]
|
||||
)
|
||||
|
||||
self.cmd = volume_group_type.ListVolumeGroupType(self.app, None)
|
||||
|
||||
def test_volume_group_type_list(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.11')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.11'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
]
|
||||
arglist = []
|
||||
verifylist = [
|
||||
('show_default', False),
|
||||
]
|
||||
@ -436,8 +457,9 @@ class TestVolumeGroupTypeList(TestVolumeGroupType):
|
||||
self.assertCountEqual(tuple(self.data), data)
|
||||
|
||||
def test_volume_group_type_list_with_default_option(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.11')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.11'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--default',
|
||||
@ -454,19 +476,17 @@ class TestVolumeGroupTypeList(TestVolumeGroupType):
|
||||
self.assertCountEqual(tuple([self.data[0]]), data)
|
||||
|
||||
def test_volume_group_type_list_pre_v311(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.10')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.10'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
]
|
||||
verifylist = [
|
||||
]
|
||||
arglist = []
|
||||
verifylist = []
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.11 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.11 or greater is required', str(exc)
|
||||
)
|
||||
|
@ -21,7 +21,6 @@ from openstackclient.volume.v3 import volume_message
|
||||
|
||||
|
||||
class TestVolumeMessage(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -33,7 +32,6 @@ class TestVolumeMessage(volume_fakes.TestVolume):
|
||||
|
||||
|
||||
class TestVolumeMessageDelete(TestVolumeMessage):
|
||||
|
||||
fake_messages = volume_fakes.create_volume_messages(count=2)
|
||||
|
||||
def setUp(self):
|
||||
@ -48,8 +46,9 @@ class TestVolumeMessageDelete(TestVolumeMessage):
|
||||
self.cmd = volume_message.DeleteMessage(self.app, None)
|
||||
|
||||
def test_message_delete(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.3')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.3'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_messages[0].id,
|
||||
@ -62,12 +61,14 @@ class TestVolumeMessageDelete(TestVolumeMessage):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.volume_messages_mock.delete.assert_called_with(
|
||||
self.fake_messages[0].id)
|
||||
self.fake_messages[0].id
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_message_delete_multiple_messages(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.3')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.3'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_messages[0].id,
|
||||
@ -87,8 +88,9 @@ class TestVolumeMessageDelete(TestVolumeMessage):
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_message_delete_multiple_messages_with_exception(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.3')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.3'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_messages[0].id,
|
||||
@ -101,22 +103,26 @@ class TestVolumeMessageDelete(TestVolumeMessage):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.volume_messages_mock.delete.side_effect = [
|
||||
self.fake_messages[0], exceptions.CommandError]
|
||||
self.fake_messages[0],
|
||||
exceptions.CommandError,
|
||||
]
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action, parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertEqual('Failed to delete 1 of 2 messages.', str(exc))
|
||||
|
||||
self.volume_messages_mock.delete.assert_any_call(
|
||||
self.fake_messages[0].id)
|
||||
self.fake_messages[0].id
|
||||
)
|
||||
self.volume_messages_mock.delete.assert_any_call('invalid_message')
|
||||
|
||||
self.assertEqual(2, self.volume_messages_mock.delete.call_count)
|
||||
|
||||
def test_message_delete_pre_v33(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.2')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.2'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_messages[0].id,
|
||||
@ -127,16 +133,14 @@ class TestVolumeMessageDelete(TestVolumeMessage):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.3 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.3 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeMessageList(TestVolumeMessage):
|
||||
|
||||
fake_project = identity_fakes.FakeProject.create_one_project()
|
||||
fake_messages = volume_fakes.create_volume_messages(count=3)
|
||||
|
||||
@ -153,17 +157,19 @@ class TestVolumeMessageList(TestVolumeMessage):
|
||||
)
|
||||
data = []
|
||||
for fake_message in fake_messages:
|
||||
data.append((
|
||||
fake_message.id,
|
||||
fake_message.event_id,
|
||||
fake_message.resource_type,
|
||||
fake_message.resource_uuid,
|
||||
fake_message.message_level,
|
||||
fake_message.user_message,
|
||||
fake_message.request_id,
|
||||
fake_message.created_at,
|
||||
fake_message.guaranteed_until,
|
||||
))
|
||||
data.append(
|
||||
(
|
||||
fake_message.id,
|
||||
fake_message.event_id,
|
||||
fake_message.resource_type,
|
||||
fake_message.resource_uuid,
|
||||
fake_message.message_level,
|
||||
fake_message.user_message,
|
||||
fake_message.request_id,
|
||||
fake_message.created_at,
|
||||
fake_message.guaranteed_until,
|
||||
)
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@ -174,8 +180,9 @@ class TestVolumeMessageList(TestVolumeMessage):
|
||||
self.cmd = volume_message.ListMessages(self.app, None)
|
||||
|
||||
def test_message_list(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.3')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.3'
|
||||
)
|
||||
|
||||
arglist = []
|
||||
verifylist = [
|
||||
@ -199,13 +206,17 @@ class TestVolumeMessageList(TestVolumeMessage):
|
||||
self.assertCountEqual(self.data, list(data))
|
||||
|
||||
def test_message_list_with_options(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.3')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.3'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
'--project', self.fake_project.name,
|
||||
'--marker', self.fake_messages[0].id,
|
||||
'--limit', '3',
|
||||
'--project',
|
||||
self.fake_project.name,
|
||||
'--marker',
|
||||
self.fake_messages[0].id,
|
||||
'--limit',
|
||||
'3',
|
||||
]
|
||||
verifylist = [
|
||||
('project', self.fake_project.name),
|
||||
@ -228,8 +239,9 @@ class TestVolumeMessageList(TestVolumeMessage):
|
||||
self.assertCountEqual(self.data, list(data))
|
||||
|
||||
def test_message_list_pre_v33(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.2')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.2'
|
||||
)
|
||||
|
||||
arglist = []
|
||||
verifylist = [
|
||||
@ -241,16 +253,14 @@ class TestVolumeMessageList(TestVolumeMessage):
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.3 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.3 or greater is required', str(exc)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeMessageShow(TestVolumeMessage):
|
||||
|
||||
fake_message = volume_fakes.create_one_volume_message()
|
||||
|
||||
columns = (
|
||||
@ -284,15 +294,12 @@ class TestVolumeMessageShow(TestVolumeMessage):
|
||||
self.cmd = volume_message.ShowMessage(self.app, None)
|
||||
|
||||
def test_message_show(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.3')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.3'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_message.id
|
||||
]
|
||||
verifylist = [
|
||||
('message_id', self.fake_message.id)
|
||||
]
|
||||
arglist = [self.fake_message.id]
|
||||
verifylist = [('message_id', self.fake_message.id)]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
@ -302,21 +309,17 @@ class TestVolumeMessageShow(TestVolumeMessage):
|
||||
self.assertEqual(self.data, data)
|
||||
|
||||
def test_message_show_pre_v33(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.2')
|
||||
self.app.client_manager.volume.api_version = api_versions.APIVersion(
|
||||
'3.2'
|
||||
)
|
||||
|
||||
arglist = [
|
||||
self.fake_message.id
|
||||
]
|
||||
verifylist = [
|
||||
('message_id', self.fake_message.id)
|
||||
]
|
||||
arglist = [self.fake_message.id]
|
||||
verifylist = [('message_id', self.fake_message.id)]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.3 or greater is required',
|
||||
str(exc))
|
||||
'--os-volume-api-version 3.3 or greater is required', str(exc)
|
||||
)
|
||||
|
@ -60,6 +60,7 @@ def make_client(instance):
|
||||
else:
|
||||
version = instance._api_version[API_NAME]
|
||||
from cinderclient import api_versions
|
||||
|
||||
# convert to APIVersion object
|
||||
version = api_versions.get_api_version(version)
|
||||
|
||||
@ -69,9 +70,7 @@ def make_client(instance):
|
||||
volume_snapshots.Snapshot.NAME_ATTR = 'display_name'
|
||||
|
||||
volume_client = utils.get_client_class(
|
||||
API_NAME,
|
||||
version.ver_major,
|
||||
API_VERSIONS
|
||||
API_NAME, version.ver_major, API_VERSIONS
|
||||
)
|
||||
LOG.debug('Instantiating volume client: %s', volume_client)
|
||||
|
||||
@ -84,7 +83,8 @@ def make_client(instance):
|
||||
kwargs = utils.build_kwargs_dict('endpoint_type', instance.interface)
|
||||
|
||||
endpoint_override = instance.sdk_connection.config.get_endpoint(
|
||||
'block-storage')
|
||||
'block-storage'
|
||||
)
|
||||
|
||||
client = volume_client(
|
||||
session=instance.session,
|
||||
@ -105,8 +105,10 @@ def build_option_parser(parser):
|
||||
'--os-volume-api-version',
|
||||
metavar='<volume-api-version>',
|
||||
default=utils.env('OS_VOLUME_API_VERSION'),
|
||||
help=_('Volume API version, default=%s '
|
||||
'(Env: OS_VOLUME_API_VERSION)') % DEFAULT_API_VERSION
|
||||
help=_(
|
||||
'Volume API version, default=%s ' '(Env: OS_VOLUME_API_VERSION)'
|
||||
)
|
||||
% DEFAULT_API_VERSION,
|
||||
)
|
||||
return parser
|
||||
|
||||
|
@ -48,10 +48,12 @@ class AssociateQos(command.Command):
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
qos_spec = utils.find_resource(volume_client.qos_specs,
|
||||
parsed_args.qos_spec)
|
||||
volume_type = utils.find_resource(volume_client.volume_types,
|
||||
parsed_args.volume_type)
|
||||
qos_spec = utils.find_resource(
|
||||
volume_client.qos_specs, parsed_args.qos_spec
|
||||
)
|
||||
volume_type = utils.find_resource(
|
||||
volume_client.volume_types, parsed_args.volume_type
|
||||
)
|
||||
|
||||
volume_client.qos_specs.associate(qos_spec.id, volume_type.id)
|
||||
|
||||
@ -72,16 +74,22 @@ class CreateQos(command.ShowOne):
|
||||
metavar='<consumer>',
|
||||
choices=consumer_choices,
|
||||
default='both',
|
||||
help=(_('Consumer of the QoS. Valid consumers: %s '
|
||||
"(defaults to 'both')") %
|
||||
utils.format_list(consumer_choices))
|
||||
help=(
|
||||
_(
|
||||
'Consumer of the QoS. Valid consumers: %s '
|
||||
"(defaults to 'both')"
|
||||
)
|
||||
% utils.format_list(consumer_choices)
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--property',
|
||||
metavar='<key=value>',
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_('Set a QoS specification property '
|
||||
'(repeat option to set multiple properties)'),
|
||||
help=_(
|
||||
'Set a QoS specification property '
|
||||
'(repeat option to set multiple properties)'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -95,8 +103,11 @@ class CreateQos(command.ShowOne):
|
||||
|
||||
qos_spec = volume_client.qos_specs.create(parsed_args.name, specs)
|
||||
qos_spec._info.update(
|
||||
{'properties':
|
||||
format_columns.DictColumn(qos_spec._info.pop('specs'))}
|
||||
{
|
||||
'properties': format_columns.DictColumn(
|
||||
qos_spec._info.pop('specs')
|
||||
)
|
||||
}
|
||||
)
|
||||
return zip(*sorted(qos_spec._info.items()))
|
||||
|
||||
@ -116,7 +127,7 @@ class DeleteQos(command.Command):
|
||||
'--force',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_("Allow to delete in-use QoS specification(s)")
|
||||
help=_("Allow to delete in-use QoS specification(s)"),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -130,14 +141,20 @@ class DeleteQos(command.Command):
|
||||
volume_client.qos_specs.delete(qos_spec.id, parsed_args.force)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete QoS specification with "
|
||||
"name or ID '%(qos)s': %(e)s"),
|
||||
{'qos': i, 'e': e})
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to delete QoS specification with "
|
||||
"name or ID '%(qos)s': %(e)s"
|
||||
),
|
||||
{'qos': i, 'e': e},
|
||||
)
|
||||
|
||||
if result > 0:
|
||||
total = len(parsed_args.qos_specs)
|
||||
msg = (_("%(result)s of %(total)s QoS specifications failed"
|
||||
" to delete.") % {'result': result, 'total': total})
|
||||
msg = _(
|
||||
"%(result)s of %(total)s QoS specifications failed"
|
||||
" to delete."
|
||||
) % {'result': result, 'total': total}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
@ -168,12 +185,14 @@ class DisassociateQos(command.Command):
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
qos_spec = utils.find_resource(volume_client.qos_specs,
|
||||
parsed_args.qos_spec)
|
||||
qos_spec = utils.find_resource(
|
||||
volume_client.qos_specs, parsed_args.qos_spec
|
||||
)
|
||||
|
||||
if parsed_args.volume_type:
|
||||
volume_type = utils.find_resource(volume_client.volume_types,
|
||||
parsed_args.volume_type)
|
||||
volume_type = utils.find_resource(
|
||||
volume_client.volume_types, parsed_args.volume_type
|
||||
)
|
||||
volume_client.qos_specs.disassociate(qos_spec.id, volume_type.id)
|
||||
elif parsed_args.all:
|
||||
volume_client.qos_specs.disassociate_all(qos_spec.id)
|
||||
@ -203,16 +222,27 @@ class ListQos(command.Lister):
|
||||
raise
|
||||
|
||||
display_columns = (
|
||||
'ID', 'Name', 'Consumer', 'Associations', 'Properties')
|
||||
'ID',
|
||||
'Name',
|
||||
'Consumer',
|
||||
'Associations',
|
||||
'Properties',
|
||||
)
|
||||
columns = ('ID', 'Name', 'Consumer', 'Associations', 'Specs')
|
||||
return (display_columns,
|
||||
(utils.get_dict_properties(
|
||||
s._info, columns,
|
||||
return (
|
||||
display_columns,
|
||||
(
|
||||
utils.get_dict_properties(
|
||||
s._info,
|
||||
columns,
|
||||
formatters={
|
||||
'Specs': format_columns.DictColumn,
|
||||
'Associations': format_columns.ListColumn
|
||||
'Associations': format_columns.ListColumn,
|
||||
},
|
||||
) for s in qos_specs_list))
|
||||
)
|
||||
for s in qos_specs_list
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class SetQos(command.Command):
|
||||
@ -229,19 +259,21 @@ class SetQos(command.Command):
|
||||
'--property',
|
||||
metavar='<key=value>',
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_('Property to add or modify for this QoS specification '
|
||||
'(repeat option to set multiple properties)'),
|
||||
help=_(
|
||||
'Property to add or modify for this QoS specification '
|
||||
'(repeat option to set multiple properties)'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
qos_spec = utils.find_resource(volume_client.qos_specs,
|
||||
parsed_args.qos_spec)
|
||||
qos_spec = utils.find_resource(
|
||||
volume_client.qos_specs, parsed_args.qos_spec
|
||||
)
|
||||
|
||||
if parsed_args.property:
|
||||
volume_client.qos_specs.set_keys(qos_spec.id,
|
||||
parsed_args.property)
|
||||
volume_client.qos_specs.set_keys(qos_spec.id, parsed_args.property)
|
||||
|
||||
|
||||
class ShowQos(command.ShowOne):
|
||||
@ -258,19 +290,25 @@ class ShowQos(command.ShowOne):
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
qos_spec = utils.find_resource(volume_client.qos_specs,
|
||||
parsed_args.qos_spec)
|
||||
qos_spec = utils.find_resource(
|
||||
volume_client.qos_specs, parsed_args.qos_spec
|
||||
)
|
||||
|
||||
qos_associations = volume_client.qos_specs.get_associations(qos_spec)
|
||||
if qos_associations:
|
||||
associations = [association.name
|
||||
for association in qos_associations]
|
||||
qos_spec._info.update({
|
||||
'associations': format_columns.ListColumn(associations)
|
||||
})
|
||||
associations = [
|
||||
association.name for association in qos_associations
|
||||
]
|
||||
qos_spec._info.update(
|
||||
{'associations': format_columns.ListColumn(associations)}
|
||||
)
|
||||
qos_spec._info.update(
|
||||
{'properties':
|
||||
format_columns.DictColumn(qos_spec._info.pop('specs'))})
|
||||
{
|
||||
'properties': format_columns.DictColumn(
|
||||
qos_spec._info.pop('specs')
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
return zip(*sorted(qos_spec._info.items()))
|
||||
|
||||
@ -289,16 +327,20 @@ class UnsetQos(command.Command):
|
||||
'--property',
|
||||
metavar='<key>',
|
||||
action='append',
|
||||
help=_('Property to remove from the QoS specification. '
|
||||
'(repeat option to unset multiple properties)'),
|
||||
help=_(
|
||||
'Property to remove from the QoS specification. '
|
||||
'(repeat option to unset multiple properties)'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
qos_spec = utils.find_resource(volume_client.qos_specs,
|
||||
parsed_args.qos_spec)
|
||||
qos_spec = utils.find_resource(
|
||||
volume_client.qos_specs, parsed_args.qos_spec
|
||||
)
|
||||
|
||||
if parsed_args.property:
|
||||
volume_client.qos_specs.unset_keys(qos_spec.id,
|
||||
parsed_args.property)
|
||||
volume_client.qos_specs.unset_keys(
|
||||
qos_spec.id, parsed_args.property
|
||||
)
|
||||
|
@ -29,18 +29,18 @@ class ListService(command.Lister):
|
||||
parser.add_argument(
|
||||
"--host",
|
||||
metavar="<host>",
|
||||
help=_("List services on specified host (name only)")
|
||||
help=_("List services on specified host (name only)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--service",
|
||||
metavar="<service>",
|
||||
help=_("List only specified service (name only)")
|
||||
help=_("List only specified service (name only)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--long",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help=_("List additional fields in output")
|
||||
help=_("List additional fields in output"),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -55,7 +55,7 @@ class ListService(command.Lister):
|
||||
"Status",
|
||||
"State",
|
||||
"Updated At",
|
||||
"Disabled Reason"
|
||||
"Disabled Reason",
|
||||
]
|
||||
else:
|
||||
columns = [
|
||||
@ -64,15 +64,22 @@ class ListService(command.Lister):
|
||||
"Zone",
|
||||
"Status",
|
||||
"State",
|
||||
"Updated At"
|
||||
"Updated At",
|
||||
]
|
||||
|
||||
data = service_client.services.list(parsed_args.host,
|
||||
parsed_args.service)
|
||||
return (columns,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
) for s in data))
|
||||
data = service_client.services.list(
|
||||
parsed_args.host, parsed_args.service
|
||||
)
|
||||
return (
|
||||
columns,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
)
|
||||
for s in data
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class SetService(command.Command):
|
||||
@ -80,51 +87,50 @@ class SetService(command.Command):
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SetService, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"host",
|
||||
metavar="<host>",
|
||||
help=_("Name of host")
|
||||
)
|
||||
parser.add_argument("host", metavar="<host>", help=_("Name of host"))
|
||||
parser.add_argument(
|
||||
"service",
|
||||
metavar="<service>",
|
||||
help=_("Name of service (Binary name)")
|
||||
help=_("Name of service (Binary name)"),
|
||||
)
|
||||
enabled_group = parser.add_mutually_exclusive_group()
|
||||
enabled_group.add_argument(
|
||||
"--enable",
|
||||
action="store_true",
|
||||
help=_("Enable volume service")
|
||||
"--enable", action="store_true", help=_("Enable volume service")
|
||||
)
|
||||
enabled_group.add_argument(
|
||||
"--disable",
|
||||
action="store_true",
|
||||
help=_("Disable volume service")
|
||||
"--disable", action="store_true", help=_("Disable volume service")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--disable-reason",
|
||||
metavar="<reason>",
|
||||
help=_("Reason for disabling the service "
|
||||
"(should be used with --disable option)")
|
||||
help=_(
|
||||
"Reason for disabling the service "
|
||||
"(should be used with --disable option)"
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
if parsed_args.disable_reason and not parsed_args.disable:
|
||||
msg = _("Cannot specify option --disable-reason without "
|
||||
"--disable specified.")
|
||||
msg = _(
|
||||
"Cannot specify option --disable-reason without "
|
||||
"--disable specified."
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
service_client = self.app.client_manager.volume
|
||||
if parsed_args.enable:
|
||||
service_client.services.enable(
|
||||
parsed_args.host, parsed_args.service)
|
||||
parsed_args.host, parsed_args.service
|
||||
)
|
||||
if parsed_args.disable:
|
||||
if parsed_args.disable_reason:
|
||||
service_client.services.disable_log_reason(
|
||||
parsed_args.host,
|
||||
parsed_args.service,
|
||||
parsed_args.disable_reason)
|
||||
parsed_args.disable_reason,
|
||||
)
|
||||
else:
|
||||
service_client.services.disable(
|
||||
parsed_args.host, parsed_args.service)
|
||||
parsed_args.host, parsed_args.service
|
||||
)
|
||||
|
@ -70,10 +70,11 @@ def _check_size_arg(args):
|
||||
volume is not specified.
|
||||
"""
|
||||
|
||||
if ((args.snapshot or args.source)
|
||||
is None and args.size is None):
|
||||
msg = _("--size is a required option if snapshot "
|
||||
"or source volume is not specified.")
|
||||
if (args.snapshot or args.source) is None and args.size is None:
|
||||
msg = _(
|
||||
"--size is a required option if snapshot "
|
||||
"or source volume is not specified."
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
@ -91,8 +92,10 @@ class CreateVolume(command.ShowOne):
|
||||
'--size',
|
||||
metavar='<size>',
|
||||
type=int,
|
||||
help=_("Volume size in GB (Required unless --snapshot or "
|
||||
"--source is specified)"),
|
||||
help=_(
|
||||
"Volume size in GB (Required unless --snapshot or "
|
||||
"--source is specified)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--type',
|
||||
@ -144,30 +147,32 @@ class CreateVolume(command.ShowOne):
|
||||
'--property',
|
||||
metavar='<key=value>',
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_('Set a property on this volume '
|
||||
'(repeat option to set multiple properties)'),
|
||||
help=_(
|
||||
'Set a property on this volume '
|
||||
'(repeat option to set multiple properties)'
|
||||
),
|
||||
)
|
||||
bootable_group = parser.add_mutually_exclusive_group()
|
||||
bootable_group.add_argument(
|
||||
"--bootable",
|
||||
action="store_true",
|
||||
help=_("Mark volume as bootable")
|
||||
help=_("Mark volume as bootable"),
|
||||
)
|
||||
bootable_group.add_argument(
|
||||
"--non-bootable",
|
||||
action="store_true",
|
||||
help=_("Mark volume as non-bootable (default)")
|
||||
help=_("Mark volume as non-bootable (default)"),
|
||||
)
|
||||
readonly_group = parser.add_mutually_exclusive_group()
|
||||
readonly_group.add_argument(
|
||||
"--read-only",
|
||||
action="store_true",
|
||||
help=_("Set volume to read-only access mode")
|
||||
help=_("Set volume to read-only access mode"),
|
||||
)
|
||||
readonly_group.add_argument(
|
||||
"--read-write",
|
||||
action="store_true",
|
||||
help=_("Set volume to read-write access mode (default)")
|
||||
help=_("Set volume to read-write access mode (default)"),
|
||||
)
|
||||
|
||||
return parser
|
||||
@ -229,11 +234,10 @@ class CreateVolume(command.ShowOne):
|
||||
volume.id,
|
||||
success_status=['available'],
|
||||
error_status=['error'],
|
||||
sleep_time=1
|
||||
sleep_time=1,
|
||||
):
|
||||
volume_client.volumes.set_bootable(
|
||||
volume.id,
|
||||
parsed_args.bootable
|
||||
volume.id, parsed_args.bootable
|
||||
)
|
||||
else:
|
||||
msg = _(
|
||||
@ -250,11 +254,10 @@ class CreateVolume(command.ShowOne):
|
||||
volume.id,
|
||||
success_status=['available'],
|
||||
error_status=['error'],
|
||||
sleep_time=1
|
||||
sleep_time=1,
|
||||
):
|
||||
volume_client.volumes.update_readonly_flag(
|
||||
volume.id,
|
||||
parsed_args.read_only
|
||||
volume.id, parsed_args.read_only
|
||||
)
|
||||
else:
|
||||
msg = _(
|
||||
@ -263,14 +266,20 @@ class CreateVolume(command.ShowOne):
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set volume read-only access "
|
||||
"mode flag: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to set volume read-only access "
|
||||
"mode flag: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
|
||||
# Map 'metadata' column to 'properties'
|
||||
volume._info.update(
|
||||
{
|
||||
'properties':
|
||||
format_columns.DictColumn(volume._info.pop('metadata')),
|
||||
'properties': format_columns.DictColumn(
|
||||
volume._info.pop('metadata')
|
||||
),
|
||||
'type': volume._info.pop('volume_type'),
|
||||
},
|
||||
)
|
||||
@ -299,8 +308,10 @@ class DeleteVolume(command.Command):
|
||||
'--force',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Attempt forced removal of volume(s), regardless of state '
|
||||
'(defaults to False)'),
|
||||
help=_(
|
||||
'Attempt forced removal of volume(s), regardless of state '
|
||||
'(defaults to False)'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -310,22 +321,27 @@ class DeleteVolume(command.Command):
|
||||
|
||||
for i in parsed_args.volumes:
|
||||
try:
|
||||
volume_obj = utils.find_resource(
|
||||
volume_client.volumes, i)
|
||||
volume_obj = utils.find_resource(volume_client.volumes, i)
|
||||
if parsed_args.force:
|
||||
volume_client.volumes.force_delete(volume_obj.id)
|
||||
else:
|
||||
volume_client.volumes.delete(volume_obj.id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete volume with "
|
||||
"name or ID '%(volume)s': %(e)s"),
|
||||
{'volume': i, 'e': e})
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to delete volume with "
|
||||
"name or ID '%(volume)s': %(e)s"
|
||||
),
|
||||
{'volume': i, 'e': e},
|
||||
)
|
||||
|
||||
if result > 0:
|
||||
total = len(parsed_args.volumes)
|
||||
msg = (_("%(result)s of %(total)s volumes failed "
|
||||
"to delete.") % {'result': result, 'total': total})
|
||||
msg = _("%(result)s of %(total)s volumes failed " "to delete.") % {
|
||||
'result': result,
|
||||
'total': total,
|
||||
}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
@ -373,7 +389,6 @@ class ListVolume(command.Lister):
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
|
||||
volume_client = self.app.client_manager.volume
|
||||
compute_client = self.app.client_manager.compute
|
||||
|
||||
@ -423,7 +438,8 @@ class ListVolume(command.Lister):
|
||||
# Just forget it if there's any trouble
|
||||
pass
|
||||
AttachmentsColumnWithCache = functools.partial(
|
||||
AttachmentsColumn, server_cache=server_cache)
|
||||
AttachmentsColumn, server_cache=server_cache
|
||||
)
|
||||
|
||||
search_opts = {
|
||||
'all_tenants': parsed_args.all_projects,
|
||||
@ -439,14 +455,23 @@ class ListVolume(command.Lister):
|
||||
limit=parsed_args.limit,
|
||||
)
|
||||
column_headers = utils.backward_compat_col_lister(
|
||||
column_headers, parsed_args.columns, {'Display Name': 'Name'})
|
||||
column_headers, parsed_args.columns, {'Display Name': 'Name'}
|
||||
)
|
||||
|
||||
return (column_headers,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
formatters={'Metadata': format_columns.DictColumn,
|
||||
'Attachments': AttachmentsColumnWithCache},
|
||||
) for s in data))
|
||||
return (
|
||||
column_headers,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
formatters={
|
||||
'Metadata': format_columns.DictColumn,
|
||||
'Attachments': AttachmentsColumnWithCache,
|
||||
},
|
||||
)
|
||||
for s in data
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class MigrateVolume(command.Command):
|
||||
@ -457,27 +482,34 @@ class MigrateVolume(command.Command):
|
||||
parser.add_argument(
|
||||
'volume',
|
||||
metavar="<volume>",
|
||||
help=_("Volume to migrate (name or ID)")
|
||||
help=_("Volume to migrate (name or ID)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--host',
|
||||
metavar="<host>",
|
||||
required=True,
|
||||
help=_("Destination host (takes the form: host@backend-name#pool)")
|
||||
help=_(
|
||||
"Destination host (takes the form: host@backend-name#pool)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--force-host-copy',
|
||||
action="store_true",
|
||||
help=_("Enable generic host-based force-migration, "
|
||||
"which bypasses driver optimizations")
|
||||
help=_(
|
||||
"Enable generic host-based force-migration, "
|
||||
"which bypasses driver optimizations"
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
|
||||
volume_client.volumes.migrate_volume(volume.id, parsed_args.host,
|
||||
parsed_args.force_host_copy,)
|
||||
volume_client.volumes.migrate_volume(
|
||||
volume.id,
|
||||
parsed_args.host,
|
||||
parsed_args.force_host_copy,
|
||||
)
|
||||
|
||||
|
||||
class SetVolume(command.Command):
|
||||
@ -510,39 +542,43 @@ class SetVolume(command.Command):
|
||||
"--no-property",
|
||||
dest="no_property",
|
||||
action="store_true",
|
||||
help=_("Remove all properties from <volume> "
|
||||
"(specify both --no-property and --property to "
|
||||
"remove the current properties before setting "
|
||||
"new properties.)"),
|
||||
help=_(
|
||||
"Remove all properties from <volume> "
|
||||
"(specify both --no-property and --property to "
|
||||
"remove the current properties before setting "
|
||||
"new properties.)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--property',
|
||||
metavar='<key=value>',
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_('Set a property on this volume '
|
||||
'(repeat option to set multiple properties)'),
|
||||
help=_(
|
||||
'Set a property on this volume '
|
||||
'(repeat option to set multiple properties)'
|
||||
),
|
||||
)
|
||||
bootable_group = parser.add_mutually_exclusive_group()
|
||||
bootable_group.add_argument(
|
||||
"--bootable",
|
||||
action="store_true",
|
||||
help=_("Mark volume as bootable")
|
||||
help=_("Mark volume as bootable"),
|
||||
)
|
||||
bootable_group.add_argument(
|
||||
"--non-bootable",
|
||||
action="store_true",
|
||||
help=_("Mark volume as non-bootable")
|
||||
help=_("Mark volume as non-bootable"),
|
||||
)
|
||||
readonly_group = parser.add_mutually_exclusive_group()
|
||||
readonly_group.add_argument(
|
||||
"--read-only",
|
||||
action="store_true",
|
||||
help=_("Set volume to read-only access mode")
|
||||
help=_("Set volume to read-only access mode"),
|
||||
)
|
||||
readonly_group.add_argument(
|
||||
"--read-write",
|
||||
action="store_true",
|
||||
help=_("Set volume to read-write access mode")
|
||||
help=_("Set volume to read-write access mode"),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -554,12 +590,18 @@ class SetVolume(command.Command):
|
||||
if parsed_args.size:
|
||||
try:
|
||||
if volume.status != 'available':
|
||||
msg = (_("Volume is in %s state, it must be available "
|
||||
"before size can be extended") % volume.status)
|
||||
msg = (
|
||||
_(
|
||||
"Volume is in %s state, it must be available "
|
||||
"before size can be extended"
|
||||
)
|
||||
% volume.status
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
if parsed_args.size <= volume.size:
|
||||
msg = (_("New size must be greater than %s GB")
|
||||
% volume.size)
|
||||
msg = (
|
||||
_("New size must be greater than %s GB") % volume.size
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
volume_client.volumes.extend(volume.id, parsed_args.size)
|
||||
except Exception as e:
|
||||
@ -569,7 +611,8 @@ class SetVolume(command.Command):
|
||||
if parsed_args.no_property:
|
||||
try:
|
||||
volume_client.volumes.delete_metadata(
|
||||
volume.id, volume.metadata.keys())
|
||||
volume.id, volume.metadata.keys()
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to clean volume properties: %s"), e)
|
||||
result += 1
|
||||
@ -577,26 +620,32 @@ class SetVolume(command.Command):
|
||||
if parsed_args.property:
|
||||
try:
|
||||
volume_client.volumes.set_metadata(
|
||||
volume.id,
|
||||
parsed_args.property)
|
||||
volume.id, parsed_args.property
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set volume property: %s"), e)
|
||||
result += 1
|
||||
if parsed_args.bootable or parsed_args.non_bootable:
|
||||
try:
|
||||
volume_client.volumes.set_bootable(
|
||||
volume.id, parsed_args.bootable)
|
||||
volume.id, parsed_args.bootable
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set volume bootable property: %s"), e)
|
||||
result += 1
|
||||
if parsed_args.read_only or parsed_args.read_write:
|
||||
try:
|
||||
volume_client.volumes.update_readonly_flag(
|
||||
volume.id,
|
||||
parsed_args.read_only)
|
||||
volume.id, parsed_args.read_only
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set volume read-only access "
|
||||
"mode flag: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to set volume read-only access "
|
||||
"mode flag: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
result += 1
|
||||
kwargs = {}
|
||||
if parsed_args.name:
|
||||
@ -607,13 +656,19 @@ class SetVolume(command.Command):
|
||||
try:
|
||||
volume_client.volumes.update(volume.id, **kwargs)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to update volume display name "
|
||||
"or display description: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to update volume display name "
|
||||
"or display description: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
result += 1
|
||||
|
||||
if result > 0:
|
||||
raise exceptions.CommandError(_("One or more of the "
|
||||
"set operations failed"))
|
||||
raise exceptions.CommandError(
|
||||
_("One or more of the " "set operations failed")
|
||||
)
|
||||
|
||||
|
||||
class ShowVolume(command.ShowOne):
|
||||
@ -634,15 +689,19 @@ class ShowVolume(command.ShowOne):
|
||||
# Map 'metadata' column to 'properties'
|
||||
volume._info.update(
|
||||
{
|
||||
'properties':
|
||||
format_columns.DictColumn(volume._info.pop('metadata')),
|
||||
'properties': format_columns.DictColumn(
|
||||
volume._info.pop('metadata')
|
||||
),
|
||||
'type': volume._info.pop('volume_type'),
|
||||
},
|
||||
)
|
||||
if 'os-vol-tenant-attr:tenant_id' in volume._info:
|
||||
volume._info.update(
|
||||
{'project_id': volume._info.pop(
|
||||
'os-vol-tenant-attr:tenant_id')}
|
||||
{
|
||||
'project_id': volume._info.pop(
|
||||
'os-vol-tenant-attr:tenant_id'
|
||||
)
|
||||
}
|
||||
)
|
||||
# Replace "display_name" by "name", keep consistent in v1 and v2
|
||||
if 'display_name' in volume._info:
|
||||
@ -669,15 +728,16 @@ class UnsetVolume(command.Command):
|
||||
'--property',
|
||||
metavar='<key>',
|
||||
action='append',
|
||||
help=_('Remove a property from volume '
|
||||
'(repeat option to remove multiple properties)'),
|
||||
help=_(
|
||||
'Remove a property from volume '
|
||||
'(repeat option to remove multiple properties)'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
volume = utils.find_resource(
|
||||
volume_client.volumes, parsed_args.volume)
|
||||
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
|
||||
|
||||
if parsed_args.property:
|
||||
volume_client.volumes.delete_metadata(
|
||||
|
@ -87,13 +87,14 @@ class CreateVolumeBackup(command.ShowOne):
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
volume_id = utils.find_resource(volume_client.volumes,
|
||||
parsed_args.volume).id
|
||||
volume_id = utils.find_resource(
|
||||
volume_client.volumes, parsed_args.volume
|
||||
).id
|
||||
backup = volume_client.backups.create(
|
||||
volume_id,
|
||||
parsed_args.container,
|
||||
parsed_args.name,
|
||||
parsed_args.description
|
||||
parsed_args.description,
|
||||
)
|
||||
|
||||
backup._info.pop('links')
|
||||
@ -119,19 +120,24 @@ class DeleteVolumeBackup(command.Command):
|
||||
|
||||
for i in parsed_args.backups:
|
||||
try:
|
||||
backup_id = utils.find_resource(
|
||||
volume_client.backups, i).id
|
||||
backup_id = utils.find_resource(volume_client.backups, i).id
|
||||
volume_client.backups.delete(backup_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete backup with "
|
||||
"name or ID '%(backup)s': %(e)s"),
|
||||
{'backup': i, 'e': e})
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to delete backup with "
|
||||
"name or ID '%(backup)s': %(e)s"
|
||||
),
|
||||
{'backup': i, 'e': e},
|
||||
)
|
||||
|
||||
if result > 0:
|
||||
total = len(parsed_args.backups)
|
||||
msg = (_("%(result)s of %(total)s backups failed "
|
||||
"to delete.") % {'result': result, 'total': total})
|
||||
msg = _("%(result)s of %(total)s backups failed " "to delete.") % {
|
||||
'result': result,
|
||||
'total': total,
|
||||
}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
@ -149,22 +155,32 @@ class ListVolumeBackup(command.Lister):
|
||||
parser.add_argument(
|
||||
"--name",
|
||||
metavar="<name>",
|
||||
help=_("Filters results by the backup name")
|
||||
help=_("Filters results by the backup name"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--status",
|
||||
metavar="<status>",
|
||||
choices=['creating', 'available', 'deleting',
|
||||
'error', 'restoring', 'error_restoring'],
|
||||
help=_("Filters results by the backup status "
|
||||
"('creating', 'available', 'deleting', "
|
||||
"'error', 'restoring' or 'error_restoring')")
|
||||
choices=[
|
||||
'creating',
|
||||
'available',
|
||||
'deleting',
|
||||
'error',
|
||||
'restoring',
|
||||
'error_restoring',
|
||||
],
|
||||
help=_(
|
||||
"Filters results by the backup status "
|
||||
"('creating', 'available', 'deleting', "
|
||||
"'error', 'restoring' or 'error_restoring')"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--volume",
|
||||
metavar="<volume>",
|
||||
help=_("Filters results by the volume which they "
|
||||
"backup (name or ID)")
|
||||
help=_(
|
||||
"Filters results by the volume which they "
|
||||
"backup (name or ID)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--all-projects',
|
||||
@ -178,8 +194,16 @@ class ListVolumeBackup(command.Lister):
|
||||
volume_client = self.app.client_manager.volume
|
||||
|
||||
if parsed_args.long:
|
||||
columns = ['ID', 'Name', 'Description', 'Status', 'Size',
|
||||
'Availability Zone', 'Volume ID', 'Container']
|
||||
columns = [
|
||||
'ID',
|
||||
'Name',
|
||||
'Description',
|
||||
'Status',
|
||||
'Size',
|
||||
'Availability Zone',
|
||||
'Volume ID',
|
||||
'Container',
|
||||
]
|
||||
column_headers = copy.deepcopy(columns)
|
||||
column_headers[6] = 'Volume'
|
||||
else:
|
||||
@ -194,13 +218,15 @@ class ListVolumeBackup(command.Lister):
|
||||
except Exception:
|
||||
# Just forget it if there's any trouble
|
||||
pass
|
||||
VolumeIdColumnWithCache = functools.partial(VolumeIdColumn,
|
||||
volume_cache=volume_cache)
|
||||
VolumeIdColumnWithCache = functools.partial(
|
||||
VolumeIdColumn, volume_cache=volume_cache
|
||||
)
|
||||
|
||||
filter_volume_id = None
|
||||
if parsed_args.volume:
|
||||
filter_volume_id = utils.find_resource(volume_client.volumes,
|
||||
parsed_args.volume).id
|
||||
filter_volume_id = utils.find_resource(
|
||||
volume_client.volumes, parsed_args.volume
|
||||
).id
|
||||
search_opts = {
|
||||
'name': parsed_args.name,
|
||||
'status': parsed_args.status,
|
||||
@ -211,11 +237,17 @@ class ListVolumeBackup(command.Lister):
|
||||
search_opts=search_opts,
|
||||
)
|
||||
|
||||
return (column_headers,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
return (
|
||||
column_headers,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
formatters={'Volume ID': VolumeIdColumnWithCache},
|
||||
) for s in data))
|
||||
)
|
||||
for s in data
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class RestoreVolumeBackup(command.Command):
|
||||
@ -226,20 +258,21 @@ class RestoreVolumeBackup(command.Command):
|
||||
parser.add_argument(
|
||||
'backup',
|
||||
metavar='<backup>',
|
||||
help=_('Backup to restore (name or ID)')
|
||||
help=_('Backup to restore (name or ID)'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'volume',
|
||||
metavar='<volume>',
|
||||
nargs='?',
|
||||
help=_('Volume to restore to (name or ID) (default to None)')
|
||||
help=_('Volume to restore to (name or ID) (default to None)'),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
backup = utils.find_resource(
|
||||
volume_client.backups, parsed_args.backup,
|
||||
volume_client.backups,
|
||||
parsed_args.backup,
|
||||
)
|
||||
volume_id = None
|
||||
if parsed_args.volume is not None:
|
||||
@ -258,13 +291,12 @@ class ShowVolumeBackup(command.ShowOne):
|
||||
parser.add_argument(
|
||||
'backup',
|
||||
metavar='<backup>',
|
||||
help=_('Backup to display (name or ID)')
|
||||
help=_('Backup to display (name or ID)'),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
backup = utils.find_resource(volume_client.backups,
|
||||
parsed_args.backup)
|
||||
backup = utils.find_resource(volume_client.backups, parsed_args.backup)
|
||||
backup._info.pop('links')
|
||||
return zip(*sorted(backup._info.items()))
|
||||
|
@ -72,8 +72,10 @@ class CreateVolumeSnapshot(command.ShowOne):
|
||||
parser.add_argument(
|
||||
'--volume',
|
||||
metavar='<volume>',
|
||||
help=_('Volume to snapshot (name or ID) '
|
||||
'(default is <snapshot-name>)'),
|
||||
help=_(
|
||||
'Volume to snapshot (name or ID) '
|
||||
'(default is <snapshot-name>)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
@ -85,8 +87,10 @@ class CreateVolumeSnapshot(command.ShowOne):
|
||||
dest='force',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Create a snapshot attached to an instance. '
|
||||
'Default is False'),
|
||||
help=_(
|
||||
'Create a snapshot attached to an instance. '
|
||||
'Default is False'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -95,18 +99,20 @@ class CreateVolumeSnapshot(command.ShowOne):
|
||||
volume = parsed_args.volume
|
||||
if not parsed_args.volume:
|
||||
volume = parsed_args.snapshot_name
|
||||
volume_id = utils.find_resource(volume_client.volumes,
|
||||
volume).id
|
||||
volume_id = utils.find_resource(volume_client.volumes, volume).id
|
||||
snapshot = volume_client.volume_snapshots.create(
|
||||
volume_id,
|
||||
parsed_args.force,
|
||||
parsed_args.snapshot_name,
|
||||
parsed_args.description
|
||||
parsed_args.description,
|
||||
)
|
||||
|
||||
snapshot._info.update(
|
||||
{'properties':
|
||||
format_columns.DictColumn(snapshot._info.pop('metadata'))}
|
||||
{
|
||||
'properties': format_columns.DictColumn(
|
||||
snapshot._info.pop('metadata')
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
return zip(*sorted(snapshot._info.items()))
|
||||
@ -132,18 +138,24 @@ class DeleteVolumeSnapshot(command.Command):
|
||||
for i in parsed_args.snapshots:
|
||||
try:
|
||||
snapshot_id = utils.find_resource(
|
||||
volume_client.volume_snapshots, i).id
|
||||
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})
|
||||
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})
|
||||
msg = _(
|
||||
"%(result)s of %(total)s snapshots failed " "to delete."
|
||||
) % {'result': result, 'total': total}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
@ -168,22 +180,29 @@ class ListVolumeSnapshot(command.Lister):
|
||||
'--name',
|
||||
metavar='<name>',
|
||||
default=None,
|
||||
help=_('Filters results by a name.')
|
||||
help=_('Filters results by a name.'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--status',
|
||||
metavar='<status>',
|
||||
choices=['available', 'error', 'creating', 'deleting',
|
||||
'error_deleting'],
|
||||
help=_("Filters results by a status. "
|
||||
"('available', 'error', 'creating', 'deleting'"
|
||||
" or 'error_deleting')")
|
||||
choices=[
|
||||
'available',
|
||||
'error',
|
||||
'creating',
|
||||
'deleting',
|
||||
'error_deleting',
|
||||
],
|
||||
help=_(
|
||||
"Filters results by a status. "
|
||||
"('available', 'error', 'creating', 'deleting'"
|
||||
" or 'error_deleting')"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--volume',
|
||||
metavar='<volume>',
|
||||
default=None,
|
||||
help=_('Filters results by a volume (name or ID).')
|
||||
help=_('Filters results by a volume (name or ID).'),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -191,14 +210,27 @@ class ListVolumeSnapshot(command.Lister):
|
||||
volume_client = self.app.client_manager.volume
|
||||
|
||||
if parsed_args.long:
|
||||
columns = ['ID', 'Display Name', 'Display Description', 'Status',
|
||||
'Size', 'Created At', 'Volume ID', 'Metadata']
|
||||
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']
|
||||
columns = [
|
||||
'ID',
|
||||
'Display Name',
|
||||
'Display Description',
|
||||
'Status',
|
||||
'Size',
|
||||
]
|
||||
column_headers = copy.deepcopy(columns)
|
||||
|
||||
# Always update Name and Description
|
||||
@ -213,13 +245,15 @@ class ListVolumeSnapshot(command.Lister):
|
||||
except Exception:
|
||||
# Just forget it if there's any trouble
|
||||
pass
|
||||
VolumeIdColumnWithCache = functools.partial(VolumeIdColumn,
|
||||
volume_cache=volume_cache)
|
||||
VolumeIdColumnWithCache = functools.partial(
|
||||
VolumeIdColumn, volume_cache=volume_cache
|
||||
)
|
||||
|
||||
volume_id = None
|
||||
if parsed_args.volume:
|
||||
volume_id = utils.find_resource(
|
||||
volume_client.volumes, parsed_args.volume).id
|
||||
volume_client.volumes, parsed_args.volume
|
||||
).id
|
||||
|
||||
search_opts = {
|
||||
'all_tenants': parsed_args.all_projects,
|
||||
@ -228,14 +262,21 @@ class ListVolumeSnapshot(command.Lister):
|
||||
'volume_id': volume_id,
|
||||
}
|
||||
|
||||
data = volume_client.volume_snapshots.list(
|
||||
search_opts=search_opts)
|
||||
return (column_headers,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
formatters={'Metadata': format_columns.DictColumn,
|
||||
'Volume ID': VolumeIdColumnWithCache},
|
||||
) for s in data))
|
||||
data = volume_client.volume_snapshots.list(search_opts=search_opts)
|
||||
return (
|
||||
column_headers,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
formatters={
|
||||
'Metadata': format_columns.DictColumn,
|
||||
'Volume ID': VolumeIdColumnWithCache,
|
||||
},
|
||||
)
|
||||
for s in data
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class SetVolumeSnapshot(command.Command):
|
||||
@ -246,40 +287,43 @@ class SetVolumeSnapshot(command.Command):
|
||||
parser.add_argument(
|
||||
'snapshot',
|
||||
metavar='<snapshot>',
|
||||
help=_('Snapshot to modify (name or ID)')
|
||||
help=_('Snapshot to modify (name or ID)'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
metavar='<name>',
|
||||
help=_('New snapshot name')
|
||||
'--name', metavar='<name>', help=_('New snapshot name')
|
||||
)
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
metavar='<description>',
|
||||
help=_('New snapshot description')
|
||||
help=_('New snapshot description'),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-property",
|
||||
dest="no_property",
|
||||
action="store_true",
|
||||
help=_("Remove all properties from <snapshot> "
|
||||
"(specify both --no-property and --property to "
|
||||
"remove the current properties before setting "
|
||||
"new properties.)"),
|
||||
help=_(
|
||||
"Remove all properties from <snapshot> "
|
||||
"(specify both --no-property and --property to "
|
||||
"remove the current properties before setting "
|
||||
"new properties.)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--property',
|
||||
metavar='<key=value>',
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_('Property to add/change for this snapshot '
|
||||
'(repeat option to set multiple properties)'),
|
||||
help=_(
|
||||
'Property to add/change for this snapshot '
|
||||
'(repeat option to set multiple properties)'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
snapshot = utils.find_resource(volume_client.volume_snapshots,
|
||||
parsed_args.snapshot)
|
||||
snapshot = utils.find_resource(
|
||||
volume_client.volume_snapshots, parsed_args.snapshot
|
||||
)
|
||||
|
||||
result = 0
|
||||
if parsed_args.no_property:
|
||||
@ -296,7 +340,8 @@ class SetVolumeSnapshot(command.Command):
|
||||
if parsed_args.property:
|
||||
try:
|
||||
volume_client.volume_snapshots.set_metadata(
|
||||
snapshot.id, parsed_args.property)
|
||||
snapshot.id, parsed_args.property
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set snapshot property: %s"), e)
|
||||
result += 1
|
||||
@ -310,13 +355,19 @@ class SetVolumeSnapshot(command.Command):
|
||||
try:
|
||||
snapshot.update(**kwargs)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to update snapshot display name "
|
||||
"or display description: %s"), 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"))
|
||||
raise exceptions.CommandError(
|
||||
_("One or more of the " "set operations failed")
|
||||
)
|
||||
|
||||
|
||||
class ShowVolumeSnapshot(command.ShowOne):
|
||||
@ -327,18 +378,22 @@ class ShowVolumeSnapshot(command.ShowOne):
|
||||
parser.add_argument(
|
||||
'snapshot',
|
||||
metavar='<snapshot>',
|
||||
help=_('Snapshot to display (name or ID)')
|
||||
help=_('Snapshot to display (name or ID)'),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
snapshot = utils.find_resource(volume_client.volume_snapshots,
|
||||
parsed_args.snapshot)
|
||||
snapshot = utils.find_resource(
|
||||
volume_client.volume_snapshots, parsed_args.snapshot
|
||||
)
|
||||
|
||||
snapshot._info.update(
|
||||
{'properties':
|
||||
format_columns.DictColumn(snapshot._info.pop('metadata'))}
|
||||
{
|
||||
'properties': format_columns.DictColumn(
|
||||
snapshot._info.pop('metadata')
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
return zip(*sorted(snapshot._info.items()))
|
||||
@ -358,15 +413,18 @@ class UnsetVolumeSnapshot(command.Command):
|
||||
'--property',
|
||||
metavar='<key>',
|
||||
action='append',
|
||||
help=_('Property to remove from snapshot '
|
||||
'(repeat option to remove multiple properties)'),
|
||||
help=_(
|
||||
'Property to remove from snapshot '
|
||||
'(repeat option to remove multiple properties)'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
snapshot = utils.find_resource(
|
||||
volume_client.volume_snapshots, parsed_args.snapshot)
|
||||
volume_client.volume_snapshots, parsed_args.snapshot
|
||||
)
|
||||
|
||||
if parsed_args.property:
|
||||
volume_client.volume_snapshots.delete_metadata(
|
||||
|
@ -48,8 +48,7 @@ class AcceptTransferRequest(command.ShowOne):
|
||||
|
||||
try:
|
||||
transfer_request_id = utils.find_resource(
|
||||
volume_client.transfers,
|
||||
parsed_args.transfer_request
|
||||
volume_client.transfers, parsed_args.transfer_request
|
||||
).id
|
||||
except exceptions.CommandError:
|
||||
# Non-admin users will fail to lookup name -> ID so we just
|
||||
@ -77,12 +76,12 @@ class CreateTransferRequest(command.ShowOne):
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
metavar="<name>",
|
||||
help=_('New transfer request name (default to None)')
|
||||
help=_('New transfer request name (default to None)'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'volume',
|
||||
metavar="<volume>",
|
||||
help=_('Volume to transfer (name or ID)')
|
||||
help=_('Volume to transfer (name or ID)'),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -127,14 +126,20 @@ class DeleteTransferRequest(command.Command):
|
||||
volume_client.transfers.delete(transfer_request_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete volume transfer request "
|
||||
"with name or ID '%(transfer)s': %(e)s")
|
||||
% {'transfer': t, 'e': e})
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to delete volume transfer request "
|
||||
"with name or ID '%(transfer)s': %(e)s"
|
||||
)
|
||||
% {'transfer': t, 'e': e}
|
||||
)
|
||||
|
||||
if result > 0:
|
||||
total = len(parsed_args.transfer_request)
|
||||
msg = (_("%(result)s of %(total)s volume transfer requests failed"
|
||||
" to delete") % {'result': result, 'total': total})
|
||||
msg = _(
|
||||
"%(result)s of %(total)s volume transfer requests failed"
|
||||
" to delete"
|
||||
) % {'result': result, 'total': total}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
@ -163,9 +168,13 @@ class ListTransferRequest(command.Lister):
|
||||
search_opts={'all_tenants': parsed_args.all_projects},
|
||||
)
|
||||
|
||||
return (column_headers, (
|
||||
utils.get_item_properties(s, columns)
|
||||
for s in volume_transfer_result))
|
||||
return (
|
||||
column_headers,
|
||||
(
|
||||
utils.get_item_properties(s, columns)
|
||||
for s in volume_transfer_result
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class ShowTransferRequest(command.ShowOne):
|
||||
|
@ -63,8 +63,10 @@ class EncryptionInfoColumn(cliff_columns.FormattableColumn):
|
||||
|
||||
def _create_encryption_type(volume_client, volume_type, parsed_args):
|
||||
if not parsed_args.encryption_provider:
|
||||
msg = _("'--encryption-provider' should be specified while "
|
||||
"creating a new encryption type")
|
||||
msg = _(
|
||||
"'--encryption-provider' should be specified while "
|
||||
"creating a new encryption type"
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
# set the default of control location while creating
|
||||
control_location = 'front-end'
|
||||
@ -74,10 +76,11 @@ def _create_encryption_type(volume_client, volume_type, parsed_args):
|
||||
'provider': parsed_args.encryption_provider,
|
||||
'cipher': parsed_args.encryption_cipher,
|
||||
'key_size': parsed_args.encryption_key_size,
|
||||
'control_location': control_location
|
||||
'control_location': control_location,
|
||||
}
|
||||
encryption = volume_client.volume_encryption_types.create(
|
||||
volume_type, body)
|
||||
volume_type, body
|
||||
)
|
||||
return encryption
|
||||
|
||||
|
||||
@ -95,44 +98,54 @@ class CreateVolumeType(command.ShowOne):
|
||||
'--property',
|
||||
metavar='<key=value>',
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_('Set a property on this volume type '
|
||||
'(repeat option to set multiple properties)'),
|
||||
help=_(
|
||||
'Set a property on this volume type '
|
||||
'(repeat option to set multiple properties)'
|
||||
),
|
||||
)
|
||||
# TODO(Huanxuan Ao): Add choices for each "--encryption-*" option.
|
||||
parser.add_argument(
|
||||
'--encryption-provider',
|
||||
metavar='<provider>',
|
||||
help=_('Set the encryption provider format for '
|
||||
'this volume type (e.g "luks" or "plain") (admin only) '
|
||||
'(This option is required when setting encryption type '
|
||||
'of a volume. Consider using other encryption options '
|
||||
'such as: "--encryption-cipher", "--encryption-key-size" '
|
||||
'and "--encryption-control-location")'),
|
||||
help=_(
|
||||
'Set the encryption provider format for '
|
||||
'this volume type (e.g "luks" or "plain") (admin only) '
|
||||
'(This option is required when setting encryption type '
|
||||
'of a volume. Consider using other encryption options '
|
||||
'such as: "--encryption-cipher", "--encryption-key-size" '
|
||||
'and "--encryption-control-location")'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--encryption-cipher',
|
||||
metavar='<cipher>',
|
||||
help=_('Set the encryption algorithm or mode for this '
|
||||
'volume type (e.g "aes-xts-plain64") (admin only)'),
|
||||
help=_(
|
||||
'Set the encryption algorithm or mode for this '
|
||||
'volume type (e.g "aes-xts-plain64") (admin only)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--encryption-key-size',
|
||||
metavar='<key-size>',
|
||||
type=int,
|
||||
help=_('Set the size of the encryption key of this '
|
||||
'volume type (e.g "128" or "256") (admin only)'),
|
||||
help=_(
|
||||
'Set the size of the encryption key of this '
|
||||
'volume type (e.g "128" or "256") (admin only)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--encryption-control-location',
|
||||
metavar='<control-location>',
|
||||
choices=['front-end', 'back-end'],
|
||||
help=_('Set the notional service where the encryption is '
|
||||
'performed ("front-end" or "back-end") (admin only) '
|
||||
'(The default value for this option is "front-end" '
|
||||
'when setting encryption type of a volume. Consider '
|
||||
'using other encryption options such as: '
|
||||
'"--encryption-cipher", "--encryption-key-size" and '
|
||||
'"--encryption-provider")'),
|
||||
help=_(
|
||||
'Set the notional service where the encryption is '
|
||||
'performed ("front-end" or "back-end") (admin only) '
|
||||
'(The default value for this option is "front-end" '
|
||||
'when setting encryption type of a volume. Consider '
|
||||
'using other encryption options such as: '
|
||||
'"--encryption-cipher", "--encryption-key-size" and '
|
||||
'"--encryption-provider")'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -143,22 +156,32 @@ class CreateVolumeType(command.ShowOne):
|
||||
if parsed_args.property:
|
||||
result = volume_type.set_keys(parsed_args.property)
|
||||
volume_type._info.update(
|
||||
{'properties': format_columns.DictColumn(result)})
|
||||
if (parsed_args.encryption_provider or
|
||||
parsed_args.encryption_cipher or
|
||||
parsed_args.encryption_key_size or
|
||||
parsed_args.encryption_control_location):
|
||||
{'properties': format_columns.DictColumn(result)}
|
||||
)
|
||||
if (
|
||||
parsed_args.encryption_provider
|
||||
or parsed_args.encryption_cipher
|
||||
or parsed_args.encryption_key_size
|
||||
or parsed_args.encryption_control_location
|
||||
):
|
||||
try:
|
||||
# create new encryption
|
||||
encryption = _create_encryption_type(
|
||||
volume_client, volume_type, parsed_args)
|
||||
volume_client, volume_type, parsed_args
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set encryption information for this "
|
||||
"volume type: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to set encryption information for this "
|
||||
"volume type: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
# add encryption info in result
|
||||
encryption._info.pop("volume_type_id", None)
|
||||
volume_type._info.update(
|
||||
{'encryption': format_columns.DictColumn(encryption._info)})
|
||||
{'encryption': format_columns.DictColumn(encryption._info)}
|
||||
)
|
||||
volume_type._info.pop("os-volume-type-access:is_public", None)
|
||||
|
||||
return zip(*sorted(volume_type._info.items()))
|
||||
@ -183,20 +206,26 @@ class DeleteVolumeType(command.Command):
|
||||
|
||||
for volume_type in parsed_args.volume_types:
|
||||
try:
|
||||
vol_type = utils.find_resource(volume_client.volume_types,
|
||||
volume_type)
|
||||
vol_type = utils.find_resource(
|
||||
volume_client.volume_types, volume_type
|
||||
)
|
||||
|
||||
volume_client.volume_types.delete(vol_type)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete volume type with "
|
||||
"name or ID '%(volume_type)s': %(e)s")
|
||||
% {'volume_type': volume_type, 'e': e})
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to delete volume type with "
|
||||
"name or ID '%(volume_type)s': %(e)s"
|
||||
)
|
||||
% {'volume_type': volume_type, 'e': e}
|
||||
)
|
||||
|
||||
if result > 0:
|
||||
total = len(parsed_args.volume_types)
|
||||
msg = (_("%(result)s of %(total)s volume types failed "
|
||||
"to delete.") % {'result': result, 'total': total})
|
||||
msg = _(
|
||||
"%(result)s of %(total)s volume types failed " "to delete."
|
||||
) % {'result': result, 'total': total}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
@ -209,13 +238,15 @@ class ListVolumeType(command.Lister):
|
||||
'--long',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('List additional fields in output')
|
||||
help=_('List additional fields in output'),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--encryption-type",
|
||||
action="store_true",
|
||||
help=_("Display encryption information for each volume type "
|
||||
"(admin only)"),
|
||||
help=_(
|
||||
"Display encryption information for each volume type "
|
||||
"(admin only)"
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -241,7 +272,7 @@ class ListVolumeType(command.Lister):
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
'volume_type_id'
|
||||
'volume_type_id',
|
||||
]
|
||||
for key in del_key:
|
||||
d._info.pop(key, None)
|
||||
@ -254,14 +285,21 @@ class ListVolumeType(command.Lister):
|
||||
column_headers += ['Encryption']
|
||||
|
||||
_EncryptionInfoColumn = functools.partial(
|
||||
EncryptionInfoColumn, encryption_data=encryption)
|
||||
EncryptionInfoColumn, encryption_data=encryption
|
||||
)
|
||||
formatters['id'] = _EncryptionInfoColumn
|
||||
|
||||
return (column_headers,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
return (
|
||||
column_headers,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
formatters=formatters,
|
||||
) for s in data))
|
||||
)
|
||||
for s in data
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class SetVolumeType(command.Command):
|
||||
@ -278,51 +316,62 @@ class SetVolumeType(command.Command):
|
||||
'--property',
|
||||
metavar='<key=value>',
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_('Set a property on this volume type '
|
||||
'(repeat option to set multiple properties)'),
|
||||
help=_(
|
||||
'Set a property on this volume type '
|
||||
'(repeat option to set multiple properties)'
|
||||
),
|
||||
)
|
||||
# TODO(Huanxuan Ao): Add choices for each "--encryption-*" option.
|
||||
parser.add_argument(
|
||||
'--encryption-provider',
|
||||
metavar='<provider>',
|
||||
help=_('Set the encryption provider format for '
|
||||
'this volume type (e.g "luks" or "plain") (admin only) '
|
||||
'(This option is required when setting encryption type '
|
||||
'of a volume. Consider using other encryption options '
|
||||
'such as: "--encryption-cipher", "--encryption-key-size" '
|
||||
'and "--encryption-control-location")'),
|
||||
help=_(
|
||||
'Set the encryption provider format for '
|
||||
'this volume type (e.g "luks" or "plain") (admin only) '
|
||||
'(This option is required when setting encryption type '
|
||||
'of a volume. Consider using other encryption options '
|
||||
'such as: "--encryption-cipher", "--encryption-key-size" '
|
||||
'and "--encryption-control-location")'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--encryption-cipher',
|
||||
metavar='<cipher>',
|
||||
help=_('Set the encryption algorithm or mode for this '
|
||||
'volume type (e.g "aes-xts-plain64") (admin only)'),
|
||||
help=_(
|
||||
'Set the encryption algorithm or mode for this '
|
||||
'volume type (e.g "aes-xts-plain64") (admin only)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--encryption-key-size',
|
||||
metavar='<key-size>',
|
||||
type=int,
|
||||
help=_('Set the size of the encryption key of this '
|
||||
'volume type (e.g "128" or "256") (admin only)'),
|
||||
help=_(
|
||||
'Set the size of the encryption key of this '
|
||||
'volume type (e.g "128" or "256") (admin only)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--encryption-control-location',
|
||||
metavar='<control-location>',
|
||||
choices=['front-end', 'back-end'],
|
||||
help=_('Set the notional service where the encryption is '
|
||||
'performed ("front-end" or "back-end") (admin only) '
|
||||
'(The default value for this option is "front-end" '
|
||||
'when setting encryption type of a volume. Consider '
|
||||
'using other encryption options such as: '
|
||||
'"--encryption-cipher", "--encryption-key-size" and '
|
||||
'"--encryption-provider")'),
|
||||
help=_(
|
||||
'Set the notional service where the encryption is '
|
||||
'performed ("front-end" or "back-end") (admin only) '
|
||||
'(The default value for this option is "front-end" '
|
||||
'when setting encryption type of a volume. Consider '
|
||||
'using other encryption options such as: '
|
||||
'"--encryption-cipher", "--encryption-key-size" and '
|
||||
'"--encryption-provider")'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
volume_type = utils.find_resource(
|
||||
volume_client.volume_types, parsed_args.volume_type)
|
||||
volume_client.volume_types, parsed_args.volume_type
|
||||
)
|
||||
|
||||
result = 0
|
||||
if parsed_args.property:
|
||||
@ -332,21 +381,30 @@ class SetVolumeType(command.Command):
|
||||
LOG.error(_("Failed to set volume type property: %s"), e)
|
||||
result += 1
|
||||
|
||||
if (parsed_args.encryption_provider or
|
||||
parsed_args.encryption_cipher or
|
||||
parsed_args.encryption_key_size or
|
||||
parsed_args.encryption_control_location):
|
||||
if (
|
||||
parsed_args.encryption_provider
|
||||
or parsed_args.encryption_cipher
|
||||
or parsed_args.encryption_key_size
|
||||
or parsed_args.encryption_control_location
|
||||
):
|
||||
try:
|
||||
_create_encryption_type(
|
||||
volume_client, volume_type, parsed_args)
|
||||
volume_client, volume_type, parsed_args
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set encryption information for this "
|
||||
"volume type: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to set encryption information for this "
|
||||
"volume type: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
result += 1
|
||||
|
||||
if result > 0:
|
||||
raise exceptions.CommandError(_("Command Failed: One or more of"
|
||||
" the operations failed"))
|
||||
raise exceptions.CommandError(
|
||||
_("Command Failed: One or more of" " the operations failed")
|
||||
)
|
||||
|
||||
|
||||
class ShowVolumeType(command.ShowOne):
|
||||
@ -357,35 +415,45 @@ class ShowVolumeType(command.ShowOne):
|
||||
parser.add_argument(
|
||||
"volume_type",
|
||||
metavar="<volume-type>",
|
||||
help=_("Volume type to display (name or ID)")
|
||||
help=_("Volume type to display (name or ID)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--encryption-type",
|
||||
action="store_true",
|
||||
help=_("Display encryption information of this volume type "
|
||||
"(admin only)"),
|
||||
help=_(
|
||||
"Display encryption information of this volume type "
|
||||
"(admin only)"
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
volume_type = utils.find_resource(
|
||||
volume_client.volume_types, parsed_args.volume_type)
|
||||
volume_client.volume_types, parsed_args.volume_type
|
||||
)
|
||||
properties = format_columns.DictColumn(
|
||||
volume_type._info.pop('extra_specs'))
|
||||
volume_type._info.pop('extra_specs')
|
||||
)
|
||||
volume_type._info.update({'properties': properties})
|
||||
if parsed_args.encryption_type:
|
||||
# show encryption type information for this volume type
|
||||
try:
|
||||
encryption = volume_client.volume_encryption_types.get(
|
||||
volume_type.id)
|
||||
volume_type.id
|
||||
)
|
||||
encryption._info.pop("volume_type_id", None)
|
||||
volume_type._info.update(
|
||||
{'encryption':
|
||||
format_columns.DictColumn(encryption._info)})
|
||||
{'encryption': format_columns.DictColumn(encryption._info)}
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to display the encryption information "
|
||||
"of this volume type: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to display the encryption information "
|
||||
"of this volume type: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
volume_type._info.pop("os-volume-type-access:is_public", None)
|
||||
return zip(*sorted(volume_type._info.items()))
|
||||
|
||||
@ -404,14 +472,18 @@ class UnsetVolumeType(command.Command):
|
||||
'--property',
|
||||
metavar='<key>',
|
||||
action='append',
|
||||
help=_('Remove a property from this volume type '
|
||||
'(repeat option to remove multiple properties)'),
|
||||
help=_(
|
||||
'Remove a property from this volume type '
|
||||
'(repeat option to remove multiple properties)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--encryption-type",
|
||||
action="store_true",
|
||||
help=_("Remove the encryption type for this volume type "
|
||||
"(admin only)"),
|
||||
help=_(
|
||||
"Remove the encryption type for this volume type "
|
||||
"(admin only)"
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -433,10 +505,16 @@ class UnsetVolumeType(command.Command):
|
||||
try:
|
||||
volume_client.volume_encryption_types.delete(volume_type)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to remove the encryption type for this "
|
||||
"volume type: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to remove the encryption type for this "
|
||||
"volume type: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
result += 1
|
||||
|
||||
if result > 0:
|
||||
raise exceptions.CommandError(_("Command Failed: One or more of"
|
||||
" the operations failed"))
|
||||
raise exceptions.CommandError(
|
||||
_("Command Failed: One or more of" " the operations failed")
|
||||
)
|
||||
|
@ -26,17 +26,19 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ExportBackupRecord(command.ShowOne):
|
||||
_description = _("""Export volume backup details.
|
||||
_description = _(
|
||||
"""Export volume backup details.
|
||||
|
||||
Backup information can be imported into a new service instance to be able to
|
||||
restore.""")
|
||||
restore."""
|
||||
)
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ExportBackupRecord, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"backup",
|
||||
metavar="<backup>",
|
||||
help=_("Backup to export (name or ID)")
|
||||
help=_("Backup to export (name or ID)"),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -55,29 +57,31 @@ restore.""")
|
||||
|
||||
|
||||
class ImportBackupRecord(command.ShowOne):
|
||||
_description = _("""Import volume backup details.
|
||||
_description = _(
|
||||
"""Import volume backup details.
|
||||
|
||||
Exported backup details contain the metadata necessary to restore to a new or
|
||||
rebuilt service instance""")
|
||||
rebuilt service instance"""
|
||||
)
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ImportBackupRecord, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"backup_service",
|
||||
metavar="<backup_service>",
|
||||
help=_("Backup service containing the backup.")
|
||||
help=_("Backup service containing the backup."),
|
||||
)
|
||||
parser.add_argument(
|
||||
"backup_metadata",
|
||||
metavar="<backup_metadata>",
|
||||
help=_("Encoded backup metadata from export.")
|
||||
help=_("Encoded backup metadata from export."),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
backup_data = volume_client.backups.import_record(
|
||||
parsed_args.backup_service,
|
||||
parsed_args.backup_metadata)
|
||||
parsed_args.backup_service, parsed_args.backup_metadata
|
||||
)
|
||||
backup_data.pop('links', None)
|
||||
return zip(*sorted(backup_data.items()))
|
||||
|
@ -33,14 +33,17 @@ def _find_volumes(parsed_args_volumes, volume_client):
|
||||
uuid = ''
|
||||
for volume in parsed_args_volumes:
|
||||
try:
|
||||
volume_id = utils.find_resource(
|
||||
volume_client.volumes, volume).id
|
||||
volume_id = utils.find_resource(volume_client.volumes, volume).id
|
||||
uuid += volume_id + ','
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to find volume with "
|
||||
"name or ID '%(volume)s':%(e)s")
|
||||
% {'volume': volume, 'e': e})
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to find volume with "
|
||||
"name or ID '%(volume)s':%(e)s"
|
||||
)
|
||||
% {'volume': volume, 'e': e}
|
||||
)
|
||||
|
||||
return result, uuid
|
||||
|
||||
@ -59,8 +62,10 @@ class AddVolumeToConsistencyGroup(command.Command):
|
||||
'volumes',
|
||||
metavar='<volume>',
|
||||
nargs='+',
|
||||
help=_('Volume(s) to add to <consistency-group> (name or ID) '
|
||||
'(repeat option to add multiple volumes)'),
|
||||
help=_(
|
||||
'Volume(s) to add to <consistency-group> (name or ID) '
|
||||
'(repeat option to add multiple volumes)'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -70,16 +75,19 @@ class AddVolumeToConsistencyGroup(command.Command):
|
||||
|
||||
if result > 0:
|
||||
total = len(parsed_args.volumes)
|
||||
LOG.error(_("%(result)s of %(total)s volumes failed "
|
||||
"to add.") % {'result': result, 'total': total})
|
||||
LOG.error(
|
||||
_("%(result)s of %(total)s volumes failed " "to add.")
|
||||
% {'result': result, 'total': total}
|
||||
)
|
||||
|
||||
if add_uuid:
|
||||
add_uuid = add_uuid.rstrip(',')
|
||||
consistency_group_id = utils.find_resource(
|
||||
volume_client.consistencygroups,
|
||||
parsed_args.consistency_group).id
|
||||
volume_client.consistencygroups, parsed_args.consistency_group
|
||||
).id
|
||||
volume_client.consistencygroups.update(
|
||||
consistency_group_id, add_volumes=add_uuid)
|
||||
consistency_group_id, add_volumes=add_uuid
|
||||
)
|
||||
|
||||
|
||||
class CreateConsistencyGroup(command.ShowOne):
|
||||
@ -143,18 +151,20 @@ class CreateConsistencyGroup(command.ShowOne):
|
||||
volume_client = self.app.client_manager.volume
|
||||
if parsed_args.volume_type:
|
||||
volume_type_id = utils.find_resource(
|
||||
volume_client.volume_types,
|
||||
parsed_args.volume_type).id
|
||||
volume_client.volume_types, parsed_args.volume_type
|
||||
).id
|
||||
consistency_group = volume_client.consistencygroups.create(
|
||||
volume_type_id,
|
||||
name=parsed_args.name,
|
||||
description=parsed_args.description,
|
||||
availability_zone=parsed_args.availability_zone
|
||||
availability_zone=parsed_args.availability_zone,
|
||||
)
|
||||
else:
|
||||
if parsed_args.availability_zone:
|
||||
msg = _("'--availability-zone' option will not work "
|
||||
"if creating consistency group from source")
|
||||
msg = _(
|
||||
"'--availability-zone' option will not work "
|
||||
"if creating consistency group from source"
|
||||
)
|
||||
LOG.warning(msg)
|
||||
|
||||
consistency_group_id = None
|
||||
@ -208,19 +218,27 @@ class DeleteConsistencyGroup(command.Command):
|
||||
for i in parsed_args.consistency_groups:
|
||||
try:
|
||||
consistency_group_id = utils.find_resource(
|
||||
volume_client.consistencygroups, i).id
|
||||
volume_client.consistencygroups, i
|
||||
).id
|
||||
volume_client.consistencygroups.delete(
|
||||
consistency_group_id, parsed_args.force)
|
||||
consistency_group_id, parsed_args.force
|
||||
)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete consistency group with "
|
||||
"name or ID '%(consistency_group)s':%(e)s")
|
||||
% {'consistency_group': i, 'e': e})
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to delete consistency group with "
|
||||
"name or ID '%(consistency_group)s':%(e)s"
|
||||
)
|
||||
% {'consistency_group': i, 'e': e}
|
||||
)
|
||||
|
||||
if result > 0:
|
||||
total = len(parsed_args.consistency_groups)
|
||||
msg = (_("%(result)s of %(total)s consistency groups failed "
|
||||
"to delete.") % {'result': result, 'total': total})
|
||||
msg = _(
|
||||
"%(result)s of %(total)s consistency groups failed "
|
||||
"to delete."
|
||||
) % {'result': result, 'total': total}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
@ -232,41 +250,56 @@ class ListConsistencyGroup(command.Lister):
|
||||
parser.add_argument(
|
||||
'--all-projects',
|
||||
action="store_true",
|
||||
help=_('Show details for all projects. Admin only. '
|
||||
'(defaults to False)')
|
||||
help=_(
|
||||
'Show details for all projects. Admin only. '
|
||||
'(defaults to False)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--long',
|
||||
action="store_true",
|
||||
help=_('List additional fields in output')
|
||||
help=_('List additional fields in output'),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
if parsed_args.long:
|
||||
columns = ['ID', 'Status', 'Availability Zone',
|
||||
'Name', 'Description', 'Volume Types']
|
||||
columns = [
|
||||
'ID',
|
||||
'Status',
|
||||
'Availability Zone',
|
||||
'Name',
|
||||
'Description',
|
||||
'Volume Types',
|
||||
]
|
||||
else:
|
||||
columns = ['ID', 'Status', 'Name']
|
||||
volume_client = self.app.client_manager.volume
|
||||
consistency_groups = volume_client.consistencygroups.list(
|
||||
detailed=True,
|
||||
search_opts={'all_tenants': parsed_args.all_projects}
|
||||
search_opts={'all_tenants': parsed_args.all_projects},
|
||||
)
|
||||
|
||||
return (columns, (
|
||||
utils.get_item_properties(
|
||||
s, columns,
|
||||
formatters={'Volume Types': format_columns.ListColumn})
|
||||
for s in consistency_groups))
|
||||
return (
|
||||
columns,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
formatters={'Volume Types': format_columns.ListColumn},
|
||||
)
|
||||
for s in consistency_groups
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class RemoveVolumeFromConsistencyGroup(command.Command):
|
||||
_description = _("Remove volume(s) from consistency group")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = \
|
||||
super(RemoveVolumeFromConsistencyGroup, self).get_parser(prog_name)
|
||||
parser = super(RemoveVolumeFromConsistencyGroup, self).get_parser(
|
||||
prog_name
|
||||
)
|
||||
parser.add_argument(
|
||||
'consistency_group',
|
||||
metavar="<consistency-group>",
|
||||
@ -276,8 +309,10 @@ class RemoveVolumeFromConsistencyGroup(command.Command):
|
||||
'volumes',
|
||||
metavar='<volume>',
|
||||
nargs='+',
|
||||
help=_('Volume(s) to remove from <consistency-group> (name or ID) '
|
||||
'(repeat option to remove multiple volumes)'),
|
||||
help=_(
|
||||
'Volume(s) to remove from <consistency-group> (name or ID) '
|
||||
'(repeat option to remove multiple volumes)'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -287,16 +322,19 @@ class RemoveVolumeFromConsistencyGroup(command.Command):
|
||||
|
||||
if result > 0:
|
||||
total = len(parsed_args.volumes)
|
||||
LOG.error(_("%(result)s of %(total)s volumes failed "
|
||||
"to remove.") % {'result': result, 'total': total})
|
||||
LOG.error(
|
||||
_("%(result)s of %(total)s volumes failed " "to remove.")
|
||||
% {'result': result, 'total': total}
|
||||
)
|
||||
|
||||
if remove_uuid:
|
||||
remove_uuid = remove_uuid.rstrip(',')
|
||||
consistency_group_id = utils.find_resource(
|
||||
volume_client.consistencygroups,
|
||||
parsed_args.consistency_group).id
|
||||
volume_client.consistencygroups, parsed_args.consistency_group
|
||||
).id
|
||||
volume_client.consistencygroups.update(
|
||||
consistency_group_id, remove_volumes=remove_uuid)
|
||||
consistency_group_id, remove_volumes=remove_uuid
|
||||
)
|
||||
|
||||
|
||||
class SetConsistencyGroup(command.Command):
|
||||
@ -307,7 +345,7 @@ class SetConsistencyGroup(command.Command):
|
||||
parser.add_argument(
|
||||
'consistency_group',
|
||||
metavar='<consistency-group>',
|
||||
help=_('Consistency group to modify (name or ID)')
|
||||
help=_('Consistency group to modify (name or ID)'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
@ -330,10 +368,11 @@ class SetConsistencyGroup(command.Command):
|
||||
kwargs['description'] = parsed_args.description
|
||||
if kwargs:
|
||||
consistency_group_id = utils.find_resource(
|
||||
volume_client.consistencygroups,
|
||||
parsed_args.consistency_group).id
|
||||
volume_client.consistencygroups, parsed_args.consistency_group
|
||||
).id
|
||||
volume_client.consistencygroups.update(
|
||||
consistency_group_id, **kwargs)
|
||||
consistency_group_id, **kwargs
|
||||
)
|
||||
|
||||
|
||||
class ShowConsistencyGroup(command.ShowOne):
|
||||
@ -344,13 +383,13 @@ class ShowConsistencyGroup(command.ShowOne):
|
||||
parser.add_argument(
|
||||
"consistency_group",
|
||||
metavar="<consistency-group>",
|
||||
help=_("Consistency group to display (name or ID)")
|
||||
help=_("Consistency group to display (name or ID)"),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
consistency_group = utils.find_resource(
|
||||
volume_client.consistencygroups,
|
||||
parsed_args.consistency_group)
|
||||
volume_client.consistencygroups, parsed_args.consistency_group
|
||||
)
|
||||
return zip(*sorted(consistency_group._info.items()))
|
||||
|
@ -30,24 +30,27 @@ class CreateConsistencyGroupSnapshot(command.ShowOne):
|
||||
_description = _("Create new consistency group snapshot.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(
|
||||
CreateConsistencyGroupSnapshot, self).get_parser(prog_name)
|
||||
parser = super(CreateConsistencyGroupSnapshot, self).get_parser(
|
||||
prog_name
|
||||
)
|
||||
parser.add_argument(
|
||||
"snapshot_name",
|
||||
metavar="<snapshot-name>",
|
||||
nargs="?",
|
||||
help=_("Name of new consistency group snapshot (default to None)")
|
||||
help=_("Name of new consistency group snapshot (default to None)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--consistency-group",
|
||||
metavar="<consistency-group>",
|
||||
help=_("Consistency group to snapshot (name or ID) "
|
||||
"(default to be the same as <snapshot-name>)")
|
||||
help=_(
|
||||
"Consistency group to snapshot (name or ID) "
|
||||
"(default to be the same as <snapshot-name>)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--description",
|
||||
metavar="<description>",
|
||||
help=_("Description of this consistency group snapshot")
|
||||
help=_("Description of this consistency group snapshot"),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -59,8 +62,8 @@ class CreateConsistencyGroupSnapshot(command.ShowOne):
|
||||
# will be the same as the new consistency group snapshot name
|
||||
consistency_group = parsed_args.snapshot_name
|
||||
consistency_group_id = utils.find_resource(
|
||||
volume_client.consistencygroups,
|
||||
consistency_group).id
|
||||
volume_client.consistencygroups, consistency_group
|
||||
).id
|
||||
consistency_group_snapshot = volume_client.cgsnapshots.create(
|
||||
consistency_group_id,
|
||||
name=parsed_args.snapshot_name,
|
||||
@ -74,13 +77,14 @@ class DeleteConsistencyGroupSnapshot(command.Command):
|
||||
_description = _("Delete consistency group snapshot(s).")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(
|
||||
DeleteConsistencyGroupSnapshot, self).get_parser(prog_name)
|
||||
parser = super(DeleteConsistencyGroupSnapshot, self).get_parser(
|
||||
prog_name
|
||||
)
|
||||
parser.add_argument(
|
||||
"consistency_group_snapshot",
|
||||
metavar="<consistency-group-snapshot>",
|
||||
nargs="+",
|
||||
help=_("Consistency group snapshot(s) to delete (name or ID)")
|
||||
help=_("Consistency group snapshot(s) to delete (name or ID)"),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -90,20 +94,27 @@ class DeleteConsistencyGroupSnapshot(command.Command):
|
||||
|
||||
for snapshot in parsed_args.consistency_group_snapshot:
|
||||
try:
|
||||
snapshot_id = utils.find_resource(volume_client.cgsnapshots,
|
||||
snapshot).id
|
||||
snapshot_id = utils.find_resource(
|
||||
volume_client.cgsnapshots, snapshot
|
||||
).id
|
||||
|
||||
volume_client.cgsnapshots.delete(snapshot_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete consistency group snapshot "
|
||||
"with name or ID '%(snapshot)s': %(e)s")
|
||||
% {'snapshot': snapshot, 'e': e})
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to delete consistency group snapshot "
|
||||
"with name or ID '%(snapshot)s': %(e)s"
|
||||
)
|
||||
% {'snapshot': snapshot, 'e': e}
|
||||
)
|
||||
|
||||
if result > 0:
|
||||
total = len(parsed_args.consistency_group_snapshot)
|
||||
msg = (_("%(result)s of %(total)s consistency group snapshots "
|
||||
"failed to delete.") % {'result': result, 'total': total})
|
||||
msg = _(
|
||||
"%(result)s of %(total)s consistency group snapshots "
|
||||
"failed to delete."
|
||||
) % {'result': result, 'total': total}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
@ -111,38 +122,54 @@ class ListConsistencyGroupSnapshot(command.Lister):
|
||||
_description = _("List consistency group snapshots.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(
|
||||
ListConsistencyGroupSnapshot, self).get_parser(prog_name)
|
||||
parser = super(ListConsistencyGroupSnapshot, self).get_parser(
|
||||
prog_name
|
||||
)
|
||||
parser.add_argument(
|
||||
'--all-projects',
|
||||
action="store_true",
|
||||
help=_('Show detail for all projects (admin only) '
|
||||
'(defaults to False)')
|
||||
help=_(
|
||||
'Show detail for all projects (admin only) '
|
||||
'(defaults to False)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--long',
|
||||
action="store_true",
|
||||
help=_('List additional fields in output')
|
||||
help=_('List additional fields in output'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--status',
|
||||
metavar="<status>",
|
||||
choices=['available', 'error', 'creating', 'deleting',
|
||||
'error_deleting'],
|
||||
help=_('Filters results by a status ("available", "error", '
|
||||
'"creating", "deleting" or "error_deleting")')
|
||||
choices=[
|
||||
'available',
|
||||
'error',
|
||||
'creating',
|
||||
'deleting',
|
||||
'error_deleting',
|
||||
],
|
||||
help=_(
|
||||
'Filters results by a status ("available", "error", '
|
||||
'"creating", "deleting" or "error_deleting")'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--consistency-group',
|
||||
metavar="<consistency-group>",
|
||||
help=_('Filters results by a consistency group (name or ID)')
|
||||
help=_('Filters results by a consistency group (name or ID)'),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
if parsed_args.long:
|
||||
columns = ['ID', 'Status', 'ConsistencyGroup ID',
|
||||
'Name', 'Description', 'Created At']
|
||||
columns = [
|
||||
'ID',
|
||||
'Status',
|
||||
'ConsistencyGroup ID',
|
||||
'Name',
|
||||
'Description',
|
||||
'Created At',
|
||||
]
|
||||
else:
|
||||
columns = ['ID', 'Status', 'Name']
|
||||
volume_client = self.app.client_manager.volume
|
||||
@ -162,28 +189,32 @@ class ListConsistencyGroupSnapshot(command.Lister):
|
||||
search_opts=search_opts,
|
||||
)
|
||||
|
||||
return (columns, (
|
||||
utils.get_item_properties(
|
||||
s, columns)
|
||||
for s in consistency_group_snapshots))
|
||||
return (
|
||||
columns,
|
||||
(
|
||||
utils.get_item_properties(s, columns)
|
||||
for s in consistency_group_snapshots
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class ShowConsistencyGroupSnapshot(command.ShowOne):
|
||||
_description = _("Display consistency group snapshot details")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(
|
||||
ShowConsistencyGroupSnapshot, self).get_parser(prog_name)
|
||||
parser = super(ShowConsistencyGroupSnapshot, self).get_parser(
|
||||
prog_name
|
||||
)
|
||||
parser.add_argument(
|
||||
"consistency_group_snapshot",
|
||||
metavar="<consistency-group-snapshot>",
|
||||
help=_("Consistency group snapshot to display (name or ID)")
|
||||
help=_("Consistency group snapshot to display (name or ID)"),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
consistency_group_snapshot = utils.find_resource(
|
||||
volume_client.cgsnapshots,
|
||||
parsed_args.consistency_group_snapshot)
|
||||
volume_client.cgsnapshots, parsed_args.consistency_group_snapshot
|
||||
)
|
||||
return zip(*sorted(consistency_group_snapshot._info.items()))
|
||||
|
@ -48,10 +48,12 @@ class AssociateQos(command.Command):
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
qos_spec = utils.find_resource(volume_client.qos_specs,
|
||||
parsed_args.qos_spec)
|
||||
volume_type = utils.find_resource(volume_client.volume_types,
|
||||
parsed_args.volume_type)
|
||||
qos_spec = utils.find_resource(
|
||||
volume_client.qos_specs, parsed_args.qos_spec
|
||||
)
|
||||
volume_type = utils.find_resource(
|
||||
volume_client.volume_types, parsed_args.volume_type
|
||||
)
|
||||
|
||||
volume_client.qos_specs.associate(qos_spec.id, volume_type.id)
|
||||
|
||||
@ -72,16 +74,22 @@ class CreateQos(command.ShowOne):
|
||||
metavar='<consumer>',
|
||||
choices=consumer_choices,
|
||||
default='both',
|
||||
help=(_('Consumer of the QoS. Valid consumers: %s '
|
||||
"(defaults to 'both')") %
|
||||
utils.format_list(consumer_choices))
|
||||
help=(
|
||||
_(
|
||||
'Consumer of the QoS. Valid consumers: %s '
|
||||
"(defaults to 'both')"
|
||||
)
|
||||
% utils.format_list(consumer_choices)
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--property',
|
||||
metavar='<key=value>',
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_('Set a QoS specification property '
|
||||
'(repeat option to set multiple properties)'),
|
||||
help=_(
|
||||
'Set a QoS specification property '
|
||||
'(repeat option to set multiple properties)'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -96,8 +104,11 @@ class CreateQos(command.ShowOne):
|
||||
qos_spec = volume_client.qos_specs.create(parsed_args.name, specs)
|
||||
|
||||
qos_spec._info.update(
|
||||
{'properties':
|
||||
format_columns.DictColumn(qos_spec._info.pop('specs'))}
|
||||
{
|
||||
'properties': format_columns.DictColumn(
|
||||
qos_spec._info.pop('specs')
|
||||
)
|
||||
}
|
||||
)
|
||||
return zip(*sorted(qos_spec._info.items()))
|
||||
|
||||
@ -117,7 +128,7 @@ class DeleteQos(command.Command):
|
||||
'--force',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_("Allow to delete in-use QoS specification(s)")
|
||||
help=_("Allow to delete in-use QoS specification(s)"),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -131,14 +142,20 @@ class DeleteQos(command.Command):
|
||||
volume_client.qos_specs.delete(qos_spec.id, parsed_args.force)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete QoS specification with "
|
||||
"name or ID '%(qos)s': %(e)s")
|
||||
% {'qos': i, 'e': e})
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to delete QoS specification with "
|
||||
"name or ID '%(qos)s': %(e)s"
|
||||
)
|
||||
% {'qos': i, 'e': e}
|
||||
)
|
||||
|
||||
if result > 0:
|
||||
total = len(parsed_args.qos_specs)
|
||||
msg = (_("%(result)s of %(total)s QoS specifications failed"
|
||||
" to delete.") % {'result': result, 'total': total})
|
||||
msg = _(
|
||||
"%(result)s of %(total)s QoS specifications failed"
|
||||
" to delete."
|
||||
) % {'result': result, 'total': total}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
@ -169,12 +186,14 @@ class DisassociateQos(command.Command):
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
qos_spec = utils.find_resource(volume_client.qos_specs,
|
||||
parsed_args.qos_spec)
|
||||
qos_spec = utils.find_resource(
|
||||
volume_client.qos_specs, parsed_args.qos_spec
|
||||
)
|
||||
|
||||
if parsed_args.volume_type:
|
||||
volume_type = utils.find_resource(volume_client.volume_types,
|
||||
parsed_args.volume_type)
|
||||
volume_type = utils.find_resource(
|
||||
volume_client.volume_types, parsed_args.volume_type
|
||||
)
|
||||
volume_client.qos_specs.disassociate(qos_spec.id, volume_type.id)
|
||||
elif parsed_args.all:
|
||||
volume_client.qos_specs.disassociate_all(qos_spec.id)
|
||||
@ -204,17 +223,28 @@ class ListQos(command.Lister):
|
||||
raise
|
||||
|
||||
display_columns = (
|
||||
'ID', 'Name', 'Consumer', 'Associations', 'Properties')
|
||||
'ID',
|
||||
'Name',
|
||||
'Consumer',
|
||||
'Associations',
|
||||
'Properties',
|
||||
)
|
||||
|
||||
columns = ('ID', 'Name', 'Consumer', 'Associations', 'Specs')
|
||||
return (display_columns,
|
||||
(utils.get_dict_properties(
|
||||
s._info, columns,
|
||||
return (
|
||||
display_columns,
|
||||
(
|
||||
utils.get_dict_properties(
|
||||
s._info,
|
||||
columns,
|
||||
formatters={
|
||||
'Specs': format_columns.DictColumn,
|
||||
'Associations': format_columns.ListColumn
|
||||
'Associations': format_columns.ListColumn,
|
||||
},
|
||||
) for s in qos_specs_list))
|
||||
)
|
||||
for s in qos_specs_list
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class SetQos(command.Command):
|
||||
@ -231,19 +261,21 @@ class SetQos(command.Command):
|
||||
'--property',
|
||||
metavar='<key=value>',
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_('Property to add or modify for this QoS specification '
|
||||
'(repeat option to set multiple properties)'),
|
||||
help=_(
|
||||
'Property to add or modify for this QoS specification '
|
||||
'(repeat option to set multiple properties)'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
qos_spec = utils.find_resource(volume_client.qos_specs,
|
||||
parsed_args.qos_spec)
|
||||
qos_spec = utils.find_resource(
|
||||
volume_client.qos_specs, parsed_args.qos_spec
|
||||
)
|
||||
|
||||
if parsed_args.property:
|
||||
volume_client.qos_specs.set_keys(qos_spec.id,
|
||||
parsed_args.property)
|
||||
volume_client.qos_specs.set_keys(qos_spec.id, parsed_args.property)
|
||||
|
||||
|
||||
class ShowQos(command.ShowOne):
|
||||
@ -260,19 +292,25 @@ class ShowQos(command.ShowOne):
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
qos_spec = utils.find_resource(volume_client.qos_specs,
|
||||
parsed_args.qos_spec)
|
||||
qos_spec = utils.find_resource(
|
||||
volume_client.qos_specs, parsed_args.qos_spec
|
||||
)
|
||||
|
||||
qos_associations = volume_client.qos_specs.get_associations(qos_spec)
|
||||
if qos_associations:
|
||||
associations = [association.name
|
||||
for association in qos_associations]
|
||||
qos_spec._info.update({
|
||||
'associations': format_columns.ListColumn(associations)
|
||||
})
|
||||
associations = [
|
||||
association.name for association in qos_associations
|
||||
]
|
||||
qos_spec._info.update(
|
||||
{'associations': format_columns.ListColumn(associations)}
|
||||
)
|
||||
qos_spec._info.update(
|
||||
{'properties':
|
||||
format_columns.DictColumn(qos_spec._info.pop('specs'))})
|
||||
{
|
||||
'properties': format_columns.DictColumn(
|
||||
qos_spec._info.pop('specs')
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
return zip(*sorted(qos_spec._info.items()))
|
||||
|
||||
@ -292,16 +330,20 @@ class UnsetQos(command.Command):
|
||||
metavar='<key>',
|
||||
action='append',
|
||||
default=[],
|
||||
help=_('Property to remove from the QoS specification. '
|
||||
'(repeat option to unset multiple properties)'),
|
||||
help=_(
|
||||
'Property to remove from the QoS specification. '
|
||||
'(repeat option to unset multiple properties)'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
qos_spec = utils.find_resource(volume_client.qos_specs,
|
||||
parsed_args.qos_spec)
|
||||
qos_spec = utils.find_resource(
|
||||
volume_client.qos_specs, parsed_args.qos_spec
|
||||
)
|
||||
|
||||
if parsed_args.property:
|
||||
volume_client.qos_specs.unset_keys(qos_spec.id,
|
||||
parsed_args.property)
|
||||
volume_client.qos_specs.unset_keys(
|
||||
qos_spec.id, parsed_args.property
|
||||
)
|
||||
|
@ -29,18 +29,18 @@ class ListService(command.Lister):
|
||||
parser.add_argument(
|
||||
"--host",
|
||||
metavar="<host>",
|
||||
help=_("List services on specified host (name only)")
|
||||
help=_("List services on specified host (name only)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--service",
|
||||
metavar="<service>",
|
||||
help=_("List only specified service (name only)")
|
||||
help=_("List only specified service (name only)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--long",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help=_("List additional fields in output")
|
||||
help=_("List additional fields in output"),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -55,7 +55,7 @@ class ListService(command.Lister):
|
||||
"Status",
|
||||
"State",
|
||||
"Updated At",
|
||||
"Disabled Reason"
|
||||
"Disabled Reason",
|
||||
]
|
||||
else:
|
||||
columns = [
|
||||
@ -64,15 +64,22 @@ class ListService(command.Lister):
|
||||
"Zone",
|
||||
"Status",
|
||||
"State",
|
||||
"Updated At"
|
||||
"Updated At",
|
||||
]
|
||||
|
||||
data = service_client.services.list(parsed_args.host,
|
||||
parsed_args.service)
|
||||
return (columns,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
) for s in data))
|
||||
data = service_client.services.list(
|
||||
parsed_args.host, parsed_args.service
|
||||
)
|
||||
return (
|
||||
columns,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
)
|
||||
for s in data
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class SetService(command.Command):
|
||||
@ -80,51 +87,50 @@ class SetService(command.Command):
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SetService, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"host",
|
||||
metavar="<host>",
|
||||
help=_("Name of host")
|
||||
)
|
||||
parser.add_argument("host", metavar="<host>", help=_("Name of host"))
|
||||
parser.add_argument(
|
||||
"service",
|
||||
metavar="<service>",
|
||||
help=_("Name of service (Binary name)")
|
||||
help=_("Name of service (Binary name)"),
|
||||
)
|
||||
enabled_group = parser.add_mutually_exclusive_group()
|
||||
enabled_group.add_argument(
|
||||
"--enable",
|
||||
action="store_true",
|
||||
help=_("Enable volume service")
|
||||
"--enable", action="store_true", help=_("Enable volume service")
|
||||
)
|
||||
enabled_group.add_argument(
|
||||
"--disable",
|
||||
action="store_true",
|
||||
help=_("Disable volume service")
|
||||
"--disable", action="store_true", help=_("Disable volume service")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--disable-reason",
|
||||
metavar="<reason>",
|
||||
help=_("Reason for disabling the service "
|
||||
"(should be used with --disable option)")
|
||||
help=_(
|
||||
"Reason for disabling the service "
|
||||
"(should be used with --disable option)"
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
if parsed_args.disable_reason and not parsed_args.disable:
|
||||
msg = _("Cannot specify option --disable-reason without "
|
||||
"--disable specified.")
|
||||
msg = _(
|
||||
"Cannot specify option --disable-reason without "
|
||||
"--disable specified."
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
service_client = self.app.client_manager.volume
|
||||
if parsed_args.enable:
|
||||
service_client.services.enable(
|
||||
parsed_args.host, parsed_args.service)
|
||||
parsed_args.host, parsed_args.service
|
||||
)
|
||||
if parsed_args.disable:
|
||||
if parsed_args.disable_reason:
|
||||
service_client.services.disable_log_reason(
|
||||
parsed_args.host,
|
||||
parsed_args.service,
|
||||
parsed_args.disable_reason)
|
||||
parsed_args.disable_reason,
|
||||
)
|
||||
else:
|
||||
service_client.services.disable(
|
||||
parsed_args.host, parsed_args.service)
|
||||
parsed_args.host, parsed_args.service
|
||||
)
|
||||
|
@ -71,10 +71,13 @@ def _check_size_arg(args):
|
||||
volume is not specified.
|
||||
"""
|
||||
|
||||
if ((args.snapshot or args.source or args.backup)
|
||||
is None and args.size is None):
|
||||
msg = _("--size is a required option if snapshot, backup "
|
||||
"or source volume are not specified.")
|
||||
if (
|
||||
args.snapshot or args.source or args.backup
|
||||
) is None and args.size is None:
|
||||
msg = _(
|
||||
"--size is a required option if snapshot, backup "
|
||||
"or source volume are not specified."
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
@ -93,8 +96,10 @@ class CreateVolume(command.ShowOne):
|
||||
"--size",
|
||||
metavar="<size>",
|
||||
type=int,
|
||||
help=_("Volume size in GB (required unless --snapshot, "
|
||||
"--source or --backup is specified)"),
|
||||
help=_(
|
||||
"Volume size in GB (required unless --snapshot, "
|
||||
"--source or --backup is specified)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--type",
|
||||
@ -120,8 +125,10 @@ class CreateVolume(command.ShowOne):
|
||||
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)"),
|
||||
help=_(
|
||||
"Restore backup to a volume (name or ID) "
|
||||
"(supported by --os-volume-api-version 3.47 or later)"
|
||||
),
|
||||
)
|
||||
source_group.add_argument(
|
||||
"--source-replicated",
|
||||
@ -147,37 +154,41 @@ class CreateVolume(command.ShowOne):
|
||||
"--property",
|
||||
metavar="<key=value>",
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_("Set a property to this volume "
|
||||
"(repeat option to set multiple properties)"),
|
||||
help=_(
|
||||
"Set a property to this volume "
|
||||
"(repeat option to set multiple properties)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--hint",
|
||||
metavar="<key=value>",
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_("Arbitrary scheduler hint key-value pairs to help boot "
|
||||
"an instance (repeat option to set multiple hints)"),
|
||||
help=_(
|
||||
"Arbitrary scheduler hint key-value pairs to help boot "
|
||||
"an instance (repeat option to set multiple hints)"
|
||||
),
|
||||
)
|
||||
bootable_group = parser.add_mutually_exclusive_group()
|
||||
bootable_group.add_argument(
|
||||
"--bootable",
|
||||
action="store_true",
|
||||
help=_("Mark volume as bootable")
|
||||
help=_("Mark volume as bootable"),
|
||||
)
|
||||
bootable_group.add_argument(
|
||||
"--non-bootable",
|
||||
action="store_true",
|
||||
help=_("Mark volume as non-bootable (default)")
|
||||
help=_("Mark volume as non-bootable (default)"),
|
||||
)
|
||||
readonly_group = parser.add_mutually_exclusive_group()
|
||||
readonly_group.add_argument(
|
||||
"--read-only",
|
||||
action="store_true",
|
||||
help=_("Set volume to read-only access mode")
|
||||
help=_("Set volume to read-only access mode"),
|
||||
)
|
||||
readonly_group.add_argument(
|
||||
"--read-write",
|
||||
action="store_true",
|
||||
help=_("Set volume to read-write access mode (default)")
|
||||
help=_("Set volume to read-write access mode (default)"),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -193,35 +204,39 @@ class CreateVolume(command.ShowOne):
|
||||
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.")
|
||||
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
|
||||
if parsed_args.source:
|
||||
source_volume_obj = utils.find_resource(
|
||||
volume_client.volumes,
|
||||
parsed_args.source)
|
||||
volume_client.volumes, parsed_args.source
|
||||
)
|
||||
source_volume = source_volume_obj.id
|
||||
size = max(size or 0, source_volume_obj.size)
|
||||
|
||||
consistency_group = None
|
||||
if parsed_args.consistency_group:
|
||||
consistency_group = utils.find_resource(
|
||||
volume_client.consistencygroups,
|
||||
parsed_args.consistency_group).id
|
||||
volume_client.consistencygroups, parsed_args.consistency_group
|
||||
).id
|
||||
|
||||
image = None
|
||||
if parsed_args.image:
|
||||
image = image_client.find_image(parsed_args.image,
|
||||
ignore_missing=False).id
|
||||
image = image_client.find_image(
|
||||
parsed_args.image, ignore_missing=False
|
||||
).id
|
||||
|
||||
snapshot = None
|
||||
if parsed_args.snapshot:
|
||||
snapshot_obj = utils.find_resource(
|
||||
volume_client.volume_snapshots,
|
||||
parsed_args.snapshot)
|
||||
volume_client.volume_snapshots, parsed_args.snapshot
|
||||
)
|
||||
snapshot = snapshot_obj.id
|
||||
# Cinder requires a value for size when creating a volume
|
||||
# even if creating from a snapshot. Cinder will create the
|
||||
@ -234,8 +249,8 @@ class CreateVolume(command.ShowOne):
|
||||
backup = None
|
||||
if parsed_args.backup:
|
||||
backup_obj = utils.find_resource(
|
||||
volume_client.backups,
|
||||
parsed_args.backup)
|
||||
volume_client.backups, parsed_args.backup
|
||||
)
|
||||
backup = backup_obj.id
|
||||
# As above
|
||||
size = max(size or 0, backup_obj.size)
|
||||
@ -262,11 +277,10 @@ class CreateVolume(command.ShowOne):
|
||||
volume.id,
|
||||
success_status=['available'],
|
||||
error_status=['error'],
|
||||
sleep_time=1
|
||||
sleep_time=1,
|
||||
):
|
||||
volume_client.volumes.set_bootable(
|
||||
volume.id,
|
||||
parsed_args.bootable
|
||||
volume.id, parsed_args.bootable
|
||||
)
|
||||
else:
|
||||
msg = _(
|
||||
@ -283,11 +297,10 @@ class CreateVolume(command.ShowOne):
|
||||
volume.id,
|
||||
success_status=['available'],
|
||||
error_status=['error'],
|
||||
sleep_time=1
|
||||
sleep_time=1,
|
||||
):
|
||||
volume_client.volumes.update_readonly_flag(
|
||||
volume.id,
|
||||
parsed_args.read_only
|
||||
volume.id, parsed_args.read_only
|
||||
)
|
||||
else:
|
||||
msg = _(
|
||||
@ -296,15 +309,21 @@ class CreateVolume(command.ShowOne):
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set volume read-only access "
|
||||
"mode flag: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to set volume read-only access "
|
||||
"mode flag: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
|
||||
# Remove key links from being displayed
|
||||
volume._info.update(
|
||||
{
|
||||
'properties':
|
||||
format_columns.DictColumn(volume._info.pop('metadata')),
|
||||
'type': volume._info.pop('volume_type')
|
||||
'properties': format_columns.DictColumn(
|
||||
volume._info.pop('metadata')
|
||||
),
|
||||
'type': volume._info.pop('volume_type'),
|
||||
}
|
||||
)
|
||||
volume._info.pop("links", None)
|
||||
@ -320,20 +339,24 @@ class DeleteVolume(command.Command):
|
||||
"volumes",
|
||||
metavar="<volume>",
|
||||
nargs="+",
|
||||
help=_("Volume(s) to delete (name or ID)")
|
||||
help=_("Volume(s) to delete (name or ID)"),
|
||||
)
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument(
|
||||
"--force",
|
||||
action="store_true",
|
||||
help=_("Attempt forced removal of volume(s), regardless of state "
|
||||
"(defaults to False)")
|
||||
help=_(
|
||||
"Attempt forced removal of volume(s), regardless of state "
|
||||
"(defaults to False)"
|
||||
),
|
||||
)
|
||||
group.add_argument(
|
||||
"--purge",
|
||||
action="store_true",
|
||||
help=_("Remove any snapshots along with volume(s) "
|
||||
"(defaults to False)")
|
||||
help=_(
|
||||
"Remove any snapshots along with volume(s) "
|
||||
"(defaults to False)"
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -343,23 +366,29 @@ class DeleteVolume(command.Command):
|
||||
|
||||
for i in parsed_args.volumes:
|
||||
try:
|
||||
volume_obj = utils.find_resource(
|
||||
volume_client.volumes, i)
|
||||
volume_obj = utils.find_resource(volume_client.volumes, i)
|
||||
if parsed_args.force:
|
||||
volume_client.volumes.force_delete(volume_obj.id)
|
||||
else:
|
||||
volume_client.volumes.delete(volume_obj.id,
|
||||
cascade=parsed_args.purge)
|
||||
volume_client.volumes.delete(
|
||||
volume_obj.id, cascade=parsed_args.purge
|
||||
)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete volume with "
|
||||
"name or ID '%(volume)s': %(e)s"),
|
||||
{'volume': i, 'e': e})
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to delete volume with "
|
||||
"name or ID '%(volume)s': %(e)s"
|
||||
),
|
||||
{'volume': i, 'e': e},
|
||||
)
|
||||
|
||||
if result > 0:
|
||||
total = len(parsed_args.volumes)
|
||||
msg = (_("%(result)s of %(total)s volumes failed "
|
||||
"to delete.") % {'result': result, 'total': total})
|
||||
msg = _("%(result)s of %(total)s volumes failed " "to delete.") % {
|
||||
'result': result,
|
||||
'total': total,
|
||||
}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
@ -371,13 +400,13 @@ class ListVolume(command.Lister):
|
||||
parser.add_argument(
|
||||
'--project',
|
||||
metavar='<project>',
|
||||
help=_('Filter results by project (name or ID) (admin only)')
|
||||
help=_('Filter results by project (name or ID) (admin only)'),
|
||||
)
|
||||
identity_common.add_project_domain_option_to_parser(parser)
|
||||
parser.add_argument(
|
||||
'--user',
|
||||
metavar='<user>',
|
||||
help=_('Filter results by user (name or ID) (admin only)')
|
||||
help=_('Filter results by user (name or ID) (admin only)'),
|
||||
)
|
||||
identity_common.add_user_domain_option_to_parser(parser)
|
||||
parser.add_argument(
|
||||
@ -417,7 +446,6 @@ class ListVolume(command.Lister):
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
|
||||
volume_client = self.app.client_manager.volume
|
||||
identity_client = self.app.client_manager.identity
|
||||
|
||||
@ -457,20 +485,22 @@ class ListVolume(command.Lister):
|
||||
# Just forget it if there's any trouble
|
||||
pass
|
||||
AttachmentsColumnWithCache = functools.partial(
|
||||
AttachmentsColumn, server_cache=server_cache)
|
||||
AttachmentsColumn, server_cache=server_cache
|
||||
)
|
||||
|
||||
project_id = None
|
||||
if parsed_args.project:
|
||||
project_id = identity_common.find_project(
|
||||
identity_client,
|
||||
parsed_args.project,
|
||||
parsed_args.project_domain).id
|
||||
parsed_args.project_domain,
|
||||
).id
|
||||
|
||||
user_id = None
|
||||
if parsed_args.user:
|
||||
user_id = identity_common.find_user(identity_client,
|
||||
parsed_args.user,
|
||||
parsed_args.user_domain).id
|
||||
user_id = identity_common.find_user(
|
||||
identity_client, parsed_args.user, parsed_args.user_domain
|
||||
).id
|
||||
|
||||
# set value of 'all_tenants' when using project option
|
||||
all_projects = bool(parsed_args.project) or parsed_args.all_projects
|
||||
@ -489,14 +519,23 @@ class ListVolume(command.Lister):
|
||||
limit=parsed_args.limit,
|
||||
)
|
||||
column_headers = utils.backward_compat_col_lister(
|
||||
column_headers, parsed_args.columns, {'Display Name': 'Name'})
|
||||
column_headers, parsed_args.columns, {'Display Name': 'Name'}
|
||||
)
|
||||
|
||||
return (column_headers,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
formatters={'Metadata': format_columns.DictColumn,
|
||||
'Attachments': AttachmentsColumnWithCache},
|
||||
) for s in data))
|
||||
return (
|
||||
column_headers,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
formatters={
|
||||
'Metadata': format_columns.DictColumn,
|
||||
'Attachments': AttachmentsColumnWithCache,
|
||||
},
|
||||
)
|
||||
for s in data
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class MigrateVolume(command.Command):
|
||||
@ -507,35 +546,44 @@ class MigrateVolume(command.Command):
|
||||
parser.add_argument(
|
||||
'volume',
|
||||
metavar="<volume>",
|
||||
help=_("Volume to migrate (name or ID)")
|
||||
help=_("Volume to migrate (name or ID)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--host',
|
||||
metavar="<host>",
|
||||
required=True,
|
||||
help=_("Destination host (takes the form: host@backend-name#pool)")
|
||||
help=_(
|
||||
"Destination host (takes the form: host@backend-name#pool)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--force-host-copy',
|
||||
action="store_true",
|
||||
help=_("Enable generic host-based force-migration, "
|
||||
"which bypasses driver optimizations")
|
||||
help=_(
|
||||
"Enable generic host-based force-migration, "
|
||||
"which bypasses driver optimizations"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--lock-volume',
|
||||
action="store_true",
|
||||
help=_("If specified, the volume state will be locked "
|
||||
"and will not allow a migration to be aborted "
|
||||
"(possibly by another operation)")
|
||||
help=_(
|
||||
"If specified, the volume state will be locked "
|
||||
"and will not allow a migration to be aborted "
|
||||
"(possibly by another operation)"
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
|
||||
volume_client.volumes.migrate_volume(volume.id, parsed_args.host,
|
||||
parsed_args.force_host_copy,
|
||||
parsed_args.lock_volume,)
|
||||
volume_client.volumes.migrate_volume(
|
||||
volume.id,
|
||||
parsed_args.host,
|
||||
parsed_args.force_host_copy,
|
||||
parsed_args.lock_volume,
|
||||
)
|
||||
|
||||
|
||||
class SetVolume(command.Command):
|
||||
@ -568,56 +616,76 @@ class SetVolume(command.Command):
|
||||
"--no-property",
|
||||
dest="no_property",
|
||||
action="store_true",
|
||||
help=_("Remove all properties from <volume> "
|
||||
"(specify both --no-property and --property to "
|
||||
"remove the current properties before setting "
|
||||
"new properties.)"),
|
||||
help=_(
|
||||
"Remove all properties from <volume> "
|
||||
"(specify both --no-property and --property to "
|
||||
"remove the current properties before setting "
|
||||
"new properties.)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--property',
|
||||
metavar='<key=value>',
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_('Set a property on this volume '
|
||||
'(repeat option to set multiple properties)'),
|
||||
help=_(
|
||||
'Set a property on this volume '
|
||||
'(repeat option to set multiple properties)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--image-property',
|
||||
metavar='<key=value>',
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_('Set an image property on this volume '
|
||||
'(repeat option to set multiple image properties)'),
|
||||
help=_(
|
||||
'Set an image property on this volume '
|
||||
'(repeat option to set multiple image properties)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--state",
|
||||
metavar="<state>",
|
||||
choices=['available', 'error', 'creating', 'deleting',
|
||||
'in-use', 'attaching', 'detaching', 'error_deleting',
|
||||
'maintenance'],
|
||||
help=_('New volume state ("available", "error", "creating", '
|
||||
'"deleting", "in-use", "attaching", "detaching", '
|
||||
'"error_deleting" or "maintenance") (admin only) '
|
||||
'(This option simply changes the state of the volume '
|
||||
'in the database with no regard to actual status, '
|
||||
'exercise caution when using)'),
|
||||
choices=[
|
||||
'available',
|
||||
'error',
|
||||
'creating',
|
||||
'deleting',
|
||||
'in-use',
|
||||
'attaching',
|
||||
'detaching',
|
||||
'error_deleting',
|
||||
'maintenance',
|
||||
],
|
||||
help=_(
|
||||
'New volume state ("available", "error", "creating", '
|
||||
'"deleting", "in-use", "attaching", "detaching", '
|
||||
'"error_deleting" or "maintenance") (admin only) '
|
||||
'(This option simply changes the state of the volume '
|
||||
'in the database with no regard to actual status, '
|
||||
'exercise caution when using)'
|
||||
),
|
||||
)
|
||||
attached_group = parser.add_mutually_exclusive_group()
|
||||
attached_group.add_argument(
|
||||
"--attached",
|
||||
action="store_true",
|
||||
help=_('Set volume attachment status to "attached" '
|
||||
'(admin only) '
|
||||
'(This option simply changes the state of the volume '
|
||||
'in the database with no regard to actual status, '
|
||||
'exercise caution when using)'),
|
||||
help=_(
|
||||
'Set volume attachment status to "attached" '
|
||||
'(admin only) '
|
||||
'(This option simply changes the state of the volume '
|
||||
'in the database with no regard to actual status, '
|
||||
'exercise caution when using)'
|
||||
),
|
||||
)
|
||||
attached_group.add_argument(
|
||||
"--detached",
|
||||
action="store_true",
|
||||
help=_('Set volume attachment status to "detached" '
|
||||
'(admin only) '
|
||||
'(This option simply changes the state of the volume '
|
||||
'in the database with no regard to actual status, '
|
||||
'exercise caution when using)'),
|
||||
help=_(
|
||||
'Set volume attachment status to "detached" '
|
||||
'(admin only) '
|
||||
'(This option simply changes the state of the volume '
|
||||
'in the database with no regard to actual status, '
|
||||
'exercise caution when using)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--type',
|
||||
@ -628,31 +696,33 @@ class SetVolume(command.Command):
|
||||
'--retype-policy',
|
||||
metavar='<retype-policy>',
|
||||
choices=['never', 'on-demand'],
|
||||
help=_('Migration policy while re-typing volume '
|
||||
'("never" or "on-demand", default is "never" ) '
|
||||
'(available only when --type option is specified)'),
|
||||
help=_(
|
||||
'Migration policy while re-typing volume '
|
||||
'("never" or "on-demand", default is "never" ) '
|
||||
'(available only when --type option is specified)'
|
||||
),
|
||||
)
|
||||
bootable_group = parser.add_mutually_exclusive_group()
|
||||
bootable_group.add_argument(
|
||||
"--bootable",
|
||||
action="store_true",
|
||||
help=_("Mark volume as bootable")
|
||||
help=_("Mark volume as bootable"),
|
||||
)
|
||||
bootable_group.add_argument(
|
||||
"--non-bootable",
|
||||
action="store_true",
|
||||
help=_("Mark volume as non-bootable")
|
||||
help=_("Mark volume as non-bootable"),
|
||||
)
|
||||
readonly_group = parser.add_mutually_exclusive_group()
|
||||
readonly_group.add_argument(
|
||||
"--read-only",
|
||||
action="store_true",
|
||||
help=_("Set volume to read-only access mode")
|
||||
help=_("Set volume to read-only access mode"),
|
||||
)
|
||||
readonly_group.add_argument(
|
||||
"--read-write",
|
||||
action="store_true",
|
||||
help=_("Set volume to read-write access mode")
|
||||
help=_("Set volume to read-write access mode"),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -664,14 +734,21 @@ class SetVolume(command.Command):
|
||||
if parsed_args.size:
|
||||
try:
|
||||
if parsed_args.size <= volume.size:
|
||||
msg = (_("New size must be greater than %s GB")
|
||||
% volume.size)
|
||||
msg = (
|
||||
_("New size must be greater than %s GB") % volume.size
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
if volume.status != 'available' and \
|
||||
not volume_client.api_version.matches('3.42'):
|
||||
|
||||
msg = (_("Volume is in %s state, it must be available "
|
||||
"before size can be extended") % volume.status)
|
||||
if (
|
||||
volume.status != 'available'
|
||||
and not volume_client.api_version.matches('3.42')
|
||||
):
|
||||
msg = (
|
||||
_(
|
||||
"Volume is in %s state, it must be available "
|
||||
"before size can be extended"
|
||||
)
|
||||
% volume.status
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
volume_client.volumes.extend(volume.id, parsed_args.size)
|
||||
except Exception as e:
|
||||
@ -681,7 +758,8 @@ class SetVolume(command.Command):
|
||||
if parsed_args.no_property:
|
||||
try:
|
||||
volume_client.volumes.delete_metadata(
|
||||
volume.id, volume.metadata.keys())
|
||||
volume.id, volume.metadata.keys()
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to clean volume properties: %s"), e)
|
||||
result += 1
|
||||
@ -689,55 +767,62 @@ class SetVolume(command.Command):
|
||||
if parsed_args.property:
|
||||
try:
|
||||
volume_client.volumes.set_metadata(
|
||||
volume.id, parsed_args.property)
|
||||
volume.id, parsed_args.property
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set volume property: %s"), e)
|
||||
result += 1
|
||||
if parsed_args.image_property:
|
||||
try:
|
||||
volume_client.volumes.set_image_metadata(
|
||||
volume.id, parsed_args.image_property)
|
||||
volume.id, parsed_args.image_property
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set image property: %s"), e)
|
||||
result += 1
|
||||
if parsed_args.state:
|
||||
try:
|
||||
volume_client.volumes.reset_state(
|
||||
volume.id, parsed_args.state)
|
||||
volume_client.volumes.reset_state(volume.id, parsed_args.state)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set volume state: %s"), e)
|
||||
result += 1
|
||||
if parsed_args.attached:
|
||||
try:
|
||||
volume_client.volumes.reset_state(
|
||||
volume.id, state=None,
|
||||
attach_status="attached")
|
||||
volume.id, state=None, attach_status="attached"
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set volume attach-status: %s"), e)
|
||||
result += 1
|
||||
if parsed_args.detached:
|
||||
try:
|
||||
volume_client.volumes.reset_state(
|
||||
volume.id, state=None,
|
||||
attach_status="detached")
|
||||
volume.id, state=None, attach_status="detached"
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set volume attach-status: %s"), e)
|
||||
result += 1
|
||||
if parsed_args.bootable or parsed_args.non_bootable:
|
||||
try:
|
||||
volume_client.volumes.set_bootable(
|
||||
volume.id, parsed_args.bootable)
|
||||
volume.id, parsed_args.bootable
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set volume bootable property: %s"), e)
|
||||
result += 1
|
||||
if parsed_args.read_only or parsed_args.read_write:
|
||||
try:
|
||||
volume_client.volumes.update_readonly_flag(
|
||||
volume.id,
|
||||
parsed_args.read_only)
|
||||
volume.id, parsed_args.read_only
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set volume read-only access "
|
||||
"mode flag: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to set volume read-only access "
|
||||
"mode flag: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
result += 1
|
||||
if parsed_args.type:
|
||||
# get the migration policy
|
||||
@ -747,20 +832,23 @@ class SetVolume(command.Command):
|
||||
try:
|
||||
# find the volume type
|
||||
volume_type = utils.find_resource(
|
||||
volume_client.volume_types,
|
||||
parsed_args.type)
|
||||
volume_client.volume_types, parsed_args.type
|
||||
)
|
||||
# reset to the new volume type
|
||||
volume_client.volumes.retype(
|
||||
volume.id,
|
||||
volume_type.id,
|
||||
migration_policy)
|
||||
volume.id, volume_type.id, migration_policy
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set volume type: %s"), e)
|
||||
result += 1
|
||||
elif parsed_args.retype_policy:
|
||||
# If the "--retype-policy" is specified without "--type"
|
||||
LOG.warning(_("'--retype-policy' option will not work "
|
||||
"without '--type' option"))
|
||||
LOG.warning(
|
||||
_(
|
||||
"'--retype-policy' option will not work "
|
||||
"without '--type' option"
|
||||
)
|
||||
)
|
||||
|
||||
kwargs = {}
|
||||
if parsed_args.name:
|
||||
@ -771,13 +859,19 @@ class SetVolume(command.Command):
|
||||
try:
|
||||
volume_client.volumes.update(volume.id, **kwargs)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to update volume display name "
|
||||
"or display description: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to update volume display name "
|
||||
"or display description: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
result += 1
|
||||
|
||||
if result > 0:
|
||||
raise exceptions.CommandError(_("One or more of the "
|
||||
"set operations failed"))
|
||||
raise exceptions.CommandError(
|
||||
_("One or more of the " "set operations failed")
|
||||
)
|
||||
|
||||
|
||||
class ShowVolume(command.ShowOne):
|
||||
@ -788,7 +882,7 @@ class ShowVolume(command.ShowOne):
|
||||
parser.add_argument(
|
||||
'volume',
|
||||
metavar="<volume>",
|
||||
help=_("Volume to display (name or ID)")
|
||||
help=_("Volume to display (name or ID)"),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -801,8 +895,9 @@ class ShowVolume(command.ShowOne):
|
||||
# 'volume_type' --> 'type'
|
||||
volume._info.update(
|
||||
{
|
||||
'properties':
|
||||
format_columns.DictColumn(volume._info.pop('metadata')),
|
||||
'properties': format_columns.DictColumn(
|
||||
volume._info.pop('metadata')
|
||||
),
|
||||
'type': volume._info.pop('volume_type'),
|
||||
},
|
||||
)
|
||||
@ -826,28 +921,32 @@ class UnsetVolume(command.Command):
|
||||
'--property',
|
||||
metavar='<key>',
|
||||
action='append',
|
||||
help=_('Remove a property from volume '
|
||||
'(repeat option to remove multiple properties)'),
|
||||
help=_(
|
||||
'Remove a property from volume '
|
||||
'(repeat option to remove multiple properties)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--image-property',
|
||||
metavar='<key>',
|
||||
action='append',
|
||||
help=_('Remove an image property from volume '
|
||||
'(repeat option to remove multiple image properties)'),
|
||||
help=_(
|
||||
'Remove an image property from volume '
|
||||
'(repeat option to remove multiple image properties)'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
volume = utils.find_resource(
|
||||
volume_client.volumes, parsed_args.volume)
|
||||
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
|
||||
|
||||
result = 0
|
||||
if parsed_args.property:
|
||||
try:
|
||||
volume_client.volumes.delete_metadata(
|
||||
volume.id, parsed_args.property)
|
||||
volume.id, parsed_args.property
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to unset volume property: %s"), e)
|
||||
result += 1
|
||||
@ -855,11 +954,13 @@ class UnsetVolume(command.Command):
|
||||
if parsed_args.image_property:
|
||||
try:
|
||||
volume_client.volumes.delete_image_metadata(
|
||||
volume.id, parsed_args.image_property)
|
||||
volume.id, parsed_args.image_property
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to unset image property: %s"), e)
|
||||
result += 1
|
||||
|
||||
if result > 0:
|
||||
raise exceptions.CommandError(_("One or more of the "
|
||||
"unset operations failed"))
|
||||
raise exceptions.CommandError(
|
||||
_("One or more of the " "unset operations failed")
|
||||
)
|
||||
|
@ -28,7 +28,7 @@ class ShowCapability(command.Lister):
|
||||
parser.add_argument(
|
||||
"host",
|
||||
metavar="<host>",
|
||||
help=_("List capabilities of specified host (host@backend-name)")
|
||||
help=_("List capabilities of specified host (host@backend-name)"),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -55,10 +55,16 @@ class ShowCapability(command.Lister):
|
||||
capability_data['key'] = key
|
||||
print_data.append(capability_data)
|
||||
|
||||
return (columns,
|
||||
(utils.get_dict_properties(
|
||||
s, columns,
|
||||
) for s in print_data))
|
||||
return (
|
||||
columns,
|
||||
(
|
||||
utils.get_dict_properties(
|
||||
s,
|
||||
columns,
|
||||
)
|
||||
for s in print_data
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class ListPool(command.Lister):
|
||||
@ -70,7 +76,7 @@ class ListPool(command.Lister):
|
||||
"--long",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help=_("Show detailed information about pools.")
|
||||
help=_("Show detailed information about pools."),
|
||||
)
|
||||
# TODO(smcginnis): Starting with Cinder microversion 3.33, user is also
|
||||
# able to pass in --filters with a <key>=<value> pair to filter on.
|
||||
@ -98,7 +104,7 @@ class ListPool(command.Lister):
|
||||
'Volumes',
|
||||
'Capacity',
|
||||
'Allocated',
|
||||
'Max Over Ratio'
|
||||
'Max Over Ratio',
|
||||
]
|
||||
else:
|
||||
columns = [
|
||||
@ -107,7 +113,13 @@ class ListPool(command.Lister):
|
||||
headers = columns
|
||||
|
||||
data = volume_client.pools.list(detailed=parsed_args.long)
|
||||
return (headers,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
) for s in data))
|
||||
return (
|
||||
headers,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
)
|
||||
for s in data
|
||||
),
|
||||
)
|
||||
|
@ -66,44 +66,42 @@ class CreateVolumeBackup(command.ShowOne):
|
||||
parser.add_argument(
|
||||
"volume",
|
||||
metavar="<volume>",
|
||||
help=_("Volume to backup (name or ID)")
|
||||
help=_("Volume to backup (name or ID)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--name",
|
||||
metavar="<name>",
|
||||
help=_("Name of the backup")
|
||||
"--name", metavar="<name>", help=_("Name of the backup")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--description",
|
||||
metavar="<description>",
|
||||
help=_("Description of the backup")
|
||||
help=_("Description of the backup"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--container",
|
||||
metavar="<container>",
|
||||
help=_("Optional backup container name")
|
||||
help=_("Optional backup container name"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--snapshot",
|
||||
metavar="<snapshot>",
|
||||
help=_("Snapshot to backup (name or ID)")
|
||||
help=_("Snapshot to backup (name or ID)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--force',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_("Allow to back up an in-use volume")
|
||||
help=_("Allow to back up an in-use volume"),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--incremental',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_("Perform an incremental backup")
|
||||
help=_("Perform an incremental backup"),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--no-incremental',
|
||||
action='store_false',
|
||||
help=_("Do not perform an incremental backup")
|
||||
help=_("Do not perform an incremental backup"),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--property',
|
||||
@ -131,14 +129,16 @@ class CreateVolumeBackup(command.ShowOne):
|
||||
volume_client = self.app.client_manager.volume
|
||||
|
||||
volume_id = utils.find_resource(
|
||||
volume_client.volumes, parsed_args.volume,
|
||||
volume_client.volumes,
|
||||
parsed_args.volume,
|
||||
).id
|
||||
|
||||
kwargs = {}
|
||||
|
||||
if parsed_args.snapshot:
|
||||
kwargs['snapshot_id'] = utils.find_resource(
|
||||
volume_client.volume_snapshots, parsed_args.snapshot,
|
||||
volume_client.volume_snapshots,
|
||||
parsed_args.snapshot,
|
||||
).id
|
||||
|
||||
if parsed_args.properties:
|
||||
@ -183,13 +183,13 @@ class DeleteVolumeBackup(command.Command):
|
||||
"backups",
|
||||
metavar="<backup>",
|
||||
nargs="+",
|
||||
help=_("Backup(s) to delete (name or ID)")
|
||||
help=_("Backup(s) to delete (name or ID)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--force',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_("Allow delete in state other than error or available")
|
||||
help=_("Allow delete in state other than error or available"),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -200,19 +200,25 @@ class DeleteVolumeBackup(command.Command):
|
||||
for i in parsed_args.backups:
|
||||
try:
|
||||
backup_id = utils.find_resource(
|
||||
volume_client.backups, i,
|
||||
volume_client.backups,
|
||||
i,
|
||||
).id
|
||||
volume_client.backups.delete(backup_id, parsed_args.force)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete backup with "
|
||||
"name or ID '%(backup)s': %(e)s")
|
||||
% {'backup': i, 'e': e})
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to delete backup with "
|
||||
"name or ID '%(backup)s': %(e)s"
|
||||
)
|
||||
% {'backup': i, 'e': e}
|
||||
)
|
||||
|
||||
if result > 0:
|
||||
total = len(parsed_args.backups)
|
||||
msg = _("%(result)s of %(total)s backups failed to delete.") % {
|
||||
'result': result, 'total': total,
|
||||
'result': result,
|
||||
'total': total,
|
||||
}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
@ -226,19 +232,23 @@ class ListVolumeBackup(command.Lister):
|
||||
"--long",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help=_("List additional fields in output")
|
||||
help=_("List additional fields in output"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--name",
|
||||
metavar="<name>",
|
||||
help=_("Filters results by the backup name")
|
||||
help=_("Filters results by the backup name"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--status",
|
||||
metavar="<status>",
|
||||
choices=[
|
||||
'creating', 'available', 'deleting',
|
||||
'error', 'restoring', 'error_restoring',
|
||||
'creating',
|
||||
'available',
|
||||
'deleting',
|
||||
'error',
|
||||
'restoring',
|
||||
'error_restoring',
|
||||
],
|
||||
help=_(
|
||||
"Filters results by the backup status, one of: "
|
||||
@ -306,26 +316,31 @@ class ListVolumeBackup(command.Lister):
|
||||
pass
|
||||
|
||||
_VolumeIdColumn = functools.partial(
|
||||
VolumeIdColumn, volume_cache=volume_cache)
|
||||
VolumeIdColumn, volume_cache=volume_cache
|
||||
)
|
||||
|
||||
filter_volume_id = None
|
||||
if parsed_args.volume:
|
||||
try:
|
||||
filter_volume_id = utils.find_resource(
|
||||
volume_client.volumes, parsed_args.volume,
|
||||
volume_client.volumes,
|
||||
parsed_args.volume,
|
||||
).id
|
||||
except exceptions.CommandError:
|
||||
# Volume with that ID does not exist, but search for backups
|
||||
# for that volume nevertheless
|
||||
LOG.debug("No volume with ID %s existing, continuing to "
|
||||
"search for backups for that volume ID",
|
||||
parsed_args.volume)
|
||||
LOG.debug(
|
||||
"No volume with ID %s existing, continuing to "
|
||||
"search for backups for that volume ID",
|
||||
parsed_args.volume,
|
||||
)
|
||||
filter_volume_id = parsed_args.volume
|
||||
|
||||
marker_backup_id = None
|
||||
if parsed_args.marker:
|
||||
marker_backup_id = utils.find_resource(
|
||||
volume_client.backups, parsed_args.marker,
|
||||
volume_client.backups,
|
||||
parsed_args.marker,
|
||||
).id
|
||||
|
||||
search_opts = {
|
||||
@ -344,8 +359,11 @@ class ListVolumeBackup(command.Lister):
|
||||
column_headers,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s, columns, formatters={'volume_id': _VolumeIdColumn},
|
||||
) for s in data
|
||||
s,
|
||||
columns,
|
||||
formatters={'volume_id': _VolumeIdColumn},
|
||||
)
|
||||
for s in data
|
||||
),
|
||||
)
|
||||
|
||||
@ -358,7 +376,7 @@ class RestoreVolumeBackup(command.ShowOne):
|
||||
parser.add_argument(
|
||||
"backup",
|
||||
metavar="<backup>",
|
||||
help=_("Backup to restore (name or ID)")
|
||||
help=_("Backup to restore (name or ID)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"volume",
|
||||
@ -368,7 +386,7 @@ class RestoreVolumeBackup(command.ShowOne):
|
||||
"Volume to restore to "
|
||||
"(name or ID for existing volume, name only for new volume) "
|
||||
"(default to None)"
|
||||
)
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--force",
|
||||
@ -376,7 +394,7 @@ class RestoreVolumeBackup(command.ShowOne):
|
||||
help=_(
|
||||
"Restore the backup to an existing volume "
|
||||
"(default to False)"
|
||||
)
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -401,11 +419,13 @@ class RestoreVolumeBackup(command.ShowOne):
|
||||
msg = _(
|
||||
"Volume '%s' already exists; if you want to restore the "
|
||||
"backup to it you need to specify the '--force' option"
|
||||
) % parsed_args.volume
|
||||
raise exceptions.CommandError(msg)
|
||||
)
|
||||
raise exceptions.CommandError(msg % parsed_args.volume)
|
||||
|
||||
return volume_client.restores.restore(
|
||||
backup.id, volume_id, volume_name,
|
||||
backup.id,
|
||||
volume_id,
|
||||
volume_name,
|
||||
)
|
||||
|
||||
|
||||
@ -417,7 +437,7 @@ class SetVolumeBackup(command.Command):
|
||||
parser.add_argument(
|
||||
"backup",
|
||||
metavar="<backup>",
|
||||
help=_("Backup to modify (name or ID)")
|
||||
help=_("Backup to modify (name or ID)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
@ -471,14 +491,12 @@ class SetVolumeBackup(command.Command):
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
backup = utils.find_resource(
|
||||
volume_client.backups, parsed_args.backup)
|
||||
backup = utils.find_resource(volume_client.backups, parsed_args.backup)
|
||||
|
||||
result = 0
|
||||
if parsed_args.state:
|
||||
try:
|
||||
volume_client.backups.reset_state(
|
||||
backup.id, parsed_args.state)
|
||||
volume_client.backups.reset_state(backup.id, parsed_args.state)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set backup state: %s"), e)
|
||||
result += 1
|
||||
@ -553,7 +571,7 @@ class UnsetVolumeBackup(command.Command):
|
||||
parser.add_argument(
|
||||
'backup',
|
||||
metavar='<backup>',
|
||||
help=_('Backup to modify (name or ID)')
|
||||
help=_('Backup to modify (name or ID)'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--property',
|
||||
@ -577,8 +595,7 @@ class UnsetVolumeBackup(command.Command):
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
backup = utils.find_resource(
|
||||
volume_client.backups, parsed_args.backup)
|
||||
backup = utils.find_resource(volume_client.backups, parsed_args.backup)
|
||||
metadata = copy.deepcopy(backup.metadata)
|
||||
|
||||
for key in parsed_args.properties:
|
||||
@ -586,7 +603,8 @@ class UnsetVolumeBackup(command.Command):
|
||||
# ignore invalid properties but continue
|
||||
LOG.warning(
|
||||
"'%s' is not a valid property for backup '%s'",
|
||||
key, parsed_args.backup,
|
||||
key,
|
||||
parsed_args.backup,
|
||||
)
|
||||
continue
|
||||
|
||||
@ -607,13 +625,12 @@ class ShowVolumeBackup(command.ShowOne):
|
||||
parser.add_argument(
|
||||
"backup",
|
||||
metavar="<backup>",
|
||||
help=_("Backup to display (name or ID)")
|
||||
help=_("Backup to display (name or ID)"),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
backup = utils.find_resource(volume_client.backups,
|
||||
parsed_args.backup)
|
||||
backup = utils.find_resource(volume_client.backups, parsed_args.backup)
|
||||
backup._info.pop("links", None)
|
||||
return zip(*sorted(backup._info.items()))
|
||||
|
@ -25,23 +25,24 @@ class FailoverVolumeHost(command.Command):
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(FailoverVolumeHost, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"host",
|
||||
metavar="<host-name>",
|
||||
help=_("Name of volume host")
|
||||
"host", metavar="<host-name>", help=_("Name of volume host")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--volume-backend",
|
||||
metavar="<backend-id>",
|
||||
required=True,
|
||||
help=_("The ID of the volume backend replication "
|
||||
"target where the host will failover to (required)")
|
||||
help=_(
|
||||
"The ID of the volume backend replication "
|
||||
"target where the host will failover to (required)"
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
service_client = self.app.client_manager.volume
|
||||
service_client.services.failover_host(parsed_args.host,
|
||||
parsed_args.volume_backend)
|
||||
service_client.services.failover_host(
|
||||
parsed_args.host, parsed_args.volume_backend
|
||||
)
|
||||
|
||||
|
||||
class SetVolumeHost(command.Command):
|
||||
@ -50,20 +51,18 @@ class SetVolumeHost(command.Command):
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SetVolumeHost, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"host",
|
||||
metavar="<host-name>",
|
||||
help=_("Name of volume host")
|
||||
"host", metavar="<host-name>", help=_("Name of volume host")
|
||||
)
|
||||
enabled_group = parser.add_mutually_exclusive_group()
|
||||
enabled_group.add_argument(
|
||||
"--disable",
|
||||
action="store_true",
|
||||
help=_("Freeze and disable the specified volume host")
|
||||
help=_("Freeze and disable the specified volume host"),
|
||||
)
|
||||
enabled_group.add_argument(
|
||||
"--enable",
|
||||
action="store_true",
|
||||
help=_("Thaw and enable the specified volume host")
|
||||
help=_("Thaw and enable the specified volume host"),
|
||||
)
|
||||
return parser
|
||||
|
||||
|
@ -72,36 +72,44 @@ class CreateVolumeSnapshot(command.ShowOne):
|
||||
parser.add_argument(
|
||||
"--volume",
|
||||
metavar="<volume>",
|
||||
help=_("Volume to snapshot (name or ID) "
|
||||
"(default is <snapshot-name>)")
|
||||
help=_(
|
||||
"Volume to snapshot (name or ID) "
|
||||
"(default is <snapshot-name>)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--description",
|
||||
metavar="<description>",
|
||||
help=_("Description of the snapshot")
|
||||
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")
|
||||
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)"),
|
||||
help=_(
|
||||
"Set a property to this snapshot "
|
||||
"(repeat option to set multiple properties)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--remote-source",
|
||||
metavar="<key=value>",
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_("The attribute(s) of the existing remote volume snapshot "
|
||||
"(admin required) (repeat option to specify multiple "
|
||||
"attributes) e.g.: '--remote-source source-name=test_name "
|
||||
"--remote-source source-id=test_id'"),
|
||||
help=_(
|
||||
"The attribute(s) of the existing remote volume snapshot "
|
||||
"(admin required) (repeat option to specify multiple "
|
||||
"attributes) e.g.: '--remote-source source-name=test_name "
|
||||
"--remote-source source-id=test_id'"
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -110,14 +118,15 @@ class CreateVolumeSnapshot(command.ShowOne):
|
||||
volume = parsed_args.volume
|
||||
if not parsed_args.volume:
|
||||
volume = parsed_args.snapshot_name
|
||||
volume_id = utils.find_resource(
|
||||
volume_client.volumes, volume).id
|
||||
volume_id = utils.find_resource(volume_client.volumes, volume).id
|
||||
if parsed_args.remote_source:
|
||||
# Create a new snapshot from an existing remote snapshot source
|
||||
if parsed_args.force:
|
||||
msg = (_("'--force' option will not work when you create "
|
||||
"new volume snapshot from an existing remote "
|
||||
"volume snapshot"))
|
||||
msg = _(
|
||||
"'--force' option will not work when you create "
|
||||
"new volume snapshot from an existing remote "
|
||||
"volume snapshot"
|
||||
)
|
||||
LOG.warning(msg)
|
||||
snapshot = volume_client.volume_snapshots.manage(
|
||||
volume_id=volume_id,
|
||||
@ -136,8 +145,11 @@ class CreateVolumeSnapshot(command.ShowOne):
|
||||
metadata=parsed_args.property,
|
||||
)
|
||||
snapshot._info.update(
|
||||
{'properties':
|
||||
format_columns.DictColumn(snapshot._info.pop('metadata'))}
|
||||
{
|
||||
'properties': format_columns.DictColumn(
|
||||
snapshot._info.pop('metadata')
|
||||
)
|
||||
}
|
||||
)
|
||||
return zip(*sorted(snapshot._info.items()))
|
||||
|
||||
@ -151,13 +163,15 @@ class DeleteVolumeSnapshot(command.Command):
|
||||
"snapshots",
|
||||
metavar="<snapshot>",
|
||||
nargs="+",
|
||||
help=_("Snapshot(s) to delete (name or ID)")
|
||||
help=_("Snapshot(s) to delete (name or ID)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--force',
|
||||
action='store_true',
|
||||
help=_("Attempt forced removal of snapshot(s), "
|
||||
"regardless of state (defaults to False)")
|
||||
help=_(
|
||||
"Attempt forced removal of snapshot(s), "
|
||||
"regardless of state (defaults to False)"
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -168,19 +182,26 @@ class DeleteVolumeSnapshot(command.Command):
|
||||
for i in parsed_args.snapshots:
|
||||
try:
|
||||
snapshot_id = utils.find_resource(
|
||||
volume_client.volume_snapshots, i).id
|
||||
volume_client.volume_snapshots, i
|
||||
).id
|
||||
volume_client.volume_snapshots.delete(
|
||||
snapshot_id, parsed_args.force)
|
||||
snapshot_id, parsed_args.force
|
||||
)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete snapshot with "
|
||||
"name or ID '%(snapshot)s': %(e)s")
|
||||
% {'snapshot': i, 'e': e})
|
||||
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})
|
||||
msg = _(
|
||||
"%(result)s of %(total)s snapshots failed " "to delete."
|
||||
) % {'result': result, 'total': total}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
@ -198,7 +219,7 @@ class ListVolumeSnapshot(command.Lister):
|
||||
parser.add_argument(
|
||||
'--project',
|
||||
metavar='<project>',
|
||||
help=_('Filter results by project (name or ID) (admin only)')
|
||||
help=_('Filter results by project (name or ID) (admin only)'),
|
||||
)
|
||||
identity_common.add_project_domain_option_to_parser(parser)
|
||||
parser.add_argument(
|
||||
@ -223,22 +244,29 @@ class ListVolumeSnapshot(command.Lister):
|
||||
'--name',
|
||||
metavar='<name>',
|
||||
default=None,
|
||||
help=_('Filters results by a name.')
|
||||
help=_('Filters results by a name.'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--status',
|
||||
metavar='<status>',
|
||||
choices=['available', 'error', 'creating', 'deleting',
|
||||
'error_deleting'],
|
||||
help=_("Filters results by a status. "
|
||||
"('available', 'error', 'creating', 'deleting'"
|
||||
" or 'error_deleting')")
|
||||
choices=[
|
||||
'available',
|
||||
'error',
|
||||
'creating',
|
||||
'deleting',
|
||||
'error_deleting',
|
||||
],
|
||||
help=_(
|
||||
"Filters results by a status. "
|
||||
"('available', 'error', 'creating', 'deleting'"
|
||||
" or 'error_deleting')"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--volume',
|
||||
metavar='<volume>',
|
||||
default=None,
|
||||
help=_('Filters results by a volume (name or ID).')
|
||||
help=_('Filters results by a volume (name or ID).'),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -247,8 +275,16 @@ class ListVolumeSnapshot(command.Lister):
|
||||
identity_client = self.app.client_manager.identity
|
||||
|
||||
if parsed_args.long:
|
||||
columns = ['ID', 'Name', 'Description', 'Status',
|
||||
'Size', 'Created At', 'Volume ID', 'Metadata']
|
||||
columns = [
|
||||
'ID',
|
||||
'Name',
|
||||
'Description',
|
||||
'Status',
|
||||
'Size',
|
||||
'Created At',
|
||||
'Volume ID',
|
||||
'Metadata',
|
||||
]
|
||||
column_headers = copy.deepcopy(columns)
|
||||
column_headers[6] = 'Volume'
|
||||
column_headers[7] = 'Properties'
|
||||
@ -264,24 +300,28 @@ class ListVolumeSnapshot(command.Lister):
|
||||
except Exception:
|
||||
# Just forget it if there's any trouble
|
||||
pass
|
||||
_VolumeIdColumn = functools.partial(VolumeIdColumn,
|
||||
volume_cache=volume_cache)
|
||||
_VolumeIdColumn = functools.partial(
|
||||
VolumeIdColumn, volume_cache=volume_cache
|
||||
)
|
||||
|
||||
volume_id = None
|
||||
if parsed_args.volume:
|
||||
volume_id = utils.find_resource(
|
||||
volume_client.volumes, parsed_args.volume).id
|
||||
volume_client.volumes, parsed_args.volume
|
||||
).id
|
||||
|
||||
project_id = None
|
||||
if parsed_args.project:
|
||||
project_id = identity_common.find_project(
|
||||
identity_client,
|
||||
parsed_args.project,
|
||||
parsed_args.project_domain).id
|
||||
parsed_args.project_domain,
|
||||
).id
|
||||
|
||||
# set value of 'all_tenants' when using project option
|
||||
all_projects = True if parsed_args.project else \
|
||||
parsed_args.all_projects
|
||||
all_projects = (
|
||||
True if parsed_args.project else parsed_args.all_projects
|
||||
)
|
||||
|
||||
search_opts = {
|
||||
'all_tenants': all_projects,
|
||||
@ -296,12 +336,20 @@ class ListVolumeSnapshot(command.Lister):
|
||||
marker=parsed_args.marker,
|
||||
limit=parsed_args.limit,
|
||||
)
|
||||
return (column_headers,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
formatters={'Metadata': format_columns.DictColumn,
|
||||
'Volume ID': _VolumeIdColumn},
|
||||
) for s in data))
|
||||
return (
|
||||
column_headers,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
formatters={
|
||||
'Metadata': format_columns.DictColumn,
|
||||
'Volume ID': _VolumeIdColumn,
|
||||
},
|
||||
)
|
||||
for s in data
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class SetVolumeSnapshot(command.Command):
|
||||
@ -312,51 +360,61 @@ class SetVolumeSnapshot(command.Command):
|
||||
parser.add_argument(
|
||||
'snapshot',
|
||||
metavar='<snapshot>',
|
||||
help=_('Snapshot to modify (name or ID)')
|
||||
help=_('Snapshot to modify (name or ID)'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
metavar='<name>',
|
||||
help=_('New snapshot name')
|
||||
'--name', metavar='<name>', help=_('New snapshot name')
|
||||
)
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
metavar='<description>',
|
||||
help=_('New snapshot description')
|
||||
help=_('New snapshot description'),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-property",
|
||||
dest="no_property",
|
||||
action="store_true",
|
||||
help=_("Remove all properties from <snapshot> "
|
||||
"(specify both --no-property and --property to "
|
||||
"remove the current properties before setting "
|
||||
"new properties.)"),
|
||||
help=_(
|
||||
"Remove all properties from <snapshot> "
|
||||
"(specify both --no-property and --property to "
|
||||
"remove the current properties before setting "
|
||||
"new properties.)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--property',
|
||||
metavar='<key=value>',
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_('Property to add/change for this snapshot '
|
||||
'(repeat option to set multiple properties)'),
|
||||
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)'),
|
||||
choices=[
|
||||
'available',
|
||||
'error',
|
||||
'creating',
|
||||
'deleting',
|
||||
'error_deleting',
|
||||
],
|
||||
help=_(
|
||||
'New snapshot state. ("available", "error", "creating", '
|
||||
'"deleting", or "error_deleting") (admin only) '
|
||||
'(This option simply changes the state of the snapshot '
|
||||
'in the database with no regard to actual status, '
|
||||
'exercise caution when using)'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
snapshot = utils.find_resource(volume_client.volume_snapshots,
|
||||
parsed_args.snapshot)
|
||||
snapshot = utils.find_resource(
|
||||
volume_client.volume_snapshots, parsed_args.snapshot
|
||||
)
|
||||
|
||||
result = 0
|
||||
if parsed_args.no_property:
|
||||
@ -373,7 +431,8 @@ class SetVolumeSnapshot(command.Command):
|
||||
if parsed_args.property:
|
||||
try:
|
||||
volume_client.volume_snapshots.set_metadata(
|
||||
snapshot.id, parsed_args.property)
|
||||
snapshot.id, parsed_args.property
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set snapshot property: %s"), e)
|
||||
result += 1
|
||||
@ -381,7 +440,8 @@ class SetVolumeSnapshot(command.Command):
|
||||
if parsed_args.state:
|
||||
try:
|
||||
volume_client.volume_snapshots.reset_state(
|
||||
snapshot.id, parsed_args.state)
|
||||
snapshot.id, parsed_args.state
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set snapshot state: %s"), e)
|
||||
result += 1
|
||||
@ -393,16 +453,18 @@ class SetVolumeSnapshot(command.Command):
|
||||
kwargs['description'] = parsed_args.description
|
||||
if kwargs:
|
||||
try:
|
||||
volume_client.volume_snapshots.update(
|
||||
snapshot.id, **kwargs)
|
||||
volume_client.volume_snapshots.update(snapshot.id, **kwargs)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to update snapshot name "
|
||||
"or description: %s"), 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"))
|
||||
raise exceptions.CommandError(
|
||||
_("One or more of the " "set operations failed")
|
||||
)
|
||||
|
||||
|
||||
class ShowVolumeSnapshot(command.ShowOne):
|
||||
@ -413,17 +475,21 @@ class ShowVolumeSnapshot(command.ShowOne):
|
||||
parser.add_argument(
|
||||
"snapshot",
|
||||
metavar="<snapshot>",
|
||||
help=_("Snapshot to display (name or ID)")
|
||||
help=_("Snapshot to display (name or ID)"),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
snapshot = utils.find_resource(
|
||||
volume_client.volume_snapshots, parsed_args.snapshot)
|
||||
volume_client.volume_snapshots, parsed_args.snapshot
|
||||
)
|
||||
snapshot._info.update(
|
||||
{'properties':
|
||||
format_columns.DictColumn(snapshot._info.pop('metadata'))}
|
||||
{
|
||||
'properties': format_columns.DictColumn(
|
||||
snapshot._info.pop('metadata')
|
||||
)
|
||||
}
|
||||
)
|
||||
return zip(*sorted(snapshot._info.items()))
|
||||
|
||||
@ -443,15 +509,18 @@ class UnsetVolumeSnapshot(command.Command):
|
||||
metavar='<key>',
|
||||
action='append',
|
||||
default=[],
|
||||
help=_('Property to remove from snapshot '
|
||||
'(repeat option to remove multiple properties)'),
|
||||
help=_(
|
||||
'Property to remove from snapshot '
|
||||
'(repeat option to remove multiple properties)'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
snapshot = utils.find_resource(
|
||||
volume_client.volume_snapshots, parsed_args.snapshot)
|
||||
volume_client.volume_snapshots, parsed_args.snapshot
|
||||
)
|
||||
|
||||
if parsed_args.property:
|
||||
volume_client.volume_snapshots.delete_metadata(
|
||||
|
@ -50,8 +50,7 @@ class AcceptTransferRequest(command.ShowOne):
|
||||
|
||||
try:
|
||||
transfer_request_id = utils.find_resource(
|
||||
volume_client.transfers,
|
||||
parsed_args.transfer_request
|
||||
volume_client.transfers, parsed_args.transfer_request
|
||||
).id
|
||||
except exceptions.CommandError:
|
||||
# Non-admin users will fail to lookup name -> ID so we just
|
||||
@ -160,14 +159,20 @@ class DeleteTransferRequest(command.Command):
|
||||
volume_client.transfers.delete(transfer_request_id)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete volume transfer request "
|
||||
"with name or ID '%(transfer)s': %(e)s")
|
||||
% {'transfer': t, 'e': e})
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to delete volume transfer request "
|
||||
"with name or ID '%(transfer)s': %(e)s"
|
||||
)
|
||||
% {'transfer': t, 'e': e}
|
||||
)
|
||||
|
||||
if result > 0:
|
||||
total = len(parsed_args.transfer_request)
|
||||
msg = (_("%(result)s of %(total)s volume transfer requests failed"
|
||||
" to delete") % {'result': result, 'total': total})
|
||||
msg = _(
|
||||
"%(result)s of %(total)s volume transfer requests failed"
|
||||
" to delete"
|
||||
) % {'result': result, 'total': total}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
@ -196,9 +201,13 @@ class ListTransferRequest(command.Lister):
|
||||
search_opts={'all_tenants': parsed_args.all_projects},
|
||||
)
|
||||
|
||||
return (column_headers, (
|
||||
utils.get_item_properties(s, columns)
|
||||
for s in volume_transfer_result))
|
||||
return (
|
||||
column_headers,
|
||||
(
|
||||
utils.get_item_properties(s, columns)
|
||||
for s in volume_transfer_result
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class ShowTransferRequest(command.ShowOne):
|
||||
|
@ -63,8 +63,10 @@ class EncryptionInfoColumn(cliff_columns.FormattableColumn):
|
||||
|
||||
def _create_encryption_type(volume_client, volume_type, parsed_args):
|
||||
if not parsed_args.encryption_provider:
|
||||
msg = _("'--encryption-provider' should be specified while "
|
||||
"creating a new encryption type")
|
||||
msg = _(
|
||||
"'--encryption-provider' should be specified while "
|
||||
"creating a new encryption type"
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
# set the default of control location while creating
|
||||
control_location = 'front-end'
|
||||
@ -74,10 +76,11 @@ def _create_encryption_type(volume_client, volume_type, parsed_args):
|
||||
'provider': parsed_args.encryption_provider,
|
||||
'cipher': parsed_args.encryption_cipher,
|
||||
'key_size': parsed_args.encryption_key_size,
|
||||
'control_location': control_location
|
||||
'control_location': control_location,
|
||||
}
|
||||
encryption = volume_client.volume_encryption_types.create(
|
||||
volume_type, body)
|
||||
volume_type, body
|
||||
)
|
||||
return encryption
|
||||
|
||||
|
||||
@ -93,10 +96,13 @@ def _set_encryption_type(volume_client, volume_type, parsed_args):
|
||||
except Exception as e:
|
||||
if type(e).__name__ == 'NotFound':
|
||||
# create new encryption type
|
||||
LOG.warning(_("No existing encryption type found, creating "
|
||||
"new encryption type for this volume type ..."))
|
||||
_create_encryption_type(
|
||||
volume_client, volume_type, parsed_args)
|
||||
LOG.warning(
|
||||
_(
|
||||
"No existing encryption type found, creating "
|
||||
"new encryption type for this volume type ..."
|
||||
)
|
||||
)
|
||||
_create_encryption_type(volume_client, volume_type, parsed_args)
|
||||
|
||||
|
||||
class CreateVolumeType(command.ShowOne):
|
||||
@ -131,50 +137,62 @@ class CreateVolumeType(command.ShowOne):
|
||||
'--property',
|
||||
metavar='<key=value>',
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_('Set a property on this volume type '
|
||||
'(repeat option to set multiple properties)'),
|
||||
help=_(
|
||||
'Set a property on this volume type '
|
||||
'(repeat option to set multiple properties)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--project',
|
||||
metavar='<project>',
|
||||
help=_("Allow <project> to access private type (name or ID) "
|
||||
"(Must be used with --private option)"),
|
||||
help=_(
|
||||
"Allow <project> to access private type (name or ID) "
|
||||
"(Must be used with --private option)"
|
||||
),
|
||||
)
|
||||
# TODO(Huanxuan Ao): Add choices for each "--encryption-*" option.
|
||||
parser.add_argument(
|
||||
'--encryption-provider',
|
||||
metavar='<provider>',
|
||||
help=_('Set the encryption provider format for '
|
||||
'this volume type (e.g "luks" or "plain") (admin only) '
|
||||
'(This option is required when setting encryption type '
|
||||
'of a volume. Consider using other encryption options '
|
||||
'such as: "--encryption-cipher", "--encryption-key-size" '
|
||||
'and "--encryption-control-location")'),
|
||||
help=_(
|
||||
'Set the encryption provider format for '
|
||||
'this volume type (e.g "luks" or "plain") (admin only) '
|
||||
'(This option is required when setting encryption type '
|
||||
'of a volume. Consider using other encryption options '
|
||||
'such as: "--encryption-cipher", "--encryption-key-size" '
|
||||
'and "--encryption-control-location")'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--encryption-cipher',
|
||||
metavar='<cipher>',
|
||||
help=_('Set the encryption algorithm or mode for this '
|
||||
'volume type (e.g "aes-xts-plain64") (admin only)'),
|
||||
help=_(
|
||||
'Set the encryption algorithm or mode for this '
|
||||
'volume type (e.g "aes-xts-plain64") (admin only)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--encryption-key-size',
|
||||
metavar='<key-size>',
|
||||
type=int,
|
||||
help=_('Set the size of the encryption key of this '
|
||||
'volume type (e.g "128" or "256") (admin only)'),
|
||||
help=_(
|
||||
'Set the size of the encryption key of this '
|
||||
'volume type (e.g "128" or "256") (admin only)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--encryption-control-location',
|
||||
metavar='<control-location>',
|
||||
choices=['front-end', 'back-end'],
|
||||
help=_('Set the notional service where the encryption is '
|
||||
'performed ("front-end" or "back-end") (admin only) '
|
||||
'(The default value for this option is "front-end" '
|
||||
'when setting encryption type of a volume. Consider '
|
||||
'using other encryption options such as: '
|
||||
'"--encryption-cipher", "--encryption-key-size" and '
|
||||
'"--encryption-provider")'),
|
||||
help=_(
|
||||
'Set the notional service where the encryption is '
|
||||
'performed ("front-end" or "back-end") (admin only) '
|
||||
'(The default value for this option is "front-end" '
|
||||
'when setting encryption type of a volume. Consider '
|
||||
'using other encryption options such as: '
|
||||
'"--encryption-cipher", "--encryption-key-size" and '
|
||||
'"--encryption-provider")'
|
||||
),
|
||||
)
|
||||
identity_common.add_project_domain_option_to_parser(parser)
|
||||
return parser
|
||||
@ -194,9 +212,7 @@ class CreateVolumeType(command.ShowOne):
|
||||
kwargs['is_public'] = False
|
||||
|
||||
volume_type = volume_client.volume_types.create(
|
||||
parsed_args.name,
|
||||
description=parsed_args.description,
|
||||
**kwargs
|
||||
parsed_args.name, description=parsed_args.description, **kwargs
|
||||
)
|
||||
volume_type._info.pop('extra_specs')
|
||||
|
||||
@ -208,30 +224,43 @@ class CreateVolumeType(command.ShowOne):
|
||||
parsed_args.project_domain,
|
||||
).id
|
||||
volume_client.volume_type_access.add_project_access(
|
||||
volume_type.id, project_id)
|
||||
volume_type.id, project_id
|
||||
)
|
||||
except Exception as e:
|
||||
msg = _("Failed to add project %(project)s access to "
|
||||
"type: %(e)s")
|
||||
msg = _(
|
||||
"Failed to add project %(project)s access to "
|
||||
"type: %(e)s"
|
||||
)
|
||||
LOG.error(msg % {'project': parsed_args.project, 'e': e})
|
||||
if parsed_args.property:
|
||||
result = volume_type.set_keys(parsed_args.property)
|
||||
volume_type._info.update(
|
||||
{'properties': format_columns.DictColumn(result)})
|
||||
if (parsed_args.encryption_provider or
|
||||
parsed_args.encryption_cipher or
|
||||
parsed_args.encryption_key_size or
|
||||
parsed_args.encryption_control_location):
|
||||
{'properties': format_columns.DictColumn(result)}
|
||||
)
|
||||
if (
|
||||
parsed_args.encryption_provider
|
||||
or parsed_args.encryption_cipher
|
||||
or parsed_args.encryption_key_size
|
||||
or parsed_args.encryption_control_location
|
||||
):
|
||||
try:
|
||||
# create new encryption
|
||||
encryption = _create_encryption_type(
|
||||
volume_client, volume_type, parsed_args)
|
||||
volume_client, volume_type, parsed_args
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set encryption information for this "
|
||||
"volume type: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to set encryption information for this "
|
||||
"volume type: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
# add encryption info in result
|
||||
encryption._info.pop("volume_type_id", None)
|
||||
volume_type._info.update(
|
||||
{'encryption': format_columns.DictColumn(encryption._info)})
|
||||
{'encryption': format_columns.DictColumn(encryption._info)}
|
||||
)
|
||||
volume_type._info.pop("os-volume-type-access:is_public", None)
|
||||
|
||||
return zip(*sorted(volume_type._info.items()))
|
||||
@ -246,7 +275,7 @@ class DeleteVolumeType(command.Command):
|
||||
"volume_types",
|
||||
metavar="<volume-type>",
|
||||
nargs="+",
|
||||
help=_("Volume type(s) to delete (name or ID)")
|
||||
help=_("Volume type(s) to delete (name or ID)"),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -256,20 +285,26 @@ class DeleteVolumeType(command.Command):
|
||||
|
||||
for volume_type in parsed_args.volume_types:
|
||||
try:
|
||||
vol_type = utils.find_resource(volume_client.volume_types,
|
||||
volume_type)
|
||||
vol_type = utils.find_resource(
|
||||
volume_client.volume_types, volume_type
|
||||
)
|
||||
|
||||
volume_client.volume_types.delete(vol_type)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete volume type with "
|
||||
"name or ID '%(volume_type)s': %(e)s")
|
||||
% {'volume_type': volume_type, 'e': e})
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to delete volume type with "
|
||||
"name or ID '%(volume_type)s': %(e)s"
|
||||
)
|
||||
% {'volume_type': volume_type, 'e': e}
|
||||
)
|
||||
|
||||
if result > 0:
|
||||
total = len(parsed_args.volume_types)
|
||||
msg = (_("%(result)s of %(total)s volume types failed "
|
||||
"to delete.") % {'result': result, 'total': total})
|
||||
msg = _(
|
||||
"%(result)s of %(total)s volume types failed " "to delete."
|
||||
) % {'result': result, 'total': total}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
@ -282,30 +317,30 @@ class ListVolumeType(command.Lister):
|
||||
'--long',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('List additional fields in output')
|
||||
help=_('List additional fields in output'),
|
||||
)
|
||||
public_group = parser.add_mutually_exclusive_group()
|
||||
public_group.add_argument(
|
||||
"--default",
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('List the default volume type')
|
||||
help=_('List the default volume type'),
|
||||
)
|
||||
public_group.add_argument(
|
||||
"--public",
|
||||
action="store_true",
|
||||
help=_("List only public types")
|
||||
"--public", action="store_true", help=_("List only public types")
|
||||
)
|
||||
public_group.add_argument(
|
||||
"--private",
|
||||
action="store_true",
|
||||
help=_("List only private types (admin only)")
|
||||
help=_("List only private types (admin only)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--encryption-type",
|
||||
action="store_true",
|
||||
help=_("Display encryption information for each volume type "
|
||||
"(admin only)"),
|
||||
help=_(
|
||||
"Display encryption information for each volume type "
|
||||
"(admin only)"
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -314,7 +349,12 @@ class ListVolumeType(command.Lister):
|
||||
if parsed_args.long:
|
||||
columns = ['ID', 'Name', 'Is Public', 'Description', 'Extra Specs']
|
||||
column_headers = [
|
||||
'ID', 'Name', 'Is Public', 'Description', 'Properties']
|
||||
'ID',
|
||||
'Name',
|
||||
'Is Public',
|
||||
'Description',
|
||||
'Properties',
|
||||
]
|
||||
else:
|
||||
columns = ['ID', 'Name', 'Is Public']
|
||||
column_headers = ['ID', 'Name', 'Is Public']
|
||||
@ -326,8 +366,7 @@ class ListVolumeType(command.Lister):
|
||||
is_public = True
|
||||
if parsed_args.private:
|
||||
is_public = False
|
||||
data = volume_client.volume_types.list(
|
||||
is_public=is_public)
|
||||
data = volume_client.volume_types.list(is_public=is_public)
|
||||
|
||||
formatters = {'Extra Specs': format_columns.DictColumn}
|
||||
|
||||
@ -341,7 +380,7 @@ class ListVolumeType(command.Lister):
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
'volume_type_id'
|
||||
'volume_type_id',
|
||||
]
|
||||
for key in del_key:
|
||||
d._info.pop(key, None)
|
||||
@ -354,14 +393,21 @@ class ListVolumeType(command.Lister):
|
||||
column_headers += ['Encryption']
|
||||
|
||||
_EncryptionInfoColumn = functools.partial(
|
||||
EncryptionInfoColumn, encryption_data=encryption)
|
||||
EncryptionInfoColumn, encryption_data=encryption
|
||||
)
|
||||
formatters['id'] = _EncryptionInfoColumn
|
||||
|
||||
return (column_headers,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
return (
|
||||
column_headers,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
formatters=formatters,
|
||||
) for s in data))
|
||||
)
|
||||
for s in data
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class SetVolumeType(command.Command):
|
||||
@ -388,52 +434,64 @@ class SetVolumeType(command.Command):
|
||||
'--property',
|
||||
metavar='<key=value>',
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_('Set a property on this volume type '
|
||||
'(repeat option to set multiple properties)'),
|
||||
help=_(
|
||||
'Set a property on this volume type '
|
||||
'(repeat option to set multiple properties)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--project',
|
||||
metavar='<project>',
|
||||
help=_('Set volume type access to project (name or ID) '
|
||||
'(admin only)'),
|
||||
help=_(
|
||||
'Set volume type access to project (name or ID) '
|
||||
'(admin only)'
|
||||
),
|
||||
)
|
||||
identity_common.add_project_domain_option_to_parser(parser)
|
||||
# TODO(Huanxuan Ao): Add choices for each "--encryption-*" option.
|
||||
parser.add_argument(
|
||||
'--encryption-provider',
|
||||
metavar='<provider>',
|
||||
help=_('Set the encryption provider format for '
|
||||
'this volume type (e.g "luks" or "plain") (admin only) '
|
||||
'(This option is required when setting encryption type '
|
||||
'of a volume for the first time. Consider using other '
|
||||
'encryption options such as: "--encryption-cipher", '
|
||||
'"--encryption-key-size" and '
|
||||
'"--encryption-control-location")'),
|
||||
help=_(
|
||||
'Set the encryption provider format for '
|
||||
'this volume type (e.g "luks" or "plain") (admin only) '
|
||||
'(This option is required when setting encryption type '
|
||||
'of a volume for the first time. Consider using other '
|
||||
'encryption options such as: "--encryption-cipher", '
|
||||
'"--encryption-key-size" and '
|
||||
'"--encryption-control-location")'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--encryption-cipher',
|
||||
metavar='<cipher>',
|
||||
help=_('Set the encryption algorithm or mode for this '
|
||||
'volume type (e.g "aes-xts-plain64") (admin only)'),
|
||||
help=_(
|
||||
'Set the encryption algorithm or mode for this '
|
||||
'volume type (e.g "aes-xts-plain64") (admin only)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--encryption-key-size',
|
||||
metavar='<key-size>',
|
||||
type=int,
|
||||
help=_('Set the size of the encryption key of this '
|
||||
'volume type (e.g "128" or "256") (admin only)'),
|
||||
help=_(
|
||||
'Set the size of the encryption key of this '
|
||||
'volume type (e.g "128" or "256") (admin only)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--encryption-control-location',
|
||||
metavar='<control-location>',
|
||||
choices=['front-end', 'back-end'],
|
||||
help=_('Set the notional service where the encryption is '
|
||||
'performed ("front-end" or "back-end") (admin only) '
|
||||
'(The default value for this option is "front-end" '
|
||||
'when setting encryption type of a volume for the '
|
||||
'first time. Consider using other encryption options '
|
||||
'such as: "--encryption-cipher", "--encryption-key-size" '
|
||||
'and "--encryption-provider")'),
|
||||
help=_(
|
||||
'Set the notional service where the encryption is '
|
||||
'performed ("front-end" or "back-end") (admin only) '
|
||||
'(The default value for this option is "front-end" '
|
||||
'when setting encryption type of a volume for the '
|
||||
'first time. Consider using other encryption options '
|
||||
'such as: "--encryption-cipher", "--encryption-key-size" '
|
||||
'and "--encryption-provider")'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -442,7 +500,8 @@ class SetVolumeType(command.Command):
|
||||
identity_client = self.app.client_manager.identity
|
||||
|
||||
volume_type = utils.find_resource(
|
||||
volume_client.volume_types, parsed_args.volume_type)
|
||||
volume_client.volume_types, parsed_args.volume_type
|
||||
)
|
||||
result = 0
|
||||
kwargs = {}
|
||||
if parsed_args.name:
|
||||
@ -452,13 +511,15 @@ class SetVolumeType(command.Command):
|
||||
|
||||
if kwargs:
|
||||
try:
|
||||
volume_client.volume_types.update(
|
||||
volume_type.id,
|
||||
**kwargs
|
||||
)
|
||||
volume_client.volume_types.update(volume_type.id, **kwargs)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to update volume type name or"
|
||||
" description: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to update volume type name or"
|
||||
" description: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
result += 1
|
||||
|
||||
if parsed_args.property:
|
||||
@ -474,29 +535,40 @@ class SetVolumeType(command.Command):
|
||||
project_info = identity_common.find_project(
|
||||
identity_client,
|
||||
parsed_args.project,
|
||||
parsed_args.project_domain)
|
||||
parsed_args.project_domain,
|
||||
)
|
||||
|
||||
volume_client.volume_type_access.add_project_access(
|
||||
volume_type.id, project_info.id)
|
||||
volume_type.id, project_info.id
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set volume type access to "
|
||||
"project: %s"), e)
|
||||
LOG.error(
|
||||
_("Failed to set volume type access to " "project: %s"), e
|
||||
)
|
||||
result += 1
|
||||
|
||||
if (parsed_args.encryption_provider or
|
||||
parsed_args.encryption_cipher or
|
||||
parsed_args.encryption_key_size or
|
||||
parsed_args.encryption_control_location):
|
||||
if (
|
||||
parsed_args.encryption_provider
|
||||
or parsed_args.encryption_cipher
|
||||
or parsed_args.encryption_key_size
|
||||
or parsed_args.encryption_control_location
|
||||
):
|
||||
try:
|
||||
_set_encryption_type(volume_client, volume_type, parsed_args)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set encryption information for this "
|
||||
"volume type: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to set encryption information for this "
|
||||
"volume type: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
result += 1
|
||||
|
||||
if result > 0:
|
||||
raise exceptions.CommandError(_("Command Failed: One or more of"
|
||||
" the operations failed"))
|
||||
raise exceptions.CommandError(
|
||||
_("Command Failed: One or more of" " the operations failed")
|
||||
)
|
||||
|
||||
|
||||
class ShowVolumeType(command.ShowOne):
|
||||
@ -507,50 +579,65 @@ class ShowVolumeType(command.ShowOne):
|
||||
parser.add_argument(
|
||||
"volume_type",
|
||||
metavar="<volume-type>",
|
||||
help=_("Volume type to display (name or ID)")
|
||||
help=_("Volume type to display (name or ID)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--encryption-type",
|
||||
action="store_true",
|
||||
help=_("Display encryption information of this volume type "
|
||||
"(admin only)"),
|
||||
help=_(
|
||||
"Display encryption information of this volume type "
|
||||
"(admin only)"
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
volume_type = utils.find_resource(
|
||||
volume_client.volume_types, parsed_args.volume_type)
|
||||
volume_client.volume_types, parsed_args.volume_type
|
||||
)
|
||||
properties = format_columns.DictColumn(
|
||||
volume_type._info.pop('extra_specs', {}))
|
||||
volume_type._info.pop('extra_specs', {})
|
||||
)
|
||||
volume_type._info.update({'properties': properties})
|
||||
access_project_ids = None
|
||||
if not volume_type.is_public:
|
||||
try:
|
||||
volume_type_access = volume_client.volume_type_access.list(
|
||||
volume_type.id)
|
||||
project_ids = [utils.get_field(item, 'project_id')
|
||||
for item in volume_type_access]
|
||||
volume_type.id
|
||||
)
|
||||
project_ids = [
|
||||
utils.get_field(item, 'project_id')
|
||||
for item in volume_type_access
|
||||
]
|
||||
# TODO(Rui Chen): This format list case can be removed after
|
||||
# patch https://review.opendev.org/#/c/330223/ merged.
|
||||
access_project_ids = format_columns.ListColumn(project_ids)
|
||||
except Exception as e:
|
||||
msg = _('Failed to get access project list for volume type '
|
||||
'%(type)s: %(e)s')
|
||||
msg = _(
|
||||
'Failed to get access project list for volume type '
|
||||
'%(type)s: %(e)s'
|
||||
)
|
||||
LOG.error(msg % {'type': volume_type.id, 'e': e})
|
||||
volume_type._info.update({'access_project_ids': access_project_ids})
|
||||
if parsed_args.encryption_type:
|
||||
# show encryption type information for this volume type
|
||||
try:
|
||||
encryption = volume_client.volume_encryption_types.get(
|
||||
volume_type.id)
|
||||
volume_type.id
|
||||
)
|
||||
encryption._info.pop("volume_type_id", None)
|
||||
volume_type._info.update(
|
||||
{'encryption':
|
||||
format_columns.DictColumn(encryption._info)})
|
||||
{'encryption': format_columns.DictColumn(encryption._info)}
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to display the encryption information "
|
||||
"of this volume type: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to display the encryption information "
|
||||
"of this volume type: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
volume_type._info.pop("os-volume-type-access:is_public", None)
|
||||
return zip(*sorted(volume_type._info.items()))
|
||||
|
||||
@ -569,21 +656,27 @@ class UnsetVolumeType(command.Command):
|
||||
'--property',
|
||||
metavar='<key>',
|
||||
action='append',
|
||||
help=_('Remove a property from this volume type '
|
||||
'(repeat option to remove multiple properties)'),
|
||||
help=_(
|
||||
'Remove a property from this volume type '
|
||||
'(repeat option to remove multiple properties)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--project',
|
||||
metavar='<project>',
|
||||
help=_('Removes volume type access to project (name or ID) '
|
||||
'(admin only)'),
|
||||
help=_(
|
||||
'Removes volume type access to project (name or ID) '
|
||||
'(admin only)'
|
||||
),
|
||||
)
|
||||
identity_common.add_project_domain_option_to_parser(parser)
|
||||
parser.add_argument(
|
||||
"--encryption-type",
|
||||
action="store_true",
|
||||
help=_("Remove the encryption type for this volume type "
|
||||
"(admin only)"),
|
||||
help=_(
|
||||
"Remove the encryption type for this volume type "
|
||||
"(admin only)"
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -610,22 +703,35 @@ class UnsetVolumeType(command.Command):
|
||||
project_info = identity_common.find_project(
|
||||
identity_client,
|
||||
parsed_args.project,
|
||||
parsed_args.project_domain)
|
||||
parsed_args.project_domain,
|
||||
)
|
||||
|
||||
volume_client.volume_type_access.remove_project_access(
|
||||
volume_type.id, project_info.id)
|
||||
volume_type.id, project_info.id
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to remove volume type access from "
|
||||
"project: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to remove volume type access from "
|
||||
"project: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
result += 1
|
||||
if parsed_args.encryption_type:
|
||||
try:
|
||||
volume_client.volume_encryption_types.delete(volume_type)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to remove the encryption type for this "
|
||||
"volume type: %s"), e)
|
||||
LOG.error(
|
||||
_(
|
||||
"Failed to remove the encryption type for this "
|
||||
"volume type: %s"
|
||||
),
|
||||
e,
|
||||
)
|
||||
result += 1
|
||||
|
||||
if result > 0:
|
||||
raise exceptions.CommandError(_("Command Failed: One or more of"
|
||||
" the operations failed"))
|
||||
raise exceptions.CommandError(
|
||||
_("Command Failed: One or more of" " the operations failed")
|
||||
)
|
||||
|
@ -31,8 +31,13 @@ def _format_cleanup_response(cleaning, unavailable):
|
||||
combined_data.append(details)
|
||||
|
||||
for obj in unavailable:
|
||||
details = (obj.id, obj.cluster_name, obj.host, obj.binary,
|
||||
'Unavailable')
|
||||
details = (
|
||||
obj.id,
|
||||
obj.cluster_name,
|
||||
obj.host,
|
||||
obj.binary,
|
||||
'Unavailable',
|
||||
)
|
||||
combined_data.append(details)
|
||||
|
||||
return (column_headers, combined_data)
|
||||
@ -49,20 +54,22 @@ class BlockStorageCleanup(command.Lister):
|
||||
parser.add_argument(
|
||||
'--cluster',
|
||||
metavar='<cluster>',
|
||||
help=_('Name of block storage cluster in which cleanup needs '
|
||||
'to be performed (name only)')
|
||||
help=_(
|
||||
'Name of block storage cluster in which cleanup needs '
|
||||
'to be performed (name only)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--host",
|
||||
metavar="<host>",
|
||||
default=None,
|
||||
help=_("Host where the service resides. (name only)")
|
||||
help=_("Host where the service resides. (name only)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--binary',
|
||||
metavar='<binary>',
|
||||
default=None,
|
||||
help=_("Name of the service binary.")
|
||||
help=_("Name of the service binary."),
|
||||
)
|
||||
service_up_parser = parser.add_mutually_exclusive_group()
|
||||
service_up_parser.add_argument(
|
||||
@ -72,7 +79,7 @@ class BlockStorageCleanup(command.Lister):
|
||||
default=None,
|
||||
help=_(
|
||||
'Filter by up status. If this is set, services need to be up.'
|
||||
)
|
||||
),
|
||||
)
|
||||
service_up_parser.add_argument(
|
||||
'--down',
|
||||
@ -81,7 +88,7 @@ class BlockStorageCleanup(command.Lister):
|
||||
help=_(
|
||||
'Filter by down status. If this is set, services need to be '
|
||||
'down.'
|
||||
)
|
||||
),
|
||||
)
|
||||
service_disabled_parser = parser.add_mutually_exclusive_group()
|
||||
service_disabled_parser.add_argument(
|
||||
@ -89,25 +96,25 @@ class BlockStorageCleanup(command.Lister):
|
||||
dest='disabled',
|
||||
action='store_true',
|
||||
default=None,
|
||||
help=_('Filter by disabled status.')
|
||||
help=_('Filter by disabled status.'),
|
||||
)
|
||||
service_disabled_parser.add_argument(
|
||||
'--enabled',
|
||||
dest='disabled',
|
||||
action='store_false',
|
||||
help=_('Filter by enabled status.')
|
||||
help=_('Filter by enabled status.'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--resource-id',
|
||||
metavar='<resource-id>',
|
||||
default=None,
|
||||
help=_('UUID of a resource to cleanup.')
|
||||
help=_('UUID of a resource to cleanup.'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--resource-type',
|
||||
metavar='<Volume|Snapshot>',
|
||||
choices=('Volume', 'Snapshot'),
|
||||
help=_('Type of resource to cleanup.')
|
||||
help=_('Type of resource to cleanup.'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--service-id',
|
||||
@ -116,7 +123,7 @@ class BlockStorageCleanup(command.Lister):
|
||||
help=_(
|
||||
'The service ID field from the DB, not the UUID of the '
|
||||
'service.'
|
||||
)
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -138,7 +145,7 @@ class BlockStorageCleanup(command.Lister):
|
||||
'disabled': parsed_args.disabled,
|
||||
'resource_id': parsed_args.resource_id,
|
||||
'resource_type': parsed_args.resource_type,
|
||||
'service_id': parsed_args.service_id
|
||||
'service_id': parsed_args.service_id,
|
||||
}
|
||||
|
||||
filters = {k: v for k, v in filters.items() if v is not None}
|
||||
|
@ -76,7 +76,9 @@ class ListBlockStorageCluster(command.Lister):
|
||||
def get_parser(self, prog_name):
|
||||
parser = super().get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--cluster', metavar='<name>', default=None,
|
||||
'--cluster',
|
||||
metavar='<name>',
|
||||
default=None,
|
||||
help=_(
|
||||
'Filter by cluster name, without backend will list '
|
||||
'all clustered services from the same cluster.'
|
||||
@ -131,7 +133,7 @@ class ListBlockStorageCluster(command.Lister):
|
||||
'--long',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_("List additional fields in output")
|
||||
help=_("List additional fields in output"),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -183,7 +185,7 @@ class SetBlockStorageCluster(command.Command):
|
||||
parser.add_argument(
|
||||
'cluster',
|
||||
metavar='<cluster>',
|
||||
help=_('Name of block storage cluster to update (name only)')
|
||||
help=_('Name of block storage cluster to update (name only)'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--binary',
|
||||
@ -192,7 +194,7 @@ class SetBlockStorageCluster(command.Command):
|
||||
help=_(
|
||||
"Name of binary to filter by; defaults to 'cinder-volume' "
|
||||
"(optional)"
|
||||
)
|
||||
),
|
||||
)
|
||||
enabled_group = parser.add_mutually_exclusive_group()
|
||||
enabled_group.add_argument(
|
||||
@ -200,13 +202,13 @@ class SetBlockStorageCluster(command.Command):
|
||||
action='store_false',
|
||||
dest='disabled',
|
||||
default=None,
|
||||
help=_('Enable cluster')
|
||||
help=_('Enable cluster'),
|
||||
)
|
||||
enabled_group.add_argument(
|
||||
'--disable',
|
||||
action='store_true',
|
||||
dest='disabled',
|
||||
help=_('Disable cluster')
|
||||
help=_('Disable cluster'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--disable-reason',
|
||||
@ -215,7 +217,7 @@ class SetBlockStorageCluster(command.Command):
|
||||
help=_(
|
||||
'Reason for disabling the cluster '
|
||||
'(should be used with --disable option)'
|
||||
)
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
|
@ -34,8 +34,10 @@ class BlockStorageLogLevelList(command.Lister):
|
||||
"--host",
|
||||
metavar="<host>",
|
||||
default="",
|
||||
help=_("List block storage service log level of specified host "
|
||||
"(name only)")
|
||||
help=_(
|
||||
"List block storage service log level of specified host "
|
||||
"(name only)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--service",
|
||||
@ -47,15 +49,18 @@ class BlockStorageLogLevelList(command.Lister):
|
||||
'cinder-api',
|
||||
'cinder-volume',
|
||||
'cinder-scheduler',
|
||||
'cinder-backup'),
|
||||
help=_("List block storage service log level of the specified "
|
||||
"service (name only)")
|
||||
'cinder-backup',
|
||||
),
|
||||
help=_(
|
||||
"List block storage service log level of the specified "
|
||||
"service (name only)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--log-prefix",
|
||||
metavar="<log-prefix>",
|
||||
default="",
|
||||
help="Prefix for the log, e.g. 'sqlalchemy'"
|
||||
help="Prefix for the log, e.g. 'sqlalchemy'",
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -78,12 +83,19 @@ class BlockStorageLogLevelList(command.Lister):
|
||||
data = service_client.services.get_log_levels(
|
||||
binary=parsed_args.service,
|
||||
server=parsed_args.host,
|
||||
prefix=parsed_args.log_prefix)
|
||||
prefix=parsed_args.log_prefix,
|
||||
)
|
||||
|
||||
return (columns,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
) for s in data))
|
||||
return (
|
||||
columns,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
)
|
||||
for s in data
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class BlockStorageLogLevelSet(command.Command):
|
||||
@ -99,14 +111,16 @@ class BlockStorageLogLevelSet(command.Command):
|
||||
metavar="<log-level>",
|
||||
choices=('INFO', 'WARNING', 'ERROR', 'DEBUG'),
|
||||
type=str.upper,
|
||||
help=_("Desired log level.")
|
||||
help=_("Desired log level."),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--host",
|
||||
metavar="<host>",
|
||||
default="",
|
||||
help=_("Set block storage service log level of specified host "
|
||||
"(name only)")
|
||||
help=_(
|
||||
"Set block storage service log level of specified host "
|
||||
"(name only)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--service",
|
||||
@ -118,15 +132,18 @@ class BlockStorageLogLevelSet(command.Command):
|
||||
'cinder-api',
|
||||
'cinder-volume',
|
||||
'cinder-scheduler',
|
||||
'cinder-backup'),
|
||||
help=_("Set block storage service log level of specified service "
|
||||
"(name only)")
|
||||
'cinder-backup',
|
||||
),
|
||||
help=_(
|
||||
"Set block storage service log level of specified service "
|
||||
"(name only)"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--log-prefix",
|
||||
metavar="<log-prefix>",
|
||||
default="",
|
||||
help="Prefix for the log, e.g. 'sqlalchemy'"
|
||||
help="Prefix for the log, e.g. 'sqlalchemy'",
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -144,4 +161,5 @@ class BlockStorageLogLevelSet(command.Command):
|
||||
level=parsed_args.level,
|
||||
binary=parsed_args.service,
|
||||
server=parsed_args.host,
|
||||
prefix=parsed_args.log_prefix)
|
||||
prefix=parsed_args.log_prefix,
|
||||
)
|
||||
|
@ -38,50 +38,61 @@ class BlockStorageManageVolumes(command.Lister):
|
||||
"host",
|
||||
metavar="<host>",
|
||||
nargs='?',
|
||||
help=_('Cinder host on which to list manageable volumes. '
|
||||
'Takes the form: host@backend-name#pool')
|
||||
help=_(
|
||||
'Cinder host on which to list manageable volumes. '
|
||||
'Takes the form: host@backend-name#pool'
|
||||
),
|
||||
)
|
||||
host_group.add_argument(
|
||||
"--cluster",
|
||||
metavar="<cluster>",
|
||||
help=_('Cinder cluster on which to list manageable volumes. '
|
||||
'Takes the form: cluster@backend-name#pool. '
|
||||
'(supported by --os-volume-api-version 3.17 or later)')
|
||||
help=_(
|
||||
'Cinder cluster on which to list manageable volumes. '
|
||||
'Takes the form: cluster@backend-name#pool. '
|
||||
'(supported by --os-volume-api-version 3.17 or later)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--detailed',
|
||||
metavar='<detailed>',
|
||||
default=True,
|
||||
help=_('Returns detailed information (Default=True).')
|
||||
help=_('Returns detailed information (Default=True).'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--marker',
|
||||
metavar='<marker>',
|
||||
default=None,
|
||||
help=_('Begin returning volumes that appear later in the volume '
|
||||
'list than that represented by this reference. This '
|
||||
'reference should be json like. Default=None.')
|
||||
help=_(
|
||||
'Begin returning volumes that appear later in the volume '
|
||||
'list than that represented by this reference. This '
|
||||
'reference should be json like. Default=None.'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--limit',
|
||||
metavar='<limit>',
|
||||
default=None,
|
||||
help=_('Maximum number of volumes to return. Default=None.')
|
||||
help=_('Maximum number of volumes to return. Default=None.'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--offset',
|
||||
metavar='<offset>',
|
||||
default=None,
|
||||
help=_('Number of volumes to skip after marker. Default=None.')
|
||||
help=_('Number of volumes to skip after marker. Default=None.'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--sort',
|
||||
metavar='<key>[:<direction>]',
|
||||
default=None,
|
||||
help=(_('Comma-separated list of sort keys and directions in the '
|
||||
help=(
|
||||
_(
|
||||
'Comma-separated list of sort keys and directions in the '
|
||||
'form of <key>[:<asc|desc>]. '
|
||||
'Valid keys: %s. '
|
||||
'Default=None.') % ', '.join(SORT_MANAGEABLE_KEY_VALUES))
|
||||
'Default=None.'
|
||||
)
|
||||
% ', '.join(SORT_MANAGEABLE_KEY_VALUES)
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -119,11 +130,13 @@ class BlockStorageManageVolumes(command.Lister):
|
||||
'safe_to_manage',
|
||||
]
|
||||
if detailed:
|
||||
columns.extend([
|
||||
'reason_not_safe',
|
||||
'cinder_id',
|
||||
'extra_info',
|
||||
])
|
||||
columns.extend(
|
||||
[
|
||||
'reason_not_safe',
|
||||
'cinder_id',
|
||||
'extra_info',
|
||||
]
|
||||
)
|
||||
|
||||
data = volume_client.volumes.list_manageable(
|
||||
host=parsed_args.host,
|
||||
@ -132,12 +145,19 @@ class BlockStorageManageVolumes(command.Lister):
|
||||
limit=parsed_args.limit,
|
||||
offset=parsed_args.offset,
|
||||
sort=parsed_args.sort,
|
||||
cluster=cluster)
|
||||
cluster=cluster,
|
||||
)
|
||||
|
||||
return (columns,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
) for s in data))
|
||||
return (
|
||||
columns,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
)
|
||||
for s in data
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class BlockStorageManageSnapshots(command.Lister):
|
||||
@ -153,50 +173,61 @@ class BlockStorageManageSnapshots(command.Lister):
|
||||
"host",
|
||||
metavar="<host>",
|
||||
nargs='?',
|
||||
help=_('Cinder host on which to list manageable snapshots. '
|
||||
'Takes the form: host@backend-name#pool')
|
||||
help=_(
|
||||
'Cinder host on which to list manageable snapshots. '
|
||||
'Takes the form: host@backend-name#pool'
|
||||
),
|
||||
)
|
||||
host_group.add_argument(
|
||||
"--cluster",
|
||||
metavar="<cluster>",
|
||||
help=_('Cinder cluster on which to list manageable snapshots. '
|
||||
'Takes the form: cluster@backend-name#pool. '
|
||||
'(supported by --os-volume-api-version 3.17 or later)')
|
||||
help=_(
|
||||
'Cinder cluster on which to list manageable snapshots. '
|
||||
'Takes the form: cluster@backend-name#pool. '
|
||||
'(supported by --os-volume-api-version 3.17 or later)'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--detailed',
|
||||
metavar='<detailed>',
|
||||
default=True,
|
||||
help=_('Returns detailed information (Default=True).')
|
||||
help=_('Returns detailed information (Default=True).'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--marker',
|
||||
metavar='<marker>',
|
||||
default=None,
|
||||
help=_('Begin returning snapshots that appear later in the '
|
||||
'snapshot list than that represented by this reference. '
|
||||
'This reference should be json like. Default=None.')
|
||||
help=_(
|
||||
'Begin returning snapshots that appear later in the '
|
||||
'snapshot list than that represented by this reference. '
|
||||
'This reference should be json like. Default=None.'
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--limit',
|
||||
metavar='<limit>',
|
||||
default=None,
|
||||
help=_('Maximum number of snapshots to return. Default=None.')
|
||||
help=_('Maximum number of snapshots to return. Default=None.'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--offset',
|
||||
metavar='<offset>',
|
||||
default=None,
|
||||
help=_('Number of snapshots to skip after marker. Default=None.')
|
||||
help=_('Number of snapshots to skip after marker. Default=None.'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--sort',
|
||||
metavar='<key>[:<direction>]',
|
||||
default=None,
|
||||
help=(_('Comma-separated list of sort keys and directions in the '
|
||||
help=(
|
||||
_(
|
||||
'Comma-separated list of sort keys and directions in the '
|
||||
'form of <key>[:<asc|desc>]. '
|
||||
'Valid keys: %s. '
|
||||
'Default=None.') % ', '.join(SORT_MANAGEABLE_KEY_VALUES))
|
||||
'Default=None.'
|
||||
)
|
||||
% ', '.join(SORT_MANAGEABLE_KEY_VALUES)
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -237,11 +268,13 @@ class BlockStorageManageSnapshots(command.Lister):
|
||||
'source_reference',
|
||||
]
|
||||
if detailed:
|
||||
columns.extend([
|
||||
'reason_not_safe',
|
||||
'cinder_id',
|
||||
'extra_info',
|
||||
])
|
||||
columns.extend(
|
||||
[
|
||||
'reason_not_safe',
|
||||
'cinder_id',
|
||||
'extra_info',
|
||||
]
|
||||
)
|
||||
|
||||
data = volume_client.volume_snapshots.list_manageable(
|
||||
host=parsed_args.host,
|
||||
@ -250,9 +283,16 @@ class BlockStorageManageSnapshots(command.Lister):
|
||||
limit=parsed_args.limit,
|
||||
offset=parsed_args.offset,
|
||||
sort=parsed_args.sort,
|
||||
cluster=cluster)
|
||||
cluster=cluster,
|
||||
)
|
||||
|
||||
return (columns,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
) for s in data))
|
||||
return (
|
||||
columns,
|
||||
(
|
||||
utils.get_item_properties(
|
||||
s,
|
||||
columns,
|
||||
)
|
||||
for s in data
|
||||
),
|
||||
)
|
||||
|
@ -42,7 +42,7 @@ class ListBlockStorageResourceFilter(command.Lister):
|
||||
|
||||
return (
|
||||
column_headers,
|
||||
(utils.get_item_properties(s, column_headers) for s in data)
|
||||
(utils.get_item_properties(s, column_headers) for s in data),
|
||||
)
|
||||
|
||||
|
||||
@ -54,7 +54,7 @@ class ShowBlockStorageResourceFilter(command.ShowOne):
|
||||
parser.add_argument(
|
||||
'resource',
|
||||
metavar='<resource>',
|
||||
help=_('Resource to show filters for (name).')
|
||||
help=_('Resource to show filters for (name).'),
|
||||
)
|
||||
|
||||
return parser
|
||||
|
@ -42,7 +42,6 @@ class VolumeSummary(command.ShowOne):
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
|
||||
volume_client = self.app.client_manager.volume
|
||||
|
||||
if volume_client.api_version < api_versions.APIVersion('3.12'):
|
||||
@ -89,13 +88,14 @@ class VolumeRevertToSnapshot(command.Command):
|
||||
parser.add_argument(
|
||||
'snapshot',
|
||||
metavar="<snapshot>",
|
||||
help=_('Name or ID of the snapshot to restore. The snapshot must '
|
||||
'be the most recent one known to cinder.'),
|
||||
help=_(
|
||||
'Name or ID of the snapshot to restore. The snapshot must '
|
||||
'be the most recent one known to cinder.'
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
|
||||
volume_client = self.app.client_manager.volume
|
||||
|
||||
if volume_client.api_version < api_versions.APIVersion('3.40'):
|
||||
@ -106,9 +106,10 @@ class VolumeRevertToSnapshot(command.Command):
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
snapshot = utils.find_resource(
|
||||
volume_client.volume_snapshots, parsed_args.snapshot)
|
||||
volume = utils.find_resource(
|
||||
volume_client.volumes, snapshot.volume_id)
|
||||
volume_client.volume_snapshots, parsed_args.snapshot
|
||||
)
|
||||
volume = utils.find_resource(volume_client.volumes, snapshot.volume_id)
|
||||
|
||||
volume_client.volumes.revert_to_snapshot(
|
||||
volume=volume, snapshot=snapshot)
|
||||
volume=volume, snapshot=snapshot
|
||||
)
|
||||
|
@ -199,15 +199,17 @@ class CreateVolumeAttachment(command.ShowOne):
|
||||
'mountpoint': parsed_args.mountpoint,
|
||||
}
|
||||
else:
|
||||
if any({
|
||||
parsed_args.initiator,
|
||||
parsed_args.ip,
|
||||
parsed_args.platform,
|
||||
parsed_args.host,
|
||||
parsed_args.host,
|
||||
parsed_args.multipath,
|
||||
parsed_args.mountpoint,
|
||||
}):
|
||||
if any(
|
||||
{
|
||||
parsed_args.initiator,
|
||||
parsed_args.ip,
|
||||
parsed_args.platform,
|
||||
parsed_args.host,
|
||||
parsed_args.host,
|
||||
parsed_args.multipath,
|
||||
parsed_args.mountpoint,
|
||||
}
|
||||
):
|
||||
msg = _(
|
||||
'You must specify the --connect option for any of the '
|
||||
'connection-specific options such as --initiator to be '
|
||||
@ -225,7 +227,8 @@ class CreateVolumeAttachment(command.ShowOne):
|
||||
)
|
||||
|
||||
attachment = volume_client.attachments.create(
|
||||
volume.id, connector, server.id, parsed_args.mode)
|
||||
volume.id, connector, server.id, parsed_args.mode
|
||||
)
|
||||
|
||||
return _format_attachment(attachment)
|
||||
|
||||
@ -346,7 +349,8 @@ class SetVolumeAttachment(command.ShowOne):
|
||||
}
|
||||
|
||||
attachment = volume_client.attachments.update(
|
||||
parsed_args.attachment, connector)
|
||||
parsed_args.attachment, connector
|
||||
)
|
||||
|
||||
return _format_attachment(attachment)
|
||||
|
||||
@ -469,7 +473,8 @@ class ListVolumeAttachment(command.Lister):
|
||||
attachments = volume_client.attachments.list(
|
||||
search_opts=search_opts,
|
||||
marker=parsed_args.marker,
|
||||
limit=parsed_args.limit)
|
||||
limit=parsed_args.limit,
|
||||
)
|
||||
|
||||
column_headers = (
|
||||
'ID',
|
||||
@ -486,10 +491,7 @@ class ListVolumeAttachment(command.Lister):
|
||||
|
||||
return (
|
||||
column_headers,
|
||||
(
|
||||
utils.get_item_properties(a, columns)
|
||||
for a in attachments
|
||||
),
|
||||
(utils.get_item_properties(a, columns) for a in attachments),
|
||||
)
|
||||
|
||||
|
||||
|
@ -155,7 +155,7 @@ class CreateVolumeGroup(command.ShowOne):
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
metavar='<description>',
|
||||
help=_('Description of a volume group.')
|
||||
help=_('Description of a volume group.'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--availability-zone',
|
||||
@ -178,8 +178,10 @@ class CreateVolumeGroup(command.ShowOne):
|
||||
)
|
||||
self.log.warning(msg)
|
||||
|
||||
volume_group_type = parsed_args.volume_group_type or \
|
||||
parsed_args.volume_group_type_legacy
|
||||
volume_group_type = (
|
||||
parsed_args.volume_group_type
|
||||
or parsed_args.volume_group_type_legacy
|
||||
)
|
||||
volume_types = parsed_args.volume_types[:]
|
||||
volume_types.extend(parsed_args.volume_types_legacy)
|
||||
|
||||
@ -229,8 +231,10 @@ class CreateVolumeGroup(command.ShowOne):
|
||||
"[--source-group|--group-snapshot]' command"
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
if (parsed_args.source_group is None and
|
||||
parsed_args.group_snapshot is None):
|
||||
if (
|
||||
parsed_args.source_group is None
|
||||
and parsed_args.group_snapshot is None
|
||||
):
|
||||
msg = _(
|
||||
"Either --source-group <source_group> or "
|
||||
"'--group-snapshot <group_snapshot>' needs to be "
|
||||
@ -239,24 +243,28 @@ class CreateVolumeGroup(command.ShowOne):
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
if parsed_args.availability_zone:
|
||||
msg = _("'--availability-zone' option will not work "
|
||||
"if creating group from source.")
|
||||
msg = _(
|
||||
"'--availability-zone' option will not work "
|
||||
"if creating group from source."
|
||||
)
|
||||
self.log.warning(msg)
|
||||
|
||||
source_group = None
|
||||
if parsed_args.source_group:
|
||||
source_group = utils.find_resource(volume_client.groups,
|
||||
parsed_args.source_group)
|
||||
source_group = utils.find_resource(
|
||||
volume_client.groups, parsed_args.source_group
|
||||
)
|
||||
group_snapshot = None
|
||||
if parsed_args.group_snapshot:
|
||||
group_snapshot = utils.find_resource(
|
||||
volume_client.group_snapshots,
|
||||
parsed_args.group_snapshot)
|
||||
volume_client.group_snapshots, parsed_args.group_snapshot
|
||||
)
|
||||
group = volume_client.groups.create_from_src(
|
||||
group_snapshot.id if group_snapshot else None,
|
||||
source_group.id if source_group else None,
|
||||
parsed_args.name,
|
||||
parsed_args.description)
|
||||
parsed_args.description,
|
||||
)
|
||||
group = volume_client.groups.get(group.id)
|
||||
return _format_group(group)
|
||||
|
||||
@ -281,7 +289,7 @@ class DeleteVolumeGroup(command.Command):
|
||||
help=_(
|
||||
'Delete the volume group even if it contains volumes. '
|
||||
'This will delete any remaining volumes in the group.',
|
||||
)
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -300,8 +308,7 @@ class DeleteVolumeGroup(command.Command):
|
||||
parsed_args.group,
|
||||
)
|
||||
|
||||
volume_client.groups.delete(
|
||||
group.id, delete_volumes=parsed_args.force)
|
||||
volume_client.groups.delete(group.id, delete_volumes=parsed_args.force)
|
||||
|
||||
|
||||
class SetVolumeGroup(command.ShowOne):
|
||||
@ -436,8 +443,7 @@ class ListVolumeGroup(command.Lister):
|
||||
'all_tenants': parsed_args.all_projects,
|
||||
}
|
||||
|
||||
groups = volume_client.groups.list(
|
||||
search_opts=search_opts)
|
||||
groups = volume_client.groups.list(search_opts=search_opts)
|
||||
|
||||
column_headers = (
|
||||
'ID',
|
||||
@ -452,10 +458,7 @@ class ListVolumeGroup(command.Lister):
|
||||
|
||||
return (
|
||||
column_headers,
|
||||
(
|
||||
utils.get_item_properties(a, columns)
|
||||
for a in groups
|
||||
),
|
||||
(utils.get_item_properties(a, columns) for a in groups),
|
||||
)
|
||||
|
||||
|
||||
@ -551,8 +554,9 @@ class ShowVolumeGroup(command.ShowOne):
|
||||
group = volume_client.groups.show(group.id, **kwargs)
|
||||
|
||||
if parsed_args.show_replication_targets:
|
||||
replication_targets = \
|
||||
replication_targets = (
|
||||
volume_client.groups.list_replication_targets(group.id)
|
||||
)
|
||||
|
||||
group.replication_targets = replication_targets
|
||||
|
||||
@ -580,7 +584,7 @@ class FailoverVolumeGroup(command.Command):
|
||||
default=False,
|
||||
help=_(
|
||||
'Allow group with attached volumes to be failed over.',
|
||||
)
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--disallow-attached-volume',
|
||||
@ -589,7 +593,7 @@ class FailoverVolumeGroup(command.Command):
|
||||
default=False,
|
||||
help=_(
|
||||
'Disallow group with attached volumes to be failed over.',
|
||||
)
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--secondary-backend-id',
|
||||
|
@ -70,7 +70,7 @@ class CreateVolumeGroupSnapshot(command.ShowOne):
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
metavar='<description>',
|
||||
help=_('Description of a volume group snapshot.')
|
||||
help=_('Description of a volume group snapshot.'),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -90,9 +90,8 @@ class CreateVolumeGroupSnapshot(command.ShowOne):
|
||||
)
|
||||
|
||||
snapshot = volume_client.group_snapshots.create(
|
||||
volume_group.id,
|
||||
parsed_args.name,
|
||||
parsed_args.description)
|
||||
volume_group.id, parsed_args.name, parsed_args.description
|
||||
)
|
||||
|
||||
return _format_group_snapshot(snapshot)
|
||||
|
||||
@ -175,8 +174,7 @@ class ListVolumeGroupSnapshot(command.Lister):
|
||||
'all_tenants': parsed_args.all_projects,
|
||||
}
|
||||
|
||||
groups = volume_client.group_snapshots.list(
|
||||
search_opts=search_opts)
|
||||
groups = volume_client.group_snapshots.list(search_opts=search_opts)
|
||||
|
||||
column_headers = (
|
||||
'ID',
|
||||
@ -191,10 +189,7 @@ class ListVolumeGroupSnapshot(command.Lister):
|
||||
|
||||
return (
|
||||
column_headers,
|
||||
(
|
||||
utils.get_item_properties(a, columns)
|
||||
for a in groups
|
||||
),
|
||||
(utils.get_item_properties(a, columns) for a in groups),
|
||||
)
|
||||
|
||||
|
||||
|
@ -70,7 +70,7 @@ class CreateVolumeGroupType(command.ShowOne):
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
metavar='<description>',
|
||||
help=_('Description of the volume group type.')
|
||||
help=_('Description of the volume group type.'),
|
||||
)
|
||||
type_group = parser.add_mutually_exclusive_group()
|
||||
type_group.add_argument(
|
||||
@ -86,7 +86,7 @@ class CreateVolumeGroupType(command.ShowOne):
|
||||
'--private',
|
||||
dest='is_public',
|
||||
action='store_false',
|
||||
help=_('Volume group type is not available to other projects')
|
||||
help=_('Volume group type is not available to other projects'),
|
||||
)
|
||||
return parser
|
||||
|
||||
@ -101,9 +101,8 @@ class CreateVolumeGroupType(command.ShowOne):
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
group_type = volume_client.group_types.create(
|
||||
parsed_args.name,
|
||||
parsed_args.description,
|
||||
parsed_args.is_public)
|
||||
parsed_args.name, parsed_args.description, parsed_args.is_public
|
||||
)
|
||||
|
||||
return _format_group_type(group_type)
|
||||
|
||||
@ -176,7 +175,7 @@ class SetVolumeGroupType(command.ShowOne):
|
||||
'--private',
|
||||
dest='is_public',
|
||||
action='store_false',
|
||||
help=_('Make volume group type unavailable to other projects.')
|
||||
help=_('Make volume group type unavailable to other projects.'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--no-property',
|
||||
@ -230,7 +229,8 @@ class SetVolumeGroupType(command.ShowOne):
|
||||
if kwargs:
|
||||
try:
|
||||
group_type = volume_client.group_types.update(
|
||||
group_type.id, **kwargs)
|
||||
group_type.id, **kwargs
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to update group type: %s"), e)
|
||||
errors += 1
|
||||
@ -251,9 +251,7 @@ class SetVolumeGroupType(command.ShowOne):
|
||||
errors += 1
|
||||
|
||||
if errors > 0:
|
||||
msg = _(
|
||||
"Command Failed: One or more of the operations failed"
|
||||
)
|
||||
msg = _("Command Failed: One or more of the operations failed")
|
||||
raise exceptions.CommandError()
|
||||
|
||||
return _format_group_type(group_type)
|
||||
@ -370,10 +368,7 @@ class ListVolumeGroupType(command.Lister):
|
||||
|
||||
return (
|
||||
column_headers,
|
||||
(
|
||||
utils.get_item_properties(a, columns)
|
||||
for a in group_types
|
||||
),
|
||||
(utils.get_item_properties(a, columns) for a in group_types),
|
||||
)
|
||||
|
||||
|
||||
|
@ -34,7 +34,7 @@ class DeleteMessage(command.Command):
|
||||
'message_ids',
|
||||
metavar='<message-id>',
|
||||
nargs='+',
|
||||
help=_('Message(s) to delete (ID)')
|
||||
help=_('Message(s) to delete (ID)'),
|
||||
)
|
||||
|
||||
return parser
|
||||
@ -60,7 +60,8 @@ class DeleteMessage(command.Command):
|
||||
if errors > 0:
|
||||
total = len(parsed_args.message_ids)
|
||||
msg = _('Failed to delete %(errors)s of %(total)s messages.') % {
|
||||
'errors': errors, 'total': total,
|
||||
'errors': errors,
|
||||
'total': total,
|
||||
}
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
@ -121,7 +122,8 @@ class ListMessages(command.Lister):
|
||||
project_id = identity_common.find_project(
|
||||
identity_client,
|
||||
parsed_args.project,
|
||||
parsed_args.project_domain).id
|
||||
parsed_args.project_domain,
|
||||
).id
|
||||
|
||||
search_opts = {
|
||||
'project_id': project_id,
|
||||
@ -129,11 +131,12 @@ class ListMessages(command.Lister):
|
||||
data = volume_client.messages.list(
|
||||
search_opts=search_opts,
|
||||
marker=parsed_args.marker,
|
||||
limit=parsed_args.limit)
|
||||
limit=parsed_args.limit,
|
||||
)
|
||||
|
||||
return (
|
||||
column_headers,
|
||||
(utils.get_item_properties(s, column_headers) for s in data)
|
||||
(utils.get_item_properties(s, column_headers) for s in data),
|
||||
)
|
||||
|
||||
|
||||
@ -145,7 +148,7 @@ class ShowMessage(command.ShowOne):
|
||||
parser.add_argument(
|
||||
'message_id',
|
||||
metavar='<message-id>',
|
||||
help=_('Message to show (ID).')
|
||||
help=_('Message to show (ID).'),
|
||||
)
|
||||
|
||||
return parser
|
||||
|
Loading…
x
Reference in New Issue
Block a user