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:
Stephen Finucane 2023-05-08 10:54:22 +01:00
parent 28ffa2bf9f
commit 35ba1d8f13
84 changed files with 5338 additions and 4437 deletions

View File

@ -16,11 +16,18 @@ from openstackclient.tests.functional import base
class BaseVolumeTests(base.TestCase): class BaseVolumeTests(base.TestCase):
"""Base class for Volume functional tests. """ """Base class for Volume functional tests."""
@classmethod @classmethod
def wait_for_status(cls, check_type, check_name, desired_status, def wait_for_status(
wait=120, interval=5, failures=None): cls,
check_type,
check_name,
desired_status,
wait=120,
interval=5,
failures=None,
):
current_status = "notset" current_status = "notset"
if failures is None: if failures is None:
failures = ['error'] failures = ['error']
@ -32,23 +39,31 @@ class BaseVolumeTests(base.TestCase):
) )
current_status = output['status'] current_status = output['status']
if current_status == desired_status: if current_status == desired_status:
print('{} {} now has status {}' print(
.format(check_type, check_name, current_status)) '{} {} now has status {}'.format(
check_type, check_name, current_status
)
)
return return
print('Checking {} {} Waiting for {} current status: {}' print(
.format(check_type, check_name, 'Checking {} {} Waiting for {} current status: {}'.format(
desired_status, current_status)) check_type, check_name, desired_status, current_status
)
)
if current_status in failures: if current_status in failures:
raise Exception( raise Exception(
'Current status {} of {} {} is one of failures {}' 'Current status {} of {} {} is one of failures {}'.format(
.format(current_status, check_type, check_name, failures)) current_status, check_type, check_name, failures
)
)
time.sleep(interval) time.sleep(interval)
total_sleep += interval total_sleep += interval
cls.assertOutput(desired_status, current_status) cls.assertOutput(desired_status, current_status)
@classmethod @classmethod
def wait_for_delete(cls, check_type, check_name, wait=120, interval=5, def wait_for_delete(
name_field=None): cls, check_type, check_name, wait=120, interval=5, name_field=None
):
total_sleep = 0 total_sleep = 0
name_field = name_field or 'Name' name_field = name_field or 'Name'
while total_sleep < wait: while total_sleep < wait:
@ -57,9 +72,15 @@ class BaseVolumeTests(base.TestCase):
if check_name not in names: if check_name not in names:
print('{} {} is now deleted'.format(check_type, check_name)) print('{} {} is now deleted'.format(check_type, check_name))
return return
print('Checking {} {} Waiting for deleted' print(
.format(check_type, check_name)) 'Checking {} {} Waiting for deleted'.format(
check_type, check_name
)
)
time.sleep(interval) time.sleep(interval)
total_sleep += interval total_sleep += interval
raise Exception('Timeout: {} {} was not deleted in {} seconds' raise Exception(
.format(check_type, check_name, wait)) 'Timeout: {} {} was not deleted in {} seconds'.format(
check_type, check_name, wait
)
)

View File

@ -16,31 +16,23 @@ from openstackclient.tests.functional.volume.v1 import common
class QosTests(common.BaseVolumeTests): class QosTests(common.BaseVolumeTests):
"""Functional tests for volume qos. """ """Functional tests for volume qos."""
def test_volume_qos_create_list(self): def test_volume_qos_create_list(self):
"""Test create, list, delete multiple""" """Test create, list, delete multiple"""
name1 = uuid.uuid4().hex name1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos create ' + 'volume qos create ' + name1,
name1,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(name1, cmd_output['name'])
name1,
cmd_output['name']
)
name2 = uuid.uuid4().hex name2 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos create ' + 'volume qos create ' + name2,
name2,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(name2, cmd_output['name'])
name2,
cmd_output['name']
)
# Test list # Test list
cmd_output = self.openstack( cmd_output = self.openstack(
@ -60,67 +52,43 @@ class QosTests(common.BaseVolumeTests):
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos create ' + 'volume qos create ' + '--consumer front-end '
'--consumer front-end ' '--property Alpha=a ' + name,
'--property Alpha=a ' +
name,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.openstack, 'volume qos delete ' + name) self.addCleanup(self.openstack, 'volume qos delete ' + name)
self.assertEqual( self.assertEqual(name, cmd_output['name'])
name,
cmd_output['name']
)
self.assertEqual( self.assertEqual("front-end", cmd_output['consumer'])
"front-end",
cmd_output['consumer']
)
# Test volume qos set # Test volume qos set
raw_output = self.openstack( raw_output = self.openstack(
'volume qos set ' + 'volume qos set '
'--property Alpha=c ' + + '--property Alpha=c '
'--property Beta=b ' + + '--property Beta=b '
name, + name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
# Test volume qos show # Test volume qos show
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos show ' + 'volume qos show ' + name,
name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(name, cmd_output['name'])
name, self.assertEqual({'Alpha': 'c', 'Beta': 'b'}, cmd_output['properties'])
cmd_output['name']
)
self.assertEqual(
{'Alpha': 'c', 'Beta': 'b'},
cmd_output['properties']
)
# Test volume qos unset # Test volume qos unset
raw_output = self.openstack( raw_output = self.openstack(
'volume qos unset ' + 'volume qos unset ' + '--property Alpha ' + name,
'--property Alpha ' +
name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos show ' + 'volume qos show ' + name,
name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(name, cmd_output['name'])
name, self.assertEqual({'Beta': 'b'}, cmd_output['properties'])
cmd_output['name']
)
self.assertEqual(
{'Beta': 'b'},
cmd_output['properties']
)
# TODO(qiangjiahui): Add tests for associate and disassociate volume type # TODO(qiangjiahui): Add tests for associate and disassociate volume type

View File

@ -24,22 +24,16 @@ class VolumeServiceTests(common.BaseVolumeTests):
# Test volume service list --service # Test volume service list --service
cmd_output = self.openstack( cmd_output = self.openstack(
'volume service list ' + 'volume service list ' + '--service ' + services[0],
'--service ' +
services[0],
parse_output=True, parse_output=True,
) )
for x in cmd_output: for x in cmd_output:
self.assertEqual( self.assertEqual(services[0], x['Binary'])
services[0],
x['Binary']
)
# TODO(zhiyong.dai): test volume service list --host after solving # TODO(zhiyong.dai): test volume service list --host after solving
# https://bugs.launchpad.net/python-openstackclient/+bug/1664451 # https://bugs.launchpad.net/python-openstackclient/+bug/1664451
def test_volume_service_set(self): def test_volume_service_set(self):
# Get a service and host # Get a service and host
cmd_output = self.openstack( cmd_output = self.openstack(
'volume service list', 'volume service list',
@ -50,9 +44,7 @@ class VolumeServiceTests(common.BaseVolumeTests):
# Test volume service set --enable # Test volume service set --enable
raw_output = self.openstack( raw_output = self.openstack(
'volume service set --enable ' + 'volume service set --enable ' + host_1 + ' ' + service_1
host_1 + ' ' +
service_1
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
@ -60,20 +52,19 @@ class VolumeServiceTests(common.BaseVolumeTests):
'volume service list --long', 'volume service list --long',
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual('enabled', cmd_output[0]['Status'])
'enabled',
cmd_output[0]['Status']
)
self.assertIsNone(cmd_output[0]['Disabled Reason']) self.assertIsNone(cmd_output[0]['Disabled Reason'])
# Test volume service set --disable and --disable-reason # Test volume service set --disable and --disable-reason
disable_reason = 'disable_reason' disable_reason = 'disable_reason'
raw_output = self.openstack( raw_output = self.openstack(
'volume service set --disable ' + 'volume service set --disable '
'--disable-reason ' + + '--disable-reason '
disable_reason + ' ' + + disable_reason
host_1 + ' ' + + ' '
service_1 + host_1
+ ' '
+ service_1
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
@ -81,11 +72,5 @@ class VolumeServiceTests(common.BaseVolumeTests):
'volume service list --long', 'volume service list --long',
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual('disabled', cmd_output[0]['Status'])
'disabled', self.assertEqual(disable_reason, cmd_output[0]['Disabled Reason'])
cmd_output[0]['Status']
)
self.assertEqual(
disable_reason,
cmd_output[0]['Disabled Reason']
)

View File

@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v1 import common
class VolumeSnapshotTests(common.BaseVolumeTests): class VolumeSnapshotTests(common.BaseVolumeTests):
"""Functional tests for volume snapshot. """ """Functional tests for volume snapshot."""
VOLLY = uuid.uuid4().hex VOLLY = uuid.uuid4().hex
@ -25,9 +25,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
super(VolumeSnapshotTests, cls).setUpClass() super(VolumeSnapshotTests, cls).setUpClass()
# create a volume for all tests to create snapshot # create a volume for all tests to create snapshot
cmd_output = cls.openstack( cmd_output = cls.openstack(
'volume create ' + 'volume create ' + '--size 1 ' + cls.VOLLY,
'--size 1 ' +
cls.VOLLY,
parse_output=True, parse_output=True,
) )
cls.wait_for_status('volume', cls.VOLLY, 'available') cls.wait_for_status('volume', cls.VOLLY, 'available')
@ -46,9 +44,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
"""Test create, delete multiple""" """Test create, delete multiple"""
name1 = uuid.uuid4().hex name1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
name1 +
' --volume ' + self.VOLLY,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -58,9 +54,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
name2 = uuid.uuid4().hex name2 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
name2 +
' --volume ' + self.VOLLY,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -72,7 +66,8 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
self.wait_for_status('volume snapshot', name2, 'available') self.wait_for_status('volume snapshot', name2, 'available')
del_output = self.openstack( del_output = self.openstack(
'volume snapshot delete ' + name1 + ' ' + name2) 'volume snapshot delete ' + name1 + ' ' + name2
)
self.assertOutput('', del_output) self.assertOutput('', del_output)
self.wait_for_delete('volume snapshot', name1) self.wait_for_delete('volume snapshot', name1)
self.wait_for_delete('volume snapshot', name2) self.wait_for_delete('volume snapshot', name2)
@ -81,9 +76,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
"""Test create, list filter""" """Test create, list filter"""
name1 = uuid.uuid4().hex name1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
name1 +
' --volume ' + self.VOLLY,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.wait_for_delete, 'volume snapshot', name1) self.addCleanup(self.wait_for_delete, 'volume snapshot', name1)
@ -104,9 +97,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
name2 = uuid.uuid4().hex name2 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
name2 +
' --volume ' + self.VOLLY,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.wait_for_delete, 'volume snapshot', name2) self.addCleanup(self.wait_for_delete, 'volume snapshot', name2)
@ -127,9 +118,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test list --long, --status # Test list --long, --status
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot list ' + 'volume snapshot list ' + '--long ' + '--status error',
'--long ' +
'--status error',
parse_output=True, parse_output=True,
) )
names = [x["Name"] for x in cmd_output] names = [x["Name"] for x in cmd_output]
@ -138,8 +127,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test list --volume # Test list --volume
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot list ' + 'volume snapshot list ' + '--volume ' + self.VOLLY,
'--volume ' + self.VOLLY,
parse_output=True, parse_output=True,
) )
names = [x["Name"] for x in cmd_output] names = [x["Name"] for x in cmd_output]
@ -148,8 +136,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test list --name # Test list --name
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot list ' + 'volume snapshot list ' + '--name ' + name1,
'--name ' + name1,
parse_output=True, parse_output=True,
) )
names = [x["Name"] for x in cmd_output] names = [x["Name"] for x in cmd_output]
@ -161,10 +148,11 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
name = uuid.uuid4().hex name = uuid.uuid4().hex
new_name = name + "_" new_name = name + "_"
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create '
'--volume ' + self.VOLLY + + '--volume '
' --description aaaa ' + + self.VOLLY
name, + ' --description aaaa '
+ name,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.wait_for_delete, 'volume snapshot', new_name) self.addCleanup(self.wait_for_delete, 'volume snapshot', new_name)
@ -185,19 +173,19 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test volume snapshot set # Test volume snapshot set
raw_output = self.openstack( raw_output = self.openstack(
'volume snapshot set ' + 'volume snapshot set '
'--name ' + new_name + + '--name '
' --description bbbb ' + + new_name
'--property Alpha=a ' + + ' --description bbbb '
'--property Beta=b ' + + '--property Alpha=a '
name, + '--property Beta=b '
+ name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
# Show snapshot set result # Show snapshot set result
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot show ' + 'volume snapshot show ' + new_name,
new_name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -219,15 +207,12 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test volume unset # Test volume unset
raw_output = self.openstack( raw_output = self.openstack(
'volume snapshot unset ' + 'volume snapshot unset ' + '--property Alpha ' + new_name,
'--property Alpha ' +
new_name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot show ' + 'volume snapshot show ' + new_name,
new_name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -237,14 +222,11 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test volume snapshot set --no-property # Test volume snapshot set --no-property
raw_output = self.openstack( raw_output = self.openstack(
'volume snapshot set ' + 'volume snapshot set ' + '--no-property ' + new_name,
'--no-property ' +
new_name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot show ' + 'volume snapshot show ' + new_name,
new_name,
parse_output=True, parse_output=True,
) )
self.assertEqual({}, cmd_output["properties"]) self.assertEqual({}, cmd_output["properties"])

View File

@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v1 import common
class TransferRequestTests(common.BaseVolumeTests): class TransferRequestTests(common.BaseVolumeTests):
"""Functional tests for transfer request. """ """Functional tests for transfer request."""
NAME = uuid.uuid4().hex NAME = uuid.uuid4().hex
VOLUME_NAME = uuid.uuid4().hex VOLUME_NAME = uuid.uuid4().hex
@ -36,7 +36,8 @@ class TransferRequestTests(common.BaseVolumeTests):
def tearDownClass(cls): def tearDownClass(cls):
try: try:
raw_output_volume = cls.openstack( raw_output_volume = cls.openstack(
'volume delete ' + cls.VOLUME_NAME) 'volume delete ' + cls.VOLUME_NAME
)
cls.assertOutput('', raw_output_volume) cls.assertOutput('', raw_output_volume)
finally: finally:
super(TransferRequestTests, cls).tearDownClass() super(TransferRequestTests, cls).tearDownClass()
@ -55,9 +56,10 @@ class TransferRequestTests(common.BaseVolumeTests):
# create volume transfer request for the volume # create volume transfer request for the volume
# and get the auth_key of the new transfer request # and get the auth_key of the new transfer request
cmd_output = self.openstack( cmd_output = self.openstack(
'volume transfer request create ' + 'volume transfer request create '
volume_name + + volume_name
' --name ' + name, + ' --name '
+ name,
parse_output=True, parse_output=True,
) )
auth_key = cmd_output['auth_key'] auth_key = cmd_output['auth_key']
@ -65,30 +67,32 @@ class TransferRequestTests(common.BaseVolumeTests):
# accept the volume transfer request # accept the volume transfer request
output = self.openstack( output = self.openstack(
'volume transfer request accept ' + 'volume transfer request accept '
name + ' ' + + name
'--auth-key ' + auth_key, + ' '
+ '--auth-key '
+ auth_key,
parse_output=True, parse_output=True,
) )
self.assertEqual(name, output.get('name')) self.assertEqual(name, output.get('name'))
# the volume transfer will be removed by default after accepted # the volume transfer will be removed by default after accepted
# so just need to delete the volume here # so just need to delete the volume here
raw_output = self.openstack( raw_output = self.openstack('volume delete ' + volume_name)
'volume delete ' + volume_name)
self.assertEqual('', raw_output) self.assertEqual('', raw_output)
def test_volume_transfer_request_list_show(self): def test_volume_transfer_request_list_show(self):
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume transfer request create ' + 'volume transfer request create '
' --name ' + name + ' ' + + ' --name '
self.VOLUME_NAME, + name
+ ' '
+ self.VOLUME_NAME,
parse_output=True, parse_output=True,
) )
self.addCleanup( self.addCleanup(
self.openstack, self.openstack, 'volume transfer request delete ' + name
'volume transfer request delete ' + name
) )
self.assertOutput(name, cmd_output['name']) self.assertOutput(name, cmd_output['name'])
auth_key = cmd_output['auth_key'] auth_key = cmd_output['auth_key']
@ -101,8 +105,7 @@ class TransferRequestTests(common.BaseVolumeTests):
self.assertIn(name, [req['Name'] for req in cmd_output]) self.assertIn(name, [req['Name'] for req in cmd_output])
cmd_output = self.openstack( cmd_output = self.openstack(
'volume transfer request show ' + 'volume transfer request show ' + name,
name,
parse_output=True, parse_output=True,
) )
self.assertEqual(name, cmd_output['name']) self.assertEqual(name, cmd_output['name'])

View File

@ -16,15 +16,13 @@ from openstackclient.tests.functional.volume.v1 import common
class VolumeTests(common.BaseVolumeTests): class VolumeTests(common.BaseVolumeTests):
"""Functional tests for volume. """ """Functional tests for volume."""
def test_volume_create_and_delete(self): def test_volume_create_and_delete(self):
"""Test create, delete multiple""" """Test create, delete multiple"""
name1 = uuid.uuid4().hex name1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--size 1 ' + name1,
'--size 1 ' +
name1,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -34,9 +32,7 @@ class VolumeTests(common.BaseVolumeTests):
name2 = uuid.uuid4().hex name2 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--size 2 ' + name2,
'--size 2 ' +
name2,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -53,9 +49,7 @@ class VolumeTests(common.BaseVolumeTests):
"""Test create, list filter""" """Test create, list filter"""
name1 = uuid.uuid4().hex name1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--size 1 ' + name1,
'--size 1 ' +
name1,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.openstack, 'volume delete ' + name1) self.addCleanup(self.openstack, 'volume delete ' + name1)
@ -67,9 +61,7 @@ class VolumeTests(common.BaseVolumeTests):
name2 = uuid.uuid4().hex name2 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--size 2 ' + name2,
'--size 2 ' +
name2,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.openstack, 'volume delete ' + name2) self.addCleanup(self.openstack, 'volume delete ' + name2)
@ -98,8 +90,7 @@ class VolumeTests(common.BaseVolumeTests):
# Test list --name # Test list --name
cmd_output = self.openstack( cmd_output = self.openstack(
'volume list ' + 'volume list ' + '--name ' + name1,
'--name ' + name1,
parse_output=True, parse_output=True,
) )
names = [x["Name"] for x in cmd_output] names = [x["Name"] for x in cmd_output]
@ -110,11 +101,11 @@ class VolumeTests(common.BaseVolumeTests):
"""Tests create volume, set, unset, show, delete""" """Tests create volume, set, unset, show, delete"""
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create '
'--size 1 ' + + '--size 1 '
'--description aaaa ' + + '--description aaaa '
'--property Alpha=a ' + + '--property Alpha=a '
name, + name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -143,21 +134,21 @@ class VolumeTests(common.BaseVolumeTests):
new_name = uuid.uuid4().hex new_name = uuid.uuid4().hex
self.addCleanup(self.openstack, 'volume delete ' + new_name) self.addCleanup(self.openstack, 'volume delete ' + new_name)
raw_output = self.openstack( raw_output = self.openstack(
'volume set ' + 'volume set '
'--name ' + new_name + + '--name '
' --size 2 ' + + new_name
'--description bbbb ' + + ' --size 2 '
'--no-property ' + + '--description bbbb '
'--property Beta=b ' + + '--no-property '
'--property Gamma=c ' + + '--property Beta=b '
'--bootable ' + + '--property Gamma=c '
name, + '--bootable '
+ name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume show ' + 'volume show ' + new_name,
new_name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -183,15 +174,12 @@ class VolumeTests(common.BaseVolumeTests):
# Test volume unset # Test volume unset
raw_output = self.openstack( raw_output = self.openstack(
'volume unset ' + 'volume unset ' + '--property Beta ' + new_name,
'--property Beta ' +
new_name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume show ' + 'volume show ' + new_name,
new_name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -203,10 +191,7 @@ class VolumeTests(common.BaseVolumeTests):
"""Test backward compatibility of create, list, show""" """Test backward compatibility of create, list, show"""
name1 = uuid.uuid4().hex name1 = uuid.uuid4().hex
output = self.openstack( output = self.openstack(
'volume create ' + 'volume create ' + '-c display_name -c id ' + '--size 1 ' + name1,
'-c display_name -c id ' +
'--size 1 ' +
name1,
parse_output=True, parse_output=True,
) )
self.assertIn('display_name', output) self.assertIn('display_name', output)
@ -220,25 +205,21 @@ class VolumeTests(common.BaseVolumeTests):
self.wait_for_status("volume", name1, "available") self.wait_for_status("volume", name1, "available")
output = self.openstack( output = self.openstack(
'volume list ' + 'volume list ' + '-c "Display Name"',
'-c "Display Name"',
parse_output=True, parse_output=True,
) )
for each_volume in output: for each_volume in output:
self.assertIn('Display Name', each_volume) self.assertIn('Display Name', each_volume)
output = self.openstack( output = self.openstack(
'volume list ' + 'volume list ' + '-c "Name"',
'-c "Name"',
parse_output=True, parse_output=True,
) )
for each_volume in output: for each_volume in output:
self.assertIn('Name', each_volume) self.assertIn('Name', each_volume)
output = self.openstack( output = self.openstack(
'volume show ' + 'volume show ' + '-c display_name -c id ' + name1,
'-c display_name -c id ' +
name1,
parse_output=True, parse_output=True,
) )
self.assertIn('display_name', output) self.assertIn('display_name', output)

View File

@ -17,19 +17,17 @@ from openstackclient.tests.functional.volume.v1 import common
class VolumeTypeTests(common.BaseVolumeTests): class VolumeTypeTests(common.BaseVolumeTests):
"""Functional tests for volume type. """ """Functional tests for volume type."""
def test_volume_type_create_list(self): def test_volume_type_create_list(self):
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create --private ' + 'volume type create --private ' + name,
name,
parse_output=True, parse_output=True,
) )
self.addCleanup( self.addCleanup(
self.openstack, self.openstack,
'volume type delete ' + 'volume type delete ' + name,
name,
) )
self.assertEqual(name, cmd_output['name']) self.assertEqual(name, cmd_output['name'])
@ -52,14 +50,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
def test_volume_type_set_unset_properties(self): def test_volume_type_set_unset_properties(self):
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create --private ' + 'volume type create --private ' + name,
name,
parse_output=True, parse_output=True,
) )
self.addCleanup( self.addCleanup(self.openstack, 'volume type delete ' + name)
self.openstack,
'volume type delete ' + name
)
self.assertEqual(name, cmd_output['name']) self.assertEqual(name, cmd_output['name'])
raw_output = self.openstack( raw_output = self.openstack(
@ -72,9 +66,7 @@ class VolumeTypeTests(common.BaseVolumeTests):
) )
self.assertEqual({'a': 'b', 'c': 'd'}, cmd_output['properties']) self.assertEqual({'a': 'b', 'c': 'd'}, cmd_output['properties'])
raw_output = self.openstack( raw_output = self.openstack('volume type unset --property a %s' % name)
'volume type unset --property a %s' % name
)
self.assertEqual("", raw_output) self.assertEqual("", raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type show %s' % name, 'volume type show %s' % name,
@ -85,14 +77,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
def test_volume_type_set_unset_multiple_properties(self): def test_volume_type_set_unset_multiple_properties(self):
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create --private ' + 'volume type create --private ' + name,
name,
parse_output=True, parse_output=True,
) )
self.addCleanup( self.addCleanup(self.openstack, 'volume type delete ' + name)
self.openstack,
'volume type delete ' + name
)
self.assertEqual(name, cmd_output['name']) self.assertEqual(name, cmd_output['name'])
raw_output = self.openstack( raw_output = self.openstack(
@ -138,12 +126,14 @@ class VolumeTypeTests(common.BaseVolumeTests):
'--encryption-provider LuksEncryptor ' '--encryption-provider LuksEncryptor '
'--encryption-cipher aes-xts-plain64 ' '--encryption-cipher aes-xts-plain64 '
'--encryption-key-size 128 ' '--encryption-key-size 128 '
'--encryption-control-location front-end ' + '--encryption-control-location front-end ' + encryption_type
encryption_type) )
expected = {'provider': 'LuksEncryptor', expected = {
'cipher': 'aes-xts-plain64', 'provider': 'LuksEncryptor',
'key_size': 128, 'cipher': 'aes-xts-plain64',
'control_location': 'front-end'} 'key_size': 128,
'control_location': 'front-end',
}
for attr, value in expected.items(): for attr, value in expected.items():
self.assertEqual(value, cmd_output['encryption'][attr]) self.assertEqual(value, cmd_output['encryption'][attr])
# test show encryption type # test show encryption type
@ -151,10 +141,12 @@ class VolumeTypeTests(common.BaseVolumeTests):
'volume type show --encryption-type ' + encryption_type, 'volume type show --encryption-type ' + encryption_type,
parse_output=True, parse_output=True,
) )
expected = {'provider': 'LuksEncryptor', expected = {
'cipher': 'aes-xts-plain64', 'provider': 'LuksEncryptor',
'key_size': 128, 'cipher': 'aes-xts-plain64',
'control_location': 'front-end'} 'key_size': 128,
'control_location': 'front-end',
}
for attr, value in expected.items(): for attr, value in expected.items():
self.assertEqual(value, cmd_output['encryption'][attr]) self.assertEqual(value, cmd_output['encryption'][attr])
# test list encryption type # test list encryption type
@ -162,12 +154,15 @@ class VolumeTypeTests(common.BaseVolumeTests):
'volume type list --encryption-type', 'volume type list --encryption-type',
parse_output=True, parse_output=True,
) )
encryption_output = [t['Encryption'] for t in cmd_output encryption_output = [
if t['Name'] == encryption_type][0] t['Encryption'] for t in cmd_output if t['Name'] == encryption_type
expected = {'provider': 'LuksEncryptor', ][0]
'cipher': 'aes-xts-plain64', expected = {
'key_size': 128, 'provider': 'LuksEncryptor',
'control_location': 'front-end'} 'cipher': 'aes-xts-plain64',
'key_size': 128,
'control_location': 'front-end',
}
for attr, value in expected.items(): for attr, value in expected.items():
self.assertEqual(value, encryption_output[attr]) self.assertEqual(value, encryption_output[attr])
# test set new encryption type # test set new encryption type
@ -176,8 +171,8 @@ class VolumeTypeTests(common.BaseVolumeTests):
'--encryption-provider LuksEncryptor ' '--encryption-provider LuksEncryptor '
'--encryption-cipher aes-xts-plain64 ' '--encryption-cipher aes-xts-plain64 '
'--encryption-key-size 128 ' '--encryption-key-size 128 '
'--encryption-control-location front-end ' + '--encryption-control-location front-end ' + self.NAME
self.NAME) )
self.assertEqual('', raw_output) self.assertEqual('', raw_output)
name = uuid.uuid4().hex name = uuid.uuid4().hex
@ -195,10 +190,12 @@ class VolumeTypeTests(common.BaseVolumeTests):
'volume type show --encryption-type ' + name, 'volume type show --encryption-type ' + name,
parse_output=True, parse_output=True,
) )
expected = {'provider': 'LuksEncryptor', expected = {
'cipher': 'aes-xts-plain64', 'provider': 'LuksEncryptor',
'key_size': 128, 'cipher': 'aes-xts-plain64',
'control_location': 'front-end'} 'key_size': 128,
'control_location': 'front-end',
}
for attr, value in expected.items(): for attr, value in expected.items():
self.assertEqual(value, cmd_output['encryption'][attr]) self.assertEqual(value, cmd_output['encryption'][attr])
# test unset encryption type # test unset encryption type

View File

@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume import base
class BaseVolumeTests(base.BaseVolumeTests): class BaseVolumeTests(base.BaseVolumeTests):
"""Base class for Volume functional tests. """ """Base class for Volume functional tests."""
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):

View File

@ -16,31 +16,23 @@ from openstackclient.tests.functional.volume.v2 import common
class QosTests(common.BaseVolumeTests): class QosTests(common.BaseVolumeTests):
"""Functional tests for volume qos. """ """Functional tests for volume qos."""
def test_volume_qos_create_delete_list(self): def test_volume_qos_create_delete_list(self):
"""Test create, list, delete multiple""" """Test create, list, delete multiple"""
name1 = uuid.uuid4().hex name1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos create ' + 'volume qos create ' + name1,
name1,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(name1, cmd_output['name'])
name1,
cmd_output['name']
)
name2 = uuid.uuid4().hex name2 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos create ' + 'volume qos create ' + name2,
name2,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(name2, cmd_output['name'])
name2,
cmd_output['name']
)
# Test list # Test list
cmd_output = self.openstack( cmd_output = self.openstack(
@ -60,126 +52,84 @@ class QosTests(common.BaseVolumeTests):
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos create ' + 'volume qos create ' + '--consumer front-end '
'--consumer front-end ' '--property Alpha=a ' + name,
'--property Alpha=a ' +
name,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.openstack, 'volume qos delete ' + name) self.addCleanup(self.openstack, 'volume qos delete ' + name)
self.assertEqual( self.assertEqual(name, cmd_output['name'])
name,
cmd_output['name']
)
self.assertEqual( self.assertEqual("front-end", cmd_output['consumer'])
"front-end", self.assertEqual({'Alpha': 'a'}, cmd_output['properties'])
cmd_output['consumer']
)
self.assertEqual(
{'Alpha': 'a'},
cmd_output['properties']
)
# Test volume qos set # Test volume qos set
raw_output = self.openstack( raw_output = self.openstack(
'volume qos set ' + 'volume qos set '
'--property Alpha=c ' + + '--property Alpha=c '
'--property Beta=b ' + + '--property Beta=b '
name, + name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
# Test volume qos show # Test volume qos show
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos show ' + 'volume qos show ' + name,
name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(name, cmd_output['name'])
name, self.assertEqual({'Alpha': 'c', 'Beta': 'b'}, cmd_output['properties'])
cmd_output['name']
)
self.assertEqual(
{'Alpha': 'c', 'Beta': 'b'},
cmd_output['properties']
)
# Test volume qos unset # Test volume qos unset
raw_output = self.openstack( raw_output = self.openstack(
'volume qos unset ' + 'volume qos unset ' + '--property Alpha ' + name,
'--property Alpha ' +
name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos show ' + 'volume qos show ' + name,
name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(name, cmd_output['name'])
name, self.assertEqual({'Beta': 'b'}, cmd_output['properties'])
cmd_output['name']
)
self.assertEqual(
{'Beta': 'b'},
cmd_output['properties']
)
def test_volume_qos_asso_disasso(self): def test_volume_qos_asso_disasso(self):
"""Tests associate and disassociate qos with volume type""" """Tests associate and disassociate qos with volume type"""
vol_type1 = uuid.uuid4().hex vol_type1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create ' + 'volume type create ' + vol_type1,
vol_type1,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(vol_type1, cmd_output['name'])
vol_type1,
cmd_output['name']
)
self.addCleanup(self.openstack, 'volume type delete ' + vol_type1) self.addCleanup(self.openstack, 'volume type delete ' + vol_type1)
vol_type2 = uuid.uuid4().hex vol_type2 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create ' + 'volume type create ' + vol_type2,
vol_type2,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(vol_type2, cmd_output['name'])
vol_type2,
cmd_output['name']
)
self.addCleanup(self.openstack, 'volume type delete ' + vol_type2) self.addCleanup(self.openstack, 'volume type delete ' + vol_type2)
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos create ' + 'volume qos create ' + name,
name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(name, cmd_output['name'])
name,
cmd_output['name']
)
self.addCleanup(self.openstack, 'volume qos delete ' + name) self.addCleanup(self.openstack, 'volume qos delete ' + name)
# Test associate # Test associate
raw_output = self.openstack( raw_output = self.openstack(
'volume qos associate ' + 'volume qos associate ' + name + ' ' + vol_type1
name + ' ' + vol_type1
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
raw_output = self.openstack( raw_output = self.openstack(
'volume qos associate ' + 'volume qos associate ' + name + ' ' + vol_type2
name + ' ' + vol_type2
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos show ' + 'volume qos show ' + name,
name,
parse_output=True, parse_output=True,
) )
types = cmd_output["associations"] types = cmd_output["associations"]
@ -188,14 +138,15 @@ class QosTests(common.BaseVolumeTests):
# Test disassociate # Test disassociate
raw_output = self.openstack( raw_output = self.openstack(
'volume qos disassociate ' + 'volume qos disassociate '
'--volume-type ' + vol_type1 + + '--volume-type '
' ' + name + vol_type1
+ ' '
+ name
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos show ' + 'volume qos show ' + name,
name,
parse_output=True, parse_output=True,
) )
types = cmd_output["associations"] types = cmd_output["associations"]
@ -204,13 +155,11 @@ class QosTests(common.BaseVolumeTests):
# Test disassociate --all # Test disassociate --all
raw_output = self.openstack( raw_output = self.openstack(
'volume qos associate ' + 'volume qos associate ' + name + ' ' + vol_type1
name + ' ' + vol_type1
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos show ' + 'volume qos show ' + name,
name,
parse_output=True, parse_output=True,
) )
types = cmd_output["associations"] types = cmd_output["associations"]
@ -218,13 +167,11 @@ class QosTests(common.BaseVolumeTests):
self.assertIn(vol_type2, types) self.assertIn(vol_type2, types)
raw_output = self.openstack( raw_output = self.openstack(
'volume qos disassociate ' + 'volume qos disassociate ' + '--all ' + name
'--all ' + name
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos show ' + 'volume qos show ' + name,
name,
parse_output=True, parse_output=True,
) )
self.assertNotIn("associations", cmd_output.keys()) self.assertNotIn("associations", cmd_output.keys())

View File

@ -25,32 +25,21 @@ class VolumeServiceTests(common.BaseVolumeTests):
# Test volume service list --service # Test volume service list --service
cmd_output = self.openstack( cmd_output = self.openstack(
'volume service list ' + 'volume service list ' + '--service ' + services[0],
'--service ' +
services[0],
parse_output=True, parse_output=True,
) )
for x in cmd_output: for x in cmd_output:
self.assertEqual( self.assertEqual(services[0], x['Binary'])
services[0],
x['Binary']
)
# Test volume service list --host # Test volume service list --host
cmd_output = self.openstack( cmd_output = self.openstack(
'volume service list ' + 'volume service list ' + '--host ' + hosts[0],
'--host ' +
hosts[0],
parse_output=True, parse_output=True,
) )
for x in cmd_output: for x in cmd_output:
self.assertIn( self.assertIn(hosts[0], x['Host'])
hosts[0],
x['Host']
)
def test_volume_service_set(self): def test_volume_service_set(self):
# Get a service and host # Get a service and host
cmd_output = self.openstack( cmd_output = self.openstack(
'volume service list', 'volume service list',
@ -61,9 +50,7 @@ class VolumeServiceTests(common.BaseVolumeTests):
# Test volume service set --enable # Test volume service set --enable
raw_output = self.openstack( raw_output = self.openstack(
'volume service set --enable ' + 'volume service set --enable ' + host_1 + ' ' + service_1
host_1 + ' ' +
service_1
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
@ -71,22 +58,19 @@ class VolumeServiceTests(common.BaseVolumeTests):
'volume service list --long', 'volume service list --long',
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual('enabled', cmd_output[0]['Status'])
'enabled', self.assertIsNone(cmd_output[0]['Disabled Reason'])
cmd_output[0]['Status']
)
self.assertIsNone(
cmd_output[0]['Disabled Reason']
)
# Test volume service set --disable and --disable-reason # Test volume service set --disable and --disable-reason
disable_reason = 'disable_reason' disable_reason = 'disable_reason'
raw_output = self.openstack( raw_output = self.openstack(
'volume service set --disable ' + 'volume service set --disable '
'--disable-reason ' + + '--disable-reason '
disable_reason + ' ' + + disable_reason
host_1 + ' ' + + ' '
service_1 + host_1
+ ' '
+ service_1
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
@ -94,11 +78,5 @@ class VolumeServiceTests(common.BaseVolumeTests):
'volume service list --long', 'volume service list --long',
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual('disabled', cmd_output[0]['Status'])
'disabled', self.assertEqual(disable_reason, cmd_output[0]['Disabled Reason'])
cmd_output[0]['Status']
)
self.assertEqual(
disable_reason,
cmd_output[0]['Disabled Reason']
)

View File

@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v2 import common
class TransferRequestTests(common.BaseVolumeTests): class TransferRequestTests(common.BaseVolumeTests):
"""Functional tests for transfer request. """ """Functional tests for transfer request."""
API_VERSION = '2' API_VERSION = '2'
@ -26,27 +26,31 @@ class TransferRequestTests(common.BaseVolumeTests):
# create a volume # create a volume
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--size 1 ' + volume_name,
'--size 1 ' +
volume_name,
parse_output=True, parse_output=True,
) )
self.assertEqual(volume_name, cmd_output['name']) self.assertEqual(volume_name, cmd_output['name'])
self.addCleanup( self.addCleanup(
self.openstack, self.openstack,
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume delete ' + + self.API_VERSION
volume_name + ' '
+ 'volume delete '
+ volume_name,
) )
self.wait_for_status("volume", volume_name, "available") self.wait_for_status("volume", volume_name, "available")
# create volume transfer request for the volume # create volume transfer request for the volume
# and get the auth_key of the new transfer request # and get the auth_key of the new transfer request
cmd_output = self.openstack( cmd_output = self.openstack(
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume transfer request create ' + + self.API_VERSION
' --name ' + xfer_name + ' ' + + ' '
volume_name, + 'volume transfer request create '
+ ' --name '
+ xfer_name
+ ' '
+ volume_name,
parse_output=True, parse_output=True,
) )
self.assertEqual(xfer_name, cmd_output['name']) self.assertEqual(xfer_name, cmd_output['name'])
@ -57,10 +61,14 @@ class TransferRequestTests(common.BaseVolumeTests):
# accept the volume transfer request # accept the volume transfer request
cmd_output = self.openstack( cmd_output = self.openstack(
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume transfer request accept ' + + self.API_VERSION
'--auth-key ' + auth_key + ' ' + + ' '
xfer_id, + 'volume transfer request accept '
+ '--auth-key '
+ auth_key
+ ' '
+ xfer_id,
parse_output=True, parse_output=True,
) )
self.assertEqual(xfer_name, cmd_output['name']) self.assertEqual(xfer_name, cmd_output['name'])
@ -72,25 +80,29 @@ class TransferRequestTests(common.BaseVolumeTests):
# create a volume # create a volume
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--size 1 ' + volume_name,
'--size 1 ' +
volume_name,
parse_output=True, parse_output=True,
) )
self.assertEqual(volume_name, cmd_output['name']) self.assertEqual(volume_name, cmd_output['name'])
self.addCleanup( self.addCleanup(
self.openstack, self.openstack,
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume delete ' + + self.API_VERSION
volume_name + ' '
+ 'volume delete '
+ volume_name,
) )
self.wait_for_status("volume", volume_name, "available") self.wait_for_status("volume", volume_name, "available")
cmd_output = self.openstack( cmd_output = self.openstack(
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume transfer request create ' + + self.API_VERSION
' --name ' + xfer_name + ' ' + + ' '
volume_name, + 'volume transfer request create '
+ ' --name '
+ xfer_name
+ ' '
+ volume_name,
parse_output=True, parse_output=True,
) )
self.assertEqual(xfer_name, cmd_output['name']) self.assertEqual(xfer_name, cmd_output['name'])
@ -100,16 +112,20 @@ class TransferRequestTests(common.BaseVolumeTests):
self.wait_for_status("volume", volume_name, "awaiting-transfer") self.wait_for_status("volume", volume_name, "awaiting-transfer")
cmd_output = self.openstack( cmd_output = self.openstack(
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume transfer request list', + self.API_VERSION
+ ' '
+ 'volume transfer request list',
parse_output=True, parse_output=True,
) )
self.assertIn(xfer_name, [req['Name'] for req in cmd_output]) self.assertIn(xfer_name, [req['Name'] for req in cmd_output])
cmd_output = self.openstack( cmd_output = self.openstack(
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume transfer request show ' + + self.API_VERSION
xfer_id, + ' '
+ 'volume transfer request show '
+ xfer_id,
parse_output=True, parse_output=True,
) )
self.assertEqual(xfer_name, cmd_output['name']) self.assertEqual(xfer_name, cmd_output['name'])
@ -120,8 +136,10 @@ class TransferRequestTests(common.BaseVolumeTests):
# to become 'available' before attempting to delete # to become 'available' before attempting to delete
# the volume. # the volume.
cmd_output = self.openstack( cmd_output = self.openstack(
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume transfer request delete ' + + self.API_VERSION
xfer_id + ' '
+ 'volume transfer request delete '
+ xfer_id
) )
self.wait_for_status("volume", volume_name, "available") self.wait_for_status("volume", volume_name, "available")

View File

@ -16,15 +16,13 @@ from openstackclient.tests.functional.volume.v2 import common
class VolumeTests(common.BaseVolumeTests): class VolumeTests(common.BaseVolumeTests):
"""Functional tests for volume. """ """Functional tests for volume."""
def test_volume_delete(self): def test_volume_delete(self):
"""Test create, delete multiple""" """Test create, delete multiple"""
name1 = uuid.uuid4().hex name1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--size 1 ' + name1,
'--size 1 ' +
name1,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -34,9 +32,7 @@ class VolumeTests(common.BaseVolumeTests):
name2 = uuid.uuid4().hex name2 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--size 2 ' + name2,
'--size 2 ' +
name2,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -53,9 +49,7 @@ class VolumeTests(common.BaseVolumeTests):
"""Test create, list filter""" """Test create, list filter"""
name1 = uuid.uuid4().hex name1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--size 1 ' + name1,
'--size 1 ' +
name1,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.openstack, 'volume delete ' + name1) self.addCleanup(self.openstack, 'volume delete ' + name1)
@ -67,9 +61,7 @@ class VolumeTests(common.BaseVolumeTests):
name2 = uuid.uuid4().hex name2 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--size 2 ' + name2,
'--size 2 ' +
name2,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.openstack, 'volume delete ' + name2) self.addCleanup(self.openstack, 'volume delete ' + name2)
@ -78,17 +70,12 @@ class VolumeTests(common.BaseVolumeTests):
cmd_output["size"], cmd_output["size"],
) )
self.wait_for_status("volume", name2, "available") self.wait_for_status("volume", name2, "available")
raw_output = self.openstack( raw_output = self.openstack('volume set ' + '--state error ' + name2)
'volume set ' +
'--state error ' +
name2
)
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
# Test list --long # Test list --long
cmd_output = self.openstack( cmd_output = self.openstack(
'volume list ' + 'volume list ' + '--long',
'--long',
parse_output=True, parse_output=True,
) )
names = [x["Name"] for x in cmd_output] names = [x["Name"] for x in cmd_output]
@ -97,8 +84,7 @@ class VolumeTests(common.BaseVolumeTests):
# Test list --status # Test list --status
cmd_output = self.openstack( cmd_output = self.openstack(
'volume list ' + 'volume list ' + '--status error',
'--status error',
parse_output=True, parse_output=True,
) )
names = [x["Name"] for x in cmd_output] names = [x["Name"] for x in cmd_output]
@ -113,11 +99,11 @@ class VolumeTests(common.BaseVolumeTests):
name = uuid.uuid4().hex name = uuid.uuid4().hex
new_name = name + "_" new_name = name + "_"
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create '
'--size 1 ' + + '--size 1 '
'--description aaaa ' + + '--description aaaa '
'--property Alpha=a ' + + '--property Alpha=a '
name, + name,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.openstack, 'volume delete ' + new_name) self.addCleanup(self.openstack, 'volume delete ' + new_name)
@ -145,23 +131,23 @@ class VolumeTests(common.BaseVolumeTests):
# Test volume set # Test volume set
raw_output = self.openstack( raw_output = self.openstack(
'volume set ' + 'volume set '
'--name ' + new_name + + '--name '
' --size 2 ' + + new_name
'--description bbbb ' + + ' --size 2 '
'--no-property ' + + '--description bbbb '
'--property Beta=b ' + + '--no-property '
'--property Gamma=c ' + + '--property Beta=b '
'--image-property a=b ' + + '--property Gamma=c '
'--image-property c=d ' + + '--image-property a=b '
'--bootable ' + + '--image-property c=d '
name, + '--bootable '
+ name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume show ' + 'volume show ' + new_name,
new_name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -191,16 +177,15 @@ class VolumeTests(common.BaseVolumeTests):
# Test volume unset # Test volume unset
raw_output = self.openstack( raw_output = self.openstack(
'volume unset ' + 'volume unset '
'--property Beta ' + + '--property Beta '
'--image-property a ' + + '--image-property a '
new_name, + new_name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume show ' + 'volume show ' + new_name,
new_name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -219,9 +204,7 @@ class VolumeTests(common.BaseVolumeTests):
snapshot_name = uuid.uuid4().hex snapshot_name = uuid.uuid4().hex
# Make a snapshot # Make a snapshot
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--size 1 ' + volume_name,
'--size 1 ' +
volume_name,
parse_output=True, parse_output=True,
) )
self.wait_for_status("volume", volume_name, "available") self.wait_for_status("volume", volume_name, "available")
@ -230,9 +213,10 @@ class VolumeTests(common.BaseVolumeTests):
cmd_output["name"], cmd_output["name"],
) )
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create '
snapshot_name + + snapshot_name
' --volume ' + volume_name, + ' --volume '
+ volume_name,
parse_output=True, parse_output=True,
) )
self.wait_for_status("volume snapshot", snapshot_name, "available") self.wait_for_status("volume snapshot", snapshot_name, "available")
@ -240,9 +224,7 @@ class VolumeTests(common.BaseVolumeTests):
name = uuid.uuid4().hex name = uuid.uuid4().hex
# Create volume from snapshot # Create volume from snapshot
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--snapshot ' + snapshot_name + ' ' + name,
'--snapshot ' + snapshot_name +
' ' + name,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.openstack, 'volume delete ' + name) self.addCleanup(self.openstack, 'volume delete ' + name)
@ -254,8 +236,7 @@ class VolumeTests(common.BaseVolumeTests):
self.wait_for_status("volume", name, "available") self.wait_for_status("volume", name, "available")
# Delete snapshot # Delete snapshot
raw_output = self.openstack( raw_output = self.openstack('volume snapshot delete ' + snapshot_name)
'volume snapshot delete ' + snapshot_name)
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
# Deleting snapshot may take time. If volume snapshot still exists when # Deleting snapshot may take time. If volume snapshot still exists when
# a parent volume delete is requested, the volume deletion will fail. # 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""" """Test backward compatibility of list command"""
name1 = uuid.uuid4().hex name1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--size 1 ' + name1,
'--size 1 ' +
name1,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.openstack, 'volume delete ' + name1) self.addCleanup(self.openstack, 'volume delete ' + name1)
@ -279,8 +258,7 @@ class VolumeTests(common.BaseVolumeTests):
# Test list -c "Display Name" # Test list -c "Display Name"
cmd_output = self.openstack( cmd_output = self.openstack(
'volume list ' + 'volume list ' + '-c "Display Name"',
'-c "Display Name"',
parse_output=True, parse_output=True,
) )
for each_volume in cmd_output: for each_volume in cmd_output:
@ -288,8 +266,7 @@ class VolumeTests(common.BaseVolumeTests):
# Test list -c "Name" # Test list -c "Name"
cmd_output = self.openstack( cmd_output = self.openstack(
'volume list ' + 'volume list ' + '-c "Name"',
'-c "Name"',
parse_output=True, parse_output=True,
) )
for each_volume in cmd_output: for each_volume in cmd_output:

View File

@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v2 import common
class VolumeBackupTests(common.BaseVolumeTests): class VolumeBackupTests(common.BaseVolumeTests):
"""Functional tests for volume backups. """ """Functional tests for volume backups."""
def setUp(self): def setUp(self):
super(VolumeBackupTests, self).setUp() super(VolumeBackupTests, self).setUp()
@ -34,29 +34,26 @@ class VolumeBackupTests(common.BaseVolumeTests):
vol_id = uuid.uuid4().hex vol_id = uuid.uuid4().hex
# create a volume # create a volume
self.openstack( self.openstack(
'volume create ' + 'volume create ' + '--size 1 ' + vol_id,
'--size 1 ' +
vol_id,
parse_output=True, parse_output=True,
) )
self.wait_for_status("volume", vol_id, "available") self.wait_for_status("volume", vol_id, "available")
# create a backup # create a backup
backup = self.openstack( backup = self.openstack(
'volume backup create ' + 'volume backup create ' + vol_id,
vol_id,
parse_output=True, parse_output=True,
) )
self.wait_for_status("volume backup", backup['id'], "available") self.wait_for_status("volume backup", backup['id'], "available")
# restore the backup # restore the backup
backup_restored = self.openstack( backup_restored = self.openstack(
'volume backup restore %s %s' 'volume backup restore %s %s' % (backup['id'], vol_id),
% (backup['id'], vol_id),
parse_output=True, parse_output=True,
) )
self.assertEqual(backup_restored['backup_id'], backup['id']) self.assertEqual(backup_restored['backup_id'], backup['id'])
self.wait_for_status("volume backup", backup['id'], "available") self.wait_for_status("volume backup", backup['id'], "available")
self.wait_for_status("volume", backup_restored['volume_id'], self.wait_for_status(
"available") "volume", backup_restored['volume_id'], "available"
)
self.addCleanup(self.openstack, 'volume delete %s' % vol_id) self.addCleanup(self.openstack, 'volume delete %s' % vol_id)

View File

@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v2 import common
class VolumeSnapshotTests(common.BaseVolumeTests): class VolumeSnapshotTests(common.BaseVolumeTests):
"""Functional tests for volume snapshot. """ """Functional tests for volume snapshot."""
VOLLY = uuid.uuid4().hex VOLLY = uuid.uuid4().hex
@ -25,9 +25,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
super(VolumeSnapshotTests, cls).setUpClass() super(VolumeSnapshotTests, cls).setUpClass()
# create a volume for all tests to create snapshot # create a volume for all tests to create snapshot
cmd_output = cls.openstack( cmd_output = cls.openstack(
'volume create ' + 'volume create ' + '--size 1 ' + cls.VOLLY,
'--size 1 ' +
cls.VOLLY,
parse_output=True, parse_output=True,
) )
cls.wait_for_status('volume', cls.VOLLY, 'available') cls.wait_for_status('volume', cls.VOLLY, 'available')
@ -37,8 +35,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
def tearDownClass(cls): def tearDownClass(cls):
try: try:
cls.wait_for_status('volume', cls.VOLLY, 'available') cls.wait_for_status('volume', cls.VOLLY, 'available')
raw_output = cls.openstack( raw_output = cls.openstack('volume delete --force ' + cls.VOLLY)
'volume delete --force ' + cls.VOLLY)
cls.assertOutput('', raw_output) cls.assertOutput('', raw_output)
finally: finally:
super(VolumeSnapshotTests, cls).tearDownClass() super(VolumeSnapshotTests, cls).tearDownClass()
@ -47,9 +44,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
"""Test create, delete multiple""" """Test create, delete multiple"""
name1 = uuid.uuid4().hex name1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
name1 +
' --volume ' + self.VOLLY,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -59,9 +54,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
name2 = uuid.uuid4().hex name2 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
name2 +
' --volume ' + self.VOLLY,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -73,7 +66,8 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
self.wait_for_status('volume snapshot', name2, 'available') self.wait_for_status('volume snapshot', name2, 'available')
del_output = self.openstack( del_output = self.openstack(
'volume snapshot delete ' + name1 + ' ' + name2) 'volume snapshot delete ' + name1 + ' ' + name2
)
self.assertOutput('', del_output) self.assertOutput('', del_output)
self.wait_for_delete('volume snapshot', name1) self.wait_for_delete('volume snapshot', name1)
self.wait_for_delete('volume snapshot', name2) self.wait_for_delete('volume snapshot', name2)
@ -82,9 +76,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
"""Test create, list filter""" """Test create, list filter"""
name1 = uuid.uuid4().hex name1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
name1 +
' --volume ' + self.VOLLY,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.wait_for_delete, 'volume snapshot', name1) self.addCleanup(self.wait_for_delete, 'volume snapshot', name1)
@ -105,9 +97,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
name2 = uuid.uuid4().hex name2 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
name2 +
' --volume ' + self.VOLLY,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.wait_for_delete, 'volume snapshot', name2) 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') self.wait_for_status('volume snapshot', name2, 'available')
raw_output = self.openstack( raw_output = self.openstack(
'volume snapshot set ' + 'volume snapshot set ' + '--state error_deleting ' + name2
'--state error_deleting ' +
name2
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
# Test list --long, --status # Test list --long, --status
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot list ' + 'volume snapshot list ' + '--long ' + '--status error_deleting',
'--long ' +
'--status error_deleting',
parse_output=True, parse_output=True,
) )
names = [x["Name"] for x in cmd_output] names = [x["Name"] for x in cmd_output]
@ -145,17 +131,13 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
self.assertIn(name2, names) self.assertIn(name2, names)
raw_output = self.openstack( raw_output = self.openstack(
'volume snapshot set ' + 'volume snapshot set ' + '--state error ' + name2
'--state error ' +
name2
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
# Test list --long, --status # Test list --long, --status
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot list ' + 'volume snapshot list ' + '--long ' + '--status error',
'--long ' +
'--status error',
parse_output=True, parse_output=True,
) )
names = [x["Name"] for x in cmd_output] names = [x["Name"] for x in cmd_output]
@ -164,8 +146,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test list --volume # Test list --volume
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot list ' + 'volume snapshot list ' + '--volume ' + self.VOLLY,
'--volume ' + self.VOLLY,
parse_output=True, parse_output=True,
) )
names = [x["Name"] for x in cmd_output] names = [x["Name"] for x in cmd_output]
@ -174,8 +155,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test list --name # Test list --name
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot list ' + 'volume snapshot list ' + '--name ' + name1,
'--name ' + name1,
parse_output=True, parse_output=True,
) )
names = [x["Name"] for x in cmd_output] names = [x["Name"] for x in cmd_output]
@ -187,11 +167,12 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
name = uuid.uuid4().hex name = uuid.uuid4().hex
new_name = name + "_" new_name = name + "_"
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create '
'--volume ' + self.VOLLY + + '--volume '
' --description aaaa ' + + self.VOLLY
'--property Alpha=a ' + + ' --description aaaa '
name, + '--property Alpha=a '
+ name,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.wait_for_delete, 'volume snapshot', new_name) self.addCleanup(self.wait_for_delete, 'volume snapshot', new_name)
@ -216,19 +197,19 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test volume snapshot set # Test volume snapshot set
raw_output = self.openstack( raw_output = self.openstack(
'volume snapshot set ' + 'volume snapshot set '
'--name ' + new_name + + '--name '
' --description bbbb ' + + new_name
'--property Alpha=c ' + + ' --description bbbb '
'--property Beta=b ' + + '--property Alpha=c '
name, + '--property Beta=b '
+ name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
# Show snapshot set result # Show snapshot set result
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot show ' + 'volume snapshot show ' + new_name,
new_name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -250,15 +231,12 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test volume snapshot unset # Test volume snapshot unset
raw_output = self.openstack( raw_output = self.openstack(
'volume snapshot unset ' + 'volume snapshot unset ' + '--property Alpha ' + new_name,
'--property Alpha ' +
new_name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot show ' + 'volume snapshot show ' + new_name,
new_name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -268,14 +246,11 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test volume snapshot set --no-property # Test volume snapshot set --no-property
raw_output = self.openstack( raw_output = self.openstack(
'volume snapshot set ' + 'volume snapshot set ' + '--no-property ' + new_name,
'--no-property ' +
new_name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot show ' + 'volume snapshot show ' + new_name,
new_name,
parse_output=True, parse_output=True,
) )
self.assertNotIn( self.assertNotIn(

View File

@ -17,13 +17,12 @@ from openstackclient.tests.functional.volume.v2 import common
class VolumeTypeTests(common.BaseVolumeTests): class VolumeTypeTests(common.BaseVolumeTests):
"""Functional tests for volume type. """ """Functional tests for volume type."""
def test_volume_type_create_list(self): def test_volume_type_create_list(self):
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create --private ' + 'volume type create --private ' + name,
name,
parse_output=True, parse_output=True,
) )
self.addCleanup( self.addCleanup(
@ -51,14 +50,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
def test_volume_type_set_unset_properties(self): def test_volume_type_set_unset_properties(self):
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create --private ' + 'volume type create --private ' + name,
name,
parse_output=True, parse_output=True,
) )
self.addCleanup( self.addCleanup(self.openstack, 'volume type delete ' + name)
self.openstack,
'volume type delete ' + name
)
self.assertEqual(name, cmd_output['name']) self.assertEqual(name, cmd_output['name'])
raw_output = self.openstack( raw_output = self.openstack(
@ -71,9 +66,7 @@ class VolumeTypeTests(common.BaseVolumeTests):
) )
self.assertEqual({'a': 'b', 'c': 'd'}, cmd_output['properties']) self.assertEqual({'a': 'b', 'c': 'd'}, cmd_output['properties'])
raw_output = self.openstack( raw_output = self.openstack('volume type unset --property a %s' % name)
'volume type unset --property a %s' % name
)
self.assertEqual("", raw_output) self.assertEqual("", raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type show %s' % name, 'volume type show %s' % name,
@ -84,14 +77,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
def test_volume_type_set_unset_multiple_properties(self): def test_volume_type_set_unset_multiple_properties(self):
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create --private ' + 'volume type create --private ' + name,
name,
parse_output=True, parse_output=True,
) )
self.addCleanup( self.addCleanup(self.openstack, 'volume type delete ' + name)
self.openstack,
'volume type delete ' + name
)
self.assertEqual(name, cmd_output['name']) self.assertEqual(name, cmd_output['name'])
raw_output = self.openstack( raw_output = self.openstack(
@ -117,14 +106,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
def test_volume_type_set_unset_project(self): def test_volume_type_set_unset_project(self):
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create --private ' + 'volume type create --private ' + name,
name,
parse_output=True, parse_output=True,
) )
self.addCleanup( self.addCleanup(self.openstack, 'volume type delete ' + name)
self.openstack,
'volume type delete ' + name
)
self.assertEqual(name, cmd_output['name']) self.assertEqual(name, cmd_output['name'])
raw_output = self.openstack( raw_output = self.openstack(
@ -161,14 +146,15 @@ class VolumeTypeTests(common.BaseVolumeTests):
'--encryption-provider LuksEncryptor ' '--encryption-provider LuksEncryptor '
'--encryption-cipher aes-xts-plain64 ' '--encryption-cipher aes-xts-plain64 '
'--encryption-key-size 128 ' '--encryption-key-size 128 '
'--encryption-control-location front-end ' + '--encryption-control-location front-end ' + encryption_type,
encryption_type,
parse_output=True, parse_output=True,
) )
expected = {'provider': 'LuksEncryptor', expected = {
'cipher': 'aes-xts-plain64', 'provider': 'LuksEncryptor',
'key_size': 128, 'cipher': 'aes-xts-plain64',
'control_location': 'front-end'} 'key_size': 128,
'control_location': 'front-end',
}
for attr, value in expected.items(): for attr, value in expected.items():
self.assertEqual(value, cmd_output['encryption'][attr]) self.assertEqual(value, cmd_output['encryption'][attr])
# test show encryption type # test show encryption type
@ -176,10 +162,12 @@ class VolumeTypeTests(common.BaseVolumeTests):
'volume type show --encryption-type ' + encryption_type, 'volume type show --encryption-type ' + encryption_type,
parse_output=True, parse_output=True,
) )
expected = {'provider': 'LuksEncryptor', expected = {
'cipher': 'aes-xts-plain64', 'provider': 'LuksEncryptor',
'key_size': 128, 'cipher': 'aes-xts-plain64',
'control_location': 'front-end'} 'key_size': 128,
'control_location': 'front-end',
}
for attr, value in expected.items(): for attr, value in expected.items():
self.assertEqual(value, cmd_output['encryption'][attr]) self.assertEqual(value, cmd_output['encryption'][attr])
# test list encryption type # test list encryption type
@ -187,35 +175,39 @@ class VolumeTypeTests(common.BaseVolumeTests):
'volume type list --encryption-type', 'volume type list --encryption-type',
parse_output=True, parse_output=True,
) )
encryption_output = [t['Encryption'] for t in cmd_output encryption_output = [
if t['Name'] == encryption_type][0] t['Encryption'] for t in cmd_output if t['Name'] == encryption_type
expected = {'provider': 'LuksEncryptor', ][0]
'cipher': 'aes-xts-plain64', expected = {
'key_size': 128, 'provider': 'LuksEncryptor',
'control_location': 'front-end'} 'cipher': 'aes-xts-plain64',
'key_size': 128,
'control_location': 'front-end',
}
for attr, value in expected.items(): for attr, value in expected.items():
self.assertEqual(value, encryption_output[attr]) self.assertEqual(value, encryption_output[attr])
# test set existing encryption type # test set existing encryption type
raw_output = self.openstack( raw_output = self.openstack(
'volume type set ' 'volume type set '
'--encryption-key-size 256 ' '--encryption-key-size 256 '
'--encryption-control-location back-end ' + '--encryption-control-location back-end ' + encryption_type
encryption_type) )
self.assertEqual('', raw_output) self.assertEqual('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type show --encryption-type ' + encryption_type, 'volume type show --encryption-type ' + encryption_type,
parse_output=True, parse_output=True,
) )
expected = {'provider': 'LuksEncryptor', expected = {
'cipher': 'aes-xts-plain64', 'provider': 'LuksEncryptor',
'key_size': 256, 'cipher': 'aes-xts-plain64',
'control_location': 'back-end'} 'key_size': 256,
'control_location': 'back-end',
}
for attr, value in expected.items(): for attr, value in expected.items():
self.assertEqual(value, cmd_output['encryption'][attr]) self.assertEqual(value, cmd_output['encryption'][attr])
# test set new encryption type # test set new encryption type
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create --private ' + 'volume type create --private ' + name,
name,
parse_output=True, parse_output=True,
) )
self.addCleanup( self.addCleanup(
@ -229,18 +221,20 @@ class VolumeTypeTests(common.BaseVolumeTests):
'--encryption-provider LuksEncryptor ' '--encryption-provider LuksEncryptor '
'--encryption-cipher aes-xts-plain64 ' '--encryption-cipher aes-xts-plain64 '
'--encryption-key-size 128 ' '--encryption-key-size 128 '
'--encryption-control-location front-end ' + '--encryption-control-location front-end ' + name
name) )
self.assertEqual('', raw_output) self.assertEqual('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type show --encryption-type ' + name, 'volume type show --encryption-type ' + name,
parse_output=True, parse_output=True,
) )
expected = {'provider': 'LuksEncryptor', expected = {
'cipher': 'aes-xts-plain64', 'provider': 'LuksEncryptor',
'key_size': 128, 'cipher': 'aes-xts-plain64',
'control_location': 'front-end'} 'key_size': 128,
'control_location': 'front-end',
}
for attr, value in expected.items(): for attr, value in expected.items():
self.assertEqual(value, cmd_output['encryption'][attr]) self.assertEqual(value, cmd_output['encryption'][attr])
# test unset encryption type # test unset encryption type

View File

@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume import base
class BaseVolumeTests(base.BaseVolumeTests): class BaseVolumeTests(base.BaseVolumeTests):
"""Base class for Volume functional tests. """ """Base class for Volume functional tests."""
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):

View File

@ -16,31 +16,23 @@ from openstackclient.tests.functional.volume.v3 import common
class QosTests(common.BaseVolumeTests): class QosTests(common.BaseVolumeTests):
"""Functional tests for volume qos. """ """Functional tests for volume qos."""
def test_volume_qos_create_delete_list(self): def test_volume_qos_create_delete_list(self):
"""Test create, list, delete multiple""" """Test create, list, delete multiple"""
name1 = uuid.uuid4().hex name1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos create ' + 'volume qos create ' + name1,
name1,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(name1, cmd_output['name'])
name1,
cmd_output['name']
)
name2 = uuid.uuid4().hex name2 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos create ' + 'volume qos create ' + name2,
name2,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(name2, cmd_output['name'])
name2,
cmd_output['name']
)
# Test list # Test list
cmd_output = self.openstack( cmd_output = self.openstack(
@ -60,126 +52,84 @@ class QosTests(common.BaseVolumeTests):
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos create ' + 'volume qos create ' + '--consumer front-end '
'--consumer front-end ' '--property Alpha=a ' + name,
'--property Alpha=a ' +
name,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.openstack, 'volume qos delete ' + name) self.addCleanup(self.openstack, 'volume qos delete ' + name)
self.assertEqual( self.assertEqual(name, cmd_output['name'])
name,
cmd_output['name']
)
self.assertEqual( self.assertEqual("front-end", cmd_output['consumer'])
"front-end", self.assertEqual({'Alpha': 'a'}, cmd_output['properties'])
cmd_output['consumer']
)
self.assertEqual(
{'Alpha': 'a'},
cmd_output['properties']
)
# Test volume qos set # Test volume qos set
raw_output = self.openstack( raw_output = self.openstack(
'volume qos set ' + 'volume qos set '
'--property Alpha=c ' + + '--property Alpha=c '
'--property Beta=b ' + + '--property Beta=b '
name, + name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
# Test volume qos show # Test volume qos show
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos show ' + 'volume qos show ' + name,
name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(name, cmd_output['name'])
name, self.assertEqual({'Alpha': 'c', 'Beta': 'b'}, cmd_output['properties'])
cmd_output['name']
)
self.assertEqual(
{'Alpha': 'c', 'Beta': 'b'},
cmd_output['properties']
)
# Test volume qos unset # Test volume qos unset
raw_output = self.openstack( raw_output = self.openstack(
'volume qos unset ' + 'volume qos unset ' + '--property Alpha ' + name,
'--property Alpha ' +
name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos show ' + 'volume qos show ' + name,
name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(name, cmd_output['name'])
name, self.assertEqual({'Beta': 'b'}, cmd_output['properties'])
cmd_output['name']
)
self.assertEqual(
{'Beta': 'b'},
cmd_output['properties']
)
def test_volume_qos_asso_disasso(self): def test_volume_qos_asso_disasso(self):
"""Tests associate and disassociate qos with volume type""" """Tests associate and disassociate qos with volume type"""
vol_type1 = uuid.uuid4().hex vol_type1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create ' + 'volume type create ' + vol_type1,
vol_type1,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(vol_type1, cmd_output['name'])
vol_type1,
cmd_output['name']
)
self.addCleanup(self.openstack, 'volume type delete ' + vol_type1) self.addCleanup(self.openstack, 'volume type delete ' + vol_type1)
vol_type2 = uuid.uuid4().hex vol_type2 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create ' + 'volume type create ' + vol_type2,
vol_type2,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(vol_type2, cmd_output['name'])
vol_type2,
cmd_output['name']
)
self.addCleanup(self.openstack, 'volume type delete ' + vol_type2) self.addCleanup(self.openstack, 'volume type delete ' + vol_type2)
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos create ' + 'volume qos create ' + name,
name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(name, cmd_output['name'])
name,
cmd_output['name']
)
self.addCleanup(self.openstack, 'volume qos delete ' + name) self.addCleanup(self.openstack, 'volume qos delete ' + name)
# Test associate # Test associate
raw_output = self.openstack( raw_output = self.openstack(
'volume qos associate ' + 'volume qos associate ' + name + ' ' + vol_type1
name + ' ' + vol_type1
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
raw_output = self.openstack( raw_output = self.openstack(
'volume qos associate ' + 'volume qos associate ' + name + ' ' + vol_type2
name + ' ' + vol_type2
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos show ' + 'volume qos show ' + name,
name,
parse_output=True, parse_output=True,
) )
types = cmd_output["associations"] types = cmd_output["associations"]
@ -188,14 +138,15 @@ class QosTests(common.BaseVolumeTests):
# Test disassociate # Test disassociate
raw_output = self.openstack( raw_output = self.openstack(
'volume qos disassociate ' + 'volume qos disassociate '
'--volume-type ' + vol_type1 + + '--volume-type '
' ' + name + vol_type1
+ ' '
+ name
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos show ' + 'volume qos show ' + name,
name,
parse_output=True, parse_output=True,
) )
types = cmd_output["associations"] types = cmd_output["associations"]
@ -204,13 +155,11 @@ class QosTests(common.BaseVolumeTests):
# Test disassociate --all # Test disassociate --all
raw_output = self.openstack( raw_output = self.openstack(
'volume qos associate ' + 'volume qos associate ' + name + ' ' + vol_type1
name + ' ' + vol_type1
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos show ' + 'volume qos show ' + name,
name,
parse_output=True, parse_output=True,
) )
types = cmd_output["associations"] types = cmd_output["associations"]
@ -218,13 +167,11 @@ class QosTests(common.BaseVolumeTests):
self.assertIn(vol_type2, types) self.assertIn(vol_type2, types)
raw_output = self.openstack( raw_output = self.openstack(
'volume qos disassociate ' + 'volume qos disassociate ' + '--all ' + name
'--all ' + name
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume qos show ' + 'volume qos show ' + name,
name,
parse_output=True, parse_output=True,
) )
self.assertNotIn("associations", cmd_output.keys()) self.assertNotIn("associations", cmd_output.keys())

View File

@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v3 import common
class TransferRequestTests(common.BaseVolumeTests): class TransferRequestTests(common.BaseVolumeTests):
"""Functional tests for transfer request. """ """Functional tests for transfer request."""
API_VERSION = '3' API_VERSION = '3'
@ -26,26 +26,31 @@ class TransferRequestTests(common.BaseVolumeTests):
# create a volume # create a volume
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--size 1 ' + volume_name,
'--size 1 ' +
volume_name,
parse_output=True, parse_output=True,
) )
self.assertEqual(volume_name, cmd_output['name']) self.assertEqual(volume_name, cmd_output['name'])
self.addCleanup( self.addCleanup(
self.openstack, self.openstack,
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume delete ' + + self.API_VERSION
volume_name + ' '
+ 'volume delete '
+ volume_name,
) )
self.wait_for_status("volume", volume_name, "available") self.wait_for_status("volume", volume_name, "available")
# create volume transfer request for the volume # create volume transfer request for the volume
# and get the auth_key of the new transfer request # and get the auth_key of the new transfer request
cmd_output = self.openstack( cmd_output = self.openstack(
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume transfer request create ' + + self.API_VERSION
' --name ' + xfer_name + ' ' + volume_name, + ' '
+ 'volume transfer request create '
+ ' --name '
+ xfer_name
+ ' '
+ volume_name,
parse_output=True, parse_output=True,
) )
self.assertEqual(xfer_name, cmd_output['name']) self.assertEqual(xfer_name, cmd_output['name'])
@ -56,9 +61,14 @@ class TransferRequestTests(common.BaseVolumeTests):
# accept the volume transfer request # accept the volume transfer request
cmd_output = self.openstack( cmd_output = self.openstack(
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume transfer request accept ' + + self.API_VERSION
'--auth-key ' + auth_key + ' ' + xfer_id, + ' '
+ 'volume transfer request accept '
+ '--auth-key '
+ auth_key
+ ' '
+ xfer_id,
parse_output=True, parse_output=True,
) )
self.assertEqual(xfer_name, cmd_output['name']) self.assertEqual(xfer_name, cmd_output['name'])
@ -70,23 +80,29 @@ class TransferRequestTests(common.BaseVolumeTests):
# create a volume # create a volume
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--size 1 ' + volume_name,
'--size 1 ' + volume_name,
parse_output=True, parse_output=True,
) )
self.assertEqual(volume_name, cmd_output['name']) self.assertEqual(volume_name, cmd_output['name'])
self.addCleanup( self.addCleanup(
self.openstack, self.openstack,
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume delete ' + + self.API_VERSION
volume_name + ' '
+ 'volume delete '
+ volume_name,
) )
self.wait_for_status("volume", volume_name, "available") self.wait_for_status("volume", volume_name, "available")
cmd_output = self.openstack( cmd_output = self.openstack(
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume transfer request create ' + + self.API_VERSION
' --name ' + xfer_name + ' ' + volume_name, + ' '
+ 'volume transfer request create '
+ ' --name '
+ xfer_name
+ ' '
+ volume_name,
parse_output=True, parse_output=True,
) )
self.assertEqual(xfer_name, cmd_output['name']) self.assertEqual(xfer_name, cmd_output['name'])
@ -96,16 +112,20 @@ class TransferRequestTests(common.BaseVolumeTests):
self.wait_for_status("volume", volume_name, "awaiting-transfer") self.wait_for_status("volume", volume_name, "awaiting-transfer")
cmd_output = self.openstack( cmd_output = self.openstack(
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume transfer request list', + self.API_VERSION
+ ' '
+ 'volume transfer request list',
parse_output=True, parse_output=True,
) )
self.assertIn(xfer_name, [req['Name'] for req in cmd_output]) self.assertIn(xfer_name, [req['Name'] for req in cmd_output])
cmd_output = self.openstack( cmd_output = self.openstack(
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume transfer request show ' + + self.API_VERSION
xfer_id, + ' '
+ 'volume transfer request show '
+ xfer_id,
parse_output=True, parse_output=True,
) )
self.assertEqual(xfer_name, cmd_output['name']) self.assertEqual(xfer_name, cmd_output['name'])
@ -116,8 +136,10 @@ class TransferRequestTests(common.BaseVolumeTests):
# to become 'available' before attempting to delete # to become 'available' before attempting to delete
# the volume. # the volume.
cmd_output = self.openstack( cmd_output = self.openstack(
'--os-volume-api-version ' + self.API_VERSION + ' ' + '--os-volume-api-version '
'volume transfer request delete ' + + self.API_VERSION
xfer_id + ' '
+ 'volume transfer request delete '
+ xfer_id
) )
self.wait_for_status("volume", volume_name, "available") self.wait_for_status("volume", volume_name, "available")

View File

@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v3 import common
class VolumeTests(common.BaseVolumeTests): class VolumeTests(common.BaseVolumeTests):
"""Functional tests for volume. """ """Functional tests for volume."""
def test_volume_delete(self): def test_volume_delete(self):
"""Test create, delete multiple""" """Test create, delete multiple"""
@ -70,11 +70,7 @@ class VolumeTests(common.BaseVolumeTests):
cmd_output["size"], cmd_output["size"],
) )
self.wait_for_status("volume", name2, "available") self.wait_for_status("volume", name2, "available")
raw_output = self.openstack( raw_output = self.openstack('volume set ' + '--state error ' + name2)
'volume set ' +
'--state error ' +
name2
)
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
# Test list --long # Test list --long
@ -103,11 +99,11 @@ class VolumeTests(common.BaseVolumeTests):
name = uuid.uuid4().hex name = uuid.uuid4().hex
new_name = name + "_" new_name = name + "_"
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create '
'--size 1 ' + + '--size 1 '
'--description aaaa ' + + '--description aaaa '
'--property Alpha=a ' + + '--property Alpha=a '
name, + name,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.openstack, 'volume delete ' + new_name) self.addCleanup(self.openstack, 'volume delete ' + new_name)
@ -135,17 +131,18 @@ class VolumeTests(common.BaseVolumeTests):
# Test volume set # Test volume set
raw_output = self.openstack( raw_output = self.openstack(
'volume set ' + 'volume set '
'--name ' + new_name + + '--name '
' --size 2 ' + + new_name
'--description bbbb ' + + ' --size 2 '
'--no-property ' + + '--description bbbb '
'--property Beta=b ' + + '--no-property '
'--property Gamma=c ' + + '--property Beta=b '
'--image-property a=b ' + + '--property Gamma=c '
'--image-property c=d ' + + '--image-property a=b '
'--bootable ' + + '--image-property c=d '
name, + '--bootable '
+ name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
self.wait_for_status("volume", new_name, "available") self.wait_for_status("volume", new_name, "available")
@ -181,10 +178,10 @@ class VolumeTests(common.BaseVolumeTests):
# Test volume unset # Test volume unset
raw_output = self.openstack( raw_output = self.openstack(
'volume unset ' + 'volume unset '
'--property Beta ' + + '--property Beta '
'--image-property a ' + + '--image-property a '
new_name, + new_name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
@ -217,9 +214,10 @@ class VolumeTests(common.BaseVolumeTests):
cmd_output["name"], cmd_output["name"],
) )
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create '
snapshot_name + + snapshot_name
' --volume ' + volume_name, + ' --volume '
+ volume_name,
parse_output=True, parse_output=True,
) )
self.wait_for_status("volume snapshot", snapshot_name, "available") self.wait_for_status("volume snapshot", snapshot_name, "available")
@ -227,9 +225,7 @@ class VolumeTests(common.BaseVolumeTests):
name = uuid.uuid4().hex name = uuid.uuid4().hex
# Create volume from snapshot # Create volume from snapshot
cmd_output = self.openstack( cmd_output = self.openstack(
'volume create ' + 'volume create ' + '--snapshot ' + snapshot_name + ' ' + name,
'--snapshot ' + snapshot_name +
' ' + name,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.openstack, 'volume delete ' + name) self.addCleanup(self.openstack, 'volume delete ' + name)
@ -241,8 +237,7 @@ class VolumeTests(common.BaseVolumeTests):
self.wait_for_status("volume", name, "available") self.wait_for_status("volume", name, "available")
# Delete snapshot # Delete snapshot
raw_output = self.openstack( raw_output = self.openstack('volume snapshot delete ' + snapshot_name)
'volume snapshot delete ' + snapshot_name)
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
# Deleting snapshot may take time. If volume snapshot still exists when # Deleting snapshot may take time. If volume snapshot still exists when
# a parent volume delete is requested, the volume deletion will fail. # a parent volume delete is requested, the volume deletion will fail.

View File

@ -16,7 +16,7 @@ from openstackclient.tests.functional.volume.v3 import common
class VolumeSnapshotTests(common.BaseVolumeTests): class VolumeSnapshotTests(common.BaseVolumeTests):
"""Functional tests for volume snapshot. """ """Functional tests for volume snapshot."""
VOLLY = uuid.uuid4().hex VOLLY = uuid.uuid4().hex
@ -25,9 +25,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
super(VolumeSnapshotTests, cls).setUpClass() super(VolumeSnapshotTests, cls).setUpClass()
# create a volume for all tests to create snapshot # create a volume for all tests to create snapshot
cmd_output = cls.openstack( cmd_output = cls.openstack(
'volume create ' + 'volume create ' + '--size 1 ' + cls.VOLLY,
'--size 1 ' +
cls.VOLLY,
parse_output=True, parse_output=True,
) )
cls.wait_for_status('volume', cls.VOLLY, 'available') cls.wait_for_status('volume', cls.VOLLY, 'available')
@ -37,8 +35,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
def tearDownClass(cls): def tearDownClass(cls):
try: try:
cls.wait_for_status('volume', cls.VOLLY, 'available') cls.wait_for_status('volume', cls.VOLLY, 'available')
raw_output = cls.openstack( raw_output = cls.openstack('volume delete --force ' + cls.VOLLY)
'volume delete --force ' + cls.VOLLY)
cls.assertOutput('', raw_output) cls.assertOutput('', raw_output)
finally: finally:
super(VolumeSnapshotTests, cls).tearDownClass() super(VolumeSnapshotTests, cls).tearDownClass()
@ -47,9 +44,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
"""Test create, delete multiple""" """Test create, delete multiple"""
name1 = uuid.uuid4().hex name1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
name1 +
' --volume ' + self.VOLLY,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -59,9 +54,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
name2 = uuid.uuid4().hex name2 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
name2 +
' --volume ' + self.VOLLY,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -73,7 +66,8 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
self.wait_for_status('volume snapshot', name2, 'available') self.wait_for_status('volume snapshot', name2, 'available')
del_output = self.openstack( del_output = self.openstack(
'volume snapshot delete ' + name1 + ' ' + name2) 'volume snapshot delete ' + name1 + ' ' + name2
)
self.assertOutput('', del_output) self.assertOutput('', del_output)
self.wait_for_delete('volume snapshot', name1) self.wait_for_delete('volume snapshot', name1)
self.wait_for_delete('volume snapshot', name2) self.wait_for_delete('volume snapshot', name2)
@ -82,9 +76,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
"""Test create, list filter""" """Test create, list filter"""
name1 = uuid.uuid4().hex name1 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
name1 +
' --volume ' + self.VOLLY,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.wait_for_delete, 'volume snapshot', name1) self.addCleanup(self.wait_for_delete, 'volume snapshot', name1)
@ -105,9 +97,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
name2 = uuid.uuid4().hex name2 = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
name2 +
' --volume ' + self.VOLLY,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.wait_for_delete, 'volume snapshot', name2) 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') self.wait_for_status('volume snapshot', name2, 'available')
raw_output = self.openstack( raw_output = self.openstack(
'volume snapshot set ' + 'volume snapshot set ' + '--state error ' + name2
'--state error ' +
name2
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
# Test list --long, --status # Test list --long, --status
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot list ' + 'volume snapshot list ' + '--long ' + '--status error',
'--long ' +
'--status error',
parse_output=True, parse_output=True,
) )
names = [x["Name"] for x in cmd_output] names = [x["Name"] for x in cmd_output]
@ -145,8 +131,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test list --volume # Test list --volume
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot list ' + 'volume snapshot list ' + '--volume ' + self.VOLLY,
'--volume ' + self.VOLLY,
parse_output=True, parse_output=True,
) )
names = [x["Name"] for x in cmd_output] names = [x["Name"] for x in cmd_output]
@ -155,8 +140,7 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test list --name # Test list --name
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot list ' + 'volume snapshot list ' + '--name ' + name1,
'--name ' + name1,
parse_output=True, parse_output=True,
) )
names = [x["Name"] for x in cmd_output] names = [x["Name"] for x in cmd_output]
@ -168,11 +152,12 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
name = uuid.uuid4().hex name = uuid.uuid4().hex
new_name = name + "_" new_name = name + "_"
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot create ' + 'volume snapshot create '
'--volume ' + self.VOLLY + + '--volume '
' --description aaaa ' + + self.VOLLY
'--property Alpha=a ' + + ' --description aaaa '
name, + '--property Alpha=a '
+ name,
parse_output=True, parse_output=True,
) )
self.addCleanup(self.wait_for_delete, 'volume snapshot', new_name) self.addCleanup(self.wait_for_delete, 'volume snapshot', new_name)
@ -197,19 +182,19 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test volume snapshot set # Test volume snapshot set
raw_output = self.openstack( raw_output = self.openstack(
'volume snapshot set ' + 'volume snapshot set '
'--name ' + new_name + + '--name '
' --description bbbb ' + + new_name
'--property Alpha=c ' + + ' --description bbbb '
'--property Beta=b ' + + '--property Alpha=c '
name, + '--property Beta=b '
+ name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
# Show snapshot set result # Show snapshot set result
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot show ' + 'volume snapshot show ' + new_name,
new_name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -231,15 +216,12 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test volume snapshot unset # Test volume snapshot unset
raw_output = self.openstack( raw_output = self.openstack(
'volume snapshot unset ' + 'volume snapshot unset ' + '--property Alpha ' + new_name,
'--property Alpha ' +
new_name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot show ' + 'volume snapshot show ' + new_name,
new_name,
parse_output=True, parse_output=True,
) )
self.assertEqual( self.assertEqual(
@ -249,14 +231,11 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
# Test volume snapshot set --no-property # Test volume snapshot set --no-property
raw_output = self.openstack( raw_output = self.openstack(
'volume snapshot set ' + 'volume snapshot set ' + '--no-property ' + new_name,
'--no-property ' +
new_name,
) )
self.assertOutput('', raw_output) self.assertOutput('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume snapshot show ' + 'volume snapshot show ' + new_name,
new_name,
parse_output=True, parse_output=True,
) )
self.assertNotIn( self.assertNotIn(

View File

@ -17,13 +17,12 @@ from openstackclient.tests.functional.volume.v3 import common
class VolumeTypeTests(common.BaseVolumeTests): class VolumeTypeTests(common.BaseVolumeTests):
"""Functional tests for volume type. """ """Functional tests for volume type."""
def test_volume_type_create_list(self): def test_volume_type_create_list(self):
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create --private ' + 'volume type create --private ' + name,
name,
parse_output=True, parse_output=True,
) )
self.addCleanup( self.addCleanup(
@ -51,14 +50,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
def test_volume_type_set_unset_properties(self): def test_volume_type_set_unset_properties(self):
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create --private ' + 'volume type create --private ' + name,
name,
parse_output=True, parse_output=True,
) )
self.addCleanup( self.addCleanup(self.openstack, 'volume type delete ' + name)
self.openstack,
'volume type delete ' + name
)
self.assertEqual(name, cmd_output['name']) self.assertEqual(name, cmd_output['name'])
raw_output = self.openstack( raw_output = self.openstack(
@ -71,9 +66,7 @@ class VolumeTypeTests(common.BaseVolumeTests):
) )
self.assertEqual({'a': 'b', 'c': 'd'}, cmd_output['properties']) self.assertEqual({'a': 'b', 'c': 'd'}, cmd_output['properties'])
raw_output = self.openstack( raw_output = self.openstack('volume type unset --property a %s' % name)
'volume type unset --property a %s' % name
)
self.assertEqual("", raw_output) self.assertEqual("", raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type show %s' % name, 'volume type show %s' % name,
@ -84,14 +77,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
def test_volume_type_set_unset_multiple_properties(self): def test_volume_type_set_unset_multiple_properties(self):
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create --private ' + 'volume type create --private ' + name,
name,
parse_output=True, parse_output=True,
) )
self.addCleanup( self.addCleanup(self.openstack, 'volume type delete ' + name)
self.openstack,
'volume type delete ' + name
)
self.assertEqual(name, cmd_output['name']) self.assertEqual(name, cmd_output['name'])
raw_output = self.openstack( raw_output = self.openstack(
@ -117,14 +106,10 @@ class VolumeTypeTests(common.BaseVolumeTests):
def test_volume_type_set_unset_project(self): def test_volume_type_set_unset_project(self):
name = uuid.uuid4().hex name = uuid.uuid4().hex
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create --private ' + 'volume type create --private ' + name,
name,
parse_output=True, parse_output=True,
) )
self.addCleanup( self.addCleanup(self.openstack, 'volume type delete ' + name)
self.openstack,
'volume type delete ' + name
)
self.assertEqual(name, cmd_output['name']) self.assertEqual(name, cmd_output['name'])
raw_output = self.openstack( raw_output = self.openstack(
@ -161,14 +146,15 @@ class VolumeTypeTests(common.BaseVolumeTests):
'--encryption-provider LuksEncryptor ' '--encryption-provider LuksEncryptor '
'--encryption-cipher aes-xts-plain64 ' '--encryption-cipher aes-xts-plain64 '
'--encryption-key-size 128 ' '--encryption-key-size 128 '
'--encryption-control-location front-end ' + '--encryption-control-location front-end ' + encryption_type,
encryption_type,
parse_output=True, parse_output=True,
) )
expected = {'provider': 'LuksEncryptor', expected = {
'cipher': 'aes-xts-plain64', 'provider': 'LuksEncryptor',
'key_size': 128, 'cipher': 'aes-xts-plain64',
'control_location': 'front-end'} 'key_size': 128,
'control_location': 'front-end',
}
for attr, value in expected.items(): for attr, value in expected.items():
self.assertEqual(value, cmd_output['encryption'][attr]) self.assertEqual(value, cmd_output['encryption'][attr])
# test show encryption type # test show encryption type
@ -176,10 +162,12 @@ class VolumeTypeTests(common.BaseVolumeTests):
'volume type show --encryption-type ' + encryption_type, 'volume type show --encryption-type ' + encryption_type,
parse_output=True, parse_output=True,
) )
expected = {'provider': 'LuksEncryptor', expected = {
'cipher': 'aes-xts-plain64', 'provider': 'LuksEncryptor',
'key_size': 128, 'cipher': 'aes-xts-plain64',
'control_location': 'front-end'} 'key_size': 128,
'control_location': 'front-end',
}
for attr, value in expected.items(): for attr, value in expected.items():
self.assertEqual(value, cmd_output['encryption'][attr]) self.assertEqual(value, cmd_output['encryption'][attr])
# test list encryption type # test list encryption type
@ -187,35 +175,39 @@ class VolumeTypeTests(common.BaseVolumeTests):
'volume type list --encryption-type', 'volume type list --encryption-type',
parse_output=True, parse_output=True,
) )
encryption_output = [t['Encryption'] for t in cmd_output encryption_output = [
if t['Name'] == encryption_type][0] t['Encryption'] for t in cmd_output if t['Name'] == encryption_type
expected = {'provider': 'LuksEncryptor', ][0]
'cipher': 'aes-xts-plain64', expected = {
'key_size': 128, 'provider': 'LuksEncryptor',
'control_location': 'front-end'} 'cipher': 'aes-xts-plain64',
'key_size': 128,
'control_location': 'front-end',
}
for attr, value in expected.items(): for attr, value in expected.items():
self.assertEqual(value, encryption_output[attr]) self.assertEqual(value, encryption_output[attr])
# test set existing encryption type # test set existing encryption type
raw_output = self.openstack( raw_output = self.openstack(
'volume type set ' 'volume type set '
'--encryption-key-size 256 ' '--encryption-key-size 256 '
'--encryption-control-location back-end ' + '--encryption-control-location back-end ' + encryption_type
encryption_type) )
self.assertEqual('', raw_output) self.assertEqual('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type show --encryption-type ' + encryption_type, 'volume type show --encryption-type ' + encryption_type,
parse_output=True, parse_output=True,
) )
expected = {'provider': 'LuksEncryptor', expected = {
'cipher': 'aes-xts-plain64', 'provider': 'LuksEncryptor',
'key_size': 256, 'cipher': 'aes-xts-plain64',
'control_location': 'back-end'} 'key_size': 256,
'control_location': 'back-end',
}
for attr, value in expected.items(): for attr, value in expected.items():
self.assertEqual(value, cmd_output['encryption'][attr]) self.assertEqual(value, cmd_output['encryption'][attr])
# test set new encryption type # test set new encryption type
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type create --private ' + 'volume type create --private ' + name,
name,
parse_output=True, parse_output=True,
) )
self.addCleanup( self.addCleanup(
@ -229,18 +221,20 @@ class VolumeTypeTests(common.BaseVolumeTests):
'--encryption-provider LuksEncryptor ' '--encryption-provider LuksEncryptor '
'--encryption-cipher aes-xts-plain64 ' '--encryption-cipher aes-xts-plain64 '
'--encryption-key-size 128 ' '--encryption-key-size 128 '
'--encryption-control-location front-end ' + '--encryption-control-location front-end ' + name
name) )
self.assertEqual('', raw_output) self.assertEqual('', raw_output)
cmd_output = self.openstack( cmd_output = self.openstack(
'volume type show --encryption-type ' + name, 'volume type show --encryption-type ' + name,
parse_output=True, parse_output=True,
) )
expected = {'provider': 'LuksEncryptor', expected = {
'cipher': 'aes-xts-plain64', 'provider': 'LuksEncryptor',
'key_size': 128, 'cipher': 'aes-xts-plain64',
'control_location': 'front-end'} 'key_size': 128,
'control_location': 'front-end',
}
for attr, value in expected.items(): for attr, value in expected.items():
self.assertEqual(value, cmd_output['encryption'][attr]) self.assertEqual(value, cmd_output['encryption'][attr])
# test unset encryption type # test unset encryption type

View File

@ -36,7 +36,6 @@ NAME = 'PhilSpector'
class TestFindResourceVolumes(test_utils.TestCase): class TestFindResourceVolumes(test_utils.TestCase):
def setUp(self): def setUp(self):
super(TestFindResourceVolumes, self).setUp() super(TestFindResourceVolumes, self).setUp()
api = mock.Mock() api = mock.Mock()
@ -44,8 +43,7 @@ class TestFindResourceVolumes(test_utils.TestCase):
api.client.get = mock.Mock() api.client.get = mock.Mock()
resp = mock.Mock() resp = mock.Mock()
body = {"volumes": [{"id": ID, 'display_name': NAME}]} body = {"volumes": [{"id": ID, 'display_name': NAME}]}
api.client.get.side_effect = [Exception("Not found"), api.client.get.side_effect = [Exception("Not found"), (resp, body)]
(resp, body)]
self.manager = volumes.VolumeManager(api) self.manager = volumes.VolumeManager(api)
def test_find(self): def test_find(self):
@ -54,12 +52,15 @@ class TestFindResourceVolumes(test_utils.TestCase):
self.assertEqual(NAME, result.display_name) self.assertEqual(NAME, result.display_name)
def test_not_find(self): def test_not_find(self):
self.assertRaises(exceptions.CommandError, utils.find_resource, self.assertRaises(
self.manager, 'GeorgeMartin') exceptions.CommandError,
utils.find_resource,
self.manager,
'GeorgeMartin',
)
class TestFindResourceVolumeSnapshots(test_utils.TestCase): class TestFindResourceVolumeSnapshots(test_utils.TestCase):
def setUp(self): def setUp(self):
super(TestFindResourceVolumeSnapshots, self).setUp() super(TestFindResourceVolumeSnapshots, self).setUp()
api = mock.Mock() api = mock.Mock()
@ -67,8 +68,7 @@ class TestFindResourceVolumeSnapshots(test_utils.TestCase):
api.client.get = mock.Mock() api.client.get = mock.Mock()
resp = mock.Mock() resp = mock.Mock()
body = {"snapshots": [{"id": ID, 'display_name': NAME}]} body = {"snapshots": [{"id": ID, 'display_name': NAME}]}
api.client.get.side_effect = [Exception("Not found"), api.client.get.side_effect = [Exception("Not found"), (resp, body)]
(resp, body)]
self.manager = volume_snapshots.SnapshotManager(api) self.manager = volume_snapshots.SnapshotManager(api)
def test_find(self): def test_find(self):
@ -77,5 +77,9 @@ class TestFindResourceVolumeSnapshots(test_utils.TestCase):
self.assertEqual(NAME, result.display_name) self.assertEqual(NAME, result.display_name)
def test_not_find(self): def test_not_find(self):
self.assertRaises(exceptions.CommandError, utils.find_resource, self.assertRaises(
self.manager, 'GeorgeMartin') exceptions.CommandError,
utils.find_resource,
self.manager,
'GeorgeMartin',
)

View File

@ -26,7 +26,6 @@ from openstackclient.volume.v1 import qos_specs
class TestQos(volume_fakes.TestVolumev1): class TestQos(volume_fakes.TestVolumev1):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -38,7 +37,6 @@ class TestQos(volume_fakes.TestVolumev1):
class TestQosAssociate(TestQos): class TestQosAssociate(TestQos):
volume_type = volume_fakes.create_one_volume_type() volume_type = volume_fakes.create_one_volume_type()
qos_spec = volume_fakes.create_one_qos() qos_spec = volume_fakes.create_one_qos()
@ -51,33 +49,23 @@ class TestQosAssociate(TestQos):
self.cmd = qos_specs.AssociateQos(self.app, None) self.cmd = qos_specs.AssociateQos(self.app, None)
def test_qos_associate(self): def test_qos_associate(self):
arglist = [ arglist = [self.qos_spec.id, self.volume_type.id]
self.qos_spec.id,
self.volume_type.id
]
verifylist = [ verifylist = [
('qos_spec', self.qos_spec.id), ('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) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.qos_mock.associate.assert_called_with( self.qos_mock.associate.assert_called_with(
self.qos_spec.id, self.qos_spec.id, self.volume_type.id
self.volume_type.id
) )
self.assertIsNone(result) self.assertIsNone(result)
class TestQosCreate(TestQos): class TestQosCreate(TestQos):
columns = ('consumer', 'id', 'name', 'properties')
columns = (
'consumer',
'id',
'name',
'properties'
)
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -86,7 +74,7 @@ class TestQosCreate(TestQos):
self.new_qos_spec.consumer, self.new_qos_spec.consumer,
self.new_qos_spec.id, self.new_qos_spec.id,
self.new_qos_spec.name, 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 self.qos_mock.create.return_value = self.new_qos_spec
# Get the command object to test # Get the command object to test
@ -104,8 +92,7 @@ class TestQosCreate(TestQos):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.qos_mock.create.assert_called_with( self.qos_mock.create.assert_called_with(
self.new_qos_spec.name, self.new_qos_spec.name, {'consumer': 'both'}
{'consumer': 'both'}
) )
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
@ -113,7 +100,8 @@ class TestQosCreate(TestQos):
def test_qos_create_with_consumer(self): def test_qos_create_with_consumer(self):
arglist = [ arglist = [
'--consumer', self.new_qos_spec.consumer, '--consumer',
self.new_qos_spec.consumer,
self.new_qos_spec.name, self.new_qos_spec.name,
] ]
verifylist = [ verifylist = [
@ -125,17 +113,19 @@ class TestQosCreate(TestQos):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.qos_mock.create.assert_called_with( self.qos_mock.create.assert_called_with(
self.new_qos_spec.name, self.new_qos_spec.name, {'consumer': self.new_qos_spec.consumer}
{'consumer': self.new_qos_spec.consumer}
) )
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertCountEqual(self.datalist, data) self.assertCountEqual(self.datalist, data)
def test_qos_create_with_properties(self): def test_qos_create_with_properties(self):
arglist = [ arglist = [
'--consumer', self.new_qos_spec.consumer, '--consumer',
'--property', 'foo=bar', self.new_qos_spec.consumer,
'--property', 'iops=9001', '--property',
'foo=bar',
'--property',
'iops=9001',
self.new_qos_spec.name, self.new_qos_spec.name,
] ]
verifylist = [ verifylist = [
@ -148,10 +138,10 @@ class TestQosCreate(TestQos):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.new_qos_spec.specs.update( 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.qos_mock.create.assert_called_with(
self.new_qos_spec.name, self.new_qos_spec.name, self.new_qos_spec.specs
self.new_qos_spec.specs
) )
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
@ -159,24 +149,18 @@ class TestQosCreate(TestQos):
class TestQosDelete(TestQos): class TestQosDelete(TestQos):
qos_specs = volume_fakes.create_qoses(count=2) qos_specs = volume_fakes.create_qoses(count=2)
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.qos_mock.get = ( self.qos_mock.get = volume_fakes.get_qoses(self.qos_specs)
volume_fakes.get_qoses(self.qos_specs))
# Get the command object to test # Get the command object to test
self.cmd = qos_specs.DeleteQos(self.app, None) self.cmd = qos_specs.DeleteQos(self.app, None)
def test_qos_delete_with_id(self): def test_qos_delete_with_id(self):
arglist = [ arglist = [self.qos_specs[0].id]
self.qos_specs[0].id verifylist = [('qos_specs', [self.qos_specs[0].id])]
]
verifylist = [
('qos_specs', [self.qos_specs[0].id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
@ -185,12 +169,8 @@ class TestQosDelete(TestQos):
self.assertIsNone(result) self.assertIsNone(result)
def test_qos_delete_with_name(self): def test_qos_delete_with_name(self):
arglist = [ arglist = [self.qos_specs[0].name]
self.qos_specs[0].name verifylist = [('qos_specs', [self.qos_specs[0].name])]
]
verifylist = [
('qos_specs', [self.qos_specs[0].name])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
@ -199,14 +179,8 @@ class TestQosDelete(TestQos):
self.assertIsNone(result) self.assertIsNone(result)
def test_qos_delete_with_force(self): def test_qos_delete_with_force(self):
arglist = [ arglist = ['--force', self.qos_specs[0].id]
'--force', verifylist = [('force', True), ('qos_specs', [self.qos_specs[0].id])]
self.qos_specs[0].id
]
verifylist = [
('force', True),
('qos_specs', [self.qos_specs[0].id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
@ -243,14 +217,16 @@ class TestQosDelete(TestQos):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [self.qos_specs[0], exceptions.CommandError] find_mock_result = [self.qos_specs[0], exceptions.CommandError]
with mock.patch.object(utils, 'find_resource', with mock.patch.object(
side_effect=find_mock_result) as find_mock: utils, 'find_resource', side_effect=find_mock_result
) as find_mock:
try: try:
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual( 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, self.qos_specs[0].id)
find_mock.assert_any_call(self.qos_mock, 'unexist_qos') find_mock.assert_any_call(self.qos_mock, 'unexist_qos')
@ -262,7 +238,6 @@ class TestQosDelete(TestQos):
class TestQosDisassociate(TestQos): class TestQosDisassociate(TestQos):
volume_type = volume_fakes.create_one_volume_type() volume_type = volume_fakes.create_one_volume_type()
qos_spec = volume_fakes.create_one_qos() qos_spec = volume_fakes.create_one_qos()
@ -276,7 +251,8 @@ class TestQosDisassociate(TestQos):
def test_qos_disassociate_with_volume_type(self): def test_qos_disassociate_with_volume_type(self):
arglist = [ arglist = [
'--volume-type', self.volume_type.id, '--volume-type',
self.volume_type.id,
self.qos_spec.id, self.qos_spec.id,
] ]
verifylist = [ verifylist = [
@ -288,8 +264,7 @@ class TestQosDisassociate(TestQos):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.qos_mock.disassociate.assert_called_with( self.qos_mock.disassociate.assert_called_with(
self.qos_spec.id, self.qos_spec.id, self.volume_type.id
self.volume_type.id
) )
self.assertIsNone(result) self.assertIsNone(result)
@ -298,9 +273,7 @@ class TestQosDisassociate(TestQos):
'--all', '--all',
self.qos_spec.id, self.qos_spec.id,
] ]
verifylist = [ verifylist = [('qos_spec', self.qos_spec.id)]
('qos_spec', self.qos_spec.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
@ -310,7 +283,6 @@ class TestQosDisassociate(TestQos):
class TestQosList(TestQos): class TestQosList(TestQos):
qos_specs = volume_fakes.create_qoses(count=2) qos_specs = volume_fakes.create_qoses(count=2)
qos_association = volume_fakes.create_one_qos_association() qos_association = volume_fakes.create_one_qos_association()
@ -323,13 +295,15 @@ class TestQosList(TestQos):
) )
data = [] data = []
for q in qos_specs: for q in qos_specs:
data.append(( data.append(
q.id, (
q.name, q.id,
q.consumer, q.name,
format_columns.ListColumn([qos_association.name]), q.consumer,
format_columns.DictColumn(q.specs), format_columns.ListColumn([qos_association.name]),
)) format_columns.DictColumn(q.specs),
)
)
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -381,7 +355,6 @@ class TestQosList(TestQos):
class TestQosSet(TestQos): class TestQosSet(TestQos):
qos_spec = volume_fakes.create_one_qos() qos_spec = volume_fakes.create_one_qos()
def setUp(self): def setUp(self):
@ -393,8 +366,10 @@ class TestQosSet(TestQos):
def test_qos_set_with_properties_with_id(self): def test_qos_set_with_properties_with_id(self):
arglist = [ arglist = [
'--property', 'foo=bar', '--property',
'--property', 'iops=9001', 'foo=bar',
'--property',
'iops=9001',
self.qos_spec.id, self.qos_spec.id,
] ]
verifylist = [ verifylist = [
@ -406,14 +381,12 @@ class TestQosSet(TestQos):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.qos_mock.set_keys.assert_called_with( self.qos_mock.set_keys.assert_called_with(
self.qos_spec.id, self.qos_spec.id, self.qos_spec.specs
self.qos_spec.specs
) )
self.assertIsNone(result) self.assertIsNone(result)
class TestQosShow(TestQos): class TestQosShow(TestQos):
qos_spec = volume_fakes.create_one_qos() qos_spec = volume_fakes.create_one_qos()
qos_association = volume_fakes.create_one_qos_association() qos_association = volume_fakes.create_one_qos_association()
@ -425,27 +398,15 @@ class TestQosShow(TestQos):
self.cmd = qos_specs.ShowQos(self.app, None) self.cmd = qos_specs.ShowQos(self.app, None)
def test_qos_show(self): def test_qos_show(self):
arglist = [ arglist = [self.qos_spec.id]
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) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.qos_mock.get.assert_called_with( self.qos_mock.get.assert_called_with(self.qos_spec.id)
self.qos_spec.id
)
collist = ( collist = ('associations', 'consumer', 'id', 'name', 'properties')
'associations',
'consumer',
'id',
'name',
'properties'
)
self.assertEqual(collist, columns) self.assertEqual(collist, columns)
datalist = ( datalist = (
format_columns.ListColumn([self.qos_association.name]), format_columns.ListColumn([self.qos_association.name]),
@ -458,7 +419,6 @@ class TestQosShow(TestQos):
class TestQosUnset(TestQos): class TestQosUnset(TestQos):
qos_spec = volume_fakes.create_one_qos() qos_spec = volume_fakes.create_one_qos()
def setUp(self): def setUp(self):
@ -470,8 +430,10 @@ class TestQosUnset(TestQos):
def test_qos_unset_with_properties(self): def test_qos_unset_with_properties(self):
arglist = [ arglist = [
'--property', 'iops', '--property',
'--property', 'foo', 'iops',
'--property',
'foo',
self.qos_spec.id, self.qos_spec.id,
] ]
verifylist = [ verifylist = [
@ -483,8 +445,7 @@ class TestQosUnset(TestQos):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.qos_mock.unset_keys.assert_called_with( self.qos_mock.unset_keys.assert_called_with(
self.qos_spec.id, self.qos_spec.id, ['iops', 'foo']
['iops', 'foo']
) )
self.assertIsNone(result) self.assertIsNone(result)

View File

@ -19,7 +19,6 @@ from openstackclient.volume.v1 import service
class TestService(volume_fakes.TestVolumev1): class TestService(volume_fakes.TestVolumev1):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -29,7 +28,6 @@ class TestService(volume_fakes.TestVolumev1):
class TestServiceList(TestService): class TestServiceList(TestService):
# The service to be listed # The service to be listed
services = volume_fakes.create_one_service() services = volume_fakes.create_one_service()
@ -43,8 +41,10 @@ class TestServiceList(TestService):
def test_service_list(self): def test_service_list(self):
arglist = [ arglist = [
'--host', self.services.host, '--host',
'--service', self.services.binary, self.services.host,
'--service',
self.services.binary,
] ]
verifylist = [ verifylist = [
('host', self.services.host), ('host', self.services.host),
@ -69,14 +69,16 @@ class TestServiceList(TestService):
# confirming if all expected columns are present in the result. # confirming if all expected columns are present in the result.
self.assertEqual(expected_columns, columns) self.assertEqual(expected_columns, columns)
datalist = (( datalist = (
self.services.binary, (
self.services.host, self.services.binary,
self.services.zone, self.services.host,
self.services.status, self.services.zone,
self.services.state, self.services.status,
self.services.updated_at, self.services.state,
), ) self.services.updated_at,
),
)
# confirming if all expected values are present in the result. # confirming if all expected values are present in the result.
self.assertEqual(datalist, tuple(data)) self.assertEqual(datalist, tuple(data))
@ -89,19 +91,20 @@ class TestServiceList(TestService):
# checking if prohibited columns are present in output # checking if prohibited columns are present in output
self.assertNotIn("Disabled Reason", columns) self.assertNotIn("Disabled Reason", columns)
self.assertNotIn(self.services.disabled_reason, self.assertNotIn(self.services.disabled_reason, tuple(data))
tuple(data))
def test_service_list_with_long_option(self): def test_service_list_with_long_option(self):
arglist = [ arglist = [
'--host', self.services.host, '--host',
'--service', self.services.binary, self.services.host,
'--long' '--service',
self.services.binary,
'--long',
] ]
verifylist = [ verifylist = [
('host', self.services.host), ('host', self.services.host),
('service', self.services.binary), ('service', self.services.binary),
('long', True) ('long', True),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -117,21 +120,23 @@ class TestServiceList(TestService):
'Status', 'Status',
'State', 'State',
'Updated At', 'Updated At',
'Disabled Reason' 'Disabled Reason',
] ]
# confirming if all expected columns are present in the result. # confirming if all expected columns are present in the result.
self.assertEqual(expected_columns, columns) self.assertEqual(expected_columns, columns)
datalist = (( datalist = (
self.services.binary, (
self.services.host, self.services.binary,
self.services.zone, self.services.host,
self.services.status, self.services.zone,
self.services.state, self.services.status,
self.services.updated_at, self.services.state,
self.services.disabled_reason, self.services.updated_at,
), ) self.services.disabled_reason,
),
)
# confirming if all expected values are present in the result. # confirming if all expected values are present in the result.
self.assertEqual(datalist, tuple(data)) self.assertEqual(datalist, tuple(data))
@ -143,7 +148,6 @@ class TestServiceList(TestService):
class TestServiceSet(TestService): class TestServiceSet(TestService):
service = volume_fakes.create_one_service() service = volume_fakes.create_one_service()
def setUp(self): def setUp(self):
@ -188,8 +192,7 @@ class TestServiceSet(TestService):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.service_mock.enable.assert_called_with( self.service_mock.enable.assert_called_with(
self.service.host, self.service.host, self.service.binary
self.service.binary
) )
self.service_mock.disable.assert_not_called() self.service_mock.disable.assert_not_called()
self.service_mock.disable_log_reason.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) result = self.cmd.take_action(parsed_args)
self.service_mock.disable.assert_called_with( self.service_mock.disable.assert_called_with(
self.service.host, self.service.host, self.service.binary
self.service.binary
) )
self.service_mock.enable.assert_not_called() self.service_mock.enable.assert_not_called()
self.service_mock.disable_log_reason.assert_not_called() self.service_mock.disable_log_reason.assert_not_called()
@ -222,7 +224,8 @@ class TestServiceSet(TestService):
reason = 'earthquake' reason = 'earthquake'
arglist = [ arglist = [
'--disable', '--disable',
'--disable-reason', reason, '--disable-reason',
reason,
self.service.host, self.service.host,
self.service.binary, self.service.binary,
] ]
@ -237,16 +240,15 @@ class TestServiceSet(TestService):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.service_mock.disable_log_reason.assert_called_with( self.service_mock.disable_log_reason.assert_called_with(
self.service.host, self.service.host, self.service.binary, reason
self.service.binary,
reason
) )
self.assertIsNone(result) self.assertIsNone(result)
def test_service_set_only_with_disable_reason(self): def test_service_set_only_with_disable_reason(self):
reason = 'earthquake' reason = 'earthquake'
arglist = [ arglist = [
'--disable-reason', reason, '--disable-reason',
reason,
self.service.host, self.service.host,
self.service.binary, self.service.binary,
] ]
@ -260,14 +262,18 @@ class TestServiceSet(TestService):
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail("CommandError should be raised.") self.fail("CommandError should be raised.")
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual("Cannot specify option --disable-reason without " self.assertEqual(
"--disable specified.", str(e)) "Cannot specify option --disable-reason without "
"--disable specified.",
str(e),
)
def test_service_set_enable_with_disable_reason(self): def test_service_set_enable_with_disable_reason(self):
reason = 'earthquake' reason = 'earthquake'
arglist = [ arglist = [
'--enable', '--enable',
'--disable-reason', reason, '--disable-reason',
reason,
self.service.host, self.service.host,
self.service.binary, self.service.binary,
] ]
@ -282,5 +288,8 @@ class TestServiceSet(TestService):
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail("CommandError should be raised.") self.fail("CommandError should be raised.")
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual("Cannot specify option --disable-reason without " self.assertEqual(
"--disable specified.", str(e)) "Cannot specify option --disable-reason without "
"--disable specified.",
str(e),
)

View File

@ -23,7 +23,6 @@ from openstackclient.volume.v1 import volume_transfer_request
class TestTransfer(volume_fakes.TestVolumev1): class TestTransfer(volume_fakes.TestVolumev1):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -37,7 +36,6 @@ class TestTransfer(volume_fakes.TestVolumev1):
class TestTransferAccept(TestTransfer): class TestTransferAccept(TestTransfer):
columns = ( columns = (
'id', 'id',
'name', 'name',
@ -59,11 +57,13 @@ class TestTransferAccept(TestTransfer):
# Get the command object to test # Get the command object to test
self.cmd = volume_transfer_request.AcceptTransferRequest( self.cmd = volume_transfer_request.AcceptTransferRequest(
self.app, None) self.app, None
)
def test_transfer_accept(self): def test_transfer_accept(self):
arglist = [ arglist = [
'--auth-key', 'key_value', '--auth-key',
'key_value',
self.volume_transfer.id, self.volume_transfer.id,
] ]
verifylist = [ verifylist = [
@ -101,7 +101,6 @@ class TestTransferAccept(TestTransfer):
class TestTransferCreate(TestTransfer): class TestTransferCreate(TestTransfer):
volume = volume_fakes.create_one_volume() volume = volume_fakes.create_one_volume()
columns = ( columns = (
@ -135,7 +134,8 @@ class TestTransferCreate(TestTransfer):
# Get the command object to test # Get the command object to test
self.cmd = volume_transfer_request.CreateTransferRequest( self.cmd = volume_transfer_request.CreateTransferRequest(
self.app, None) self.app, None
)
def test_transfer_create_without_name(self): def test_transfer_create_without_name(self):
arglist = [ arglist = [
@ -148,14 +148,14 @@ class TestTransferCreate(TestTransfer):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.transfer_mock.create.assert_called_once_with( self.transfer_mock.create.assert_called_once_with(self.volume.id, None)
self.volume.id, None)
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data) self.assertEqual(self.data, data)
def test_transfer_create_with_name(self): def test_transfer_create_with_name(self):
arglist = [ arglist = [
'--name', self.volume_transfer.name, '--name',
self.volume_transfer.name,
self.volume.id, self.volume.id,
] ]
verifylist = [ verifylist = [
@ -167,13 +167,14 @@ class TestTransferCreate(TestTransfer):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.transfer_mock.create.assert_called_once_with( 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.columns, columns)
self.assertEqual(self.data, data) self.assertEqual(self.data, data)
class TestTransferDelete(TestTransfer): class TestTransferDelete(TestTransfer):
volume_transfers = volume_fakes.create_transfers(count=2) volume_transfers = volume_fakes.create_transfers(count=2)
def setUp(self): def setUp(self):
@ -186,21 +187,19 @@ class TestTransferDelete(TestTransfer):
# Get the command object to mock # Get the command object to mock
self.cmd = volume_transfer_request.DeleteTransferRequest( self.cmd = volume_transfer_request.DeleteTransferRequest(
self.app, None) self.app, None
)
def test_transfer_delete(self): def test_transfer_delete(self):
arglist = [ arglist = [self.volume_transfers[0].id]
self.volume_transfers[0].id verifylist = [("transfer_request", [self.volume_transfers[0].id])]
]
verifylist = [
("transfer_request", [self.volume_transfers[0].id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.transfer_mock.delete.assert_called_with( self.transfer_mock.delete.assert_called_with(
self.volume_transfers[0].id) self.volume_transfers[0].id
)
self.assertIsNone(result) self.assertIsNone(result)
def test_delete_multiple_transfers(self): def test_delete_multiple_transfers(self):
@ -232,17 +231,21 @@ class TestTransferDelete(TestTransfer):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [self.volume_transfers[0], exceptions.CommandError] find_mock_result = [self.volume_transfers[0], exceptions.CommandError]
with mock.patch.object(utils, 'find_resource', with mock.patch.object(
side_effect=find_mock_result) as find_mock: utils, 'find_resource', side_effect=find_mock_result
) as find_mock:
try: try:
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual('1 of 2 volume transfer requests failed ' self.assertEqual(
'to delete', str(e)) '1 of 2 volume transfer requests failed ' 'to delete',
str(e),
)
find_mock.assert_any_call( 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') find_mock.assert_any_call(self.transfer_mock, 'unexist_transfer')
self.assertEqual(2, find_mock.call_count) self.assertEqual(2, find_mock.call_count)
@ -252,7 +255,6 @@ class TestTransferDelete(TestTransfer):
class TestTransferList(TestTransfer): class TestTransferList(TestTransfer):
# The Transfers to be listed # The Transfers to be listed
volume_transfers = volume_fakes.create_one_transfer() volume_transfers = volume_fakes.create_one_transfer()
@ -283,28 +285,25 @@ class TestTransferList(TestTransfer):
# confirming if all expected columns are present in the result. # confirming if all expected columns are present in the result.
self.assertEqual(expected_columns, columns) self.assertEqual(expected_columns, columns)
datalist = (( datalist = (
self.volume_transfers.id, (
self.volume_transfers.name, self.volume_transfers.id,
self.volume_transfers.volume_id, self.volume_transfers.name,
), ) self.volume_transfers.volume_id,
),
)
# confirming if all expected values are present in the result. # confirming if all expected values are present in the result.
self.assertEqual(datalist, tuple(data)) self.assertEqual(datalist, tuple(data))
# checking if proper call was made to list volume_transfers # checking if proper call was made to list volume_transfers
self.transfer_mock.list.assert_called_with( self.transfer_mock.list.assert_called_with(
detailed=True, detailed=True, search_opts={'all_tenants': 0}
search_opts={'all_tenants': 0}
) )
def test_transfer_list_with_argument(self): def test_transfer_list_with_argument(self):
arglist = [ arglist = ["--all-projects"]
"--all-projects" verifylist = [("all_projects", True)]
]
verifylist = [
("all_projects", True)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) 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. # confirming if all expected columns are present in the result.
self.assertEqual(expected_columns, columns) self.assertEqual(expected_columns, columns)
datalist = (( datalist = (
self.volume_transfers.id, (
self.volume_transfers.name, self.volume_transfers.id,
self.volume_transfers.volume_id, self.volume_transfers.name,
), ) self.volume_transfers.volume_id,
),
)
# confirming if all expected values are present in the result. # confirming if all expected values are present in the result.
self.assertEqual(datalist, tuple(data)) self.assertEqual(datalist, tuple(data))
# checking if proper call was made to list volume_transfers # checking if proper call was made to list volume_transfers
self.transfer_mock.list.assert_called_with( self.transfer_mock.list.assert_called_with(
detailed=True, detailed=True, search_opts={'all_tenants': 1}
search_opts={'all_tenants': 1}
) )
class TestTransferShow(TestTransfer): class TestTransferShow(TestTransfer):
columns = ( columns = (
'created_at', 'created_at',
'id', 'id',
@ -363,8 +362,7 @@ class TestTransferShow(TestTransfer):
self.transfer_mock.get.return_value = self.volume_transfer self.transfer_mock.get.return_value = self.volume_transfer
# Get the command object to test # Get the command object to test
self.cmd = volume_transfer_request.ShowTransferRequest( self.cmd = volume_transfer_request.ShowTransferRequest(self.app, None)
self.app, None)
def test_transfer_show(self): def test_transfer_show(self):
arglist = [ arglist = [
@ -377,7 +375,6 @@ class TestTransferShow(TestTransfer):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.transfer_mock.get.assert_called_once_with( self.transfer_mock.get.assert_called_once_with(self.volume_transfer.id)
self.volume_transfer.id)
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data) self.assertEqual(self.data, data)

View File

@ -25,7 +25,6 @@ from openstackclient.volume.v1 import volume_type
class TestType(volume_fakes.TestVolumev1): class TestType(volume_fakes.TestVolumev1):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -33,12 +32,12 @@ class TestType(volume_fakes.TestVolumev1):
self.types_mock.reset_mock() self.types_mock.reset_mock()
self.encryption_types_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.encryption_types_mock.reset_mock()
class TestTypeCreate(TestType): class TestTypeCreate(TestType):
columns = ( columns = (
'description', 'description',
'id', 'id',
@ -110,10 +109,14 @@ class TestTypeCreate(TestType):
self.new_volume_type.name, self.new_volume_type.name,
) )
arglist = [ arglist = [
'--encryption-provider', 'LuksEncryptor', '--encryption-provider',
'--encryption-cipher', 'aes-xts-plain64', 'LuksEncryptor',
'--encryption-key-size', '128', '--encryption-cipher',
'--encryption-control-location', 'front-end', 'aes-xts-plain64',
'--encryption-key-size',
'128',
'--encryption-control-location',
'front-end',
self.new_volume_type.name, self.new_volume_type.name,
] ]
verifylist = [ verifylist = [
@ -144,7 +147,6 @@ class TestTypeCreate(TestType):
class TestTypeDelete(TestType): class TestTypeDelete(TestType):
volume_types = volume_fakes.create_volume_types(count=2) volume_types = volume_fakes.create_volume_types(count=2)
def setUp(self): def setUp(self):
@ -157,12 +159,8 @@ class TestTypeDelete(TestType):
self.cmd = volume_type.DeleteVolumeType(self.app, None) self.cmd = volume_type.DeleteVolumeType(self.app, None)
def test_type_delete(self): def test_type_delete(self):
arglist = [ arglist = [self.volume_types[0].id]
self.volume_types[0].id verifylist = [("volume_types", [self.volume_types[0].id])]
]
verifylist = [
("volume_types", [self.volume_types[0].id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
@ -199,17 +197,18 @@ class TestTypeDelete(TestType):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [self.volume_types[0], exceptions.CommandError] find_mock_result = [self.volume_types[0], exceptions.CommandError]
with mock.patch.object(utils, 'find_resource', with mock.patch.object(
side_effect=find_mock_result) as find_mock: utils, 'find_resource', side_effect=find_mock_result
) as find_mock:
try: try:
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual('1 of 2 volume types failed to delete.', self.assertEqual(
str(e)) '1 of 2 volume types failed to delete.', str(e)
)
find_mock.assert_any_call( find_mock.assert_any_call(self.types_mock, self.volume_types[0].id)
self.types_mock, self.volume_types[0].id)
find_mock.assert_any_call(self.types_mock, 'unexist_type') find_mock.assert_any_call(self.types_mock, 'unexist_type')
self.assertEqual(2, find_mock.call_count) self.assertEqual(2, find_mock.call_count)
@ -219,7 +218,6 @@ class TestTypeDelete(TestType):
class TestTypeList(TestType): class TestTypeList(TestType):
volume_types = volume_fakes.create_volume_types() volume_types = volume_fakes.create_volume_types()
columns = [ columns = [
@ -227,28 +225,27 @@ class TestTypeList(TestType):
"Name", "Name",
"Is Public", "Is Public",
] ]
columns_long = [ columns_long = ["ID", "Name", "Is Public", "Properties"]
"ID",
"Name",
"Is Public",
"Properties"
]
data = [] data = []
for t in volume_types: for t in volume_types:
data.append(( data.append(
t.id, (
t.name, t.id,
t.is_public, t.name,
)) t.is_public,
)
)
data_long = [] data_long = []
for t in volume_types: for t in volume_types:
data_long.append(( data_long.append(
t.id, (
t.name, t.id,
t.is_public, t.name,
format_columns.DictColumn(t.extra_specs), t.is_public,
)) format_columns.DictColumn(t.extra_specs),
)
)
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -300,21 +297,25 @@ class TestTypeList(TestType):
"Encryption", "Encryption",
] ]
encryption_data = [] encryption_data = []
encryption_data.append(( encryption_data.append(
self.volume_types[0].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,
{self.volume_types[0].id: encryption_info}), self.volume_types[0].name,
)) self.volume_types[0].is_public,
encryption_data.append(( volume_type.EncryptionInfoColumn(
self.volume_types[1].id, self.volume_types[0].id,
self.volume_types[1].name, {self.volume_types[0].id: encryption_info},
self.volume_types[1].is_public, ),
volume_type.EncryptionInfoColumn( )
self.volume_types[1].id, {}), )
)) 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] self.encryption_types_mock.list.return_value = [encryption_type]
arglist = [ arglist = [
@ -333,7 +334,6 @@ class TestTypeList(TestType):
class TestTypeSet(TestType): class TestTypeSet(TestType):
volume_type = volume_fakes.create_one_volume_type( volume_type = volume_fakes.create_one_volume_type(
methods={'set_keys': None}, methods={'set_keys': None},
) )
@ -361,7 +361,8 @@ class TestTypeSet(TestType):
def test_type_set_property(self): def test_type_set_property(self):
arglist = [ arglist = [
'--property', 'myprop=myvalue', '--property',
'myprop=myvalue',
self.volume_type.id, self.volume_type.id,
] ]
verifylist = [ verifylist = [
@ -372,15 +373,20 @@ class TestTypeSet(TestType):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.volume_type.set_keys.assert_called_once_with( self.volume_type.set_keys.assert_called_once_with(
{'myprop': 'myvalue'}) {'myprop': 'myvalue'}
)
self.assertIsNone(result) self.assertIsNone(result)
def test_type_set_new_encryption(self): def test_type_set_new_encryption(self):
arglist = [ arglist = [
'--encryption-provider', 'LuksEncryptor', '--encryption-provider',
'--encryption-cipher', 'aes-xts-plain64', 'LuksEncryptor',
'--encryption-key-size', '128', '--encryption-cipher',
'--encryption-control-location', 'front-end', 'aes-xts-plain64',
'--encryption-key-size',
'128',
'--encryption-control-location',
'front-end',
self.volume_type.id, self.volume_type.id,
] ]
verifylist = [ verifylist = [
@ -407,9 +413,12 @@ class TestTypeSet(TestType):
def test_type_set_new_encryption_without_provider(self): def test_type_set_new_encryption_without_provider(self):
arglist = [ arglist = [
'--encryption-cipher', 'aes-xts-plain64', '--encryption-cipher',
'--encryption-key-size', '128', 'aes-xts-plain64',
'--encryption-control-location', 'front-end', '--encryption-key-size',
'128',
'--encryption-control-location',
'front-end',
self.volume_type.id, self.volume_type.id,
] ]
verifylist = [ verifylist = [
@ -423,15 +432,15 @@ class TestTypeSet(TestType):
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual("Command Failed: One or more of" self.assertEqual(
" the operations failed", "Command Failed: One or more of" " the operations failed",
str(e)) str(e),
)
self.encryption_types_mock.create.assert_not_called() self.encryption_types_mock.create.assert_not_called()
self.encryption_types_mock.update.assert_not_called() self.encryption_types_mock.update.assert_not_called()
class TestTypeShow(TestType): class TestTypeShow(TestType):
columns = ( columns = (
'description', 'description',
'id', 'id',
@ -449,7 +458,7 @@ class TestTypeShow(TestType):
self.volume_type.id, self.volume_type.id,
True, True,
self.volume_type.name, 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 self.types_mock.get.return_value = self.volume_type
@ -458,9 +467,7 @@ class TestTypeShow(TestType):
self.cmd = volume_type.ShowVolumeType(self.app, None) self.cmd = volume_type.ShowVolumeType(self.app, None)
def test_type_show(self): def test_type_show(self):
arglist = [ arglist = [self.volume_type.id]
self.volume_type.id
]
verifylist = [ verifylist = [
("volume_type", self.volume_type.id), ("volume_type", self.volume_type.id),
("encryption_type", False), ("encryption_type", False),
@ -500,15 +507,12 @@ class TestTypeShow(TestType):
self.volume_type.id, self.volume_type.id,
True, True,
self.volume_type.name, self.volume_type.name,
format_columns.DictColumn(self.volume_type.extra_specs) format_columns.DictColumn(self.volume_type.extra_specs),
) )
arglist = [ arglist = ['--encryption-type', self.volume_type.id]
'--encryption-type',
self.volume_type.id
]
verifylist = [ verifylist = [
('encryption_type', True), ('encryption_type', True),
("volume_type", self.volume_type.id) ("volume_type", self.volume_type.id),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -520,7 +524,6 @@ class TestTypeShow(TestType):
class TestTypeUnset(TestType): class TestTypeUnset(TestType):
volume_type = volume_fakes.create_one_volume_type( volume_type = volume_fakes.create_one_volume_type(
methods={'unset_keys': None}, methods={'unset_keys': None},
) )
@ -535,8 +538,10 @@ class TestTypeUnset(TestType):
def test_type_unset_property(self): def test_type_unset_property(self):
arglist = [ arglist = [
'--property', 'property', '--property',
'--property', 'multi_property', 'property',
'--property',
'multi_property',
self.volume_type.id, self.volume_type.id,
] ]
verifylist = [ verifylist = [
@ -549,24 +554,29 @@ class TestTypeUnset(TestType):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.volume_type.unset_keys.assert_called_once_with( self.volume_type.unset_keys.assert_called_once_with(
['property', 'multi_property']) ['property', 'multi_property']
)
self.encryption_types_mock.delete.assert_not_called() self.encryption_types_mock.delete.assert_not_called()
self.assertIsNone(result) self.assertIsNone(result)
def test_type_unset_failed_with_missing_volume_type_argument(self): def test_type_unset_failed_with_missing_volume_type_argument(self):
arglist = [ arglist = [
'--property', 'property', '--property',
'--property', 'multi_property', 'property',
'--property',
'multi_property',
] ]
verifylist = [ verifylist = [
('property', ['property', 'multi_property']), ('property', ['property', 'multi_property']),
] ]
self.assertRaises(tests_utils.ParserException, self.assertRaises(
self.check_parser, tests_utils.ParserException,
self.cmd, self.check_parser,
arglist, self.cmd,
verifylist) arglist,
verifylist,
)
def test_type_unset_nothing(self): def test_type_unset_nothing(self):
arglist = [ arglist = [
@ -598,7 +608,6 @@ class TestTypeUnset(TestType):
class TestColumns(TestType): class TestColumns(TestType):
def test_encryption_info_column_with_info(self): def test_encryption_info_column_with_info(self):
fake_volume_type = volume_fakes.create_one_volume_type() fake_volume_type = volume_fakes.create_one_volume_type()
type_id = fake_volume_type.id type_id = fake_volume_type.id
@ -609,10 +618,12 @@ class TestColumns(TestType):
'key_size': None, 'key_size': None,
'control_location': 'front-end', 'control_location': 'front-end',
} }
col = volume_type.EncryptionInfoColumn(type_id, col = volume_type.EncryptionInfoColumn(
{type_id: encryption_info}) type_id, {type_id: encryption_info}
self.assertEqual(utils.format_dict(encryption_info), )
col.human_readable()) self.assertEqual(
utils.format_dict(encryption_info), col.human_readable()
)
self.assertEqual(encryption_info, col.machine_readable()) self.assertEqual(encryption_info, col.machine_readable())
def test_encryption_info_column_without_info(self): def test_encryption_info_column_without_info(self):

View File

@ -29,7 +29,6 @@ from openstackclient.volume.v1 import volume
class TestVolume(volume_fakes.TestVolumev1): class TestVolume(volume_fakes.TestVolumev1):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -57,7 +56,6 @@ class TestVolume(volume_fakes.TestVolumev1):
class TestVolumeCreate(TestVolume): class TestVolumeCreate(TestVolume):
project = identity_fakes.FakeProject.create_one_project() project = identity_fakes.FakeProject.create_one_project()
user = identity_fakes.FakeUser.create_one_user() user = identity_fakes.FakeUser.create_one_user()
@ -100,7 +98,8 @@ class TestVolumeCreate(TestVolume):
def test_volume_create_min_options(self): def test_volume_create_min_options(self):
arglist = [ arglist = [
'--size', str(self.new_volume.size), '--size',
str(self.new_volume.size),
self.new_volume.display_name, self.new_volume.display_name,
] ]
verifylist = [ verifylist = [
@ -137,10 +136,14 @@ class TestVolumeCreate(TestVolume):
def test_volume_create_options(self): def test_volume_create_options(self):
arglist = [ arglist = [
'--size', str(self.new_volume.size), '--size',
'--description', self.new_volume.display_description, str(self.new_volume.size),
'--type', self.new_volume.volume_type, '--description',
'--availability-zone', self.new_volume.availability_zone, self.new_volume.display_description,
'--type',
self.new_volume.volume_type,
'--availability-zone',
self.new_volume.availability_zone,
self.new_volume.display_name, self.new_volume.display_name,
] ]
verifylist = [ verifylist = [
@ -186,9 +189,12 @@ class TestVolumeCreate(TestVolume):
self.users_mock.get.return_value = self.user self.users_mock.get.return_value = self.user
arglist = [ arglist = [
'--size', str(self.new_volume.size), '--size',
'--project', self.project.id, str(self.new_volume.size),
'--user', self.user.id, '--project',
self.project.id,
'--user',
self.user.id,
self.new_volume.display_name, self.new_volume.display_name,
] ]
verifylist = [ verifylist = [
@ -233,9 +239,12 @@ class TestVolumeCreate(TestVolume):
self.users_mock.get.return_value = self.user self.users_mock.get.return_value = self.user
arglist = [ arglist = [
'--size', str(self.new_volume.size), '--size',
'--project', self.project.name, str(self.new_volume.size),
'--user', self.user.name, '--project',
self.project.name,
'--user',
self.user.name,
self.new_volume.display_name, self.new_volume.display_name,
] ]
verifylist = [ verifylist = [
@ -275,9 +284,12 @@ class TestVolumeCreate(TestVolume):
def test_volume_create_properties(self): def test_volume_create_properties(self):
arglist = [ arglist = [
'--property', 'Alpha=a', '--property',
'--property', 'Beta=b', 'Alpha=a',
'--size', str(self.new_volume.size), '--property',
'Beta=b',
'--size',
str(self.new_volume.size),
self.new_volume.display_name, self.new_volume.display_name,
] ]
verifylist = [ verifylist = [
@ -319,8 +331,10 @@ class TestVolumeCreate(TestVolume):
self.images_mock.get.return_value = image self.images_mock.get.return_value = image
arglist = [ arglist = [
'--image', image.id, '--image',
'--size', str(self.new_volume.size), image.id,
'--size',
str(self.new_volume.size),
self.new_volume.display_name, self.new_volume.display_name,
] ]
verifylist = [ verifylist = [
@ -362,8 +376,10 @@ class TestVolumeCreate(TestVolume):
self.images_mock.get.return_value = image self.images_mock.get.return_value = image
arglist = [ arglist = [
'--image', image.name, '--image',
'--size', str(self.new_volume.size), image.name,
'--size',
str(self.new_volume.size),
self.new_volume.display_name, self.new_volume.display_name,
] ]
verifylist = [ verifylist = [
@ -403,7 +419,8 @@ class TestVolumeCreate(TestVolume):
def test_volume_create_with_source(self): def test_volume_create_with_source(self):
self.volumes_mock.get.return_value = self.new_volume self.volumes_mock.get.return_value = self.new_volume
arglist = [ arglist = [
'--source', self.new_volume.id, '--source',
self.new_volume.id,
self.new_volume.display_name, self.new_volume.display_name,
] ]
verifylist = [ verifylist = [
@ -435,7 +452,8 @@ class TestVolumeCreate(TestVolume):
arglist = [ arglist = [
'--bootable', '--bootable',
'--read-only', '--read-only',
'--size', str(self.new_volume.size), '--size',
str(self.new_volume.size),
self.new_volume.display_name, self.new_volume.display_name,
] ]
verifylist = [ verifylist = [
@ -447,8 +465,7 @@ class TestVolumeCreate(TestVolume):
('name', self.new_volume.display_name), ('name', self.new_volume.display_name),
] ]
parsed_args = self.check_parser( parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
@ -469,16 +486,19 @@ class TestVolumeCreate(TestVolume):
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertCountEqual(self.datalist, data) self.assertCountEqual(self.datalist, data)
self.volumes_mock.set_bootable.assert_called_with( 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.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) @mock.patch.object(utils, 'wait_for_status', return_value=True)
def test_volume_create_with_nonbootable_and_readwrite(self, mock_wait): def test_volume_create_with_nonbootable_and_readwrite(self, mock_wait):
arglist = [ arglist = [
'--non-bootable', '--non-bootable',
'--read-write', '--read-write',
'--size', str(self.new_volume.size), '--size',
str(self.new_volume.size),
self.new_volume.display_name, self.new_volume.display_name,
] ]
verifylist = [ verifylist = [
@ -490,8 +510,7 @@ class TestVolumeCreate(TestVolume):
('name', self.new_volume.display_name), ('name', self.new_volume.display_name),
] ]
parsed_args = self.check_parser( parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
@ -512,25 +531,28 @@ class TestVolumeCreate(TestVolume):
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertCountEqual(self.datalist, data) self.assertCountEqual(self.datalist, data)
self.volumes_mock.set_bootable.assert_called_with( 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.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(volume.LOG, 'error')
@mock.patch.object(utils, 'wait_for_status', return_value=True) @mock.patch.object(utils, 'wait_for_status', return_value=True)
def test_volume_create_with_bootable_and_readonly_fail( def test_volume_create_with_bootable_and_readonly_fail(
self, mock_wait, mock_error): self, mock_wait, mock_error
):
self.volumes_mock.set_bootable.side_effect = ( self.volumes_mock.set_bootable.side_effect = exceptions.CommandError()
exceptions.CommandError())
self.volumes_mock.update_readonly_flag.side_effect = ( self.volumes_mock.update_readonly_flag.side_effect = (
exceptions.CommandError()) exceptions.CommandError()
)
arglist = [ arglist = [
'--bootable', '--bootable',
'--read-only', '--read-only',
'--size', str(self.new_volume.size), '--size',
str(self.new_volume.size),
self.new_volume.display_name, self.new_volume.display_name,
] ]
verifylist = [ verifylist = [
@ -542,8 +564,7 @@ class TestVolumeCreate(TestVolume):
('name', self.new_volume.display_name), ('name', self.new_volume.display_name),
] ]
parsed_args = self.check_parser( parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
@ -565,18 +586,22 @@ class TestVolumeCreate(TestVolume):
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertCountEqual(self.datalist, data) self.assertCountEqual(self.datalist, data)
self.volumes_mock.set_bootable.assert_called_with( 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.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(volume.LOG, 'error')
@mock.patch.object(utils, 'wait_for_status', return_value=False) @mock.patch.object(utils, 'wait_for_status', return_value=False)
def test_volume_create_non_available_with_readonly( def test_volume_create_non_available_with_readonly(
self, mock_wait, mock_error): self, mock_wait, mock_error
):
arglist = [ arglist = [
'--non-bootable', '--non-bootable',
'--read-only', '--read-only',
'--size', str(self.new_volume.size), '--size',
str(self.new_volume.size),
self.new_volume.display_name, self.new_volume.display_name,
] ]
verifylist = [ verifylist = [
@ -588,8 +613,7 @@ class TestVolumeCreate(TestVolume):
('name', self.new_volume.display_name), ('name', self.new_volume.display_name),
] ]
parsed_args = self.check_parser( parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
@ -620,15 +644,20 @@ class TestVolumeCreate(TestVolume):
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(exceptions.CommandError, self.cmd.take_action, self.assertRaises(
parsed_args) exceptions.CommandError, self.cmd.take_action, parsed_args
)
def test_volume_create_with_multi_source(self): def test_volume_create_with_multi_source(self):
arglist = [ arglist = [
'--image', 'source_image', '--image',
'--source', 'source_volume', 'source_image',
'--snapshot', 'source_snapshot', '--source',
'--size', str(self.new_volume.size), 'source_volume',
'--snapshot',
'source_snapshot',
'--size',
str(self.new_volume.size),
self.new_volume.display_name, self.new_volume.display_name,
] ]
verifylist = [ verifylist = [
@ -639,13 +668,20 @@ class TestVolumeCreate(TestVolume):
('name', self.new_volume.display_name), ('name', self.new_volume.display_name),
] ]
self.assertRaises(tests_utils.ParserException, self.check_parser, self.assertRaises(
self.cmd, arglist, verifylist) tests_utils.ParserException,
self.check_parser,
self.cmd,
arglist,
verifylist,
)
def test_volume_create_backward_compatibility(self): def test_volume_create_backward_compatibility(self):
arglist = [ arglist = [
'-c', 'display_name', '-c',
'--size', str(self.new_volume.size), 'display_name',
'--size',
str(self.new_volume.size),
self.new_volume.display_name, self.new_volume.display_name,
] ]
verifylist = [ verifylist = [
@ -676,7 +712,6 @@ class TestVolumeCreate(TestVolume):
class TestVolumeDelete(TestVolume): class TestVolumeDelete(TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -688,9 +723,7 @@ class TestVolumeDelete(TestVolume):
def test_volume_delete_one_volume(self): def test_volume_delete_one_volume(self):
volumes = self.setup_volumes_mock(count=1) volumes = self.setup_volumes_mock(count=1)
arglist = [ arglist = [volumes[0].id]
volumes[0].id
]
verifylist = [ verifylist = [
("force", False), ("force", False),
("volumes", [volumes[0].id]), ("volumes", [volumes[0].id]),
@ -732,14 +765,14 @@ class TestVolumeDelete(TestVolume):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [volumes[0], exceptions.CommandError] find_mock_result = [volumes[0], exceptions.CommandError]
with mock.patch.object(utils, 'find_resource', with mock.patch.object(
side_effect=find_mock_result) as find_mock: utils, 'find_resource', side_effect=find_mock_result
) as find_mock:
try: try:
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual('1 of 2 volumes failed to delete.', self.assertEqual('1 of 2 volumes failed to delete.', str(e))
str(e))
find_mock.assert_any_call(self.volumes_mock, volumes[0].id) find_mock.assert_any_call(self.volumes_mock, volumes[0].id)
find_mock.assert_any_call(self.volumes_mock, 'unexist_volume') find_mock.assert_any_call(self.volumes_mock, 'unexist_volume')
@ -767,7 +800,6 @@ class TestVolumeDelete(TestVolume):
class TestVolumeList(TestVolume): class TestVolumeList(TestVolume):
_volume = volume_fakes.create_one_volume() _volume = volume_fakes.create_one_volume()
columns = ( columns = (
'ID', 'ID',
@ -812,7 +844,8 @@ class TestVolumeList(TestVolume):
def test_volume_list_name(self): def test_volume_list_name(self):
arglist = [ arglist = [
'--name', self._volume.display_name, '--name',
self._volume.display_name,
] ]
verifylist = [ verifylist = [
('long', False), ('long', False),
@ -829,7 +862,8 @@ class TestVolumeList(TestVolume):
def test_volume_list_status(self): def test_volume_list_status(self):
arglist = [ arglist = [
'--status', self._volume.status, '--status',
self._volume.status,
] ]
verifylist = [ verifylist = [
('long', False), ('long', False),
@ -889,22 +923,26 @@ class TestVolumeList(TestVolume):
) )
self.assertEqual(collist, columns) self.assertEqual(collist, columns)
datalist = (( datalist = (
self._volume.id, (
self._volume.display_name, self._volume.id,
self._volume.status, self._volume.display_name,
self._volume.size, self._volume.status,
self._volume.volume_type, self._volume.size,
self._volume.bootable, self._volume.volume_type,
volume.AttachmentsColumn(self._volume.attachments), self._volume.bootable,
format_columns.DictColumn(self._volume.metadata), volume.AttachmentsColumn(self._volume.attachments),
), ) format_columns.DictColumn(self._volume.metadata),
),
)
self.assertCountEqual(datalist, tuple(data)) self.assertCountEqual(datalist, tuple(data))
def test_volume_list_with_limit_and_offset(self): def test_volume_list_with_limit_and_offset(self):
arglist = [ arglist = [
'--limit', '2', '--limit',
'--offset', '5', '2',
'--offset',
'5',
] ]
verifylist = [ verifylist = [
('long', False), ('long', False),
@ -932,17 +970,24 @@ class TestVolumeList(TestVolume):
def test_volume_list_negative_limit(self): def test_volume_list_negative_limit(self):
arglist = [ arglist = [
"--limit", "-2", "--limit",
"-2",
] ]
verifylist = [ verifylist = [
("limit", -2), ("limit", -2),
] ]
self.assertRaises(argparse.ArgumentTypeError, self.check_parser, self.assertRaises(
self.cmd, arglist, verifylist) argparse.ArgumentTypeError,
self.check_parser,
self.cmd,
arglist,
verifylist,
)
def test_volume_list_backward_compatibility(self): def test_volume_list_backward_compatibility(self):
arglist = [ arglist = [
'-c', 'Display Name', '-c',
'Display Name',
] ]
verifylist = [ verifylist = [
('columns', ['Display Name']), ('columns', ['Display Name']),
@ -963,7 +1008,6 @@ class TestVolumeList(TestVolume):
class TestVolumeMigrate(TestVolume): class TestVolumeMigrate(TestVolume):
_volume = volume_fakes.create_one_volume() _volume = volume_fakes.create_one_volume()
def setUp(self): def setUp(self):
@ -976,7 +1020,8 @@ class TestVolumeMigrate(TestVolume):
def test_volume_migrate(self): def test_volume_migrate(self):
arglist = [ arglist = [
"--host", "host@backend-name#pool", "--host",
"host@backend-name#pool",
self._volume.id, self._volume.id,
] ]
verifylist = [ verifylist = [
@ -989,13 +1034,15 @@ class TestVolumeMigrate(TestVolume):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.volumes_mock.get.assert_called_once_with(self._volume.id) self.volumes_mock.get.assert_called_once_with(self._volume.id)
self.volumes_mock.migrate_volume.assert_called_once_with( 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) self.assertIsNone(result)
def test_volume_migrate_with_option(self): def test_volume_migrate_with_option(self):
arglist = [ arglist = [
"--force-host-copy", "--force-host-copy",
"--host", "host@backend-name#pool", "--host",
"host@backend-name#pool",
self._volume.id, self._volume.id,
] ]
verifylist = [ verifylist = [
@ -1008,7 +1055,8 @@ class TestVolumeMigrate(TestVolume):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.volumes_mock.get.assert_called_once_with(self._volume.id) self.volumes_mock.get.assert_called_once_with(self._volume.id)
self.volumes_mock.migrate_volume.assert_called_once_with( 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) self.assertIsNone(result)
def test_volume_migrate_without_host(self): def test_volume_migrate_without_host(self):
@ -1020,12 +1068,16 @@ class TestVolumeMigrate(TestVolume):
("volume", self._volume.id), ("volume", self._volume.id),
] ]
self.assertRaises(tests_utils.ParserException, self.check_parser, self.assertRaises(
self.cmd, arglist, verifylist) tests_utils.ParserException,
self.check_parser,
self.cmd,
arglist,
verifylist,
)
class TestVolumeSet(TestVolume): class TestVolumeSet(TestVolume):
_volume = volume_fakes.create_one_volume() _volume = volume_fakes.create_one_volume()
def setUp(self): def setUp(self):
@ -1055,7 +1107,8 @@ class TestVolumeSet(TestVolume):
def test_volume_set_name(self): def test_volume_set_name(self):
arglist = [ arglist = [
'--name', 'qwerty', '--name',
'qwerty',
self._volume.display_name, self._volume.display_name,
] ]
verifylist = [ verifylist = [
@ -1073,15 +1126,13 @@ class TestVolumeSet(TestVolume):
kwargs = { kwargs = {
'display_name': 'qwerty', 'display_name': 'qwerty',
} }
self.volumes_mock.update.assert_called_with( self.volumes_mock.update.assert_called_with(self._volume.id, **kwargs)
self._volume.id,
**kwargs
)
self.assertIsNone(result) self.assertIsNone(result)
def test_volume_set_description(self): def test_volume_set_description(self):
arglist = [ arglist = [
'--description', 'new desc', '--description',
'new desc',
self._volume.display_name, self._volume.display_name,
] ]
verifylist = [ verifylist = [
@ -1099,15 +1150,13 @@ class TestVolumeSet(TestVolume):
kwargs = { kwargs = {
'display_description': 'new desc', 'display_description': 'new desc',
} }
self.volumes_mock.update.assert_called_with( self.volumes_mock.update.assert_called_with(self._volume.id, **kwargs)
self._volume.id,
**kwargs
)
self.assertIsNone(result) self.assertIsNone(result)
def test_volume_set_size(self): def test_volume_set_size(self):
arglist = [ arglist = [
'--size', '130', '--size',
'130',
self._volume.display_name, self._volume.display_name,
] ]
verifylist = [ verifylist = [
@ -1123,16 +1172,14 @@ class TestVolumeSet(TestVolume):
# Set expected values # Set expected values
size = 130 size = 130
self.volumes_mock.extend.assert_called_with( self.volumes_mock.extend.assert_called_with(self._volume.id, size)
self._volume.id,
size
)
self.assertIsNone(result) self.assertIsNone(result)
def test_volume_set_size_smaller(self): def test_volume_set_size_smaller(self):
self._volume.status = 'available' self._volume.status = 'available'
arglist = [ arglist = [
'--size', '1', '--size',
'1',
self._volume.display_name, self._volume.display_name,
] ]
verifylist = [ verifylist = [
@ -1144,14 +1191,15 @@ class TestVolumeSet(TestVolume):
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(exceptions.CommandError, self.assertRaises(
self.cmd.take_action, exceptions.CommandError, self.cmd.take_action, parsed_args
parsed_args) )
def test_volume_set_size_not_available(self): def test_volume_set_size_not_available(self):
self._volume.status = 'error' self._volume.status = 'error'
arglist = [ arglist = [
'--size', '130', '--size',
'130',
self._volume.display_name, self._volume.display_name,
] ]
verifylist = [ verifylist = [
@ -1163,14 +1211,15 @@ class TestVolumeSet(TestVolume):
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(exceptions.CommandError, self.assertRaises(
self.cmd.take_action, exceptions.CommandError, self.cmd.take_action, parsed_args
parsed_args) )
def test_volume_set_property(self): def test_volume_set_property(self):
arglist = [ arglist = [
'--no-property', '--no-property',
'--property', 'myprop=myvalue', '--property',
'myprop=myvalue',
self._volume.display_name, self._volume.display_name,
] ]
verifylist = [ verifylist = [
@ -1183,23 +1232,19 @@ class TestVolumeSet(TestVolume):
('property', {'myprop': 'myvalue'}), ('property', {'myprop': 'myvalue'}),
('volume', self._volume.display_name), ('volume', self._volume.display_name),
('bootable', False), ('bootable', False),
('non_bootable', False) ('non_bootable', False),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
# Set expected values # Set expected values
metadata = { metadata = {'myprop': 'myvalue'}
'myprop': 'myvalue'
}
self.volumes_mock.set_metadata.assert_called_with( self.volumes_mock.set_metadata.assert_called_with(
self._volume.id, self._volume.id, metadata
metadata
) )
self.volumes_mock.delete_metadata.assert_called_with( self.volumes_mock.delete_metadata.assert_called_with(
self._volume.id, self._volume.id, self._volume.metadata.keys()
self._volume.metadata.keys()
) )
self.volumes_mock.update_readonly_flag.assert_not_called() self.volumes_mock.update_readonly_flag.assert_not_called()
self.assertIsNone(result) self.assertIsNone(result)
@ -1207,69 +1252,64 @@ class TestVolumeSet(TestVolume):
def test_volume_set_bootable(self): def test_volume_set_bootable(self):
arglist = [ arglist = [
['--bootable', self._volume.id], ['--bootable', self._volume.id],
['--non-bootable', self._volume.id] ['--non-bootable', self._volume.id],
] ]
verifylist = [ verifylist = [
[ [
('bootable', True), ('bootable', True),
('non_bootable', False), ('non_bootable', False),
('volume', self._volume.id) ('volume', self._volume.id),
], ],
[ [
('bootable', False), ('bootable', False),
('non_bootable', True), ('non_bootable', True),
('volume', self._volume.id) ('volume', self._volume.id),
] ],
] ]
for index in range(len(arglist)): for index in range(len(arglist)):
parsed_args = self.check_parser( parsed_args = self.check_parser(
self.cmd, arglist[index], verifylist[index]) self.cmd, arglist[index], verifylist[index]
)
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.volumes_mock.set_bootable.assert_called_with( 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): def test_volume_set_readonly(self):
arglist = [ arglist = ['--read-only', self._volume.id]
'--read-only',
self._volume.id
]
verifylist = [ verifylist = [
('read_only', True), ('read_only', True),
('read_write', False), ('read_write', False),
('volume', self._volume.id) ('volume', self._volume.id),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.volumes_mock.update_readonly_flag.assert_called_once_with( self.volumes_mock.update_readonly_flag.assert_called_once_with(
self._volume.id, self._volume.id, True
True) )
self.assertIsNone(result) self.assertIsNone(result)
def test_volume_set_read_write(self): def test_volume_set_read_write(self):
arglist = [ arglist = ['--read-write', self._volume.id]
'--read-write',
self._volume.id
]
verifylist = [ verifylist = [
('read_only', False), ('read_only', False),
('read_write', True), ('read_write', True),
('volume', self._volume.id) ('volume', self._volume.id),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.volumes_mock.update_readonly_flag.assert_called_once_with( self.volumes_mock.update_readonly_flag.assert_called_once_with(
self._volume.id, self._volume.id, False
False) )
self.assertIsNone(result) self.assertIsNone(result)
class TestVolumeShow(TestVolume): class TestVolumeShow(TestVolume):
columns = ( columns = (
'attachments', 'attachments',
'availability_zone', 'availability_zone',
@ -1307,12 +1347,8 @@ class TestVolumeShow(TestVolume):
self.cmd = volume.ShowVolume(self.app, None) self.cmd = volume.ShowVolume(self.app, None)
def test_volume_show(self): def test_volume_show(self):
arglist = [ arglist = [self._volume.id]
self._volume.id verifylist = [("volume", self._volume.id)]
]
verifylist = [
("volume", self._volume.id)
]
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) columns, data = self.cmd.take_action(parsed_args)
@ -1323,7 +1359,8 @@ class TestVolumeShow(TestVolume):
def test_volume_show_backward_compatibility(self): def test_volume_show_backward_compatibility(self):
arglist = [ arglist = [
'-c', 'display_name', '-c',
'display_name',
self._volume.id, self._volume.id,
] ]
verifylist = [ verifylist = [
@ -1342,7 +1379,6 @@ class TestVolumeShow(TestVolume):
class TestVolumeUnset(TestVolume): class TestVolumeUnset(TestVolume):
_volume = volume_fakes.create_one_volume() _volume = volume_fakes.create_one_volume()
def setUp(self): def setUp(self):
@ -1369,7 +1405,8 @@ class TestVolumeUnset(TestVolume):
def test_volume_unset_property(self): def test_volume_unset_property(self):
arglist = [ arglist = [
'--property', 'myprop', '--property',
'myprop',
self._volume.display_name, self._volume.display_name,
] ]
verifylist = [ verifylist = [
@ -1387,15 +1424,15 @@ class TestVolumeUnset(TestVolume):
class TestColumns(TestVolume): class TestColumns(TestVolume):
def test_attachments_column_without_server_cache(self): def test_attachments_column_without_server_cache(self):
_volume = volume_fakes.create_one_volume() _volume = volume_fakes.create_one_volume()
server_id = _volume.attachments[0]['server_id'] server_id = _volume.attachments[0]['server_id']
device = _volume.attachments[0]['device'] device = _volume.attachments[0]['device']
col = volume.AttachmentsColumn(_volume.attachments, {}) col = volume.AttachmentsColumn(_volume.attachments, {})
self.assertEqual('Attached to %s on %s ' % (server_id, device), self.assertEqual(
col.human_readable()) 'Attached to %s on %s ' % (server_id, device), col.human_readable()
)
self.assertEqual(_volume.attachments, col.machine_readable()) self.assertEqual(_volume.attachments, col.machine_readable())
def test_attachments_column_with_server_cache(self): def test_attachments_column_with_server_cache(self):
@ -1410,5 +1447,6 @@ class TestColumns(TestVolume):
col = volume.AttachmentsColumn(_volume.attachments, server_cache) col = volume.AttachmentsColumn(_volume.attachments, server_cache)
self.assertEqual( self.assertEqual(
'Attached to %s on %s ' % ('fake-server-name', device), 'Attached to %s on %s ' % ('fake-server-name', device),
col.human_readable()) col.human_readable(),
)
self.assertEqual(_volume.attachments, col.machine_readable()) self.assertEqual(_volume.attachments, col.machine_readable())

View File

@ -23,7 +23,6 @@ from openstackclient.volume.v1 import volume_backup
class TestBackup(volume_fakes.TestVolumev1): class TestBackup(volume_fakes.TestVolumev1):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -38,7 +37,6 @@ class TestBackup(volume_fakes.TestVolumev1):
class TestBackupCreate(TestBackup): class TestBackupCreate(TestBackup):
volume = volume_fakes.create_one_volume() volume = volume_fakes.create_one_volume()
columns = ( columns = (
@ -79,9 +77,12 @@ class TestBackupCreate(TestBackup):
def test_backup_create(self): def test_backup_create(self):
arglist = [ arglist = [
"--name", self.new_backup.name, "--name",
"--description", self.new_backup.description, self.new_backup.name,
"--container", self.new_backup.container, "--description",
self.new_backup.description,
"--container",
self.new_backup.container,
self.new_backup.volume_id, self.new_backup.volume_id,
] ]
verifylist = [ verifylist = [
@ -105,8 +106,10 @@ class TestBackupCreate(TestBackup):
def test_backup_create_without_name(self): def test_backup_create_without_name(self):
arglist = [ arglist = [
"--description", self.new_backup.description, "--description",
"--container", self.new_backup.container, self.new_backup.description,
"--container",
self.new_backup.container,
self.new_backup.volume_id, self.new_backup.volume_id,
] ]
verifylist = [ verifylist = [
@ -129,7 +132,6 @@ class TestBackupCreate(TestBackup):
class TestBackupDelete(TestBackup): class TestBackupDelete(TestBackup):
backups = volume_fakes.create_backups(count=2) backups = volume_fakes.create_backups(count=2)
def setUp(self): def setUp(self):
@ -142,18 +144,13 @@ class TestBackupDelete(TestBackup):
self.cmd = volume_backup.DeleteVolumeBackup(self.app, None) self.cmd = volume_backup.DeleteVolumeBackup(self.app, None)
def test_backup_delete(self): def test_backup_delete(self):
arglist = [ arglist = [self.backups[0].id]
self.backups[0].id verifylist = [("backups", [self.backups[0].id])]
]
verifylist = [
("backups", [self.backups[0].id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.backups_mock.delete.assert_called_with( self.backups_mock.delete.assert_called_with(self.backups[0].id)
self.backups[0].id)
self.assertIsNone(result) self.assertIsNone(result)
def test_delete_multiple_backups(self): def test_delete_multiple_backups(self):
@ -185,14 +182,14 @@ class TestBackupDelete(TestBackup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [self.backups[0], exceptions.CommandError] find_mock_result = [self.backups[0], exceptions.CommandError]
with mock.patch.object(utils, 'find_resource', with mock.patch.object(
side_effect=find_mock_result) as find_mock: utils, 'find_resource', side_effect=find_mock_result
) as find_mock:
try: try:
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual('1 of 2 backups failed to delete.', self.assertEqual('1 of 2 backups failed to delete.', str(e))
str(e))
find_mock.assert_any_call(self.backups_mock, self.backups[0].id) find_mock.assert_any_call(self.backups_mock, self.backups[0].id)
find_mock.assert_any_call(self.backups_mock, 'unexist_backup') find_mock.assert_any_call(self.backups_mock, 'unexist_backup')
@ -204,7 +201,6 @@ class TestBackupDelete(TestBackup):
class TestBackupList(TestBackup): class TestBackupList(TestBackup):
volume = volume_fakes.create_one_volume() volume = volume_fakes.create_one_volume()
backups = volume_fakes.create_backups( backups = volume_fakes.create_backups(
attrs={'volume_id': volume.display_name}, attrs={'volume_id': volume.display_name},
@ -226,25 +222,29 @@ class TestBackupList(TestBackup):
data = [] data = []
for b in backups: for b in backups:
data.append(( data.append(
b.id, (
b.name, b.id,
b.description, b.name,
b.status, b.description,
b.size, b.status,
)) b.size,
)
)
data_long = [] data_long = []
for b in backups: for b in backups:
data_long.append(( data_long.append(
b.id, (
b.name, b.id,
b.description, b.name,
b.status, b.description,
b.size, b.status,
b.availability_zone, b.size,
volume_backup.VolumeIdColumn(b.volume_id), b.availability_zone,
b.container, volume_backup.VolumeIdColumn(b.volume_id),
)) b.container,
)
)
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -284,10 +284,13 @@ class TestBackupList(TestBackup):
def test_backup_list_with_options(self): def test_backup_list_with_options(self):
arglist = [ arglist = [
"--long", "--long",
"--name", self.backups[0].name, "--name",
"--status", "error", self.backups[0].name,
"--volume", self.volume.id, "--status",
"--all-projects" "error",
"--volume",
self.volume.id,
"--all-projects",
] ]
verifylist = [ verifylist = [
("long", True), ("long", True),
@ -315,7 +318,6 @@ class TestBackupList(TestBackup):
class TestBackupRestore(TestBackup): class TestBackupRestore(TestBackup):
volume = volume_fakes.create_one_volume() volume = volume_fakes.create_one_volume()
backup = volume_fakes.create_one_backup( backup = volume_fakes.create_one_backup(
attrs={'volume_id': volume.id}, attrs={'volume_id': volume.id},
@ -345,8 +347,7 @@ class TestBackupRestore(TestBackup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.restores_mock.restore.assert_called_with(self.backup.id, self.restores_mock.restore.assert_called_with(self.backup.id, None)
None)
self.assertIsNotNone(result) self.assertIsNotNone(result)
def test_backup_restore_with_existing_volume(self): def test_backup_restore_with_existing_volume(self):
@ -362,7 +363,8 @@ class TestBackupRestore(TestBackup):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.restores_mock.restore.assert_called_with( self.restores_mock.restore.assert_called_with(
self.backup.id, self.backup.volume_id, self.backup.id,
self.backup.volume_id,
) )
self.assertIsNotNone(result) self.assertIsNotNone(result)
@ -377,7 +379,8 @@ class TestBackupRestore(TestBackup):
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
with mock.patch.object( with mock.patch.object(
utils, 'find_resource', utils,
'find_resource',
side_effect=exceptions.CommandError(), side_effect=exceptions.CommandError(),
): ):
self.assertRaises( self.assertRaises(
@ -388,7 +391,6 @@ class TestBackupRestore(TestBackup):
class TestBackupShow(TestBackup): class TestBackupShow(TestBackup):
columns = ( columns = (
'availability_zone', 'availability_zone',
'container', 'container',
@ -422,12 +424,8 @@ class TestBackupShow(TestBackup):
self.cmd = volume_backup.ShowVolumeBackup(self.app, None) self.cmd = volume_backup.ShowVolumeBackup(self.app, None)
def test_backup_show(self): def test_backup_show(self):
arglist = [ arglist = [self.backup.id]
self.backup.id verifylist = [("backup", self.backup.id)]
]
verifylist = [
("backup", self.backup.id)
]
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) columns, data = self.cmd.take_action(parsed_args)

View File

@ -1182,12 +1182,12 @@ class FakeLimits(object):
@property @property
def absolute(self): 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) yield FakeAbsoluteLimit(name, value)
def absolute_limits(self): def absolute_limits(self):
reference_data = [] 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)) reference_data.append((name, value))
return reference_data return reference_data

View File

@ -17,7 +17,6 @@ from openstackclient.volume.v2 import backup_record
class TestBackupRecord(volume_fakes.TestVolume): class TestBackupRecord(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -26,7 +25,6 @@ class TestBackupRecord(volume_fakes.TestVolume):
class TestBackupRecordExport(TestBackupRecord): class TestBackupRecordExport(TestBackupRecord):
new_backup = volume_fakes.create_one_backup( new_backup = volume_fakes.create_one_backup(
attrs={'volume_id': 'a54708a2-0388-4476-a909-09579f885c25'}, attrs={'volume_id': 'a54708a2-0388-4476-a909-09579f885c25'},
) )
@ -81,7 +79,6 @@ class TestBackupRecordExport(TestBackupRecord):
class TestBackupRecordImport(TestBackupRecord): class TestBackupRecordImport(TestBackupRecord):
new_backup = volume_fakes.create_one_backup( new_backup = volume_fakes.create_one_backup(
attrs={'volume_id': 'a54708a2-0388-4476-a909-09579f885c25'}, attrs={'volume_id': 'a54708a2-0388-4476-a909-09579f885c25'},
) )
@ -101,8 +98,10 @@ class TestBackupRecordImport(TestBackupRecord):
"fake_backup_record_data", "fake_backup_record_data",
] ]
verifylist = [ verifylist = [
("backup_service", (
"cinder.backup.drivers.swift.SwiftBackupDriver"), "backup_service",
"cinder.backup.drivers.swift.SwiftBackupDriver",
),
("backup_metadata", "fake_backup_record_data"), ("backup_metadata", "fake_backup_record_data"),
] ]

View File

@ -24,21 +24,19 @@ from openstackclient.volume.v2 import consistency_group
class TestConsistencyGroup(volume_fakes.TestVolume): class TestConsistencyGroup(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
# Get a shortcut to the TransferManager Mock # Get a shortcut to the TransferManager Mock
self.consistencygroups_mock = ( self.consistencygroups_mock = (
self.app.client_manager.volume.consistencygroups) self.app.client_manager.volume.consistencygroups
)
self.consistencygroups_mock.reset_mock() self.consistencygroups_mock.reset_mock()
self.cgsnapshots_mock = ( self.cgsnapshots_mock = self.app.client_manager.volume.cgsnapshots
self.app.client_manager.volume.cgsnapshots)
self.cgsnapshots_mock.reset_mock() self.cgsnapshots_mock.reset_mock()
self.volumes_mock = ( self.volumes_mock = self.app.client_manager.volume.volumes
self.app.client_manager.volume.volumes)
self.volumes_mock.reset_mock() self.volumes_mock.reset_mock()
self.types_mock = self.app.client_manager.volume.volume_types self.types_mock = self.app.client_manager.volume.volume_types
@ -46,17 +44,16 @@ class TestConsistencyGroup(volume_fakes.TestVolume):
class TestConsistencyGroupAddVolume(TestConsistencyGroup): class TestConsistencyGroupAddVolume(TestConsistencyGroup):
_consistency_group = volume_fakes.create_one_consistency_group() _consistency_group = volume_fakes.create_one_consistency_group()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.consistencygroups_mock.get.return_value = ( self.consistencygroups_mock.get.return_value = self._consistency_group
self._consistency_group)
# Get the command object to test # Get the command object to test
self.cmd = \ self.cmd = consistency_group.AddVolumeToConsistencyGroup(
consistency_group.AddVolumeToConsistencyGroup(self.app, None) self.app, None
)
def test_add_one_volume_to_consistency_group(self): def test_add_one_volume_to_consistency_group(self):
volume = volume_fakes.create_one_volume() volume = volume_fakes.create_one_volume()
@ -78,8 +75,7 @@ class TestConsistencyGroupAddVolume(TestConsistencyGroup):
'add_volumes': volume.id, 'add_volumes': volume.id,
} }
self.consistencygroups_mock.update.assert_called_once_with( self.consistencygroups_mock.update.assert_called_once_with(
self._consistency_group.id, self._consistency_group.id, **kwargs
**kwargs
) )
self.assertIsNone(result) self.assertIsNone(result)
@ -104,14 +100,14 @@ class TestConsistencyGroupAddVolume(TestConsistencyGroup):
'add_volumes': volumes[0].id + ',' + volumes[1].id, 'add_volumes': volumes[0].id + ',' + volumes[1].id,
} }
self.consistencygroups_mock.update.assert_called_once_with( self.consistencygroups_mock.update.assert_called_once_with(
self._consistency_group.id, self._consistency_group.id, **kwargs
**kwargs
) )
self.assertIsNone(result) self.assertIsNone(result)
@mock.patch.object(consistency_group.LOG, 'error') @mock.patch.object(consistency_group.LOG, 'error')
def test_add_multiple_volumes_to_consistency_group_with_exception( def test_add_multiple_volumes_to_consistency_group_with_exception(
self, mock_error, self,
mock_error,
): ):
volume = volume_fakes.create_one_volume() volume = volume_fakes.create_one_volume()
arglist = [ arglist = [
@ -126,20 +122,22 @@ class TestConsistencyGroupAddVolume(TestConsistencyGroup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [volume, find_mock_result = [
exceptions.CommandError, volume,
self._consistency_group] exceptions.CommandError,
with mock.patch.object(utils, 'find_resource', self._consistency_group,
side_effect=find_mock_result) as find_mock: ]
with mock.patch.object(
utils, 'find_resource', side_effect=find_mock_result
) as find_mock:
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
mock_error.assert_called_with("1 of 2 volumes failed to add.") mock_error.assert_called_with("1 of 2 volumes failed to add.")
self.assertIsNone(result) self.assertIsNone(result)
find_mock.assert_any_call(self.consistencygroups_mock, find_mock.assert_any_call(
self._consistency_group.id) 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, volume.id)
find_mock.assert_any_call(self.volumes_mock, find_mock.assert_any_call(self.volumes_mock, 'unexist_volume')
'unexist_volume')
self.assertEqual(3, find_mock.call_count) self.assertEqual(3, find_mock.call_count)
self.consistencygroups_mock.update.assert_called_once_with( self.consistencygroups_mock.update.assert_called_once_with(
self._consistency_group.id, add_volumes=volume.id self._consistency_group.id, add_volumes=volume.id
@ -147,7 +145,6 @@ class TestConsistencyGroupAddVolume(TestConsistencyGroup):
class TestConsistencyGroupCreate(TestConsistencyGroup): class TestConsistencyGroupCreate(TestConsistencyGroup):
volume_type = volume_fakes.create_one_volume_type() volume_type = volume_fakes.create_one_volume_type()
new_consistency_group = volume_fakes.create_one_consistency_group() new_consistency_group = volume_fakes.create_one_consistency_group()
consistency_group_snapshot = ( consistency_group_snapshot = (
@ -176,22 +173,28 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.consistencygroups_mock.create.return_value = ( self.consistencygroups_mock.create.return_value = (
self.new_consistency_group) self.new_consistency_group
)
self.consistencygroups_mock.create_from_src.return_value = ( self.consistencygroups_mock.create_from_src.return_value = (
self.new_consistency_group) self.new_consistency_group
)
self.consistencygroups_mock.get.return_value = ( self.consistencygroups_mock.get.return_value = (
self.new_consistency_group) self.new_consistency_group
)
self.types_mock.get.return_value = self.volume_type self.types_mock.get.return_value = self.volume_type
self.cgsnapshots_mock.get.return_value = ( self.cgsnapshots_mock.get.return_value = (
self.consistency_group_snapshot) self.consistency_group_snapshot
)
# Get the command object to test # Get the command object to test
self.cmd = consistency_group.CreateConsistencyGroup(self.app, None) self.cmd = consistency_group.CreateConsistencyGroup(self.app, None)
def test_consistency_group_create(self): def test_consistency_group_create(self):
arglist = [ arglist = [
'--volume-type', self.volume_type.id, '--volume-type',
'--description', self.new_consistency_group.description, self.volume_type.id,
'--description',
self.new_consistency_group.description,
'--availability-zone', '--availability-zone',
self.new_consistency_group.availability_zone, self.new_consistency_group.availability_zone,
self.new_consistency_group.name, self.new_consistency_group.name,
@ -199,16 +202,17 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
verifylist = [ verifylist = [
('volume_type', self.volume_type.id), ('volume_type', self.volume_type.id),
('description', self.new_consistency_group.description), ('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), ('name', self.new_consistency_group.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) columns, data = self.cmd.take_action(parsed_args)
self.types_mock.get.assert_called_once_with( self.types_mock.get.assert_called_once_with(self.volume_type.id)
self.volume_type.id)
self.consistencygroups_mock.get.assert_not_called() self.consistencygroups_mock.get.assert_not_called()
self.consistencygroups_mock.create.assert_called_once_with( self.consistencygroups_mock.create.assert_called_once_with(
self.volume_type.id, self.volume_type.id,
@ -222,23 +226,26 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
def test_consistency_group_create_without_name(self): def test_consistency_group_create_without_name(self):
arglist = [ arglist = [
'--volume-type', self.volume_type.id, '--volume-type',
'--description', self.new_consistency_group.description, self.volume_type.id,
'--description',
self.new_consistency_group.description,
'--availability-zone', '--availability-zone',
self.new_consistency_group.availability_zone, self.new_consistency_group.availability_zone,
] ]
verifylist = [ verifylist = [
('volume_type', self.volume_type.id), ('volume_type', self.volume_type.id),
('description', self.new_consistency_group.description), ('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) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.types_mock.get.assert_called_once_with( self.types_mock.get.assert_called_once_with(self.volume_type.id)
self.volume_type.id)
self.consistencygroups_mock.get.assert_not_called() self.consistencygroups_mock.get.assert_not_called()
self.consistencygroups_mock.create.assert_called_once_with( self.consistencygroups_mock.create.assert_called_once_with(
self.volume_type.id, self.volume_type.id,
@ -252,8 +259,10 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
def test_consistency_group_create_from_source(self): def test_consistency_group_create_from_source(self):
arglist = [ arglist = [
'--consistency-group-source', self.new_consistency_group.id, '--consistency-group-source',
'--description', self.new_consistency_group.description, self.new_consistency_group.id,
'--description',
self.new_consistency_group.description,
self.new_consistency_group.name, self.new_consistency_group.name,
] ]
verifylist = [ verifylist = [
@ -267,7 +276,8 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
self.types_mock.get.assert_not_called() self.types_mock.get.assert_not_called()
self.consistencygroups_mock.get.assert_called_once_with( 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( self.consistencygroups_mock.create_from_src.assert_called_with(
None, None,
self.new_consistency_group.id, self.new_consistency_group.id,
@ -280,8 +290,10 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
def test_consistency_group_create_from_snapshot(self): def test_consistency_group_create_from_snapshot(self):
arglist = [ arglist = [
'--consistency-group-snapshot', self.consistency_group_snapshot.id, '--consistency-group-snapshot',
'--description', self.new_consistency_group.description, self.consistency_group_snapshot.id,
'--description',
self.new_consistency_group.description,
self.new_consistency_group.name, self.new_consistency_group.name,
] ]
verifylist = [ verifylist = [
@ -295,7 +307,8 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
self.types_mock.get.assert_not_called() self.types_mock.get.assert_not_called()
self.cgsnapshots_mock.get.assert_called_once_with( 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.consistencygroups_mock.create_from_src.assert_called_with(
self.consistency_group_snapshot.id, self.consistency_group_snapshot.id,
None, None,
@ -308,9 +321,7 @@ class TestConsistencyGroupCreate(TestConsistencyGroup):
class TestConsistencyGroupDelete(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): def setUp(self):
super().setUp() super().setUp()
@ -324,18 +335,15 @@ class TestConsistencyGroupDelete(TestConsistencyGroup):
self.cmd = consistency_group.DeleteConsistencyGroup(self.app, None) self.cmd = consistency_group.DeleteConsistencyGroup(self.app, None)
def test_consistency_group_delete(self): def test_consistency_group_delete(self):
arglist = [ arglist = [self.consistency_groups[0].id]
self.consistency_groups[0].id verifylist = [("consistency_groups", [self.consistency_groups[0].id])]
]
verifylist = [
("consistency_groups", [self.consistency_groups[0].id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.consistencygroups_mock.delete.assert_called_with( self.consistencygroups_mock.delete.assert_called_with(
self.consistency_groups[0].id, False) self.consistency_groups[0].id, False
)
self.assertIsNone(result) self.assertIsNone(result)
def test_consistency_group_delete_with_force(self): def test_consistency_group_delete_with_force(self):
@ -345,14 +353,15 @@ class TestConsistencyGroupDelete(TestConsistencyGroup):
] ]
verifylist = [ verifylist = [
('force', True), ('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) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.consistencygroups_mock.delete.assert_called_with( self.consistencygroups_mock.delete.assert_called_with(
self.consistency_groups[0].id, True) self.consistency_groups[0].id, True
)
self.assertIsNone(result) self.assertIsNone(result)
def test_delete_multiple_consistency_groups(self): def test_delete_multiple_consistency_groups(self):
@ -383,21 +392,27 @@ class TestConsistencyGroupDelete(TestConsistencyGroup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [self.consistency_groups[0], find_mock_result = [
exceptions.CommandError] self.consistency_groups[0],
with mock.patch.object(utils, 'find_resource', exceptions.CommandError,
side_effect=find_mock_result) as find_mock: ]
with mock.patch.object(
utils, 'find_resource', side_effect=find_mock_result
) as find_mock:
try: try:
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual('1 of 2 consistency groups failed to delete.', self.assertEqual(
str(e)) '1 of 2 consistency groups failed to delete.', str(e)
)
find_mock.assert_any_call(self.consistencygroups_mock, find_mock.assert_any_call(
self.consistency_groups[0].id) 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, 'unexist_consistency_group'
)
self.assertEqual(2, find_mock.call_count) self.assertEqual(2, find_mock.call_count)
self.consistencygroups_mock.delete.assert_called_once_with( self.consistencygroups_mock.delete.assert_called_once_with(
@ -406,7 +421,6 @@ class TestConsistencyGroupDelete(TestConsistencyGroup):
class TestConsistencyGroupList(TestConsistencyGroup): class TestConsistencyGroupList(TestConsistencyGroup):
consistency_groups = volume_fakes.create_consistency_groups(count=2) consistency_groups = volume_fakes.create_consistency_groups(count=2)
columns = [ columns = [
@ -424,21 +438,25 @@ class TestConsistencyGroupList(TestConsistencyGroup):
] ]
data = [] data = []
for c in consistency_groups: for c in consistency_groups:
data.append(( data.append(
c.id, (
c.status, c.id,
c.name, c.status,
)) c.name,
)
)
data_long = [] data_long = []
for c in consistency_groups: for c in consistency_groups:
data_long.append(( data_long.append(
c.id, (
c.status, c.id,
c.availability_zone, c.status,
c.name, c.availability_zone,
c.description, c.name,
format_columns.ListColumn(c.volume_types) c.description,
)) format_columns.ListColumn(c.volume_types),
)
)
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -458,14 +476,13 @@ class TestConsistencyGroupList(TestConsistencyGroup):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.consistencygroups_mock.list.assert_called_once_with( 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.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, list(data)) self.assertCountEqual(self.data, list(data))
def test_consistency_group_list_with_all_project(self): def test_consistency_group_list_with_all_project(self):
arglist = [ arglist = ["--all-projects"]
"--all-projects"
]
verifylist = [ verifylist = [
("all_projects", True), ("all_projects", True),
("long", False), ("long", False),
@ -475,7 +492,8 @@ class TestConsistencyGroupList(TestConsistencyGroup):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.consistencygroups_mock.list.assert_called_once_with( 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.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, list(data)) self.assertCountEqual(self.data, list(data))
@ -492,23 +510,23 @@ class TestConsistencyGroupList(TestConsistencyGroup):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.consistencygroups_mock.list.assert_called_once_with( 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.assertEqual(self.columns_long, columns)
self.assertCountEqual(self.data_long, list(data)) self.assertCountEqual(self.data_long, list(data))
class TestConsistencyGroupRemoveVolume(TestConsistencyGroup): class TestConsistencyGroupRemoveVolume(TestConsistencyGroup):
_consistency_group = volume_fakes.create_one_consistency_group() _consistency_group = volume_fakes.create_one_consistency_group()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.consistencygroups_mock.get.return_value = ( self.consistencygroups_mock.get.return_value = self._consistency_group
self._consistency_group)
# Get the command object to test # Get the command object to test
self.cmd = \ self.cmd = consistency_group.RemoveVolumeFromConsistencyGroup(
consistency_group.RemoveVolumeFromConsistencyGroup(self.app, None) self.app, None
)
def test_remove_one_volume_from_consistency_group(self): def test_remove_one_volume_from_consistency_group(self):
volume = volume_fakes.create_one_volume() volume = volume_fakes.create_one_volume()
@ -530,8 +548,7 @@ class TestConsistencyGroupRemoveVolume(TestConsistencyGroup):
'remove_volumes': volume.id, 'remove_volumes': volume.id,
} }
self.consistencygroups_mock.update.assert_called_once_with( self.consistencygroups_mock.update.assert_called_once_with(
self._consistency_group.id, self._consistency_group.id, **kwargs
**kwargs
) )
self.assertIsNone(result) self.assertIsNone(result)
@ -556,8 +573,7 @@ class TestConsistencyGroupRemoveVolume(TestConsistencyGroup):
'remove_volumes': volumes[0].id + ',' + volumes[1].id, 'remove_volumes': volumes[0].id + ',' + volumes[1].id,
} }
self.consistencygroups_mock.update.assert_called_once_with( self.consistencygroups_mock.update.assert_called_once_with(
self._consistency_group.id, self._consistency_group.id, **kwargs
**kwargs
) )
self.assertIsNone(result) self.assertIsNone(result)
@ -579,20 +595,22 @@ class TestConsistencyGroupRemoveVolume(TestConsistencyGroup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [volume, find_mock_result = [
exceptions.CommandError, volume,
self._consistency_group] exceptions.CommandError,
with mock.patch.object(utils, 'find_resource', self._consistency_group,
side_effect=find_mock_result) as find_mock: ]
with mock.patch.object(
utils, 'find_resource', side_effect=find_mock_result
) as find_mock:
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
mock_error.assert_called_with("1 of 2 volumes failed to remove.") mock_error.assert_called_with("1 of 2 volumes failed to remove.")
self.assertIsNone(result) self.assertIsNone(result)
find_mock.assert_any_call(self.consistencygroups_mock, find_mock.assert_any_call(
self._consistency_group.id) 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, volume.id)
find_mock.assert_any_call(self.volumes_mock, find_mock.assert_any_call(self.volumes_mock, 'unexist_volume')
'unexist_volume')
self.assertEqual(3, find_mock.call_count) self.assertEqual(3, find_mock.call_count)
self.consistencygroups_mock.update.assert_called_once_with( self.consistencygroups_mock.update.assert_called_once_with(
self._consistency_group.id, remove_volumes=volume.id self._consistency_group.id, remove_volumes=volume.id
@ -600,21 +618,20 @@ class TestConsistencyGroupRemoveVolume(TestConsistencyGroup):
class TestConsistencyGroupSet(TestConsistencyGroup): class TestConsistencyGroupSet(TestConsistencyGroup):
consistency_group = volume_fakes.create_one_consistency_group() consistency_group = volume_fakes.create_one_consistency_group()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.consistencygroups_mock.get.return_value = ( self.consistencygroups_mock.get.return_value = self.consistency_group
self.consistency_group)
# Get the command object to test # Get the command object to test
self.cmd = consistency_group.SetConsistencyGroup(self.app, None) self.cmd = consistency_group.SetConsistencyGroup(self.app, None)
def test_consistency_group_set_name(self): def test_consistency_group_set_name(self):
new_name = 'new_name' new_name = 'new_name'
arglist = [ arglist = [
'--name', new_name, '--name',
new_name,
self.consistency_group.id, self.consistency_group.id,
] ]
verifylist = [ verifylist = [
@ -631,15 +648,15 @@ class TestConsistencyGroupSet(TestConsistencyGroup):
'name': new_name, 'name': new_name,
} }
self.consistencygroups_mock.update.assert_called_once_with( self.consistencygroups_mock.update.assert_called_once_with(
self.consistency_group.id, self.consistency_group.id, **kwargs
**kwargs
) )
self.assertIsNone(result) self.assertIsNone(result)
def test_consistency_group_set_description(self): def test_consistency_group_set_description(self):
new_description = 'new_description' new_description = 'new_description'
arglist = [ arglist = [
'--description', new_description, '--description',
new_description,
self.consistency_group.id, self.consistency_group.id,
] ]
verifylist = [ verifylist = [
@ -656,8 +673,7 @@ class TestConsistencyGroupSet(TestConsistencyGroup):
'description': new_description, 'description': new_description,
} }
self.consistencygroups_mock.update.assert_called_once_with( self.consistencygroups_mock.update.assert_called_once_with(
self.consistency_group.id, self.consistency_group.id, **kwargs
**kwargs
) )
self.assertIsNone(result) self.assertIsNone(result)
@ -690,15 +706,12 @@ class TestConsistencyGroupShow(TestConsistencyGroup):
self.cmd = consistency_group.ShowConsistencyGroup(self.app, None) self.cmd = consistency_group.ShowConsistencyGroup(self.app, None)
def test_consistency_group_show(self): def test_consistency_group_show(self):
arglist = [ arglist = [self.consistency_group.id]
self.consistency_group.id verifylist = [("consistency_group", self.consistency_group.id)]
]
verifylist = [
("consistency_group", self.consistency_group.id)
]
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) columns, data = self.cmd.take_action(parsed_args)
self.consistencygroups_mock.get.assert_called_once_with( self.consistencygroups_mock.get.assert_called_once_with(
self.consistency_group.id) self.consistency_group.id
)
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)

View File

@ -19,21 +19,19 @@ from openstackclient.volume.v2 import consistency_group_snapshot
class TestConsistencyGroupSnapshot(volume_fakes.TestVolume): class TestConsistencyGroupSnapshot(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super(TestConsistencyGroupSnapshot, self).setUp() super(TestConsistencyGroupSnapshot, self).setUp()
# Get a shortcut to the TransferManager Mock # Get a shortcut to the TransferManager Mock
self.cgsnapshots_mock = ( self.cgsnapshots_mock = self.app.client_manager.volume.cgsnapshots
self.app.client_manager.volume.cgsnapshots)
self.cgsnapshots_mock.reset_mock() self.cgsnapshots_mock.reset_mock()
self.consistencygroups_mock = ( self.consistencygroups_mock = (
self.app.client_manager.volume.consistencygroups) self.app.client_manager.volume.consistencygroups
)
self.consistencygroups_mock.reset_mock() self.consistencygroups_mock.reset_mock()
class TestConsistencyGroupSnapshotCreate(TestConsistencyGroupSnapshot): class TestConsistencyGroupSnapshotCreate(TestConsistencyGroupSnapshot):
_consistency_group_snapshot = ( _consistency_group_snapshot = (
volume_fakes.create_one_consistency_group_snapshot() volume_fakes.create_one_consistency_group_snapshot()
) )
@ -59,18 +57,21 @@ class TestConsistencyGroupSnapshotCreate(TestConsistencyGroupSnapshot):
def setUp(self): def setUp(self):
super(TestConsistencyGroupSnapshotCreate, self).setUp() super(TestConsistencyGroupSnapshotCreate, self).setUp()
self.cgsnapshots_mock.create.return_value = ( self.cgsnapshots_mock.create.return_value = (
self._consistency_group_snapshot) self._consistency_group_snapshot
self.consistencygroups_mock.get.return_value = ( )
self.consistency_group) self.consistencygroups_mock.get.return_value = self.consistency_group
# Get the command object to test # Get the command object to test
self.cmd = (consistency_group_snapshot. self.cmd = consistency_group_snapshot.CreateConsistencyGroupSnapshot(
CreateConsistencyGroupSnapshot(self.app, None)) self.app, None
)
def test_consistency_group_snapshot_create(self): def test_consistency_group_snapshot_create(self):
arglist = [ arglist = [
'--consistency-group', self.consistency_group.id, '--consistency-group',
'--description', self._consistency_group_snapshot.description, self.consistency_group.id,
'--description',
self._consistency_group_snapshot.description,
self._consistency_group_snapshot.name, self._consistency_group_snapshot.name,
] ]
verifylist = [ verifylist = [
@ -83,7 +84,8 @@ class TestConsistencyGroupSnapshotCreate(TestConsistencyGroupSnapshot):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.consistencygroups_mock.get.assert_called_once_with( 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.cgsnapshots_mock.create.assert_called_once_with(
self.consistency_group.id, self.consistency_group.id,
name=self._consistency_group_snapshot.name, name=self._consistency_group_snapshot.name,
@ -95,7 +97,8 @@ class TestConsistencyGroupSnapshotCreate(TestConsistencyGroupSnapshot):
def test_consistency_group_snapshot_create_no_consistency_group(self): def test_consistency_group_snapshot_create_no_consistency_group(self):
arglist = [ arglist = [
'--description', self._consistency_group_snapshot.description, '--description',
self._consistency_group_snapshot.description,
self._consistency_group_snapshot.name, self._consistency_group_snapshot.name,
] ]
verifylist = [ verifylist = [
@ -107,7 +110,8 @@ class TestConsistencyGroupSnapshotCreate(TestConsistencyGroupSnapshot):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.consistencygroups_mock.get.assert_called_once_with( 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.cgsnapshots_mock.create.assert_called_once_with(
self.consistency_group.id, self.consistency_group.id,
name=self._consistency_group_snapshot.name, name=self._consistency_group_snapshot.name,
@ -119,7 +123,6 @@ class TestConsistencyGroupSnapshotCreate(TestConsistencyGroupSnapshot):
class TestConsistencyGroupSnapshotDelete(TestConsistencyGroupSnapshot): class TestConsistencyGroupSnapshotDelete(TestConsistencyGroupSnapshot):
consistency_group_snapshots = ( consistency_group_snapshots = (
volume_fakes.create_consistency_group_snapshots(count=2) volume_fakes.create_consistency_group_snapshots(count=2)
) )
@ -135,23 +138,25 @@ class TestConsistencyGroupSnapshotDelete(TestConsistencyGroupSnapshot):
self.cgsnapshots_mock.delete.return_value = None self.cgsnapshots_mock.delete.return_value = None
# Get the command object to mock # Get the command object to mock
self.cmd = (consistency_group_snapshot. self.cmd = consistency_group_snapshot.DeleteConsistencyGroupSnapshot(
DeleteConsistencyGroupSnapshot(self.app, None)) self.app, None
)
def test_consistency_group_snapshot_delete(self): def test_consistency_group_snapshot_delete(self):
arglist = [ arglist = [self.consistency_group_snapshots[0].id]
self.consistency_group_snapshots[0].id
]
verifylist = [ 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) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.cgsnapshots_mock.delete.assert_called_once_with( self.cgsnapshots_mock.delete.assert_called_once_with(
self.consistency_group_snapshots[0].id) self.consistency_group_snapshots[0].id
)
self.assertIsNone(result) self.assertIsNone(result)
def test_multiple_consistency_group_snapshots_delete(self): def test_multiple_consistency_group_snapshots_delete(self):
@ -173,7 +178,6 @@ class TestConsistencyGroupSnapshotDelete(TestConsistencyGroupSnapshot):
class TestConsistencyGroupSnapshotList(TestConsistencyGroupSnapshot): class TestConsistencyGroupSnapshotList(TestConsistencyGroupSnapshot):
consistency_group_snapshots = ( consistency_group_snapshots = (
volume_fakes.create_consistency_group_snapshots(count=2) volume_fakes.create_consistency_group_snapshots(count=2)
) )
@ -194,32 +198,36 @@ class TestConsistencyGroupSnapshotList(TestConsistencyGroupSnapshot):
] ]
data = [] data = []
for c in consistency_group_snapshots: for c in consistency_group_snapshots:
data.append(( data.append(
c.id, (
c.status, c.id,
c.name, c.status,
)) c.name,
)
)
data_long = [] data_long = []
for c in consistency_group_snapshots: for c in consistency_group_snapshots:
data_long.append(( data_long.append(
c.id, (
c.status, c.id,
c.consistencygroup_id, c.status,
c.name, c.consistencygroup_id,
c.description, c.name,
c.created_at, c.description,
)) c.created_at,
)
)
def setUp(self): def setUp(self):
super(TestConsistencyGroupSnapshotList, self).setUp() super(TestConsistencyGroupSnapshotList, self).setUp()
self.cgsnapshots_mock.list.return_value = ( self.cgsnapshots_mock.list.return_value = (
self.consistency_group_snapshots) self.consistency_group_snapshots
)
self.consistencygroups_mock.get.return_value = self.consistency_group self.consistencygroups_mock.get.return_value = self.consistency_group
# Get the command to test # Get the command to test
self.cmd = ( self.cmd = consistency_group_snapshot.ListConsistencyGroupSnapshot(
consistency_group_snapshot. self.app, None
ListConsistencyGroupSnapshot(self.app, None)
) )
def test_consistency_group_snapshot_list_without_options(self): def test_consistency_group_snapshot_list_without_options(self):
@ -240,7 +248,8 @@ class TestConsistencyGroupSnapshotList(TestConsistencyGroupSnapshot):
'consistencygroup_id': None, 'consistencygroup_id': None,
} }
self.cgsnapshots_mock.list.assert_called_once_with( 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.columns, columns)
self.assertEqual(self.data, list(data)) self.assertEqual(self.data, list(data))
@ -264,15 +273,18 @@ class TestConsistencyGroupSnapshotList(TestConsistencyGroupSnapshot):
'consistencygroup_id': None, 'consistencygroup_id': None,
} }
self.cgsnapshots_mock.list.assert_called_once_with( 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.columns_long, columns)
self.assertEqual(self.data_long, list(data)) self.assertEqual(self.data_long, list(data))
def test_consistency_group_snapshot_list_with_options(self): def test_consistency_group_snapshot_list_with_options(self):
arglist = [ arglist = [
"--all-project", "--all-project",
"--status", self.consistency_group_snapshots[0].status, "--status",
"--consistency-group", self.consistency_group.id, self.consistency_group_snapshots[0].status,
"--consistency-group",
self.consistency_group.id,
] ]
verifylist = [ verifylist = [
("all_projects", True), ("all_projects", True),
@ -290,15 +302,16 @@ class TestConsistencyGroupSnapshotList(TestConsistencyGroupSnapshot):
'consistencygroup_id': self.consistency_group.id, 'consistencygroup_id': self.consistency_group.id,
} }
self.consistencygroups_mock.get.assert_called_once_with( self.consistencygroups_mock.get.assert_called_once_with(
self.consistency_group.id) self.consistency_group.id
)
self.cgsnapshots_mock.list.assert_called_once_with( 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.columns, columns)
self.assertEqual(self.data, list(data)) self.assertEqual(self.data, list(data))
class TestConsistencyGroupSnapshotShow(TestConsistencyGroupSnapshot): class TestConsistencyGroupSnapshotShow(TestConsistencyGroupSnapshot):
_consistency_group_snapshot = ( _consistency_group_snapshot = (
volume_fakes.create_one_consistency_group_snapshot() volume_fakes.create_one_consistency_group_snapshot()
) )
@ -324,20 +337,21 @@ class TestConsistencyGroupSnapshotShow(TestConsistencyGroupSnapshot):
super(TestConsistencyGroupSnapshotShow, self).setUp() super(TestConsistencyGroupSnapshotShow, self).setUp()
self.cgsnapshots_mock.get.return_value = ( self.cgsnapshots_mock.get.return_value = (
self._consistency_group_snapshot) self._consistency_group_snapshot
self.cmd = (consistency_group_snapshot. )
ShowConsistencyGroupSnapshot(self.app, None)) self.cmd = consistency_group_snapshot.ShowConsistencyGroupSnapshot(
self.app, None
)
def test_consistency_group_snapshot_show(self): def test_consistency_group_snapshot_show(self):
arglist = [ arglist = [self._consistency_group_snapshot.id]
self._consistency_group_snapshot.id
]
verifylist = [ verifylist = [
("consistency_group_snapshot", self._consistency_group_snapshot.id) ("consistency_group_snapshot", self._consistency_group_snapshot.id)
] ]
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) columns, data = self.cmd.take_action(parsed_args)
self.cgsnapshots_mock.get.assert_called_once_with( 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.columns, columns)
self.assertEqual(self.data, data) self.assertEqual(self.data, data)

View File

@ -26,7 +26,6 @@ from openstackclient.volume.v2 import qos_specs
class TestQos(volume_fakes.TestVolume): class TestQos(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super(TestQos, self).setUp() super(TestQos, self).setUp()
@ -38,7 +37,6 @@ class TestQos(volume_fakes.TestVolume):
class TestQosAssociate(TestQos): class TestQosAssociate(TestQos):
volume_type = volume_fakes.create_one_volume_type() volume_type = volume_fakes.create_one_volume_type()
qos_spec = volume_fakes.create_one_qos() qos_spec = volume_fakes.create_one_qos()
@ -51,33 +49,23 @@ class TestQosAssociate(TestQos):
self.cmd = qos_specs.AssociateQos(self.app, None) self.cmd = qos_specs.AssociateQos(self.app, None)
def test_qos_associate(self): def test_qos_associate(self):
arglist = [ arglist = [self.qos_spec.id, self.volume_type.id]
self.qos_spec.id,
self.volume_type.id
]
verifylist = [ verifylist = [
('qos_spec', self.qos_spec.id), ('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) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.qos_mock.associate.assert_called_with( self.qos_mock.associate.assert_called_with(
self.qos_spec.id, self.qos_spec.id, self.volume_type.id
self.volume_type.id
) )
self.assertIsNone(result) self.assertIsNone(result)
class TestQosCreate(TestQos): class TestQosCreate(TestQos):
columns = ('consumer', 'id', 'name', 'properties')
columns = (
'consumer',
'id',
'name',
'properties'
)
def setUp(self): def setUp(self):
super(TestQosCreate, self).setUp() super(TestQosCreate, self).setUp()
@ -89,7 +77,7 @@ class TestQosCreate(TestQos):
self.new_qos_spec.consumer, self.new_qos_spec.consumer,
self.new_qos_spec.id, self.new_qos_spec.id,
self.new_qos_spec.name, 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 # Get the command object to test
@ -107,8 +95,7 @@ class TestQosCreate(TestQos):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.qos_mock.create.assert_called_with( self.qos_mock.create.assert_called_with(
self.new_qos_spec.name, self.new_qos_spec.name, {'consumer': 'both'}
{'consumer': 'both'}
) )
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
@ -116,7 +103,8 @@ class TestQosCreate(TestQos):
def test_qos_create_with_consumer(self): def test_qos_create_with_consumer(self):
arglist = [ arglist = [
'--consumer', self.new_qos_spec.consumer, '--consumer',
self.new_qos_spec.consumer,
self.new_qos_spec.name, self.new_qos_spec.name,
] ]
verifylist = [ verifylist = [
@ -128,8 +116,7 @@ class TestQosCreate(TestQos):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.qos_mock.create.assert_called_with( self.qos_mock.create.assert_called_with(
self.new_qos_spec.name, self.new_qos_spec.name, {'consumer': self.new_qos_spec.consumer}
{'consumer': self.new_qos_spec.consumer}
) )
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
@ -137,9 +124,12 @@ class TestQosCreate(TestQos):
def test_qos_create_with_properties(self): def test_qos_create_with_properties(self):
arglist = [ arglist = [
'--consumer', self.new_qos_spec.consumer, '--consumer',
'--property', 'foo=bar', self.new_qos_spec.consumer,
'--property', 'iops=9001', '--property',
'foo=bar',
'--property',
'iops=9001',
self.new_qos_spec.name, self.new_qos_spec.name,
] ]
verifylist = [ verifylist = [
@ -153,9 +143,11 @@ class TestQosCreate(TestQos):
self.qos_mock.create.assert_called_with( self.qos_mock.create.assert_called_with(
self.new_qos_spec.name, self.new_qos_spec.name,
{'consumer': self.new_qos_spec.consumer, {
'foo': 'bar', 'consumer': self.new_qos_spec.consumer,
'iops': '9001'} 'foo': 'bar',
'iops': '9001',
},
) )
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
@ -163,47 +155,33 @@ class TestQosCreate(TestQos):
class TestQosDelete(TestQos): class TestQosDelete(TestQos):
qos_specs = volume_fakes.create_qoses(count=2) qos_specs = volume_fakes.create_qoses(count=2)
def setUp(self): def setUp(self):
super(TestQosDelete, self).setUp() super(TestQosDelete, self).setUp()
self.qos_mock.get = ( self.qos_mock.get = volume_fakes.get_qoses(self.qos_specs)
volume_fakes.get_qoses(self.qos_specs))
# Get the command object to test # Get the command object to test
self.cmd = qos_specs.DeleteQos(self.app, None) self.cmd = qos_specs.DeleteQos(self.app, None)
def test_qos_delete(self): def test_qos_delete(self):
arglist = [ arglist = [self.qos_specs[0].id]
self.qos_specs[0].id verifylist = [('qos_specs', [self.qos_specs[0].id])]
]
verifylist = [
('qos_specs', [self.qos_specs[0].id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.qos_mock.delete.assert_called_with( self.qos_mock.delete.assert_called_with(self.qos_specs[0].id, False)
self.qos_specs[0].id, False)
self.assertIsNone(result) self.assertIsNone(result)
def test_qos_delete_with_force(self): def test_qos_delete_with_force(self):
arglist = [ arglist = ['--force', self.qos_specs[0].id]
'--force', verifylist = [('force', True), ('qos_specs', [self.qos_specs[0].id])]
self.qos_specs[0].id
]
verifylist = [
('force', True),
('qos_specs', [self.qos_specs[0].id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.qos_mock.delete.assert_called_with( self.qos_mock.delete.assert_called_with(self.qos_specs[0].id, True)
self.qos_specs[0].id, True)
self.assertIsNone(result) self.assertIsNone(result)
def test_delete_multiple_qoses(self): def test_delete_multiple_qoses(self):
@ -235,14 +213,16 @@ class TestQosDelete(TestQos):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [self.qos_specs[0], exceptions.CommandError] find_mock_result = [self.qos_specs[0], exceptions.CommandError]
with mock.patch.object(utils, 'find_resource', with mock.patch.object(
side_effect=find_mock_result) as find_mock: utils, 'find_resource', side_effect=find_mock_result
) as find_mock:
try: try:
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual( 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, self.qos_specs[0].id)
find_mock.assert_any_call(self.qos_mock, 'unexist_qos') find_mock.assert_any_call(self.qos_mock, 'unexist_qos')
@ -254,7 +234,6 @@ class TestQosDelete(TestQos):
class TestQosDisassociate(TestQos): class TestQosDisassociate(TestQos):
volume_type = volume_fakes.create_one_volume_type() volume_type = volume_fakes.create_one_volume_type()
qos_spec = volume_fakes.create_one_qos() qos_spec = volume_fakes.create_one_qos()
@ -268,7 +247,8 @@ class TestQosDisassociate(TestQos):
def test_qos_disassociate_with_volume_type(self): def test_qos_disassociate_with_volume_type(self):
arglist = [ arglist = [
'--volume-type', self.volume_type.id, '--volume-type',
self.volume_type.id,
self.qos_spec.id, self.qos_spec.id,
] ]
verifylist = [ verifylist = [
@ -280,8 +260,7 @@ class TestQosDisassociate(TestQos):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.qos_mock.disassociate.assert_called_with( self.qos_mock.disassociate.assert_called_with(
self.qos_spec.id, self.qos_spec.id, self.volume_type.id
self.volume_type.id
) )
self.assertIsNone(result) self.assertIsNone(result)
@ -290,9 +269,7 @@ class TestQosDisassociate(TestQos):
'--all', '--all',
self.qos_spec.id, self.qos_spec.id,
] ]
verifylist = [ verifylist = [('qos_spec', self.qos_spec.id)]
('qos_spec', self.qos_spec.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
@ -302,7 +279,6 @@ class TestQosDisassociate(TestQos):
class TestQosList(TestQos): class TestQosList(TestQos):
qos_specs = volume_fakes.create_qoses(count=2) qos_specs = volume_fakes.create_qoses(count=2)
qos_association = volume_fakes.create_one_qos_association() qos_association = volume_fakes.create_one_qos_association()
@ -315,13 +291,15 @@ class TestQosList(TestQos):
) )
data = [] data = []
for q in qos_specs: for q in qos_specs:
data.append(( data.append(
q.id, (
q.name, q.id,
q.consumer, q.name,
format_columns.ListColumn([qos_association.name]), q.consumer,
format_columns.DictColumn(q.specs), format_columns.ListColumn([qos_association.name]),
)) format_columns.DictColumn(q.specs),
)
)
def setUp(self): def setUp(self):
super(TestQosList, self).setUp() super(TestQosList, self).setUp()
@ -373,7 +351,6 @@ class TestQosList(TestQos):
class TestQosSet(TestQos): class TestQosSet(TestQos):
qos_spec = volume_fakes.create_one_qos() qos_spec = volume_fakes.create_one_qos()
def setUp(self): def setUp(self):
@ -385,8 +362,10 @@ class TestQosSet(TestQos):
def test_qos_set_with_properties_with_id(self): def test_qos_set_with_properties_with_id(self):
arglist = [ arglist = [
'--property', 'foo=bar', '--property',
'--property', 'iops=9001', 'foo=bar',
'--property',
'iops=9001',
self.qos_spec.id, self.qos_spec.id,
] ]
verifylist = [ verifylist = [
@ -398,24 +377,16 @@ class TestQosSet(TestQos):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.qos_mock.set_keys.assert_called_with( self.qos_mock.set_keys.assert_called_with(
self.qos_spec.id, self.qos_spec.id, self.qos_spec.specs
self.qos_spec.specs
) )
self.assertIsNone(result) self.assertIsNone(result)
class TestQosShow(TestQos): class TestQosShow(TestQos):
qos_spec = volume_fakes.create_one_qos() qos_spec = volume_fakes.create_one_qos()
qos_association = volume_fakes.create_one_qos_association() qos_association = volume_fakes.create_one_qos_association()
columns = ( columns = ('associations', 'consumer', 'id', 'name', 'properties')
'associations',
'consumer',
'id',
'name',
'properties'
)
data = ( data = (
format_columns.ListColumn([qos_association.name]), format_columns.ListColumn([qos_association.name]),
qos_spec.consumer, qos_spec.consumer,
@ -434,26 +405,19 @@ class TestQosShow(TestQos):
self.cmd = qos_specs.ShowQos(self.app, None) self.cmd = qos_specs.ShowQos(self.app, None)
def test_qos_show(self): def test_qos_show(self):
arglist = [ arglist = [self.qos_spec.id]
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) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.qos_mock.get.assert_called_with( self.qos_mock.get.assert_called_with(self.qos_spec.id)
self.qos_spec.id
)
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, tuple(data)) self.assertCountEqual(self.data, tuple(data))
class TestQosUnset(TestQos): class TestQosUnset(TestQos):
qos_spec = volume_fakes.create_one_qos() qos_spec = volume_fakes.create_one_qos()
def setUp(self): def setUp(self):
@ -465,8 +429,10 @@ class TestQosUnset(TestQos):
def test_qos_unset_with_properties(self): def test_qos_unset_with_properties(self):
arglist = [ arglist = [
'--property', 'iops', '--property',
'--property', 'foo', 'iops',
'--property',
'foo',
self.qos_spec.id, self.qos_spec.id,
] ]
verifylist = [ verifylist = [
@ -478,7 +444,6 @@ class TestQosUnset(TestQos):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.qos_mock.unset_keys.assert_called_with( self.qos_mock.unset_keys.assert_called_with(
self.qos_spec.id, self.qos_spec.id, ['iops', 'foo']
['iops', 'foo']
) )
self.assertIsNone(result) self.assertIsNone(result)

View File

@ -19,7 +19,6 @@ from openstackclient.volume.v2 import service
class TestService(volume_fakes.TestVolume): class TestService(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -29,7 +28,6 @@ class TestService(volume_fakes.TestVolume):
class TestServiceList(TestService): class TestServiceList(TestService):
# The service to be listed # The service to be listed
services = volume_fakes.create_one_service() services = volume_fakes.create_one_service()
@ -43,8 +41,10 @@ class TestServiceList(TestService):
def test_service_list(self): def test_service_list(self):
arglist = [ arglist = [
'--host', self.services.host, '--host',
'--service', self.services.binary, self.services.host,
'--service',
self.services.binary,
] ]
verifylist = [ verifylist = [
('host', self.services.host), ('host', self.services.host),
@ -69,14 +69,16 @@ class TestServiceList(TestService):
# confirming if all expected columns are present in the result. # confirming if all expected columns are present in the result.
self.assertEqual(expected_columns, columns) self.assertEqual(expected_columns, columns)
datalist = (( datalist = (
self.services.binary, (
self.services.host, self.services.binary,
self.services.zone, self.services.host,
self.services.status, self.services.zone,
self.services.state, self.services.status,
self.services.updated_at, self.services.state,
), ) self.services.updated_at,
),
)
# confirming if all expected values are present in the result. # confirming if all expected values are present in the result.
self.assertEqual(datalist, tuple(data)) self.assertEqual(datalist, tuple(data))
@ -89,19 +91,20 @@ class TestServiceList(TestService):
# checking if prohibited columns are present in output # checking if prohibited columns are present in output
self.assertNotIn("Disabled Reason", columns) self.assertNotIn("Disabled Reason", columns)
self.assertNotIn(self.services.disabled_reason, self.assertNotIn(self.services.disabled_reason, tuple(data))
tuple(data))
def test_service_list_with_long_option(self): def test_service_list_with_long_option(self):
arglist = [ arglist = [
'--host', self.services.host, '--host',
'--service', self.services.binary, self.services.host,
'--long' '--service',
self.services.binary,
'--long',
] ]
verifylist = [ verifylist = [
('host', self.services.host), ('host', self.services.host),
('service', self.services.binary), ('service', self.services.binary),
('long', True) ('long', True),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -117,21 +120,23 @@ class TestServiceList(TestService):
'Status', 'Status',
'State', 'State',
'Updated At', 'Updated At',
'Disabled Reason' 'Disabled Reason',
] ]
# confirming if all expected columns are present in the result. # confirming if all expected columns are present in the result.
self.assertEqual(expected_columns, columns) self.assertEqual(expected_columns, columns)
datalist = (( datalist = (
self.services.binary, (
self.services.host, self.services.binary,
self.services.zone, self.services.host,
self.services.status, self.services.zone,
self.services.state, self.services.status,
self.services.updated_at, self.services.state,
self.services.disabled_reason, self.services.updated_at,
), ) self.services.disabled_reason,
),
)
# confirming if all expected values are present in the result. # confirming if all expected values are present in the result.
self.assertEqual(datalist, tuple(data)) self.assertEqual(datalist, tuple(data))
@ -143,7 +148,6 @@ class TestServiceList(TestService):
class TestServiceSet(TestService): class TestServiceSet(TestService):
service = volume_fakes.create_one_service() service = volume_fakes.create_one_service()
def setUp(self): def setUp(self):
@ -188,8 +192,7 @@ class TestServiceSet(TestService):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.service_mock.enable.assert_called_with( self.service_mock.enable.assert_called_with(
self.service.host, self.service.host, self.service.binary
self.service.binary
) )
self.service_mock.disable.assert_not_called() self.service_mock.disable.assert_not_called()
self.service_mock.disable_log_reason.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) result = self.cmd.take_action(parsed_args)
self.service_mock.disable.assert_called_with( self.service_mock.disable.assert_called_with(
self.service.host, self.service.host, self.service.binary
self.service.binary
) )
self.service_mock.enable.assert_not_called() self.service_mock.enable.assert_not_called()
self.service_mock.disable_log_reason.assert_not_called() self.service_mock.disable_log_reason.assert_not_called()
@ -222,7 +224,8 @@ class TestServiceSet(TestService):
reason = 'earthquake' reason = 'earthquake'
arglist = [ arglist = [
'--disable', '--disable',
'--disable-reason', reason, '--disable-reason',
reason,
self.service.host, self.service.host,
self.service.binary, self.service.binary,
] ]
@ -237,16 +240,15 @@ class TestServiceSet(TestService):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.service_mock.disable_log_reason.assert_called_with( self.service_mock.disable_log_reason.assert_called_with(
self.service.host, self.service.host, self.service.binary, reason
self.service.binary,
reason
) )
self.assertIsNone(result) self.assertIsNone(result)
def test_service_set_only_with_disable_reason(self): def test_service_set_only_with_disable_reason(self):
reason = 'earthquake' reason = 'earthquake'
arglist = [ arglist = [
'--disable-reason', reason, '--disable-reason',
reason,
self.service.host, self.service.host,
self.service.binary, self.service.binary,
] ]
@ -260,14 +262,18 @@ class TestServiceSet(TestService):
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail("CommandError should be raised.") self.fail("CommandError should be raised.")
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual("Cannot specify option --disable-reason without " self.assertEqual(
"--disable specified.", str(e)) "Cannot specify option --disable-reason without "
"--disable specified.",
str(e),
)
def test_service_set_enable_with_disable_reason(self): def test_service_set_enable_with_disable_reason(self):
reason = 'earthquake' reason = 'earthquake'
arglist = [ arglist = [
'--enable', '--enable',
'--disable-reason', reason, '--disable-reason',
reason,
self.service.host, self.service.host,
self.service.binary, self.service.binary,
] ]
@ -282,5 +288,8 @@ class TestServiceSet(TestService):
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail("CommandError should be raised.") self.fail("CommandError should be raised.")
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual("Cannot specify option --disable-reason without " self.assertEqual(
"--disable specified.", str(e)) "Cannot specify option --disable-reason without "
"--disable specified.",
str(e),
)

View File

@ -26,7 +26,6 @@ from openstackclient.volume.v2 import volume_type
class TestType(volume_fakes.TestVolume): class TestType(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -34,11 +33,13 @@ class TestType(volume_fakes.TestVolume):
self.types_mock.reset_mock() self.types_mock.reset_mock()
self.types_access_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.types_access_mock.reset_mock()
self.encryption_types_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.encryption_types_mock.reset_mock()
self.projects_mock = self.app.client_manager.identity.projects self.projects_mock = self.app.client_manager.identity.projects
@ -46,7 +47,6 @@ class TestType(volume_fakes.TestVolume):
class TestTypeCreate(TestType): class TestTypeCreate(TestType):
project = identity_fakes.FakeProject.create_one_project() project = identity_fakes.FakeProject.create_one_project()
columns = ( columns = (
'description', 'description',
@ -73,7 +73,8 @@ class TestTypeCreate(TestType):
def test_type_create_public(self): def test_type_create_public(self):
arglist = [ arglist = [
"--description", self.new_volume_type.description, "--description",
self.new_volume_type.description,
"--public", "--public",
self.new_volume_type.name, self.new_volume_type.name,
] ]
@ -97,9 +98,11 @@ class TestTypeCreate(TestType):
def test_type_create_private(self): def test_type_create_private(self):
arglist = [ arglist = [
"--description", self.new_volume_type.description, "--description",
self.new_volume_type.description,
"--private", "--private",
"--project", self.project.id, "--project",
self.project.id,
self.new_volume_type.name, self.new_volume_type.name,
] ]
verifylist = [ verifylist = [
@ -123,7 +126,8 @@ class TestTypeCreate(TestType):
def test_public_type_create_with_project(self): def test_public_type_create_with_project(self):
arglist = [ arglist = [
'--project', self.project.id, '--project',
self.project.id,
self.new_volume_type.name, self.new_volume_type.name,
] ]
verifylist = [ verifylist = [
@ -132,9 +136,9 @@ class TestTypeCreate(TestType):
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(exceptions.CommandError, self.assertRaises(
self.cmd.take_action, exceptions.CommandError, self.cmd.take_action, parsed_args
parsed_args) )
def test_type_create_with_encryption(self): def test_type_create_with_encryption(self):
encryption_info = { encryption_info = {
@ -166,10 +170,14 @@ class TestTypeCreate(TestType):
self.new_volume_type.name, self.new_volume_type.name,
) )
arglist = [ arglist = [
'--encryption-provider', 'LuksEncryptor', '--encryption-provider',
'--encryption-cipher', 'aes-xts-plain64', 'LuksEncryptor',
'--encryption-key-size', '128', '--encryption-cipher',
'--encryption-control-location', 'front-end', 'aes-xts-plain64',
'--encryption-key-size',
'128',
'--encryption-control-location',
'front-end',
self.new_volume_type.name, self.new_volume_type.name,
] ]
verifylist = [ verifylist = [
@ -201,7 +209,6 @@ class TestTypeCreate(TestType):
class TestTypeDelete(TestType): class TestTypeDelete(TestType):
volume_types = volume_fakes.create_volume_types(count=2) volume_types = volume_fakes.create_volume_types(count=2)
def setUp(self): def setUp(self):
@ -216,12 +223,8 @@ class TestTypeDelete(TestType):
self.cmd = volume_type.DeleteVolumeType(self.app, None) self.cmd = volume_type.DeleteVolumeType(self.app, None)
def test_type_delete(self): def test_type_delete(self):
arglist = [ arglist = [self.volume_types[0].id]
self.volume_types[0].id verifylist = [("volume_types", [self.volume_types[0].id])]
]
verifylist = [
("volume_types", [self.volume_types[0].id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
@ -258,16 +261,17 @@ class TestTypeDelete(TestType):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [self.volume_types[0], exceptions.CommandError] find_mock_result = [self.volume_types[0], exceptions.CommandError]
with mock.patch.object(utils, 'find_resource', with mock.patch.object(
side_effect=find_mock_result) as find_mock: utils, 'find_resource', side_effect=find_mock_result
) as find_mock:
try: try:
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual('1 of 2 volume types failed to delete.', self.assertEqual(
str(e)) '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') find_mock.assert_any_call(self.types_mock, 'unexist_type')
self.assertEqual(2, find_mock.call_count) self.assertEqual(2, find_mock.call_count)
@ -277,7 +281,6 @@ class TestTypeDelete(TestType):
class TestTypeList(TestType): class TestTypeList(TestType):
volume_types = volume_fakes.create_volume_types() volume_types = volume_fakes.create_volume_types()
columns = [ columns = [
@ -285,31 +288,28 @@ class TestTypeList(TestType):
"Name", "Name",
"Is Public", "Is Public",
] ]
columns_long = columns + [ columns_long = columns + ["Description", "Properties"]
"Description", data_with_default_type = [(volume_types[0].id, volume_types[0].name, True)]
"Properties"
]
data_with_default_type = [(
volume_types[0].id,
volume_types[0].name,
True
)]
data = [] data = []
for t in volume_types: for t in volume_types:
data.append(( data.append(
t.id, (
t.name, t.id,
t.is_public, t.name,
)) t.is_public,
)
)
data_long = [] data_long = []
for t in volume_types: for t in volume_types:
data_long.append(( data_long.append(
t.id, (
t.name, t.id,
t.is_public, t.name,
t.description, t.is_public,
format_columns.DictColumn(t.extra_specs), t.description,
)) format_columns.DictColumn(t.extra_specs),
)
)
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -401,21 +401,25 @@ class TestTypeList(TestType):
"Encryption", "Encryption",
] ]
encryption_data = [] encryption_data = []
encryption_data.append(( encryption_data.append(
self.volume_types[0].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,
{self.volume_types[0].id: encryption_info}), self.volume_types[0].name,
)) self.volume_types[0].is_public,
encryption_data.append(( volume_type.EncryptionInfoColumn(
self.volume_types[1].id, self.volume_types[0].id,
self.volume_types[1].name, {self.volume_types[0].id: encryption_info},
self.volume_types[1].is_public, ),
volume_type.EncryptionInfoColumn( )
self.volume_types[1].id, {}), )
)) 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] self.encryption_types_mock.list.return_value = [encryption_type]
arglist = [ arglist = [
@ -434,7 +438,6 @@ class TestTypeList(TestType):
class TestTypeSet(TestType): class TestTypeSet(TestType):
project = identity_fakes.FakeProject.create_one_project() project = identity_fakes.FakeProject.create_one_project()
volume_type = volume_fakes.create_one_volume_type( volume_type = volume_fakes.create_one_volume_type(
methods={'set_keys': None}, methods={'set_keys': None},
@ -455,7 +458,8 @@ class TestTypeSet(TestType):
def test_type_set_name(self): def test_type_set_name(self):
new_name = 'new_name' new_name = 'new_name'
arglist = [ arglist = [
'--name', new_name, '--name',
new_name,
self.volume_type.id, self.volume_type.id,
] ]
verifylist = [ verifylist = [
@ -473,15 +477,15 @@ class TestTypeSet(TestType):
'name': new_name, 'name': new_name,
} }
self.types_mock.update.assert_called_with( self.types_mock.update.assert_called_with(
self.volume_type.id, self.volume_type.id, **kwargs
**kwargs
) )
self.assertIsNone(result) self.assertIsNone(result)
def test_type_set_description(self): def test_type_set_description(self):
new_desc = 'new_desc' new_desc = 'new_desc'
arglist = [ arglist = [
'--description', new_desc, '--description',
new_desc,
self.volume_type.id, self.volume_type.id,
] ]
verifylist = [ verifylist = [
@ -499,14 +503,14 @@ class TestTypeSet(TestType):
'description': new_desc, 'description': new_desc,
} }
self.types_mock.update.assert_called_with( self.types_mock.update.assert_called_with(
self.volume_type.id, self.volume_type.id, **kwargs
**kwargs
) )
self.assertIsNone(result) self.assertIsNone(result)
def test_type_set_property(self): def test_type_set_property(self):
arglist = [ arglist = [
'--property', 'myprop=myvalue', '--property',
'myprop=myvalue',
self.volume_type.id, self.volume_type.id,
] ]
verifylist = [ verifylist = [
@ -519,12 +523,14 @@ class TestTypeSet(TestType):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.volume_type.set_keys.assert_called_once_with( self.volume_type.set_keys.assert_called_once_with(
{'myprop': 'myvalue'}) {'myprop': 'myvalue'}
)
self.assertIsNone(result) self.assertIsNone(result)
def test_type_set_not_called_without_project_argument(self): def test_type_set_not_called_without_project_argument(self):
arglist = [ arglist = [
'--project', '', '--project',
'',
self.volume_type.id, self.volume_type.id,
] ]
verifylist = [ verifylist = [
@ -541,21 +547,25 @@ class TestTypeSet(TestType):
def test_type_set_failed_with_missing_volume_type_argument(self): def test_type_set_failed_with_missing_volume_type_argument(self):
arglist = [ arglist = [
'--project', 'identity_fakes.project_id', '--project',
'identity_fakes.project_id',
] ]
verifylist = [ verifylist = [
('project', 'identity_fakes.project_id'), ('project', 'identity_fakes.project_id'),
] ]
self.assertRaises(tests_utils.ParserException, self.assertRaises(
self.check_parser, tests_utils.ParserException,
self.cmd, self.check_parser,
arglist, self.cmd,
verifylist) arglist,
verifylist,
)
def test_type_set_project_access(self): def test_type_set_project_access(self):
arglist = [ arglist = [
'--project', self.project.id, '--project',
self.project.id,
self.volume_type.id, self.volume_type.id,
] ]
verifylist = [ verifylist = [
@ -573,13 +583,18 @@ class TestTypeSet(TestType):
) )
def test_type_set_new_encryption(self): def test_type_set_new_encryption(self):
self.encryption_types_mock.update.side_effect = ( self.encryption_types_mock.update.side_effect = exceptions.NotFound(
exceptions.NotFound('NotFound')) 'NotFound'
)
arglist = [ arglist = [
'--encryption-provider', 'LuksEncryptor', '--encryption-provider',
'--encryption-cipher', 'aes-xts-plain64', 'LuksEncryptor',
'--encryption-key-size', '128', '--encryption-cipher',
'--encryption-control-location', 'front-end', 'aes-xts-plain64',
'--encryption-key-size',
'128',
'--encryption-control-location',
'front-end',
self.volume_type.id, self.volume_type.id,
] ]
verifylist = [ verifylist = [
@ -610,12 +625,14 @@ class TestTypeSet(TestType):
@mock.patch.object(utils, 'find_resource') @mock.patch.object(utils, 'find_resource')
def test_type_set_existing_encryption(self, mock_find): def test_type_set_existing_encryption(self, mock_find):
mock_find.side_effect = [self.volume_type, mock_find.side_effect = [self.volume_type, "existing_encryption_type"]
"existing_encryption_type"]
arglist = [ arglist = [
'--encryption-provider', 'LuksEncryptor', '--encryption-provider',
'--encryption-cipher', 'aes-xts-plain64', 'LuksEncryptor',
'--encryption-control-location', 'front-end', '--encryption-cipher',
'aes-xts-plain64',
'--encryption-control-location',
'front-end',
self.volume_type.id, self.volume_type.id,
] ]
verifylist = [ verifylist = [
@ -640,12 +657,16 @@ class TestTypeSet(TestType):
self.assertIsNone(result) self.assertIsNone(result)
def test_type_set_new_encryption_without_provider(self): def test_type_set_new_encryption_without_provider(self):
self.encryption_types_mock.update.side_effect = ( self.encryption_types_mock.update.side_effect = exceptions.NotFound(
exceptions.NotFound('NotFound')) 'NotFound'
)
arglist = [ arglist = [
'--encryption-cipher', 'aes-xts-plain64', '--encryption-cipher',
'--encryption-key-size', '128', 'aes-xts-plain64',
'--encryption-control-location', 'front-end', '--encryption-key-size',
'128',
'--encryption-control-location',
'front-end',
self.volume_type.id, self.volume_type.id,
] ]
verifylist = [ verifylist = [
@ -659,9 +680,10 @@ class TestTypeSet(TestType):
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual("Command Failed: One or more of" self.assertEqual(
" the operations failed", "Command Failed: One or more of" " the operations failed",
str(e)) str(e),
)
body = { body = {
'cipher': 'aes-xts-plain64', 'cipher': 'aes-xts-plain64',
'key_size': 128, 'key_size': 128,
@ -675,7 +697,6 @@ class TestTypeSet(TestType):
class TestTypeShow(TestType): class TestTypeShow(TestType):
columns = ( columns = (
'access_project_ids', 'access_project_ids',
'description', 'description',
@ -695,7 +716,7 @@ class TestTypeShow(TestType):
self.volume_type.id, self.volume_type.id,
True, True,
self.volume_type.name, 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 self.types_mock.get.return_value = self.volume_type
@ -704,12 +725,10 @@ class TestTypeShow(TestType):
self.cmd = volume_type.ShowVolumeType(self.app, None) self.cmd = volume_type.ShowVolumeType(self.app, None)
def test_type_show(self): def test_type_show(self):
arglist = [ arglist = [self.volume_type.id]
self.volume_type.id
]
verifylist = [ verifylist = [
("encryption_type", False), ("encryption_type", False),
("volume_type", self.volume_type.id) ("volume_type", self.volume_type.id),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -720,12 +739,8 @@ class TestTypeShow(TestType):
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_type_show_with_access(self): def test_type_show_with_access(self):
arglist = [ arglist = [self.volume_type.id]
self.volume_type.id verifylist = [("volume_type", self.volume_type.id)]
]
verifylist = [
("volume_type", self.volume_type.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
private_type = volume_fakes.create_one_volume_type( private_type = volume_fakes.create_one_volume_type(
@ -744,9 +759,11 @@ class TestTypeShow(TestType):
): ):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.types_mock.get.assert_called_once_with( 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( self.types_access_mock.list.assert_called_once_with(
private_type.id) private_type.id
)
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
private_type_data = ( private_type_data = (
@ -755,31 +772,31 @@ class TestTypeShow(TestType):
private_type.id, private_type.id,
private_type.is_public, private_type.is_public,
private_type.name, private_type.name,
format_columns.DictColumn(private_type.extra_specs) format_columns.DictColumn(private_type.extra_specs),
) )
self.assertCountEqual(private_type_data, data) self.assertCountEqual(private_type_data, data)
def test_type_show_with_list_access_exec(self): def test_type_show_with_list_access_exec(self):
arglist = [ arglist = [self.volume_type.id]
self.volume_type.id verifylist = [("volume_type", self.volume_type.id)]
]
verifylist = [
("volume_type", self.volume_type.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
private_type = volume_fakes.create_one_volume_type( private_type = volume_fakes.create_one_volume_type(
attrs={'is_public': False}, attrs={'is_public': False},
) )
with mock.patch.object(self.types_mock, 'get', with mock.patch.object(
return_value=private_type): 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_access_mock, 'list', side_effect=Exception()
):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.types_mock.get.assert_called_once_with( 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( self.types_access_mock.list.assert_called_once_with(
private_type.id) private_type.id
)
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
private_type_data = ( private_type_data = (
@ -788,7 +805,7 @@ class TestTypeShow(TestType):
private_type.id, private_type.id,
private_type.is_public, private_type.is_public,
private_type.name, private_type.name,
format_columns.DictColumn(private_type.extra_specs) format_columns.DictColumn(private_type.extra_specs),
) )
self.assertCountEqual(private_type_data, data) self.assertCountEqual(private_type_data, data)
@ -821,15 +838,12 @@ class TestTypeShow(TestType):
self.volume_type.id, self.volume_type.id,
True, True,
self.volume_type.name, self.volume_type.name,
format_columns.DictColumn(self.volume_type.extra_specs) format_columns.DictColumn(self.volume_type.extra_specs),
) )
arglist = [ arglist = ['--encryption-type', self.volume_type.id]
'--encryption-type',
self.volume_type.id
]
verifylist = [ verifylist = [
('encryption_type', True), ('encryption_type', True),
("volume_type", self.volume_type.id) ("volume_type", self.volume_type.id),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -841,7 +855,6 @@ class TestTypeShow(TestType):
class TestTypeUnset(TestType): class TestTypeUnset(TestType):
project = identity_fakes.FakeProject.create_one_project() project = identity_fakes.FakeProject.create_one_project()
volume_type = volume_fakes.create_one_volume_type( volume_type = volume_fakes.create_one_volume_type(
methods={'unset_keys': None}, methods={'unset_keys': None},
@ -860,8 +873,10 @@ class TestTypeUnset(TestType):
def test_type_unset(self): def test_type_unset(self):
arglist = [ arglist = [
'--property', 'property', '--property',
'--property', 'multi_property', 'property',
'--property',
'multi_property',
self.volume_type.id, self.volume_type.id,
] ]
verifylist = [ verifylist = [
@ -873,12 +888,14 @@ class TestTypeUnset(TestType):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.volume_type.unset_keys.assert_called_once_with( self.volume_type.unset_keys.assert_called_once_with(
['property', 'multi_property']) ['property', 'multi_property']
)
self.assertIsNone(result) self.assertIsNone(result)
def test_type_unset_project_access(self): def test_type_unset_project_access(self):
arglist = [ arglist = [
'--project', self.project.id, '--project',
self.project.id,
self.volume_type.id, self.volume_type.id,
] ]
verifylist = [ verifylist = [
@ -897,7 +914,8 @@ class TestTypeUnset(TestType):
def test_type_unset_not_called_without_project_argument(self): def test_type_unset_not_called_without_project_argument(self):
arglist = [ arglist = [
'--project', '', '--project',
'',
self.volume_type.id, self.volume_type.id,
] ]
verifylist = [ verifylist = [
@ -915,17 +933,20 @@ class TestTypeUnset(TestType):
def test_type_unset_failed_with_missing_volume_type_argument(self): def test_type_unset_failed_with_missing_volume_type_argument(self):
arglist = [ arglist = [
'--project', 'identity_fakes.project_id', '--project',
'identity_fakes.project_id',
] ]
verifylist = [ verifylist = [
('project', 'identity_fakes.project_id'), ('project', 'identity_fakes.project_id'),
] ]
self.assertRaises(tests_utils.ParserException, self.assertRaises(
self.check_parser, tests_utils.ParserException,
self.cmd, self.check_parser,
arglist, self.cmd,
verifylist) arglist,
verifylist,
)
def test_type_unset_encryption_type(self): def test_type_unset_encryption_type(self):
arglist = [ arglist = [
@ -944,7 +965,6 @@ class TestTypeUnset(TestType):
class TestColumns(TestType): class TestColumns(TestType):
def test_encryption_info_column_with_info(self): def test_encryption_info_column_with_info(self):
fake_volume_type = volume_fakes.create_one_volume_type() fake_volume_type = volume_fakes.create_one_volume_type()
type_id = fake_volume_type.id type_id = fake_volume_type.id
@ -955,10 +975,12 @@ class TestColumns(TestType):
'key_size': None, 'key_size': None,
'control_location': 'front-end', 'control_location': 'front-end',
} }
col = volume_type.EncryptionInfoColumn(type_id, col = volume_type.EncryptionInfoColumn(
{type_id: encryption_info}) type_id, {type_id: encryption_info}
self.assertEqual(utils.format_dict(encryption_info), )
col.human_readable()) self.assertEqual(
utils.format_dict(encryption_info), col.human_readable()
)
self.assertEqual(encryption_info, col.machine_readable()) self.assertEqual(encryption_info, col.machine_readable())
def test_encryption_info_column_without_info(self): def test_encryption_info_column_without_info(self):

File diff suppressed because it is too large Load Diff

View File

@ -105,9 +105,7 @@ class TestListVolumePool(volume_fakes.TestVolume):
# confirming if all expected columns are present in the result. # confirming if all expected columns are present in the result.
self.assertEqual(expected_columns, columns) self.assertEqual(expected_columns, columns)
datalist = (( datalist = ((self.pools.name,),)
self.pools.name,
), )
# confirming if all expected values are present in the result. # confirming if all expected values are present in the result.
self.assertEqual(datalist, tuple(data)) self.assertEqual(datalist, tuple(data))
@ -122,12 +120,8 @@ class TestListVolumePool(volume_fakes.TestVolume):
self.assertNotIn("storage_protocol", columns) self.assertNotIn("storage_protocol", columns)
def test_service_list_with_long_option(self): def test_service_list_with_long_option(self):
arglist = [ arglist = ['--long']
'--long' verifylist = [('long', True)]
]
verifylist = [
('long', True)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class Lister in cliff, abstract method take_action() # 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. # confirming if all expected columns are present in the result.
self.assertEqual(expected_columns, columns) self.assertEqual(expected_columns, columns)
datalist = (( datalist = (
self.pools.name, (
self.pools.storage_protocol, self.pools.name,
self.pools.thick_provisioning_support, self.pools.storage_protocol,
self.pools.thin_provisioning_support, self.pools.thick_provisioning_support,
self.pools.total_volumes, self.pools.thin_provisioning_support,
self.pools.total_capacity_gb, self.pools.total_volumes,
self.pools.allocated_capacity_gb, self.pools.total_capacity_gb,
self.pools.max_over_subscription_ratio, self.pools.allocated_capacity_gb,
), ) self.pools.max_over_subscription_ratio,
),
)
# confirming if all expected values are present in the result. # confirming if all expected values are present in the result.
self.assertEqual(datalist, tuple(data)) self.assertEqual(datalist, tuple(data))

View File

@ -24,7 +24,6 @@ from openstackclient.volume.v2 import volume_backup
class TestBackup(volume_fakes.TestVolume): class TestBackup(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -39,11 +38,11 @@ class TestBackup(volume_fakes.TestVolume):
class TestBackupCreate(TestBackup): class TestBackupCreate(TestBackup):
volume = volume_fakes.create_one_volume() volume = volume_fakes.create_one_volume()
snapshot = volume_fakes.create_one_snapshot() snapshot = volume_fakes.create_one_snapshot()
new_backup = volume_fakes.create_one_backup( 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 = ( columns = (
'availability_zone', 'availability_zone',
@ -82,12 +81,16 @@ class TestBackupCreate(TestBackup):
def test_backup_create(self): def test_backup_create(self):
arglist = [ arglist = [
"--name", self.new_backup.name, "--name",
"--description", self.new_backup.description, self.new_backup.name,
"--container", self.new_backup.container, "--description",
self.new_backup.description,
"--container",
self.new_backup.container,
"--force", "--force",
"--incremental", "--incremental",
"--snapshot", self.new_backup.snapshot_id, "--snapshot",
self.new_backup.snapshot_id,
self.new_backup.volume_id, self.new_backup.volume_id,
] ]
verifylist = [ verifylist = [
@ -116,12 +119,15 @@ class TestBackupCreate(TestBackup):
self.assertEqual(self.data, data) self.assertEqual(self.data, data)
def test_backup_create_with_properties(self): def test_backup_create_with_properties(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.43') '3.43'
)
arglist = [ arglist = [
"--property", "foo=bar", "--property",
"--property", "wow=much-cool", "foo=bar",
"--property",
"wow=much-cool",
self.new_backup.volume_id, self.new_backup.volume_id,
] ]
verifylist = [ verifylist = [
@ -145,12 +151,15 @@ class TestBackupCreate(TestBackup):
self.assertEqual(self.data, data) self.assertEqual(self.data, data)
def test_backup_create_with_properties_pre_v343(self): def test_backup_create_with_properties_pre_v343(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.42') '3.42'
)
arglist = [ arglist = [
"--property", "foo=bar", "--property",
"--property", "wow=much-cool", "foo=bar",
"--property",
"wow=much-cool",
self.new_backup.volume_id, self.new_backup.volume_id,
] ]
verifylist = [ verifylist = [
@ -160,17 +169,18 @@ class TestBackupCreate(TestBackup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn("--os-volume-api-version 3.43 or greater", str(exc)) self.assertIn("--os-volume-api-version 3.43 or greater", str(exc))
def test_backup_create_with_availability_zone(self): def test_backup_create_with_availability_zone(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.51') '3.51'
)
arglist = [ arglist = [
"--availability-zone", "my-az", "--availability-zone",
"my-az",
self.new_backup.volume_id, self.new_backup.volume_id,
] ]
verifylist = [ verifylist = [
@ -194,11 +204,13 @@ class TestBackupCreate(TestBackup):
self.assertEqual(self.data, data) self.assertEqual(self.data, data)
def test_backup_create_with_availability_zone_pre_v351(self): def test_backup_create_with_availability_zone_pre_v351(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.50') '3.50'
)
arglist = [ arglist = [
"--availability-zone", "my-az", "--availability-zone",
"my-az",
self.new_backup.volume_id, self.new_backup.volume_id,
] ]
verifylist = [ verifylist = [
@ -208,15 +220,16 @@ class TestBackupCreate(TestBackup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn("--os-volume-api-version 3.51 or greater", str(exc)) self.assertIn("--os-volume-api-version 3.51 or greater", str(exc))
def test_backup_create_without_name(self): def test_backup_create_without_name(self):
arglist = [ arglist = [
"--description", self.new_backup.description, "--description",
"--container", self.new_backup.container, self.new_backup.description,
"--container",
self.new_backup.container,
self.new_backup.volume_id, self.new_backup.volume_id,
] ]
verifylist = [ verifylist = [
@ -241,32 +254,25 @@ class TestBackupCreate(TestBackup):
class TestBackupDelete(TestBackup): class TestBackupDelete(TestBackup):
backups = volume_fakes.create_backups(count=2) backups = volume_fakes.create_backups(count=2)
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.backups_mock.get = ( self.backups_mock.get = volume_fakes.get_backups(self.backups)
volume_fakes.get_backups(self.backups))
self.backups_mock.delete.return_value = None self.backups_mock.delete.return_value = None
# Get the command object to mock # Get the command object to mock
self.cmd = volume_backup.DeleteVolumeBackup(self.app, None) self.cmd = volume_backup.DeleteVolumeBackup(self.app, None)
def test_backup_delete(self): def test_backup_delete(self):
arglist = [ arglist = [self.backups[0].id]
self.backups[0].id verifylist = [("backups", [self.backups[0].id])]
]
verifylist = [
("backups", [self.backups[0].id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.backups_mock.delete.assert_called_with( self.backups_mock.delete.assert_called_with(self.backups[0].id, False)
self.backups[0].id, False)
self.assertIsNone(result) self.assertIsNone(result)
def test_backup_delete_with_force(self): def test_backup_delete_with_force(self):
@ -274,10 +280,7 @@ class TestBackupDelete(TestBackup):
'--force', '--force',
self.backups[0].id, self.backups[0].id,
] ]
verifylist = [ verifylist = [('force', True), ("backups", [self.backups[0].id])]
('force', True),
("backups", [self.backups[0].id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
@ -314,14 +317,14 @@ class TestBackupDelete(TestBackup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [self.backups[0], exceptions.CommandError] find_mock_result = [self.backups[0], exceptions.CommandError]
with mock.patch.object(utils, 'find_resource', with mock.patch.object(
side_effect=find_mock_result) as find_mock: utils, 'find_resource', side_effect=find_mock_result
) as find_mock:
try: try:
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual('1 of 2 backups failed to delete.', self.assertEqual('1 of 2 backups failed to delete.', str(e))
str(e))
find_mock.assert_any_call(self.backups_mock, self.backups[0].id) find_mock.assert_any_call(self.backups_mock, self.backups[0].id)
find_mock.assert_any_call(self.backups_mock, 'unexist_backup') find_mock.assert_any_call(self.backups_mock, 'unexist_backup')
@ -333,10 +336,10 @@ class TestBackupDelete(TestBackup):
class TestBackupList(TestBackup): class TestBackupList(TestBackup):
volume = volume_fakes.create_one_volume() volume = volume_fakes.create_one_volume()
backups = volume_fakes.create_backups( backups = volume_fakes.create_backups(
attrs={'volume_id': volume.name}, count=3) attrs={'volume_id': volume.name}, count=3
)
columns = ( columns = (
'ID', 'ID',
@ -353,25 +356,29 @@ class TestBackupList(TestBackup):
data = [] data = []
for b in backups: for b in backups:
data.append(( data.append(
b.id, (
b.name, b.id,
b.description, b.name,
b.status, b.description,
b.size, b.status,
)) b.size,
)
)
data_long = [] data_long = []
for b in backups: for b in backups:
data_long.append(( data_long.append(
b.id, (
b.name, b.id,
b.description, b.name,
b.status, b.description,
b.size, b.status,
b.availability_zone, b.size,
volume_backup.VolumeIdColumn(b.volume_id), b.availability_zone,
b.container, volume_backup.VolumeIdColumn(b.volume_id),
)) b.container,
)
)
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -417,12 +424,17 @@ class TestBackupList(TestBackup):
def test_backup_list_with_options(self): def test_backup_list_with_options(self):
arglist = [ arglist = [
"--long", "--long",
"--name", self.backups[0].name, "--name",
"--status", "error", self.backups[0].name,
"--volume", self.volume.id, "--status",
"--marker", self.backups[0].id, "error",
"--volume",
self.volume.id,
"--marker",
self.backups[0].id,
"--all-projects", "--all-projects",
"--limit", "3", "--limit",
"3",
] ]
verifylist = [ verifylist = [
("long", True), ("long", True),
@ -455,7 +467,6 @@ class TestBackupList(TestBackup):
class TestBackupRestore(TestBackup): class TestBackupRestore(TestBackup):
volume = volume_fakes.create_one_volume() volume = volume_fakes.create_one_volume()
backup = volume_fakes.create_one_backup( backup = volume_fakes.create_one_backup(
attrs={'volume_id': volume.id}, attrs={'volume_id': volume.id},
@ -477,9 +488,7 @@ class TestBackupRestore(TestBackup):
def test_backup_restore(self): def test_backup_restore(self):
self.volumes_mock.get.side_effect = exceptions.CommandError() self.volumes_mock.get.side_effect = exceptions.CommandError()
self.volumes_mock.find.side_effect = exceptions.CommandError() self.volumes_mock.find.side_effect = exceptions.CommandError()
arglist = [ arglist = [self.backup.id]
self.backup.id
]
verifylist = [ verifylist = [
("backup", self.backup.id), ("backup", self.backup.id),
("volume", None), ("volume", None),
@ -488,7 +497,9 @@ class TestBackupRestore(TestBackup):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.restores_mock.restore.assert_called_with( self.restores_mock.restore.assert_called_with(
self.backup.id, None, None, self.backup.id,
None,
None,
) )
self.assertIsNotNone(result) self.assertIsNotNone(result)
@ -507,7 +518,9 @@ class TestBackupRestore(TestBackup):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.restores_mock.restore.assert_called_with( 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) self.assertIsNotNone(result)
@ -526,7 +539,9 @@ class TestBackupRestore(TestBackup):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.restores_mock.restore.assert_called_with( self.restores_mock.restore.assert_called_with(
self.backup.id, self.volume.id, None, self.backup.id,
self.volume.id,
None,
) )
self.assertIsNotNone(result) self.assertIsNotNone(result)
@ -549,7 +564,6 @@ class TestBackupRestore(TestBackup):
class TestBackupSet(TestBackup): class TestBackupSet(TestBackup):
backup = volume_fakes.create_one_backup( backup = volume_fakes.create_one_backup(
attrs={'metadata': {'wow': 'cool'}}, attrs={'metadata': {'wow': 'cool'}},
) )
@ -563,11 +577,13 @@ class TestBackupSet(TestBackup):
self.cmd = volume_backup.SetVolumeBackup(self.app, None) self.cmd = volume_backup.SetVolumeBackup(self.app, None)
def test_backup_set_name(self): def test_backup_set_name(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.9') '3.9'
)
arglist = [ arglist = [
'--name', 'new_name', '--name',
'new_name',
self.backup.id, self.backup.id,
] ]
verifylist = [ verifylist = [
@ -580,15 +596,18 @@ class TestBackupSet(TestBackup):
# returns nothing # returns nothing
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.backups_mock.update.assert_called_once_with( self.backups_mock.update.assert_called_once_with(
self.backup.id, **{'name': 'new_name'}) self.backup.id, **{'name': 'new_name'}
)
self.assertIsNone(result) self.assertIsNone(result)
def test_backup_set_name_pre_v39(self): def test_backup_set_name_pre_v39(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.8') '3.8'
)
arglist = [ arglist = [
'--name', 'new_name', '--name',
'new_name',
self.backup.id, self.backup.id,
] ]
verifylist = [ verifylist = [
@ -598,17 +617,18 @@ class TestBackupSet(TestBackup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn("--os-volume-api-version 3.9 or greater", str(exc)) self.assertIn("--os-volume-api-version 3.9 or greater", str(exc))
def test_backup_set_description(self): def test_backup_set_description(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.9') '3.9'
)
arglist = [ arglist = [
'--description', 'new_description', '--description',
'new_description',
self.backup.id, self.backup.id,
] ]
verifylist = [ verifylist = [
@ -621,21 +641,20 @@ class TestBackupSet(TestBackup):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
# Set expected values # Set expected values
kwargs = { kwargs = {'description': 'new_description'}
'description': 'new_description'
}
self.backups_mock.update.assert_called_once_with( self.backups_mock.update.assert_called_once_with(
self.backup.id, self.backup.id, **kwargs
**kwargs
) )
self.assertIsNone(result) self.assertIsNone(result)
def test_backup_set_description_pre_v39(self): def test_backup_set_description_pre_v39(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.8') '3.8'
)
arglist = [ arglist = [
'--description', 'new_description', '--description',
'new_description',
self.backup.id, self.backup.id,
] ]
verifylist = [ verifylist = [
@ -646,52 +665,43 @@ class TestBackupSet(TestBackup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn("--os-volume-api-version 3.9 or greater", str(exc)) self.assertIn("--os-volume-api-version 3.9 or greater", str(exc))
def test_backup_set_state(self): def test_backup_set_state(self):
arglist = [ arglist = ['--state', 'error', self.backup.id]
'--state', 'error', verifylist = [('state', 'error'), ('backup', self.backup.id)]
self.backup.id
]
verifylist = [
('state', 'error'),
('backup', self.backup.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.backups_mock.reset_state.assert_called_once_with( self.backups_mock.reset_state.assert_called_once_with(
self.backup.id, 'error') self.backup.id, 'error'
)
self.assertIsNone(result) self.assertIsNone(result)
def test_backup_set_state_failed(self): def test_backup_set_state_failed(self):
self.backups_mock.reset_state.side_effect = exceptions.CommandError() self.backups_mock.reset_state.side_effect = exceptions.CommandError()
arglist = [ arglist = ['--state', 'error', self.backup.id]
'--state', 'error', verifylist = [('state', 'error'), ('backup', self.backup.id)]
self.backup.id
]
verifylist = [
('state', 'error'),
('backup', self.backup.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
try: try:
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual('One or more of the set operations failed', self.assertEqual(
str(e)) 'One or more of the set operations failed', str(e)
)
self.backups_mock.reset_state.assert_called_with( self.backups_mock.reset_state.assert_called_with(
self.backup.id, 'error') self.backup.id, 'error'
)
def test_backup_set_no_property(self): def test_backup_set_no_property(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.43') '3.43'
)
arglist = [ arglist = [
'--no-property', '--no-property',
@ -710,14 +720,14 @@ class TestBackupSet(TestBackup):
'metadata': {}, 'metadata': {},
} }
self.backups_mock.update.assert_called_once_with( self.backups_mock.update.assert_called_once_with(
self.backup.id, self.backup.id, **kwargs
**kwargs
) )
self.assertIsNone(result) self.assertIsNone(result)
def test_backup_set_no_property_pre_v343(self): def test_backup_set_no_property_pre_v343(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.42') '3.42'
)
arglist = [ arglist = [
'--no-property', '--no-property',
@ -730,17 +740,18 @@ class TestBackupSet(TestBackup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn("--os-volume-api-version 3.43 or greater", str(exc)) self.assertIn("--os-volume-api-version 3.43 or greater", str(exc))
def test_backup_set_property(self): def test_backup_set_property(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.43') '3.43'
)
arglist = [ arglist = [
'--property', 'foo=bar', '--property',
'foo=bar',
self.backup.id, self.backup.id,
] ]
verifylist = [ verifylist = [
@ -756,17 +767,18 @@ class TestBackupSet(TestBackup):
'metadata': {'wow': 'cool', 'foo': 'bar'}, 'metadata': {'wow': 'cool', 'foo': 'bar'},
} }
self.backups_mock.update.assert_called_once_with( self.backups_mock.update.assert_called_once_with(
self.backup.id, self.backup.id, **kwargs
**kwargs
) )
self.assertIsNone(result) self.assertIsNone(result)
def test_backup_set_property_pre_v343(self): def test_backup_set_property_pre_v343(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.42') '3.42'
)
arglist = [ arglist = [
'--property', 'foo=bar', '--property',
'foo=bar',
self.backup.id, self.backup.id,
] ]
verifylist = [ verifylist = [
@ -776,14 +788,12 @@ class TestBackupSet(TestBackup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn("--os-volume-api-version 3.43 or greater", str(exc)) self.assertIn("--os-volume-api-version 3.43 or greater", str(exc))
class TestBackupUnset(TestBackup): class TestBackupUnset(TestBackup):
backup = volume_fakes.create_one_backup( backup = volume_fakes.create_one_backup(
attrs={'metadata': {'foo': 'bar'}}, attrs={'metadata': {'foo': 'bar'}},
) )
@ -797,11 +807,13 @@ class TestBackupUnset(TestBackup):
self.cmd = volume_backup.UnsetVolumeBackup(self.app, None) self.cmd = volume_backup.UnsetVolumeBackup(self.app, None)
def test_backup_unset_property(self): def test_backup_unset_property(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.43') '3.43'
)
arglist = [ arglist = [
'--property', 'foo', '--property',
'foo',
self.backup.id, self.backup.id,
] ]
verifylist = [ verifylist = [
@ -817,17 +829,18 @@ class TestBackupUnset(TestBackup):
'metadata': {}, 'metadata': {},
} }
self.backups_mock.update.assert_called_once_with( self.backups_mock.update.assert_called_once_with(
self.backup.id, self.backup.id, **kwargs
**kwargs
) )
self.assertIsNone(result) self.assertIsNone(result)
def test_backup_unset_property_pre_v343(self): def test_backup_unset_property_pre_v343(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.42') '3.42'
)
arglist = [ arglist = [
'--property', 'foo', '--property',
'foo',
self.backup.id, self.backup.id,
] ]
verifylist = [ verifylist = [
@ -837,14 +850,12 @@ class TestBackupUnset(TestBackup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn("--os-volume-api-version 3.43 or greater", str(exc)) self.assertIn("--os-volume-api-version 3.43 or greater", str(exc))
class TestBackupShow(TestBackup): class TestBackupShow(TestBackup):
backup = volume_fakes.create_one_backup() backup = volume_fakes.create_one_backup()
columns = ( columns = (
@ -880,12 +891,8 @@ class TestBackupShow(TestBackup):
self.cmd = volume_backup.ShowVolumeBackup(self.app, None) self.cmd = volume_backup.ShowVolumeBackup(self.app, None)
def test_backup_show(self): def test_backup_show(self):
arglist = [ arglist = [self.backup.id]
self.backup.id verifylist = [("backup", self.backup.id)]
]
verifylist = [
("backup", self.backup.id)
]
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) columns, data = self.cmd.take_action(parsed_args)

View File

@ -17,7 +17,6 @@ from openstackclient.volume.v2 import volume_host
class TestVolumeHost(volume_fakes.TestVolume): class TestVolumeHost(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -26,7 +25,6 @@ class TestVolumeHost(volume_fakes.TestVolume):
class TestVolumeHostSet(TestVolumeHost): class TestVolumeHostSet(TestVolumeHost):
service = volume_fakes.create_one_service() service = volume_fakes.create_one_service()
def setUp(self): def setUp(self):
@ -88,7 +86,6 @@ class TestVolumeHostSet(TestVolumeHost):
class TestVolumeHostFailover(TestVolumeHost): class TestVolumeHostFailover(TestVolumeHost):
service = volume_fakes.create_one_service() service = volume_fakes.create_one_service()
def setUp(self): def setUp(self):
@ -101,7 +98,8 @@ class TestVolumeHostFailover(TestVolumeHost):
def test_volume_host_failover(self): def test_volume_host_failover(self):
arglist = [ arglist = [
'--volume-backend', 'backend_test', '--volume-backend',
'backend_test',
self.service.host, self.service.host,
] ]
verifylist = [ verifylist = [
@ -113,5 +111,6 @@ class TestVolumeHostFailover(TestVolumeHost):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.host_mock.failover_host.assert_called_with( self.host_mock.failover_host.assert_called_with(
self.service.host, 'backend_test') self.service.host, 'backend_test'
)
self.assertIsNone(result) self.assertIsNone(result)

View File

@ -26,7 +26,6 @@ from openstackclient.volume.v2 import volume_snapshot
class TestVolumeSnapshot(volume_fakes.TestVolume): class TestVolumeSnapshot(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -39,7 +38,6 @@ class TestVolumeSnapshot(volume_fakes.TestVolume):
class TestVolumeSnapshotCreate(TestVolumeSnapshot): class TestVolumeSnapshotCreate(TestVolumeSnapshot):
columns = ( columns = (
'created_at', 'created_at',
'description', 'description',
@ -56,7 +54,8 @@ class TestVolumeSnapshotCreate(TestVolumeSnapshot):
self.volume = volume_fakes.create_one_volume() self.volume = volume_fakes.create_one_volume()
self.new_snapshot = volume_fakes.create_one_snapshot( self.new_snapshot = volume_fakes.create_one_snapshot(
attrs={'volume_id': self.volume.id}) attrs={'volume_id': self.volume.id}
)
self.data = ( self.data = (
self.new_snapshot.created_at, self.new_snapshot.created_at,
@ -77,11 +76,15 @@ class TestVolumeSnapshotCreate(TestVolumeSnapshot):
def test_snapshot_create(self): def test_snapshot_create(self):
arglist = [ arglist = [
"--volume", self.new_snapshot.volume_id, "--volume",
"--description", self.new_snapshot.description, self.new_snapshot.volume_id,
"--description",
self.new_snapshot.description,
"--force", "--force",
'--property', 'Alpha=a', '--property',
'--property', 'Beta=b', 'Alpha=a',
'--property',
'Beta=b',
self.new_snapshot.name, self.new_snapshot.name,
] ]
verifylist = [ verifylist = [
@ -107,7 +110,8 @@ class TestVolumeSnapshotCreate(TestVolumeSnapshot):
def test_snapshot_create_without_name(self): def test_snapshot_create_without_name(self):
arglist = [ arglist = [
"--volume", self.new_snapshot.volume_id, "--volume",
self.new_snapshot.volume_id,
] ]
verifylist = [ verifylist = [
("volume", self.new_snapshot.volume_id), ("volume", self.new_snapshot.volume_id),
@ -122,21 +126,21 @@ class TestVolumeSnapshotCreate(TestVolumeSnapshot):
def test_snapshot_create_without_volume(self): def test_snapshot_create_without_volume(self):
arglist = [ arglist = [
"--description", self.new_snapshot.description, "--description",
self.new_snapshot.description,
"--force", "--force",
self.new_snapshot.name self.new_snapshot.name,
] ]
verifylist = [ verifylist = [
("description", self.new_snapshot.description), ("description", self.new_snapshot.description),
("force", True), ("force", True),
("snapshot_name", self.new_snapshot.name) ("snapshot_name", self.new_snapshot.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) columns, data = self.cmd.take_action(parsed_args)
self.volumes_mock.get.assert_called_once_with( self.volumes_mock.get.assert_called_once_with(self.new_snapshot.name)
self.new_snapshot.name)
self.snapshots_mock.create.assert_called_once_with( self.snapshots_mock.create.assert_called_once_with(
self.new_snapshot.volume_id, self.new_snapshot.volume_id,
force=True, force=True,
@ -149,13 +153,18 @@ class TestVolumeSnapshotCreate(TestVolumeSnapshot):
def test_snapshot_create_with_remote_source(self): def test_snapshot_create_with_remote_source(self):
arglist = [ arglist = [
'--remote-source', 'source-name=test_source_name', '--remote-source',
'--remote-source', 'source-id=test_source_id', 'source-name=test_source_name',
'--volume', self.new_snapshot.volume_id, '--remote-source',
'source-id=test_source_id',
'--volume',
self.new_snapshot.volume_id,
self.new_snapshot.name, self.new_snapshot.name,
] ]
ref_dict = {'source-name': 'test_source_name', ref_dict = {
'source-id': 'test_source_id'} 'source-name': 'test_source_name',
'source-id': 'test_source_id',
}
verifylist = [ verifylist = [
('remote_source', ref_dict), ('remote_source', ref_dict),
('volume', self.new_snapshot.volume_id), ('volume', self.new_snapshot.volume_id),
@ -178,49 +187,39 @@ class TestVolumeSnapshotCreate(TestVolumeSnapshot):
class TestVolumeSnapshotDelete(TestVolumeSnapshot): class TestVolumeSnapshotDelete(TestVolumeSnapshot):
snapshots = volume_fakes.create_snapshots(count=2) snapshots = volume_fakes.create_snapshots(count=2)
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.snapshots_mock.get = ( self.snapshots_mock.get = volume_fakes.get_snapshots(self.snapshots)
volume_fakes.get_snapshots(self.snapshots))
self.snapshots_mock.delete.return_value = None self.snapshots_mock.delete.return_value = None
# Get the command object to mock # Get the command object to mock
self.cmd = volume_snapshot.DeleteVolumeSnapshot(self.app, None) self.cmd = volume_snapshot.DeleteVolumeSnapshot(self.app, None)
def test_snapshot_delete(self): def test_snapshot_delete(self):
arglist = [ arglist = [self.snapshots[0].id]
self.snapshots[0].id verifylist = [("snapshots", [self.snapshots[0].id])]
]
verifylist = [
("snapshots", [self.snapshots[0].id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.snapshots_mock.delete.assert_called_with( self.snapshots_mock.delete.assert_called_with(
self.snapshots[0].id, False) self.snapshots[0].id, False
)
self.assertIsNone(result) self.assertIsNone(result)
def test_snapshot_delete_with_force(self): def test_snapshot_delete_with_force(self):
arglist = [ arglist = ['--force', self.snapshots[0].id]
'--force', verifylist = [('force', True), ("snapshots", [self.snapshots[0].id])]
self.snapshots[0].id
]
verifylist = [
('force', True),
("snapshots", [self.snapshots[0].id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.snapshots_mock.delete.assert_called_with( self.snapshots_mock.delete.assert_called_with(
self.snapshots[0].id, True) self.snapshots[0].id, True
)
self.assertIsNone(result) self.assertIsNone(result)
def test_delete_multiple_snapshots(self): def test_delete_multiple_snapshots(self):
@ -252,17 +251,18 @@ class TestVolumeSnapshotDelete(TestVolumeSnapshot):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [self.snapshots[0], exceptions.CommandError] find_mock_result = [self.snapshots[0], exceptions.CommandError]
with mock.patch.object(utils, 'find_resource', with mock.patch.object(
side_effect=find_mock_result) as find_mock: utils, 'find_resource', side_effect=find_mock_result
) as find_mock:
try: try:
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual('1 of 2 snapshots failed to delete.', self.assertEqual('1 of 2 snapshots failed to delete.', str(e))
str(e))
find_mock.assert_any_call( 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') find_mock.assert_any_call(self.snapshots_mock, 'unexist_snapshot')
self.assertEqual(2, find_mock.call_count) self.assertEqual(2, find_mock.call_count)
@ -272,47 +272,42 @@ class TestVolumeSnapshotDelete(TestVolumeSnapshot):
class TestVolumeSnapshotList(TestVolumeSnapshot): class TestVolumeSnapshotList(TestVolumeSnapshot):
volume = volume_fakes.create_one_volume() volume = volume_fakes.create_one_volume()
project = project_fakes.FakeProject.create_one_project() project = project_fakes.FakeProject.create_one_project()
snapshots = volume_fakes.create_snapshots( snapshots = volume_fakes.create_snapshots(
attrs={'volume_id': volume.name}, count=3) attrs={'volume_id': volume.name}, count=3
)
columns = [ columns = ["ID", "Name", "Description", "Status", "Size"]
"ID", columns_long = columns + ["Created At", "Volume", "Properties"]
"Name",
"Description",
"Status",
"Size"
]
columns_long = columns + [
"Created At",
"Volume",
"Properties"
]
data = [] data = []
for s in snapshots: for s in snapshots:
data.append(( data.append(
s.id, (
s.name, s.id,
s.description, s.name,
s.status, s.description,
s.size, s.status,
)) s.size,
)
)
data_long = [] data_long = []
for s in snapshots: for s in snapshots:
data_long.append(( data_long.append(
s.id, (
s.name, s.id,
s.description, s.name,
s.status, s.description,
s.size, s.status,
s.created_at, s.size,
volume_snapshot.VolumeIdColumn( s.created_at,
s.volume_id, volume_cache={volume.id: volume}), volume_snapshot.VolumeIdColumn(
format_columns.DictColumn(s.metadata), s.volume_id, volume_cache={volume.id: volume}
)) ),
format_columns.DictColumn(s.metadata),
)
)
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -326,23 +321,21 @@ class TestVolumeSnapshotList(TestVolumeSnapshot):
def test_snapshot_list_without_options(self): def test_snapshot_list_without_options(self):
arglist = [] arglist = []
verifylist = [ verifylist = [('all_projects', False), ('long', False)]
('all_projects', False),
('long', False)
]
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) columns, data = self.cmd.take_action(parsed_args)
self.snapshots_mock.list.assert_called_once_with( self.snapshots_mock.list.assert_called_once_with(
limit=None, marker=None, limit=None,
marker=None,
search_opts={ search_opts={
'all_tenants': False, 'all_tenants': False,
'name': None, 'name': None,
'status': None, 'status': None,
'project_id': None, 'project_id': None,
'volume_id': None 'volume_id': None,
} },
) )
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data)) self.assertEqual(self.data, list(data))
@ -350,9 +343,12 @@ class TestVolumeSnapshotList(TestVolumeSnapshot):
def test_snapshot_list_with_options(self): def test_snapshot_list_with_options(self):
arglist = [ arglist = [
"--long", "--long",
"--limit", "2", "--limit",
"--project", self.project.id, "2",
"--marker", self.snapshots[0].id, "--project",
self.project.id,
"--marker",
self.snapshots[0].id,
] ]
verifylist = [ verifylist = [
("long", True), ("long", True),
@ -373,8 +369,8 @@ class TestVolumeSnapshotList(TestVolumeSnapshot):
'project_id': self.project.id, 'project_id': self.project.id,
'name': None, 'name': None,
'status': None, 'status': None,
'volume_id': None 'volume_id': None,
} },
) )
self.assertEqual(self.columns_long, columns) self.assertEqual(self.columns_long, columns)
self.assertEqual(self.data_long, list(data)) self.assertEqual(self.data_long, list(data))
@ -383,30 +379,29 @@ class TestVolumeSnapshotList(TestVolumeSnapshot):
arglist = [ arglist = [
'--all-projects', '--all-projects',
] ]
verifylist = [ verifylist = [('long', False), ('all_projects', True)]
('long', False),
('all_projects', True)
]
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) columns, data = self.cmd.take_action(parsed_args)
self.snapshots_mock.list.assert_called_once_with( self.snapshots_mock.list.assert_called_once_with(
limit=None, marker=None, limit=None,
marker=None,
search_opts={ search_opts={
'all_tenants': True, 'all_tenants': True,
'name': None, 'name': None,
'status': None, 'status': None,
'project_id': None, 'project_id': None,
'volume_id': None 'volume_id': None,
} },
) )
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data)) self.assertEqual(self.data, list(data))
def test_snapshot_list_name_option(self): def test_snapshot_list_name_option(self):
arglist = [ arglist = [
'--name', self.snapshots[0].name, '--name',
self.snapshots[0].name,
] ]
verifylist = [ verifylist = [
('all_projects', False), ('all_projects', False),
@ -418,21 +413,23 @@ class TestVolumeSnapshotList(TestVolumeSnapshot):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.snapshots_mock.list.assert_called_once_with( self.snapshots_mock.list.assert_called_once_with(
limit=None, marker=None, limit=None,
marker=None,
search_opts={ search_opts={
'all_tenants': False, 'all_tenants': False,
'name': self.snapshots[0].name, 'name': self.snapshots[0].name,
'status': None, 'status': None,
'project_id': None, 'project_id': None,
'volume_id': None 'volume_id': None,
} },
) )
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data)) self.assertEqual(self.data, list(data))
def test_snapshot_list_status_option(self): def test_snapshot_list_status_option(self):
arglist = [ arglist = [
'--status', self.snapshots[0].status, '--status',
self.snapshots[0].status,
] ]
verifylist = [ verifylist = [
('all_projects', False), ('all_projects', False),
@ -444,21 +441,23 @@ class TestVolumeSnapshotList(TestVolumeSnapshot):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.snapshots_mock.list.assert_called_once_with( self.snapshots_mock.list.assert_called_once_with(
limit=None, marker=None, limit=None,
marker=None,
search_opts={ search_opts={
'all_tenants': False, 'all_tenants': False,
'name': None, 'name': None,
'status': self.snapshots[0].status, 'status': self.snapshots[0].status,
'project_id': None, 'project_id': None,
'volume_id': None 'volume_id': None,
} },
) )
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data)) self.assertEqual(self.data, list(data))
def test_snapshot_list_volumeid_option(self): def test_snapshot_list_volumeid_option(self):
arglist = [ arglist = [
'--volume', self.volume.id, '--volume',
self.volume.id,
] ]
verifylist = [ verifylist = [
('all_projects', False), ('all_projects', False),
@ -470,31 +469,37 @@ class TestVolumeSnapshotList(TestVolumeSnapshot):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.snapshots_mock.list.assert_called_once_with( self.snapshots_mock.list.assert_called_once_with(
limit=None, marker=None, limit=None,
marker=None,
search_opts={ search_opts={
'all_tenants': False, 'all_tenants': False,
'name': None, 'name': None,
'status': None, 'status': None,
'project_id': None, 'project_id': None,
'volume_id': self.volume.id 'volume_id': self.volume.id,
} },
) )
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data)) self.assertEqual(self.data, list(data))
def test_snapshot_list_negative_limit(self): def test_snapshot_list_negative_limit(self):
arglist = [ arglist = [
"--limit", "-2", "--limit",
"-2",
] ]
verifylist = [ verifylist = [
("limit", -2), ("limit", -2),
] ]
self.assertRaises(argparse.ArgumentTypeError, self.check_parser, self.assertRaises(
self.cmd, arglist, verifylist) argparse.ArgumentTypeError,
self.check_parser,
self.cmd,
arglist,
verifylist,
)
class TestVolumeSnapshotSet(TestVolumeSnapshot): class TestVolumeSnapshotSet(TestVolumeSnapshot):
snapshot = volume_fakes.create_one_snapshot() snapshot = volume_fakes.create_one_snapshot()
def setUp(self): def setUp(self):
@ -524,9 +529,12 @@ class TestVolumeSnapshotSet(TestVolumeSnapshot):
def test_snapshot_set_name_and_property(self): def test_snapshot_set_name_and_property(self):
arglist = [ arglist = [
"--name", "new_snapshot", "--name",
"--property", "x=y", "new_snapshot",
"--property", "foo=foo", "--property",
"x=y",
"--property",
"foo=foo",
self.snapshot.id, self.snapshot.id,
] ]
new_property = {"x": "y", "foo": "foo"} new_property = {"x": "y", "foo": "foo"}
@ -543,7 +551,8 @@ class TestVolumeSnapshotSet(TestVolumeSnapshot):
"name": "new_snapshot", "name": "new_snapshot",
} }
self.snapshots_mock.update.assert_called_with( self.snapshots_mock.update.assert_called_with(
self.snapshot.id, **kwargs) self.snapshot.id, **kwargs
)
self.snapshots_mock.set_metadata.assert_called_with( self.snapshots_mock.set_metadata.assert_called_with(
self.snapshot.id, new_property self.snapshot.id, new_property
) )
@ -573,7 +582,8 @@ class TestVolumeSnapshotSet(TestVolumeSnapshot):
def test_snapshot_set_with_no_property_and_property(self): def test_snapshot_set_with_no_property_and_property(self):
arglist = [ arglist = [
"--no-property", "--no-property",
"--property", "foo_1=bar_1", "--property",
"foo_1=bar_1",
self.snapshot.id, self.snapshot.id,
] ]
verifylist = [ verifylist = [
@ -591,58 +601,52 @@ class TestVolumeSnapshotSet(TestVolumeSnapshot):
self.snapshot.id, ["foo"] self.snapshot.id, ["foo"]
) )
self.snapshots_mock.set_metadata.assert_called_once_with( 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) self.assertIsNone(result)
def test_snapshot_set_state_to_error(self): def test_snapshot_set_state_to_error(self):
arglist = [ arglist = ["--state", "error", self.snapshot.id]
"--state", "error", verifylist = [("state", "error"), ("snapshot", self.snapshot.id)]
self.snapshot.id
]
verifylist = [
("state", "error"),
("snapshot", self.snapshot.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.snapshots_mock.reset_state.assert_called_with( self.snapshots_mock.reset_state.assert_called_with(
self.snapshot.id, "error") self.snapshot.id, "error"
)
self.assertIsNone(result) self.assertIsNone(result)
def test_volume_set_state_failed(self): def test_volume_set_state_failed(self):
self.snapshots_mock.reset_state.side_effect = exceptions.CommandError() self.snapshots_mock.reset_state.side_effect = exceptions.CommandError()
arglist = [ arglist = ['--state', 'error', self.snapshot.id]
'--state', 'error', verifylist = [('state', 'error'), ('snapshot', self.snapshot.id)]
self.snapshot.id
]
verifylist = [
('state', 'error'),
('snapshot', self.snapshot.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
try: try:
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual('One or more of the set operations failed', self.assertEqual(
str(e)) 'One or more of the set operations failed', str(e)
)
self.snapshots_mock.reset_state.assert_called_once_with( 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): def test_volume_set_name_and_state_failed(self):
self.snapshots_mock.reset_state.side_effect = exceptions.CommandError() self.snapshots_mock.reset_state.side_effect = exceptions.CommandError()
arglist = [ arglist = [
'--state', 'error', '--state',
"--name", "new_snapshot", 'error',
self.snapshot.id "--name",
"new_snapshot",
self.snapshot.id,
] ]
verifylist = [ verifylist = [
('state', 'error'), ('state', 'error'),
("name", "new_snapshot"), ("name", "new_snapshot"),
('snapshot', self.snapshot.id) ('snapshot', self.snapshot.id),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -650,19 +654,21 @@ class TestVolumeSnapshotSet(TestVolumeSnapshot):
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual('One or more of the set operations failed', self.assertEqual(
str(e)) 'One or more of the set operations failed', str(e)
)
kwargs = { kwargs = {
"name": "new_snapshot", "name": "new_snapshot",
} }
self.snapshots_mock.update.assert_called_once_with( 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.snapshots_mock.reset_state.assert_called_once_with(
self.snapshot.id, 'error') self.snapshot.id, 'error'
)
class TestVolumeSnapshotShow(TestVolumeSnapshot): class TestVolumeSnapshotShow(TestVolumeSnapshot):
columns = ( columns = (
'created_at', 'created_at',
'description', 'description',
@ -695,12 +701,8 @@ class TestVolumeSnapshotShow(TestVolumeSnapshot):
self.cmd = volume_snapshot.ShowVolumeSnapshot(self.app, None) self.cmd = volume_snapshot.ShowVolumeSnapshot(self.app, None)
def test_snapshot_show(self): def test_snapshot_show(self):
arglist = [ arglist = [self.snapshot.id]
self.snapshot.id verifylist = [("snapshot", self.snapshot.id)]
]
verifylist = [
("snapshot", self.snapshot.id)
]
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) columns, data = self.cmd.take_action(parsed_args)
@ -711,7 +713,6 @@ class TestVolumeSnapshotShow(TestVolumeSnapshot):
class TestVolumeSnapshotUnset(TestVolumeSnapshot): class TestVolumeSnapshotUnset(TestVolumeSnapshot):
snapshot = volume_fakes.create_one_snapshot() snapshot = volume_fakes.create_one_snapshot()
def setUp(self): def setUp(self):
@ -724,7 +725,8 @@ class TestVolumeSnapshotUnset(TestVolumeSnapshot):
def test_snapshot_unset(self): def test_snapshot_unset(self):
arglist = [ arglist = [
"--property", "foo", "--property",
"foo",
self.snapshot.id, self.snapshot.id,
] ]
verifylist = [ verifylist = [

View File

@ -25,7 +25,6 @@ from openstackclient.volume.v2 import volume_transfer_request
class TestTransfer(volume_fakes.TestVolume): class TestTransfer(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -39,7 +38,6 @@ class TestTransfer(volume_fakes.TestVolume):
class TestTransferAccept(TestTransfer): class TestTransferAccept(TestTransfer):
columns = ( columns = (
'id', 'id',
'name', 'name',
@ -61,11 +59,13 @@ class TestTransferAccept(TestTransfer):
# Get the command object to test # Get the command object to test
self.cmd = volume_transfer_request.AcceptTransferRequest( self.cmd = volume_transfer_request.AcceptTransferRequest(
self.app, None) self.app, None
)
def test_transfer_accept(self): def test_transfer_accept(self):
arglist = [ arglist = [
'--auth-key', 'key_value', '--auth-key',
'key_value',
self.volume_transfer.id, self.volume_transfer.id,
] ]
verifylist = [ verifylist = [
@ -104,7 +104,6 @@ class TestTransferAccept(TestTransfer):
class TestTransferCreate(TestTransfer): class TestTransferCreate(TestTransfer):
volume = volume_fakes.create_one_volume() volume = volume_fakes.create_one_volume()
columns = ( columns = (
@ -138,7 +137,8 @@ class TestTransferCreate(TestTransfer):
# Get the command object to test # Get the command object to test
self.cmd = volume_transfer_request.CreateTransferRequest( self.cmd = volume_transfer_request.CreateTransferRequest(
self.app, None) self.app, None
)
def test_transfer_create_without_name(self): def test_transfer_create_without_name(self):
arglist = [ arglist = [
@ -151,14 +151,14 @@ class TestTransferCreate(TestTransfer):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.transfer_mock.create.assert_called_once_with( self.transfer_mock.create.assert_called_once_with(self.volume.id, None)
self.volume.id, None)
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data) self.assertEqual(self.data, data)
def test_transfer_create_with_name(self): def test_transfer_create_with_name(self):
arglist = [ arglist = [
'--name', self.volume_transfer.name, '--name',
self.volume_transfer.name,
self.volume.id, self.volume.id,
] ]
verifylist = [ verifylist = [
@ -170,13 +170,16 @@ class TestTransferCreate(TestTransfer):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.transfer_mock.create.assert_called_once_with( 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.columns, columns)
self.assertEqual(self.data, data) self.assertEqual(self.data, data)
def test_transfer_create_with_no_snapshots(self): def test_transfer_create_with_no_snapshots(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.55') '3.55'
)
arglist = [ arglist = [
'--no-snapshots', '--no-snapshots',
@ -192,13 +195,15 @@ class TestTransferCreate(TestTransfer):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.transfer_mock.create.assert_called_once_with( 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.columns, columns)
self.assertEqual(self.data, data) self.assertEqual(self.data, data)
def test_transfer_create_pre_v355(self): def test_transfer_create_pre_v355(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.54') '3.54'
)
arglist = [ arglist = [
'--no-snapshots', '--no-snapshots',
@ -212,16 +217,14 @@ class TestTransferCreate(TestTransfer):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.55 or greater is required', '--os-volume-api-version 3.55 or greater is required', str(exc)
str(exc)) )
class TestTransferDelete(TestTransfer): class TestTransferDelete(TestTransfer):
volume_transfers = volume_fakes.create_transfers(count=2) volume_transfers = volume_fakes.create_transfers(count=2)
def setUp(self): def setUp(self):
@ -234,21 +237,19 @@ class TestTransferDelete(TestTransfer):
# Get the command object to mock # Get the command object to mock
self.cmd = volume_transfer_request.DeleteTransferRequest( self.cmd = volume_transfer_request.DeleteTransferRequest(
self.app, None) self.app, None
)
def test_transfer_delete(self): def test_transfer_delete(self):
arglist = [ arglist = [self.volume_transfers[0].id]
self.volume_transfers[0].id verifylist = [("transfer_request", [self.volume_transfers[0].id])]
]
verifylist = [
("transfer_request", [self.volume_transfers[0].id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.transfer_mock.delete.assert_called_with( self.transfer_mock.delete.assert_called_with(
self.volume_transfers[0].id) self.volume_transfers[0].id
)
self.assertIsNone(result) self.assertIsNone(result)
def test_delete_multiple_transfers(self): def test_delete_multiple_transfers(self):
@ -280,17 +281,21 @@ class TestTransferDelete(TestTransfer):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [self.volume_transfers[0], exceptions.CommandError] find_mock_result = [self.volume_transfers[0], exceptions.CommandError]
with mock.patch.object(utils, 'find_resource', with mock.patch.object(
side_effect=find_mock_result) as find_mock: utils, 'find_resource', side_effect=find_mock_result
) as find_mock:
try: try:
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.') self.fail('CommandError should be raised.')
except exceptions.CommandError as e: except exceptions.CommandError as e:
self.assertEqual('1 of 2 volume transfer requests failed ' self.assertEqual(
'to delete', str(e)) '1 of 2 volume transfer requests failed ' 'to delete',
str(e),
)
find_mock.assert_any_call( 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') find_mock.assert_any_call(self.transfer_mock, 'unexist_transfer')
self.assertEqual(2, find_mock.call_count) self.assertEqual(2, find_mock.call_count)
@ -300,7 +305,6 @@ class TestTransferDelete(TestTransfer):
class TestTransferList(TestTransfer): class TestTransferList(TestTransfer):
# The Transfers to be listed # The Transfers to be listed
volume_transfers = volume_fakes.create_one_transfer() volume_transfers = volume_fakes.create_one_transfer()
@ -331,28 +335,25 @@ class TestTransferList(TestTransfer):
# confirming if all expected columns are present in the result. # confirming if all expected columns are present in the result.
self.assertEqual(expected_columns, columns) self.assertEqual(expected_columns, columns)
datalist = (( datalist = (
self.volume_transfers.id, (
self.volume_transfers.name, self.volume_transfers.id,
self.volume_transfers.volume_id, self.volume_transfers.name,
), ) self.volume_transfers.volume_id,
),
)
# confirming if all expected values are present in the result. # confirming if all expected values are present in the result.
self.assertEqual(datalist, tuple(data)) self.assertEqual(datalist, tuple(data))
# checking if proper call was made to list volume_transfers # checking if proper call was made to list volume_transfers
self.transfer_mock.list.assert_called_with( self.transfer_mock.list.assert_called_with(
detailed=True, detailed=True, search_opts={'all_tenants': 0}
search_opts={'all_tenants': 0}
) )
def test_transfer_list_with_argument(self): def test_transfer_list_with_argument(self):
arglist = [ arglist = ["--all-projects"]
"--all-projects" verifylist = [("all_projects", True)]
]
verifylist = [
("all_projects", True)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) 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. # confirming if all expected columns are present in the result.
self.assertEqual(expected_columns, columns) self.assertEqual(expected_columns, columns)
datalist = (( datalist = (
self.volume_transfers.id, (
self.volume_transfers.name, self.volume_transfers.id,
self.volume_transfers.volume_id, self.volume_transfers.name,
), ) self.volume_transfers.volume_id,
),
)
# confirming if all expected values are present in the result. # confirming if all expected values are present in the result.
self.assertEqual(datalist, tuple(data)) self.assertEqual(datalist, tuple(data))
# checking if proper call was made to list volume_transfers # checking if proper call was made to list volume_transfers
self.transfer_mock.list.assert_called_with( self.transfer_mock.list.assert_called_with(
detailed=True, detailed=True, search_opts={'all_tenants': 1}
search_opts={'all_tenants': 1}
) )
class TestTransferShow(TestTransfer): class TestTransferShow(TestTransfer):
columns = ( columns = (
'created_at', 'created_at',
'id', 'id',
@ -411,8 +412,7 @@ class TestTransferShow(TestTransfer):
self.transfer_mock.get.return_value = self.volume_transfer self.transfer_mock.get.return_value = self.volume_transfer
# Get the command object to test # Get the command object to test
self.cmd = volume_transfer_request.ShowTransferRequest( self.cmd = volume_transfer_request.ShowTransferRequest(self.app, None)
self.app, None)
def test_transfer_show(self): def test_transfer_show(self):
arglist = [ arglist = [
@ -425,7 +425,6 @@ class TestTransferShow(TestTransfer):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.transfer_mock.get.assert_called_once_with( self.transfer_mock.get.assert_called_once_with(self.volume_transfer.id)
self.volume_transfer.id)
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data) self.assertEqual(self.data, data)

View File

@ -455,7 +455,8 @@ def create_service_log_level_entry(attrs=None):
service_log_level_info.update(attrs) service_log_level_info.update(attrs)
service_log_level = fakes.FakeResource( service_log_level = fakes.FakeResource(
None, service_log_level_info, loaded=True) None, service_log_level_info, loaded=True
)
return service_log_level return service_log_level
@ -481,10 +482,13 @@ def create_cleanup_records():
cleaning_records.append(cleaning_work_info) cleaning_records.append(cleaning_work_info)
unavailable_records.append(unavailable_work_info) unavailable_records.append(unavailable_work_info)
cleaning = [fakes.FakeResource( cleaning = [
None, obj, loaded=True) for obj in cleaning_records] fakes.FakeResource(None, obj, loaded=True) for obj in cleaning_records
unavailable = [fakes.FakeResource( ]
None, obj, loaded=True) for obj in unavailable_records] unavailable = [
fakes.FakeResource(None, obj, loaded=True)
for obj in unavailable_records
]
return cleaning, unavailable return cleaning, unavailable
@ -513,7 +517,8 @@ def create_volume_manage_list_records(count=2):
volume_manage_list = [] volume_manage_list = []
for i in range(count): for i in range(count):
volume_manage_list.append( volume_manage_list.append(
create_one_manage_record({'size': str(i + 1)})) create_one_manage_record({'size': str(i + 1)})
)
return volume_manage_list return volume_manage_list
@ -522,6 +527,7 @@ def create_snapshot_manage_list_records(count=2):
snapshot_manage_list = [] snapshot_manage_list = []
for i in range(count): for i in range(count):
snapshot_manage_list.append( 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 return snapshot_manage_list

View File

@ -20,7 +20,6 @@ from openstackclient.volume.v3 import block_storage_cleanup
class TestBlockStorage(volume_fakes.TestVolume): class TestBlockStorage(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -30,7 +29,6 @@ class TestBlockStorage(volume_fakes.TestVolume):
class TestBlockStorageCleanup(TestBlockStorage): class TestBlockStorageCleanup(TestBlockStorage):
cleaning, unavailable = volume_fakes.create_cleanup_records() cleaning, unavailable = volume_fakes.create_cleanup_records()
def setUp(self): def setUp(self):
@ -39,15 +37,14 @@ class TestBlockStorageCleanup(TestBlockStorage):
self.worker_mock.clean.return_value = (self.cleaning, self.unavailable) self.worker_mock.clean.return_value = (self.cleaning, self.unavailable)
# Get the command object to test # Get the command object to test
self.cmd = \ self.cmd = block_storage_cleanup.BlockStorageCleanup(self.app, None)
block_storage_cleanup.BlockStorageCleanup(self.app, None)
def test_cleanup(self): def test_cleanup(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.24') '3.24'
)
arglist = [ arglist = []
]
verifylist = [ verifylist = [
('cluster', None), ('cluster', None),
('host', None), ('host', None),
@ -62,22 +59,12 @@ class TestBlockStorageCleanup(TestBlockStorage):
expected_columns = ('ID', 'Cluster Name', 'Host', 'Binary', 'Status') expected_columns = ('ID', 'Cluster Name', 'Host', 'Binary', 'Status')
cleaning_data = tuple( cleaning_data = tuple(
( (obj.id, obj.cluster_name, obj.host, obj.binary, 'Cleaning')
obj.id, for obj in self.cleaning
obj.cluster_name,
obj.host,
obj.binary,
'Cleaning'
) for obj in self.cleaning
) )
unavailable_data = tuple( unavailable_data = tuple(
( (obj.id, obj.cluster_name, obj.host, obj.binary, 'Unavailable')
obj.id, for obj in self.unavailable
obj.cluster_name,
obj.host,
obj.binary,
'Unavailable'
) for obj in self.unavailable
) )
expected_data = cleaning_data + unavailable_data expected_data = cleaning_data + unavailable_data
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
@ -91,8 +78,7 @@ class TestBlockStorageCleanup(TestBlockStorage):
self.worker_mock.clean.assert_called_once_with() self.worker_mock.clean.assert_called_once_with()
def test_block_storage_cleanup_pre_324(self): def test_block_storage_cleanup_pre_324(self):
arglist = [ arglist = []
]
verifylist = [ verifylist = [
('cluster', None), ('cluster', None),
('host', None), ('host', None),
@ -104,14 +90,17 @@ class TestBlockStorageCleanup(TestBlockStorage):
('service_id', None), ('service_id', None),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises(exceptions.CommandError, self.cmd.take_action, exc = self.assertRaises(
parsed_args) exceptions.CommandError, self.cmd.take_action, parsed_args
)
self.assertIn( 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): def test_cleanup_with_args(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.24') '3.24'
)
fake_cluster = 'fake-cluster' fake_cluster = 'fake-cluster'
fake_host = 'fake-host' fake_host = 'fake-host'
@ -120,14 +109,20 @@ class TestBlockStorageCleanup(TestBlockStorage):
fake_resource_type = 'Volume' fake_resource_type = 'Volume'
fake_service_id = 1 fake_service_id = 1
arglist = [ arglist = [
'--cluster', fake_cluster, '--cluster',
'--host', fake_host, fake_cluster,
'--binary', fake_binary, '--host',
fake_host,
'--binary',
fake_binary,
'--down', '--down',
'--enabled', '--enabled',
'--resource-id', fake_resource_id, '--resource-id',
'--resource-type', fake_resource_type, fake_resource_id,
'--service-id', str(fake_service_id), '--resource-type',
fake_resource_type,
'--service-id',
str(fake_service_id),
] ]
verifylist = [ verifylist = [
('cluster', fake_cluster), ('cluster', fake_cluster),
@ -143,22 +138,12 @@ class TestBlockStorageCleanup(TestBlockStorage):
expected_columns = ('ID', 'Cluster Name', 'Host', 'Binary', 'Status') expected_columns = ('ID', 'Cluster Name', 'Host', 'Binary', 'Status')
cleaning_data = tuple( cleaning_data = tuple(
( (obj.id, obj.cluster_name, obj.host, obj.binary, 'Cleaning')
obj.id, for obj in self.cleaning
obj.cluster_name,
obj.host,
obj.binary,
'Cleaning'
) for obj in self.cleaning
) )
unavailable_data = tuple( unavailable_data = tuple(
( (obj.id, obj.cluster_name, obj.host, obj.binary, 'Unavailable')
obj.id, for obj in self.unavailable
obj.cluster_name,
obj.host,
obj.binary,
'Unavailable'
) for obj in self.unavailable
) )
expected_data = cleaning_data + unavailable_data expected_data = cleaning_data + unavailable_data
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
@ -175,4 +160,5 @@ class TestBlockStorageCleanup(TestBlockStorage):
disabled=False, disabled=False,
resource_id=fake_resource_id, resource_id=fake_resource_id,
resource_type=fake_resource_type, resource_type=fake_resource_type,
service_id=fake_service_id) service_id=fake_service_id,
)

View File

@ -18,7 +18,6 @@ from openstackclient.volume.v3 import block_storage_cluster
class TestBlockStorageCluster(volume_fakes.TestVolume): class TestBlockStorageCluster(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -28,7 +27,6 @@ class TestBlockStorageCluster(volume_fakes.TestVolume):
class TestBlockStorageClusterList(TestBlockStorageCluster): class TestBlockStorageClusterList(TestBlockStorageCluster):
# The cluster to be listed # The cluster to be listed
fake_clusters = volume_fakes.create_clusters() fake_clusters = volume_fakes.create_clusters()
@ -38,15 +36,16 @@ class TestBlockStorageClusterList(TestBlockStorageCluster):
self.cluster_mock.list.return_value = self.fake_clusters self.cluster_mock.list.return_value = self.fake_clusters
# Get the command object to test # Get the command object to test
self.cmd = \ self.cmd = block_storage_cluster.ListBlockStorageCluster(
block_storage_cluster.ListBlockStorageCluster(self.app, None) self.app, None
)
def test_cluster_list(self): def test_cluster_list(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.7') '3.7'
)
arglist = [ arglist = []
]
verifylist = [ verifylist = [
('cluster', None), ('cluster', None),
('binary', None), ('binary', None),
@ -65,7 +64,8 @@ class TestBlockStorageClusterList(TestBlockStorageCluster):
cluster.binary, cluster.binary,
cluster.state, cluster.state,
cluster.status, cluster.status,
) for cluster in self.fake_clusters )
for cluster in self.fake_clusters
) )
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
@ -84,16 +84,21 @@ class TestBlockStorageClusterList(TestBlockStorageCluster):
) )
def test_cluster_list_with_full_options(self): def test_cluster_list_with_full_options(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.7') '3.7'
)
arglist = [ arglist = [
'--cluster', 'foo', '--cluster',
'--binary', 'bar', 'foo',
'--binary',
'bar',
'--up', '--up',
'--disabled', '--disabled',
'--num-hosts', '5', '--num-hosts',
'--num-down-hosts', '0', '5',
'--num-down-hosts',
'0',
'--long', '--long',
] ]
verifylist = [ verifylist = [
@ -131,7 +136,8 @@ class TestBlockStorageClusterList(TestBlockStorageCluster):
cluster.disabled_reason, cluster.disabled_reason,
cluster.created_at, cluster.created_at,
cluster.updated_at, cluster.updated_at,
) for cluster in self.fake_clusters )
for cluster in self.fake_clusters
) )
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
@ -150,11 +156,11 @@ class TestBlockStorageClusterList(TestBlockStorageCluster):
) )
def test_cluster_list_pre_v37(self): def test_cluster_list_pre_v37(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.6') '3.6'
)
arglist = [ arglist = []
]
verifylist = [ verifylist = [
('cluster', None), ('cluster', None),
('binary', None), ('binary', None),
@ -167,15 +173,14 @@ class TestBlockStorageClusterList(TestBlockStorageCluster):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( 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): class TestBlockStorageClusterSet(TestBlockStorageCluster):
cluster = volume_fakes.create_one_cluster() cluster = volume_fakes.create_one_cluster()
columns = ( columns = (
'Name', 'Name',
@ -213,12 +218,12 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
self.cluster_mock.update.return_value = self.cluster self.cluster_mock.update.return_value = self.cluster
self.cmd = \ self.cmd = block_storage_cluster.SetBlockStorageCluster(self.app, None)
block_storage_cluster.SetBlockStorageCluster(self.app, None)
def test_cluster_set(self): def test_cluster_set(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.7') '3.7'
)
arglist = [ arglist = [
'--enable', '--enable',
@ -245,13 +250,16 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
) )
def test_cluster_set_disable_with_reason(self): def test_cluster_set_disable_with_reason(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.7') '3.7'
)
arglist = [ arglist = [
'--binary', self.cluster.binary, '--binary',
self.cluster.binary,
'--disable', '--disable',
'--disable-reason', 'foo', '--disable-reason',
'foo',
self.cluster.name, self.cluster.name,
] ]
verifylist = [ verifylist = [
@ -274,11 +282,13 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
) )
def test_cluster_set_only_with_disable_reason(self): def test_cluster_set_only_with_disable_reason(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.7') '3.7'
)
arglist = [ arglist = [
'--disable-reason', 'foo', '--disable-reason',
'foo',
self.cluster.name, self.cluster.name,
] ]
verifylist = [ verifylist = [
@ -290,19 +300,21 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( 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): def test_cluster_set_enable_with_disable_reason(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.7') '3.7'
)
arglist = [ arglist = [
'--enable', '--enable',
'--disable-reason', 'foo', '--disable-reason',
'foo',
self.cluster.name, self.cluster.name,
] ]
verifylist = [ verifylist = [
@ -314,15 +326,16 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( 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): def test_cluster_set_pre_v37(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.6') '3.6'
)
arglist = [ arglist = [
'--enable', '--enable',
@ -338,15 +351,14 @@ class TestBlockStorageClusterSet(TestBlockStorageCluster):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( 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): class TestBlockStorageClusterShow(TestBlockStorageCluster):
cluster = volume_fakes.create_one_cluster() cluster = volume_fakes.create_one_cluster()
columns = ( columns = (
'Name', 'Name',
@ -384,15 +396,18 @@ class TestBlockStorageClusterShow(TestBlockStorageCluster):
self.cluster_mock.show.return_value = self.cluster self.cluster_mock.show.return_value = self.cluster
self.cmd = \ self.cmd = block_storage_cluster.ShowBlockStorageCluster(
block_storage_cluster.ShowBlockStorageCluster(self.app, None) self.app, None
)
def test_cluster_show(self): def test_cluster_show(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.7') '3.7'
)
arglist = [ arglist = [
'--binary', self.cluster.binary, '--binary',
self.cluster.binary,
self.cluster.name, self.cluster.name,
] ]
verifylist = [ verifylist = [
@ -412,11 +427,13 @@ class TestBlockStorageClusterShow(TestBlockStorageCluster):
) )
def test_cluster_show_pre_v37(self): def test_cluster_show_pre_v37(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.6') '3.6'
)
arglist = [ arglist = [
'--binary', self.cluster.binary, '--binary',
self.cluster.binary,
self.cluster.name, self.cluster.name,
] ]
verifylist = [ verifylist = [
@ -427,8 +444,8 @@ class TestBlockStorageClusterShow(TestBlockStorageCluster):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( 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)
)

View File

@ -22,7 +22,6 @@ from openstackclient.volume.v3 import block_storage_log_level as service
class TestService(volume_fakes.TestVolume): class TestService(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -32,7 +31,6 @@ class TestService(volume_fakes.TestVolume):
class TestBlockStorageLogLevelList(TestService): class TestBlockStorageLogLevelList(TestService):
service_log = volume_fakes.create_service_log_level_entry() service_log = volume_fakes.create_service_log_level_entry()
def setUp(self): def setUp(self):
@ -44,12 +42,16 @@ class TestBlockStorageLogLevelList(TestService):
self.cmd = service.BlockStorageLogLevelList(self.app, None) self.cmd = service.BlockStorageLogLevelList(self.app, None)
def test_block_storage_log_level_list(self): def test_block_storage_log_level_list(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.32') '3.32'
)
arglist = [ arglist = [
'--host', self.service_log.host, '--host',
'--service', self.service_log.binary, self.service_log.host,
'--log-prefix', self.service_log.prefix, '--service',
self.service_log.binary,
'--log-prefix',
self.service_log.prefix,
] ]
verifylist = [ verifylist = [
('host', self.service_log.host), ('host', self.service_log.host),
@ -70,12 +72,14 @@ class TestBlockStorageLogLevelList(TestService):
# confirming if all expected columns are present in the result. # confirming if all expected columns are present in the result.
self.assertEqual(expected_columns, columns) self.assertEqual(expected_columns, columns)
datalist = (( datalist = (
self.service_log.binary, (
self.service_log.host, self.service_log.binary,
self.service_log.prefix, self.service_log.host,
self.service_log.level, self.service_log.prefix,
), ) self.service_log.level,
),
)
# confirming if all expected values are present in the result. # confirming if all expected values are present in the result.
self.assertEqual(datalist, tuple(data)) self.assertEqual(datalist, tuple(data))
@ -89,9 +93,12 @@ class TestBlockStorageLogLevelList(TestService):
def test_block_storage_log_level_list_pre_332(self): def test_block_storage_log_level_list_pre_332(self):
arglist = [ arglist = [
'--host', self.service_log.host, '--host',
'--service', 'cinder-api', self.service_log.host,
'--log-prefix', 'cinder_test.api.common', '--service',
'cinder-api',
'--log-prefix',
'cinder_test.api.common',
] ]
verifylist = [ verifylist = [
('host', self.service_log.host), ('host', self.service_log.host),
@ -100,18 +107,24 @@ class TestBlockStorageLogLevelList(TestService):
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises(exceptions.CommandError, self.cmd.take_action, exc = self.assertRaises(
parsed_args) exceptions.CommandError, self.cmd.take_action, parsed_args
)
self.assertIn( 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): def test_block_storage_log_level_list_invalid_service_name(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.32') '3.32'
)
arglist = [ arglist = [
'--host', self.service_log.host, '--host',
'--service', 'nova-api', self.service_log.host,
'--log-prefix', 'cinder_test.api.common', '--service',
'nova-api',
'--log-prefix',
'cinder_test.api.common',
] ]
verifylist = [ verifylist = [
('host', self.service_log.host), ('host', self.service_log.host),
@ -119,13 +132,17 @@ class TestBlockStorageLogLevelList(TestService):
('log_prefix', 'cinder_test.api.common'), ('log_prefix', 'cinder_test.api.common'),
] ]
self.assertRaises(tests_utils.ParserException, self.check_parser, self.assertRaises(
self.cmd, arglist, verifylist) tests_utils.ParserException,
self.check_parser,
self.cmd,
arglist,
verifylist,
)
@ddt.ddt @ddt.ddt
class TestBlockStorageLogLevelSet(TestService): class TestBlockStorageLogLevelSet(TestService):
service_log = volume_fakes.create_service_log_level_entry() service_log = volume_fakes.create_service_log_level_entry()
def setUp(self): def setUp(self):
@ -135,13 +152,17 @@ class TestBlockStorageLogLevelSet(TestService):
self.cmd = service.BlockStorageLogLevelSet(self.app, None) self.cmd = service.BlockStorageLogLevelSet(self.app, None)
def test_block_storage_log_level_set(self): def test_block_storage_log_level_set(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.32') '3.32'
)
arglist = [ arglist = [
'ERROR', 'ERROR',
'--host', self.service_log.host, '--host',
'--service', self.service_log.binary, self.service_log.host,
'--log-prefix', self.service_log.prefix, '--service',
self.service_log.binary,
'--log-prefix',
self.service_log.prefix,
] ]
verifylist = [ verifylist = [
('level', 'ERROR'), ('level', 'ERROR'),
@ -164,9 +185,12 @@ class TestBlockStorageLogLevelSet(TestService):
def test_block_storage_log_level_set_pre_332(self): def test_block_storage_log_level_set_pre_332(self):
arglist = [ arglist = [
'ERROR', 'ERROR',
'--host', self.service_log.host, '--host',
'--service', 'cinder-api', self.service_log.host,
'--log-prefix', 'cinder_test.api.common', '--service',
'cinder-api',
'--log-prefix',
'cinder_test.api.common',
] ]
verifylist = [ verifylist = [
('level', 'ERROR'), ('level', 'ERROR'),
@ -176,19 +200,25 @@ class TestBlockStorageLogLevelSet(TestService):
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises(exceptions.CommandError, self.cmd.take_action, exc = self.assertRaises(
parsed_args) exceptions.CommandError, self.cmd.take_action, parsed_args
)
self.assertIn( 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): def test_block_storage_log_level_set_invalid_service_name(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.32') '3.32'
)
arglist = [ arglist = [
'ERROR', 'ERROR',
'--host', self.service_log.host, '--host',
'--service', 'nova-api', self.service_log.host,
'--log-prefix', 'cinder.api.common', '--service',
'nova-api',
'--log-prefix',
'cinder.api.common',
] ]
verifylist = [ verifylist = [
('level', 'ERROR'), ('level', 'ERROR'),
@ -197,18 +227,27 @@ class TestBlockStorageLogLevelSet(TestService):
('log_prefix', 'cinder.api.common'), ('log_prefix', 'cinder.api.common'),
] ]
self.assertRaises(tests_utils.ParserException, self.check_parser, self.assertRaises(
self.cmd, arglist, verifylist) tests_utils.ParserException,
self.check_parser,
self.cmd,
arglist,
verifylist,
)
@ddt.data('WARNING', 'info', 'Error', 'debuG', 'fake-log-level') @ddt.data('WARNING', 'info', 'Error', 'debuG', 'fake-log-level')
def test_block_storage_log_level_set_log_level(self, log_level): def test_block_storage_log_level_set_log_level(self, log_level):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.32') '3.32'
)
arglist = [ arglist = [
log_level, log_level,
'--host', self.service_log.host, '--host',
'--service', 'cinder-api', self.service_log.host,
'--log-prefix', 'cinder.api.common', '--service',
'cinder-api',
'--log-prefix',
'cinder.api.common',
] ]
verifylist = [ verifylist = [
('level', log_level.upper()), ('level', log_level.upper()),
@ -218,8 +257,13 @@ class TestBlockStorageLogLevelSet(TestService):
] ]
if log_level == 'fake-log-level': if log_level == 'fake-log-level':
self.assertRaises(tests_utils.ParserException, self.check_parser, self.assertRaises(
self.cmd, arglist, verifylist) tests_utils.ParserException,
self.check_parser,
self.cmd,
arglist,
verifylist,
)
else: else:
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -230,4 +274,5 @@ class TestBlockStorageLogLevelSet(TestService):
level=log_level.upper(), level=log_level.upper(),
server=self.service_log.host, server=self.service_log.host,
binary=self.service_log.binary, binary=self.service_log.binary,
prefix=self.service_log.prefix) prefix=self.service_log.prefix,
)

View File

@ -21,7 +21,6 @@ from openstackclient.volume.v3 import block_storage_manage
class TestBlockStorageManage(v2_volume_fakes.TestVolume): class TestBlockStorageManage(v2_volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -32,22 +31,24 @@ class TestBlockStorageManage(v2_volume_fakes.TestVolume):
class TestBlockStorageVolumeManage(TestBlockStorageManage): class TestBlockStorageVolumeManage(TestBlockStorageManage):
volume_manage_list = volume_fakes.create_volume_manage_list_records() volume_manage_list = volume_fakes.create_volume_manage_list_records()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.volumes_mock.list_manageable.return_value = ( self.volumes_mock.list_manageable.return_value = (
self.volume_manage_list) self.volume_manage_list
)
# Get the command object to test # Get the command object to test
self.cmd = block_storage_manage.BlockStorageManageVolumes( self.cmd = block_storage_manage.BlockStorageManageVolumes(
self.app, None) self.app, None
)
def test_block_storage_volume_manage_list(self): def test_block_storage_volume_manage_list(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.8') '3.8'
)
host = 'fake_host' host = 'fake_host'
arglist = [ arglist = [
host, host,
@ -108,51 +109,65 @@ class TestBlockStorageVolumeManage(TestBlockStorageManage):
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises(exceptions.CommandError, self.cmd.take_action, exc = self.assertRaises(
parsed_args) exceptions.CommandError, self.cmd.take_action, parsed_args
)
self.assertIn( 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): def test_block_storage_volume_manage_pre_317(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.16') '3.16'
)
cluster = 'fake_cluster' cluster = 'fake_cluster'
arglist = [ arglist = [
'--cluster', cluster, '--cluster',
cluster,
] ]
verifylist = [ verifylist = [
('cluster', cluster), ('cluster', cluster),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises(exceptions.CommandError, self.cmd.take_action, exc = self.assertRaises(
parsed_args) exceptions.CommandError, self.cmd.take_action, parsed_args
)
self.assertIn( 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)) self.assertIn('--cluster', str(exc))
def test_block_storage_volume_manage_host_and_cluster(self): def test_block_storage_volume_manage_host_and_cluster(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.17') '3.17'
)
host = 'fake_host' host = 'fake_host'
cluster = 'fake_cluster' cluster = 'fake_cluster'
arglist = [ arglist = [
host, host,
'--cluster', cluster, '--cluster',
cluster,
] ]
verifylist = [ verifylist = [
('host', host), ('host', host),
('cluster', cluster), ('cluster', cluster),
] ]
exc = self.assertRaises(tests_utils.ParserException, exc = self.assertRaises(
self.check_parser, self.cmd, tests_utils.ParserException,
arglist, verifylist) self.check_parser,
self.cmd,
arglist,
verifylist,
)
self.assertIn( 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): def test_block_storage_volume_manage_list_all_args(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.8') '3.8'
)
host = 'fake_host' host = 'fake_host'
detailed = True detailed = True
marker = 'fake_marker' marker = 'fake_marker'
@ -161,11 +176,16 @@ class TestBlockStorageVolumeManage(TestBlockStorageManage):
sort = 'size:asc' sort = 'size:asc'
arglist = [ arglist = [
host, host,
'--detailed', str(detailed), '--detailed',
'--marker', marker, str(detailed),
'--limit', limit, '--marker',
'--offset', offset, marker,
'--sort', sort, '--limit',
limit,
'--offset',
offset,
'--sort',
sort,
] ]
verifylist = [ verifylist = [
('host', host), ('host', host),
@ -220,22 +240,24 @@ class TestBlockStorageVolumeManage(TestBlockStorageManage):
class TestBlockStorageSnapshotManage(TestBlockStorageManage): class TestBlockStorageSnapshotManage(TestBlockStorageManage):
snapshot_manage_list = volume_fakes.create_snapshot_manage_list_records() snapshot_manage_list = volume_fakes.create_snapshot_manage_list_records()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.snapshots_mock.list_manageable.return_value = ( self.snapshots_mock.list_manageable.return_value = (
self.snapshot_manage_list) self.snapshot_manage_list
)
# Get the command object to test # Get the command object to test
self.cmd = block_storage_manage.BlockStorageManageSnapshots( self.cmd = block_storage_manage.BlockStorageManageSnapshots(
self.app, None) self.app, None
)
def test_block_storage_snapshot_manage_list(self): def test_block_storage_snapshot_manage_list(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.8') '3.8'
)
host = 'fake_host' host = 'fake_host'
arglist = [ arglist = [
host, host,
@ -298,51 +320,65 @@ class TestBlockStorageSnapshotManage(TestBlockStorageManage):
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises(exceptions.CommandError, self.cmd.take_action, exc = self.assertRaises(
parsed_args) exceptions.CommandError, self.cmd.take_action, parsed_args
)
self.assertIn( 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): def test_block_storage_volume_manage_pre_317(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.16') '3.16'
)
cluster = 'fake_cluster' cluster = 'fake_cluster'
arglist = [ arglist = [
'--cluster', cluster, '--cluster',
cluster,
] ]
verifylist = [ verifylist = [
('cluster', cluster), ('cluster', cluster),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises(exceptions.CommandError, self.cmd.take_action, exc = self.assertRaises(
parsed_args) exceptions.CommandError, self.cmd.take_action, parsed_args
)
self.assertIn( 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)) self.assertIn('--cluster', str(exc))
def test_block_storage_volume_manage_host_and_cluster(self): def test_block_storage_volume_manage_host_and_cluster(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.17') '3.17'
)
host = 'fake_host' host = 'fake_host'
cluster = 'fake_cluster' cluster = 'fake_cluster'
arglist = [ arglist = [
host, host,
'--cluster', cluster, '--cluster',
cluster,
] ]
verifylist = [ verifylist = [
('host', host), ('host', host),
('cluster', cluster), ('cluster', cluster),
] ]
exc = self.assertRaises(tests_utils.ParserException, exc = self.assertRaises(
self.check_parser, self.cmd, tests_utils.ParserException,
arglist, verifylist) self.check_parser,
self.cmd,
arglist,
verifylist,
)
self.assertIn( 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): def test_block_storage_volume_manage_list_all_args(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.8') '3.8'
)
host = 'fake_host' host = 'fake_host'
detailed = True detailed = True
marker = 'fake_marker' marker = 'fake_marker'
@ -351,11 +387,16 @@ class TestBlockStorageSnapshotManage(TestBlockStorageManage):
sort = 'size:asc' sort = 'size:asc'
arglist = [ arglist = [
host, host,
'--detailed', str(detailed), '--detailed',
'--marker', marker, str(detailed),
'--limit', limit, '--marker',
'--offset', offset, marker,
'--sort', sort, '--limit',
limit,
'--offset',
offset,
'--sort',
sort,
] ]
verifylist = [ verifylist = [
('host', host), ('host', host),

View File

@ -18,34 +18,38 @@ from openstackclient.volume.v3 import block_storage_resource_filter
class TestBlockStorageResourceFilter(volume_fakes.TestVolume): class TestBlockStorageResourceFilter(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
# Get a shortcut to the ResourceFilterManager Mock # Get a shortcut to the ResourceFilterManager Mock
self.resource_filter_mock = \ self.resource_filter_mock = (
self.app.client_manager.volume.resource_filters self.app.client_manager.volume.resource_filters
)
self.resource_filter_mock.reset_mock() self.resource_filter_mock.reset_mock()
class TestBlockStorageResourceFilterList(TestBlockStorageResourceFilter): class TestBlockStorageResourceFilterList(TestBlockStorageResourceFilter):
# The resource filters to be listed # The resource filters to be listed
fake_resource_filters = volume_fakes.create_resource_filters() fake_resource_filters = volume_fakes.create_resource_filters()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.resource_filter_mock.list.return_value = \ self.resource_filter_mock.list.return_value = (
self.fake_resource_filters self.fake_resource_filters
)
# Get the command object to test # Get the command object to test
self.cmd = block_storage_resource_filter\ self.cmd = (
.ListBlockStorageResourceFilter(self.app, None) block_storage_resource_filter.ListBlockStorageResourceFilter(
self.app, None
)
)
def test_resource_filter_list(self): def test_resource_filter_list(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.33') '3.33'
)
arglist = [] arglist = []
verifylist = [] verifylist = []
@ -56,7 +60,8 @@ class TestBlockStorageResourceFilterList(TestBlockStorageResourceFilter):
( (
resource_filter.resource, resource_filter.resource,
resource_filter.filters, 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) columns, data = self.cmd.take_action(parsed_args)
@ -67,39 +72,44 @@ class TestBlockStorageResourceFilterList(TestBlockStorageResourceFilter):
self.resource_filter_mock.list.assert_called_with() self.resource_filter_mock.list.assert_called_with()
def test_resource_filter_list_pre_v333(self): def test_resource_filter_list_pre_v333(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.32') '3.32'
)
arglist = [] arglist = []
verifylist = [] verifylist = []
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( 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): class TestBlockStorageResourceFilterShow(TestBlockStorageResourceFilter):
# The resource filters to be listed # The resource filters to be listed
fake_resource_filter = volume_fakes.create_one_resource_filter() fake_resource_filter = volume_fakes.create_one_resource_filter()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.resource_filter_mock.list.return_value = \ self.resource_filter_mock.list.return_value = iter(
iter([self.fake_resource_filter]) [self.fake_resource_filter]
)
# Get the command object to test # Get the command object to test
self.cmd = block_storage_resource_filter\ self.cmd = (
.ShowBlockStorageResourceFilter(self.app, None) block_storage_resource_filter.ShowBlockStorageResourceFilter(
self.app, None
)
)
def test_resource_filter_show(self): def test_resource_filter_show(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.33') '3.33'
)
arglist = [ arglist = [
self.fake_resource_filter.resource, self.fake_resource_filter.resource,
@ -123,8 +133,9 @@ class TestBlockStorageResourceFilterShow(TestBlockStorageResourceFilter):
self.resource_filter_mock.list.assert_called_with(resource='volume') self.resource_filter_mock.list.assert_called_with(resource='volume')
def test_resource_filter_show_pre_v333(self): def test_resource_filter_show_pre_v333(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.32') '3.32'
)
arglist = [ arglist = [
self.fake_resource_filter.resource, self.fake_resource_filter.resource,
@ -135,8 +146,8 @@ class TestBlockStorageResourceFilterShow(TestBlockStorageResourceFilter):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( 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)
)

View File

@ -25,7 +25,6 @@ from openstackclient.volume.v3 import volume
class TestVolumeSummary(volume_fakes.TestVolume): class TestVolumeSummary(volume_fakes.TestVolume):
columns = [ columns = [
'Total Count', 'Total Count',
'Total Size', 'Total Size',
@ -41,15 +40,18 @@ class TestVolumeSummary(volume_fakes.TestVolume):
self.return_dict = { self.return_dict = {
'volume-summary': { 'volume-summary': {
'total_count': 2, '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 self.volumes_mock.summary.return_value = self.return_dict
# Get the command object to test # Get the command object to test
self.cmd = volume.VolumeSummary(self.app, None) self.cmd = volume.VolumeSummary(self.app, None)
def test_volume_summary(self): def test_volume_summary(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.12') '3.12'
)
arglist = [ arglist = [
'--all-projects', '--all-projects',
] ]
@ -66,9 +68,7 @@ class TestVolumeSummary(volume_fakes.TestVolume):
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
datalist = ( datalist = (2, self.mock_vol_1.size + self.mock_vol_2.size)
2,
self.mock_vol_1.size + self.mock_vol_2.size)
self.assertCountEqual(datalist, tuple(data)) self.assertCountEqual(datalist, tuple(data))
def test_volume_summary_pre_312(self): 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) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.12 or greater is required', '--os-volume-api-version 3.12 or greater is required', str(exc)
str(exc)) )
def test_volume_summary_with_metadata(self): def test_volume_summary_with_metadata(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.36') '3.36'
)
combine_meta = {**self.mock_vol_1.metadata, **self.mock_vol_2.metadata} combine_meta = {**self.mock_vol_1.metadata, **self.mock_vol_2.metadata}
meta_dict = copy.deepcopy(self.return_dict) meta_dict = copy.deepcopy(self.return_dict)
@ -119,12 +119,12 @@ class TestVolumeSummary(volume_fakes.TestVolume):
datalist = ( datalist = (
2, 2,
self.mock_vol_1.size + self.mock_vol_2.size, 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)) self.assertCountEqual(datalist, tuple(data))
class TestVolumeRevertToSnapshot(volume_fakes.TestVolume): class TestVolumeRevertToSnapshot(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -134,7 +134,8 @@ class TestVolumeRevertToSnapshot(volume_fakes.TestVolume):
self.snapshots_mock.reset_mock() self.snapshots_mock.reset_mock()
self.mock_volume = volume_fakes.create_one_volume() self.mock_volume = volume_fakes.create_one_volume()
self.mock_snapshot = volume_fakes.create_one_snapshot( 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 # Get the command object to test
self.cmd = volume.VolumeRevertToSnapshot(self.app, None) 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) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.40 or greater is required', '--os-volume-api-version 3.40 or greater is required', str(exc)
str(exc)) )
def test_volume_revert_to_snapshot(self): def test_volume_revert_to_snapshot(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.40') '3.40'
)
arglist = [ arglist = [
self.mock_snapshot.id, self.mock_snapshot.id,
] ]
@ -168,8 +169,9 @@ class TestVolumeRevertToSnapshot(volume_fakes.TestVolume):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [self.mock_snapshot, self.mock_volume] find_mock_result = [self.mock_snapshot, self.mock_volume]
with mock.patch.object(utils, 'find_resource', with mock.patch.object(
side_effect=find_mock_result) as find_mock: utils, 'find_resource', side_effect=find_mock_result
) as find_mock:
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.volumes_mock.revert_to_snapshot.assert_called_once_with( self.volumes_mock.revert_to_snapshot.assert_called_once_with(

View File

@ -21,15 +21,15 @@ from openstackclient.volume.v3 import volume_attachment
class TestVolumeAttachment(volume_fakes.TestVolume): class TestVolumeAttachment(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.volumes_mock = self.app.client_manager.volume.volumes self.volumes_mock = self.app.client_manager.volume.volumes
self.volumes_mock.reset_mock() self.volumes_mock.reset_mock()
self.volume_attachments_mock = \ self.volume_attachments_mock = (
self.app.client_manager.volume.attachments self.app.client_manager.volume.attachments
)
self.volume_attachments_mock.reset_mock() self.volume_attachments_mock.reset_mock()
self.projects_mock = self.app.client_manager.identity.projects self.projects_mock = self.app.client_manager.identity.projects
@ -40,7 +40,6 @@ class TestVolumeAttachment(volume_fakes.TestVolume):
class TestVolumeAttachmentCreate(TestVolumeAttachment): class TestVolumeAttachmentCreate(TestVolumeAttachment):
volume = volume_fakes.create_one_volume() volume = volume_fakes.create_one_volume()
server = compute_fakes.FakeServer.create_one_server() server = compute_fakes.FakeServer.create_one_server()
volume_attachment = volume_fakes.create_one_volume_attachment( volume_attachment = volume_fakes.create_one_volume_attachment(
@ -74,14 +73,16 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
self.volumes_mock.get.return_value = self.volume self.volumes_mock.get.return_value = self.volume
self.servers_mock.get.return_value = self.server self.servers_mock.get.return_value = self.server
# VolumeAttachmentManager.create returns a dict # 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.volume_attachment.to_dict()
)
self.cmd = volume_attachment.CreateVolumeAttachment(self.app, None) self.cmd = volume_attachment.CreateVolumeAttachment(self.app, None)
def test_volume_attachment_create(self): def test_volume_attachment_create(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.27') '3.27'
)
arglist = [ arglist = [
self.volume.id, self.volume.id,
@ -107,27 +108,38 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
self.volumes_mock.get.assert_called_once_with(self.volume.id) self.volumes_mock.get.assert_called_once_with(self.volume.id)
self.servers_mock.get.assert_called_once_with(self.server.id) self.servers_mock.get.assert_called_once_with(self.server.id)
self.volume_attachments_mock.create.assert_called_once_with( 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.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_attachment_create_with_connect(self): def test_volume_attachment_create_with_connect(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.54') '3.54'
)
arglist = [ arglist = [
self.volume.id, self.volume.id,
self.server.id, self.server.id,
'--connect', '--connect',
'--initiator', 'iqn.1993-08.org.debian:01:cad181614cec', '--initiator',
'--ip', '192.168.1.20', 'iqn.1993-08.org.debian:01:cad181614cec',
'--host', 'my-host', '--ip',
'--platform', 'x86_64', '192.168.1.20',
'--os-type', 'linux2', '--host',
'my-host',
'--platform',
'x86_64',
'--os-type',
'linux2',
'--multipath', '--multipath',
'--mountpoint', '/dev/vdb', '--mountpoint',
'--mode', 'null', '/dev/vdb',
'--mode',
'null',
] ]
verifylist = [ verifylist = [
('volume', self.volume.id), ('volume', self.volume.id),
@ -146,27 +158,33 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
connect_info = dict([ connect_info = dict(
('initiator', 'iqn.1993-08.org.debian:01:cad181614cec'), [
('ip', '192.168.1.20'), ('initiator', 'iqn.1993-08.org.debian:01:cad181614cec'),
('host', 'my-host'), ('ip', '192.168.1.20'),
('platform', 'x86_64'), ('host', 'my-host'),
('os_type', 'linux2'), ('platform', 'x86_64'),
('multipath', True), ('os_type', 'linux2'),
('mountpoint', '/dev/vdb'), ('multipath', True),
]) ('mountpoint', '/dev/vdb'),
]
)
self.volumes_mock.get.assert_called_once_with(self.volume.id) self.volumes_mock.get.assert_called_once_with(self.volume.id)
self.servers_mock.get.assert_called_once_with(self.server.id) self.servers_mock.get.assert_called_once_with(self.server.id)
self.volume_attachments_mock.create.assert_called_once_with( 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.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_attachment_create_pre_v327(self): def test_volume_attachment_create_pre_v327(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.26') '3.26'
)
arglist = [ arglist = [
self.volume.id, self.volume.id,
@ -179,21 +197,22 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.27 or greater is required', '--os-volume-api-version 3.27 or greater is required', str(exc)
str(exc)) )
def test_volume_attachment_create_with_mode_pre_v354(self): def test_volume_attachment_create_with_mode_pre_v354(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.53') '3.53'
)
arglist = [ arglist = [
self.volume.id, self.volume.id,
self.server.id, self.server.id,
'--mode', 'rw', '--mode',
'rw',
] ]
verifylist = [ verifylist = [
('volume', self.volume.id), ('volume', self.volume.id),
@ -203,21 +222,22 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.54 or greater is required', '--os-volume-api-version 3.54 or greater is required', str(exc)
str(exc)) )
def test_volume_attachment_create_with_connect_missing_arg(self): def test_volume_attachment_create_with_connect_missing_arg(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.54') '3.54'
)
arglist = [ arglist = [
self.volume.id, self.volume.id,
self.server.id, self.server.id,
'--initiator', 'iqn.1993-08.org.debian:01:cad181614cec', '--initiator',
'iqn.1993-08.org.debian:01:cad181614cec',
] ]
verifylist = [ verifylist = [
('volume', self.volume.id), ('volume', self.volume.id),
@ -228,16 +248,14 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'You must specify the --connect option for any', 'You must specify the --connect option for any', str(exc)
str(exc)) )
class TestVolumeAttachmentDelete(TestVolumeAttachment): class TestVolumeAttachmentDelete(TestVolumeAttachment):
volume_attachment = volume_fakes.create_one_volume_attachment() volume_attachment = volume_fakes.create_one_volume_attachment()
def setUp(self): def setUp(self):
@ -248,8 +266,9 @@ class TestVolumeAttachmentDelete(TestVolumeAttachment):
self.cmd = volume_attachment.DeleteVolumeAttachment(self.app, None) self.cmd = volume_attachment.DeleteVolumeAttachment(self.app, None)
def test_volume_attachment_delete(self): def test_volume_attachment_delete(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.27') '3.27'
)
arglist = [ arglist = [
self.volume_attachment.id, self.volume_attachment.id,
@ -267,8 +286,9 @@ class TestVolumeAttachmentDelete(TestVolumeAttachment):
self.assertIsNone(result) self.assertIsNone(result)
def test_volume_attachment_delete_pre_v327(self): def test_volume_attachment_delete_pre_v327(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.26') '3.26'
)
arglist = [ arglist = [
self.volume_attachment.id, self.volume_attachment.id,
@ -279,16 +299,14 @@ class TestVolumeAttachmentDelete(TestVolumeAttachment):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.27 or greater is required', '--os-volume-api-version 3.27 or greater is required', str(exc)
str(exc)) )
class TestVolumeAttachmentSet(TestVolumeAttachment): class TestVolumeAttachmentSet(TestVolumeAttachment):
volume_attachment = volume_fakes.create_one_volume_attachment() volume_attachment = volume_fakes.create_one_volume_attachment()
columns = ( columns = (
@ -315,24 +333,32 @@ class TestVolumeAttachmentSet(TestVolumeAttachment):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.volume_attachments_mock.update.return_value = \ self.volume_attachments_mock.update.return_value = (
self.volume_attachment self.volume_attachment
)
self.cmd = volume_attachment.SetVolumeAttachment(self.app, None) self.cmd = volume_attachment.SetVolumeAttachment(self.app, None)
def test_volume_attachment_set(self): def test_volume_attachment_set(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.27') '3.27'
)
arglist = [ arglist = [
self.volume_attachment.id, self.volume_attachment.id,
'--initiator', 'iqn.1993-08.org.debian:01:cad181614cec', '--initiator',
'--ip', '192.168.1.20', 'iqn.1993-08.org.debian:01:cad181614cec',
'--host', 'my-host', '--ip',
'--platform', 'x86_64', '192.168.1.20',
'--os-type', 'linux2', '--host',
'my-host',
'--platform',
'x86_64',
'--os-type',
'linux2',
'--multipath', '--multipath',
'--mountpoint', '/dev/vdb', '--mountpoint',
'/dev/vdb',
] ]
verifylist = [ verifylist = [
('attachment', self.volume_attachment.id), ('attachment', self.volume_attachment.id),
@ -348,29 +374,34 @@ class TestVolumeAttachmentSet(TestVolumeAttachment):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
connect_info = dict([ connect_info = dict(
('initiator', 'iqn.1993-08.org.debian:01:cad181614cec'), [
('ip', '192.168.1.20'), ('initiator', 'iqn.1993-08.org.debian:01:cad181614cec'),
('host', 'my-host'), ('ip', '192.168.1.20'),
('platform', 'x86_64'), ('host', 'my-host'),
('os_type', 'linux2'), ('platform', 'x86_64'),
('multipath', True), ('os_type', 'linux2'),
('mountpoint', '/dev/vdb'), ('multipath', True),
]) ('mountpoint', '/dev/vdb'),
]
)
self.volume_attachments_mock.update.assert_called_once_with( 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.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_attachment_set_pre_v327(self): def test_volume_attachment_set_pre_v327(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.26') '3.26'
)
arglist = [ arglist = [
self.volume_attachment.id, self.volume_attachment.id,
'--initiator', 'iqn.1993-08.org.debian:01:cad181614cec', '--initiator',
'iqn.1993-08.org.debian:01:cad181614cec',
] ]
verifylist = [ verifylist = [
('attachment', self.volume_attachment.id), ('attachment', self.volume_attachment.id),
@ -379,16 +410,14 @@ class TestVolumeAttachmentSet(TestVolumeAttachment):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.27 or greater is required', '--os-volume-api-version 3.27 or greater is required', str(exc)
str(exc)) )
class TestVolumeAttachmentComplete(TestVolumeAttachment): class TestVolumeAttachmentComplete(TestVolumeAttachment):
volume_attachment = volume_fakes.create_one_volume_attachment() volume_attachment = volume_fakes.create_one_volume_attachment()
def setUp(self): def setUp(self):
@ -399,8 +428,9 @@ class TestVolumeAttachmentComplete(TestVolumeAttachment):
self.cmd = volume_attachment.CompleteVolumeAttachment(self.app, None) self.cmd = volume_attachment.CompleteVolumeAttachment(self.app, None)
def test_volume_attachment_complete(self): def test_volume_attachment_complete(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.44') '3.44'
)
arglist = [ arglist = [
self.volume_attachment.id, self.volume_attachment.id,
@ -418,8 +448,9 @@ class TestVolumeAttachmentComplete(TestVolumeAttachment):
self.assertIsNone(result) self.assertIsNone(result)
def test_volume_attachment_complete_pre_v344(self): def test_volume_attachment_complete_pre_v344(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.43') '3.43'
)
arglist = [ arglist = [
self.volume_attachment.id, self.volume_attachment.id,
@ -430,16 +461,14 @@ class TestVolumeAttachmentComplete(TestVolumeAttachment):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.44 or greater is required', '--os-volume-api-version 3.44 or greater is required', str(exc)
str(exc)) )
class TestVolumeAttachmentList(TestVolumeAttachment): class TestVolumeAttachmentList(TestVolumeAttachment):
project = identity_fakes.FakeProject.create_one_project() project = identity_fakes.FakeProject.create_one_project()
volume_attachments = volume_fakes.create_volume_attachments() volume_attachments = volume_fakes.create_volume_attachments()
@ -455,21 +484,24 @@ class TestVolumeAttachmentList(TestVolumeAttachment):
volume_attachment.volume_id, volume_attachment.volume_id,
volume_attachment.instance, volume_attachment.instance,
volume_attachment.status, volume_attachment.status,
) for volume_attachment in volume_attachments )
for volume_attachment in volume_attachments
] ]
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.projects_mock.get.return_value = self.project 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.volume_attachments
)
self.cmd = volume_attachment.ListVolumeAttachment(self.app, None) self.cmd = volume_attachment.ListVolumeAttachment(self.app, None)
def test_volume_attachment_list(self): def test_volume_attachment_list(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.27') '3.27'
)
arglist = [] arglist = []
verifylist = [ verifylist = [
@ -498,15 +530,21 @@ class TestVolumeAttachmentList(TestVolumeAttachment):
self.assertCountEqual(tuple(self.data), data) self.assertCountEqual(tuple(self.data), data)
def test_volume_attachment_list_with_options(self): def test_volume_attachment_list_with_options(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.27') '3.27'
)
arglist = [ arglist = [
'--project', self.project.name, '--project',
'--volume-id', 'volume-id', self.project.name,
'--status', 'attached', '--volume-id',
'--marker', 'volume-attachment-id', 'volume-id',
'--limit', '2', '--status',
'attached',
'--marker',
'volume-attachment-id',
'--limit',
'2',
] ]
verifylist = [ verifylist = [
('project', self.project.name), ('project', self.project.name),
@ -534,8 +572,9 @@ class TestVolumeAttachmentList(TestVolumeAttachment):
self.assertCountEqual(tuple(self.data), data) self.assertCountEqual(tuple(self.data), data)
def test_volume_attachment_list_pre_v327(self): def test_volume_attachment_list_pre_v327(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.26') '3.26'
)
arglist = [] arglist = []
verifylist = [ verifylist = [
@ -549,9 +588,8 @@ class TestVolumeAttachmentList(TestVolumeAttachment):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.27 or greater is required', '--os-volume-api-version 3.27 or greater is required', str(exc)
str(exc)) )

View File

@ -21,27 +21,27 @@ from openstackclient.volume.v3 import volume_group
class TestVolumeGroup(volume_fakes.TestVolume): class TestVolumeGroup(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.volume_groups_mock = self.app.client_manager.volume.groups self.volume_groups_mock = self.app.client_manager.volume.groups
self.volume_groups_mock.reset_mock() self.volume_groups_mock.reset_mock()
self.volume_group_types_mock = \ self.volume_group_types_mock = (
self.app.client_manager.volume.group_types self.app.client_manager.volume.group_types
)
self.volume_group_types_mock.reset_mock() self.volume_group_types_mock.reset_mock()
self.volume_types_mock = self.app.client_manager.volume.volume_types self.volume_types_mock = self.app.client_manager.volume.volume_types
self.volume_types_mock.reset_mock() self.volume_types_mock.reset_mock()
self.volume_group_snapshots_mock = \ self.volume_group_snapshots_mock = (
self.app.client_manager.volume.group_snapshots self.app.client_manager.volume.group_snapshots
)
self.volume_group_snapshots_mock.reset_mock() self.volume_group_snapshots_mock.reset_mock()
class TestVolumeGroupCreate(TestVolumeGroup): class TestVolumeGroupCreate(TestVolumeGroup):
fake_volume_type = volume_fakes.create_one_volume_type() fake_volume_type = volume_fakes.create_one_volume_type()
fake_volume_group_type = volume_fakes.create_one_volume_group_type() fake_volume_group_type = volume_fakes.create_one_volume_group_type()
fake_volume_group = volume_fakes.create_one_volume_group( fake_volume_group = volume_fakes.create_one_volume_group(
@ -50,8 +50,9 @@ class TestVolumeGroupCreate(TestVolumeGroup):
'volume_types': [fake_volume_type.id], 'volume_types': [fake_volume_type.id],
}, },
) )
fake_volume_group_snapshot = \ fake_volume_group_snapshot = (
volume_fakes.create_one_volume_group_snapshot() volume_fakes.create_one_volume_group_snapshot()
)
columns = ( columns = (
'ID', 'ID',
@ -84,24 +85,30 @@ class TestVolumeGroupCreate(TestVolumeGroup):
super().setUp() super().setUp()
self.volume_types_mock.get.return_value = self.fake_volume_type 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.fake_volume_group_type
)
self.volume_groups_mock.create.return_value = self.fake_volume_group 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.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.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.fake_volume_group_snapshot
)
self.cmd = volume_group.CreateVolumeGroup(self.app, None) self.cmd = volume_group.CreateVolumeGroup(self.app, None)
def test_volume_group_create(self): def test_volume_group_create(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.13') '3.13'
)
arglist = [ arglist = [
'--volume-group-type', self.fake_volume_group_type.id, '--volume-group-type',
'--volume-type', self.fake_volume_type.id, self.fake_volume_group_type.id,
'--volume-type',
self.fake_volume_type.id,
] ]
verifylist = [ verifylist = [
('volume_group_type', self.fake_volume_group_type.id), ('volume_group_type', self.fake_volume_group_type.id),
@ -115,9 +122,11 @@ class TestVolumeGroupCreate(TestVolumeGroup):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.volume_group_types_mock.get.assert_called_once_with( 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.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.volume_groups_mock.create.assert_called_once_with(
self.fake_volume_group_type.id, self.fake_volume_group_type.id,
self.fake_volume_type.id, self.fake_volume_type.id,
@ -129,8 +138,9 @@ class TestVolumeGroupCreate(TestVolumeGroup):
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_group_create__legacy(self): def test_volume_group_create__legacy(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.13') '3.13'
)
arglist = [ arglist = [
self.fake_volume_group_type.id, self.fake_volume_group_type.id,
@ -149,9 +159,11 @@ class TestVolumeGroupCreate(TestVolumeGroup):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.volume_group_types_mock.get.assert_called_once_with( 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.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.volume_groups_mock.create.assert_called_once_with(
self.fake_volume_group_type.id, self.fake_volume_group_type.id,
self.fake_volume_type.id, self.fake_volume_type.id,
@ -168,11 +180,13 @@ class TestVolumeGroupCreate(TestVolumeGroup):
) )
def test_volume_group_create_no_volume_type(self): def test_volume_group_create_no_volume_type(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.13') '3.13'
)
arglist = [ arglist = [
'--volume-group-type', self.fake_volume_group_type.id, '--volume-group-type',
self.fake_volume_group_type.id,
] ]
verifylist = [ verifylist = [
('volume_group_type', self.fake_volume_group_type.id), ('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) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--volume-types is a required argument when creating ', '--volume-types is a required argument when creating ', str(exc)
str(exc)) )
def test_volume_group_create_with_options(self): def test_volume_group_create_with_options(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.13') '3.13'
)
arglist = [ arglist = [
'--volume-group-type', self.fake_volume_group_type.id, '--volume-group-type',
'--volume-type', self.fake_volume_type.id, self.fake_volume_group_type.id,
'--name', 'foo', '--volume-type',
'--description', 'hello, world', self.fake_volume_type.id,
'--availability-zone', 'bar', '--name',
'foo',
'--description',
'hello, world',
'--availability-zone',
'bar',
] ]
verifylist = [ verifylist = [
('volume_group_type', self.fake_volume_group_type.id), ('volume_group_type', self.fake_volume_group_type.id),
@ -213,9 +232,11 @@ class TestVolumeGroupCreate(TestVolumeGroup):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.volume_group_types_mock.get.assert_called_once_with( 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.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.volume_groups_mock.create.assert_called_once_with(
self.fake_volume_group_type.id, self.fake_volume_group_type.id,
self.fake_volume_type.id, self.fake_volume_type.id,
@ -227,12 +248,15 @@ class TestVolumeGroupCreate(TestVolumeGroup):
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_group_create_pre_v313(self): def test_volume_group_create_pre_v313(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.12') '3.12'
)
arglist = [ arglist = [
'--volume-group-type', self.fake_volume_group_type.id, '--volume-group-type',
'--volume-type', self.fake_volume_type.id, self.fake_volume_group_type.id,
'--volume-type',
self.fake_volume_type.id,
] ]
verifylist = [ verifylist = [
('volume_group_type', self.fake_volume_group_type.id), ('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) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.13 or greater is required', '--os-volume-api-version 3.13 or greater is required', str(exc)
str(exc)) )
def test_volume_group_create_from_source_group(self): def test_volume_group_create_from_source_group(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.14') '3.14'
)
arglist = [ arglist = [
'--source-group', self.fake_volume_group.id, '--source-group',
self.fake_volume_group.id,
] ]
verifylist = [ verifylist = [
('source_group', self.fake_volume_group.id), ('source_group', self.fake_volume_group.id),
@ -266,8 +291,11 @@ class TestVolumeGroupCreate(TestVolumeGroup):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.volume_groups_mock.get.assert_has_calls( 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( self.volume_groups_mock.create_from_src.assert_called_once_with(
None, None,
self.fake_volume_group.id, self.fake_volume_group.id,
@ -278,11 +306,13 @@ class TestVolumeGroupCreate(TestVolumeGroup):
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_group_create_from_group_snapshot(self): def test_volume_group_create_from_group_snapshot(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.14') '3.14'
)
arglist = [ arglist = [
'--group-snapshot', self.fake_volume_group_snapshot.id, '--group-snapshot',
self.fake_volume_group_snapshot.id,
] ]
verifylist = [ verifylist = [
('group_snapshot', self.fake_volume_group_snapshot.id), ('group_snapshot', self.fake_volume_group_snapshot.id),
@ -292,9 +322,11 @@ class TestVolumeGroupCreate(TestVolumeGroup):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.volume_group_snapshots_mock.get.assert_called_once_with( 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.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.volume_groups_mock.create_from_src.assert_called_once_with(
self.fake_volume_group_snapshot.id, self.fake_volume_group_snapshot.id,
None, None,
@ -305,11 +337,13 @@ class TestVolumeGroupCreate(TestVolumeGroup):
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_group_create_from_src_pre_v314(self): def test_volume_group_create_from_src_pre_v314(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.13') '3.13'
)
arglist = [ arglist = [
'--source-group', self.fake_volume_group.id, '--source-group',
self.fake_volume_group.id,
] ]
verifylist = [ verifylist = [
('source_group', self.fake_volume_group.id), ('source_group', self.fake_volume_group.id),
@ -317,38 +351,42 @@ class TestVolumeGroupCreate(TestVolumeGroup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.14 or greater is required', '--os-volume-api-version 3.14 or greater is required', str(exc)
str(exc)) )
def test_volume_group_create_from_src_source_group_group_snapshot(self): def test_volume_group_create_from_src_source_group_group_snapshot(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.14') '3.14'
)
arglist = [ arglist = [
'--source-group', self.fake_volume_group.id, '--source-group',
'--group-snapshot', self.fake_volume_group_snapshot.id, self.fake_volume_group.id,
'--group-snapshot',
self.fake_volume_group_snapshot.id,
] ]
verifylist = [ verifylist = [
('source_group', self.fake_volume_group.id), ('source_group', self.fake_volume_group.id),
('group_snapshot', self.fake_volume_group_snapshot.id), ('group_snapshot', self.fake_volume_group_snapshot.id),
] ]
exc = self.assertRaises(tests_utils.ParserException, exc = self.assertRaises(
self.check_parser, tests_utils.ParserException,
self.cmd, self.check_parser,
arglist, self.cmd,
verifylist) arglist,
verifylist,
)
self.assertIn( self.assertIn(
'--group-snapshot: not allowed with argument --source-group', '--group-snapshot: not allowed with argument --source-group',
str(exc)) str(exc),
)
class TestVolumeGroupDelete(TestVolumeGroup): class TestVolumeGroupDelete(TestVolumeGroup):
fake_volume_group = volume_fakes.create_one_volume_group() fake_volume_group = volume_fakes.create_one_volume_group()
def setUp(self): def setUp(self):
@ -360,8 +398,9 @@ class TestVolumeGroupDelete(TestVolumeGroup):
self.cmd = volume_group.DeleteVolumeGroup(self.app, None) self.cmd = volume_group.DeleteVolumeGroup(self.app, None)
def test_volume_group_delete(self): def test_volume_group_delete(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.13') '3.13'
)
arglist = [ arglist = [
self.fake_volume_group.id, self.fake_volume_group.id,
@ -376,13 +415,15 @@ class TestVolumeGroupDelete(TestVolumeGroup):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.volume_groups_mock.delete.assert_called_once_with( 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) self.assertIsNone(result)
def test_volume_group_delete_pre_v313(self): def test_volume_group_delete_pre_v313(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.12') '3.12'
)
arglist = [ arglist = [
self.fake_volume_group.id, self.fake_volume_group.id,
@ -394,16 +435,14 @@ class TestVolumeGroupDelete(TestVolumeGroup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.13 or greater is required', '--os-volume-api-version 3.13 or greater is required', str(exc)
str(exc)) )
class TestVolumeGroupSet(TestVolumeGroup): class TestVolumeGroupSet(TestVolumeGroup):
fake_volume_group = volume_fakes.create_one_volume_group() fake_volume_group = volume_fakes.create_one_volume_group()
columns = ( columns = (
@ -442,13 +481,16 @@ class TestVolumeGroupSet(TestVolumeGroup):
self.cmd = volume_group.SetVolumeGroup(self.app, None) self.cmd = volume_group.SetVolumeGroup(self.app, None)
def test_volume_group_set(self): def test_volume_group_set(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.13') '3.13'
)
arglist = [ arglist = [
self.fake_volume_group.id, self.fake_volume_group.id,
'--name', 'foo', '--name',
'--description', 'hello, world', 'foo',
'--description',
'hello, world',
] ]
verifylist = [ verifylist = [
('group', self.fake_volume_group.id), ('group', self.fake_volume_group.id),
@ -460,14 +502,17 @@ class TestVolumeGroupSet(TestVolumeGroup):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.volume_groups_mock.update.assert_called_once_with( 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.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_group_with_enable_replication_option(self): def test_volume_group_with_enable_replication_option(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.38') '3.38'
)
arglist = [ arglist = [
self.fake_volume_group.id, self.fake_volume_group.id,
@ -482,18 +527,22 @@ class TestVolumeGroupSet(TestVolumeGroup):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.volume_groups_mock.enable_replication.assert_called_once_with( 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.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_group_set_pre_v313(self): def test_volume_group_set_pre_v313(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.12') '3.12'
)
arglist = [ arglist = [
self.fake_volume_group.id, self.fake_volume_group.id,
'--name', 'foo', '--name',
'--description', 'hello, world', 'foo',
'--description',
'hello, world',
] ]
verifylist = [ verifylist = [
('group', self.fake_volume_group.id), ('group', self.fake_volume_group.id),
@ -503,16 +552,16 @@ class TestVolumeGroupSet(TestVolumeGroup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.13 or greater is required', '--os-volume-api-version 3.13 or greater is required', str(exc)
str(exc)) )
def test_volume_group_with_enable_replication_option_pre_v338(self): def test_volume_group_with_enable_replication_option_pre_v338(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.37') '3.37'
)
arglist = [ arglist = [
self.fake_volume_group.id, self.fake_volume_group.id,
@ -525,16 +574,14 @@ class TestVolumeGroupSet(TestVolumeGroup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.38 or greater is required', '--os-volume-api-version 3.38 or greater is required', str(exc)
str(exc)) )
class TestVolumeGroupList(TestVolumeGroup): class TestVolumeGroupList(TestVolumeGroup):
fake_volume_groups = volume_fakes.create_volume_groups() fake_volume_groups = volume_fakes.create_volume_groups()
columns = ( columns = (
@ -547,7 +594,8 @@ class TestVolumeGroupList(TestVolumeGroup):
fake_volume_group.id, fake_volume_group.id,
fake_volume_group.status, fake_volume_group.status,
fake_volume_group.name, fake_volume_group.name,
) for fake_volume_group in fake_volume_groups )
for fake_volume_group in fake_volume_groups
] ]
def setUp(self): def setUp(self):
@ -558,8 +606,9 @@ class TestVolumeGroupList(TestVolumeGroup):
self.cmd = volume_group.ListVolumeGroup(self.app, None) self.cmd = volume_group.ListVolumeGroup(self.app, None)
def test_volume_group_list(self): def test_volume_group_list(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.13') '3.13'
)
arglist = [ arglist = [
'--all-projects', '--all-projects',
@ -580,8 +629,9 @@ class TestVolumeGroupList(TestVolumeGroup):
self.assertCountEqual(tuple(self.data), data) self.assertCountEqual(tuple(self.data), data)
def test_volume_group_list_pre_v313(self): def test_volume_group_list_pre_v313(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.12') '3.12'
)
arglist = [ arglist = [
'--all-projects', '--all-projects',
@ -592,16 +642,14 @@ class TestVolumeGroupList(TestVolumeGroup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.13 or greater is required', '--os-volume-api-version 3.13 or greater is required', str(exc)
str(exc)) )
class TestVolumeGroupFailover(TestVolumeGroup): class TestVolumeGroupFailover(TestVolumeGroup):
fake_volume_group = volume_fakes.create_one_volume_group() fake_volume_group = volume_fakes.create_one_volume_group()
def setUp(self): def setUp(self):
@ -613,13 +661,15 @@ class TestVolumeGroupFailover(TestVolumeGroup):
self.cmd = volume_group.FailoverVolumeGroup(self.app, None) self.cmd = volume_group.FailoverVolumeGroup(self.app, None)
def test_volume_group_failover(self): def test_volume_group_failover(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.38') '3.38'
)
arglist = [ arglist = [
self.fake_volume_group.id, self.fake_volume_group.id,
'--allow-attached-volume', '--allow-attached-volume',
'--secondary-backend-id', 'foo', '--secondary-backend-id',
'foo',
] ]
verifylist = [ verifylist = [
('group', self.fake_volume_group.id), ('group', self.fake_volume_group.id),
@ -638,13 +688,15 @@ class TestVolumeGroupFailover(TestVolumeGroup):
self.assertIsNone(result) self.assertIsNone(result)
def test_volume_group_failover_pre_v338(self): def test_volume_group_failover_pre_v338(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.37') '3.37'
)
arglist = [ arglist = [
self.fake_volume_group.id, self.fake_volume_group.id,
'--allow-attached-volume', '--allow-attached-volume',
'--secondary-backend-id', 'foo', '--secondary-backend-id',
'foo',
] ]
verifylist = [ verifylist = [
('group', self.fake_volume_group.id), ('group', self.fake_volume_group.id),
@ -654,9 +706,8 @@ class TestVolumeGroupFailover(TestVolumeGroup):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.38 or greater is required', '--os-volume-api-version 3.38 or greater is required', str(exc)
str(exc)) )

View File

@ -18,23 +18,23 @@ from openstackclient.volume.v3 import volume_group_snapshot
class TestVolumeGroupSnapshot(volume_fakes.TestVolume): class TestVolumeGroupSnapshot(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.volume_groups_mock = self.app.client_manager.volume.groups self.volume_groups_mock = self.app.client_manager.volume.groups
self.volume_groups_mock.reset_mock() self.volume_groups_mock.reset_mock()
self.volume_group_snapshots_mock = \ self.volume_group_snapshots_mock = (
self.app.client_manager.volume.group_snapshots self.app.client_manager.volume.group_snapshots
)
self.volume_group_snapshots_mock.reset_mock() self.volume_group_snapshots_mock.reset_mock()
class TestVolumeGroupSnapshotCreate(TestVolumeGroupSnapshot): class TestVolumeGroupSnapshotCreate(TestVolumeGroupSnapshot):
fake_volume_group = volume_fakes.create_one_volume_group() fake_volume_group = volume_fakes.create_one_volume_group()
fake_volume_group_snapshot = \ fake_volume_group_snapshot = (
volume_fakes.create_one_volume_group_snapshot() volume_fakes.create_one_volume_group_snapshot()
)
columns = ( columns = (
'ID', 'ID',
@ -57,17 +57,21 @@ class TestVolumeGroupSnapshotCreate(TestVolumeGroupSnapshot):
super().setUp() super().setUp()
self.volume_groups_mock.get.return_value = self.fake_volume_group 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.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.fake_volume_group_snapshot
)
self.cmd = volume_group_snapshot.CreateVolumeGroupSnapshot( self.cmd = volume_group_snapshot.CreateVolumeGroupSnapshot(
self.app, None) self.app, None
)
def test_volume_group_snapshot_create(self): def test_volume_group_snapshot_create(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.14') '3.14'
)
arglist = [ arglist = [
self.fake_volume_group.id, self.fake_volume_group.id,
@ -82,21 +86,27 @@ class TestVolumeGroupSnapshotCreate(TestVolumeGroupSnapshot):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.volume_groups_mock.get.assert_called_once_with( 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.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.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_group_snapshot_create_with_options(self): def test_volume_group_snapshot_create_with_options(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.14') '3.14'
)
arglist = [ arglist = [
self.fake_volume_group.id, self.fake_volume_group.id,
'--name', 'foo', '--name',
'--description', 'hello, world', 'foo',
'--description',
'hello, world',
] ]
verifylist = [ verifylist = [
('volume_group', self.fake_volume_group.id), ('volume_group', self.fake_volume_group.id),
@ -108,16 +118,20 @@ class TestVolumeGroupSnapshotCreate(TestVolumeGroupSnapshot):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.volume_groups_mock.get.assert_called_once_with( 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.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.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_group_snapshot_create_pre_v314(self): def test_volume_group_snapshot_create_pre_v314(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.13') '3.13'
)
arglist = [ arglist = [
self.fake_volume_group.id, self.fake_volume_group.id,
@ -130,32 +144,34 @@ class TestVolumeGroupSnapshotCreate(TestVolumeGroupSnapshot):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.14 or greater is required', '--os-volume-api-version 3.14 or greater is required', str(exc)
str(exc)) )
class TestVolumeGroupSnapshotDelete(TestVolumeGroupSnapshot): class TestVolumeGroupSnapshotDelete(TestVolumeGroupSnapshot):
fake_volume_group_snapshot = (
fake_volume_group_snapshot = \
volume_fakes.create_one_volume_group_snapshot() volume_fakes.create_one_volume_group_snapshot()
)
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.volume_group_snapshots_mock.get.return_value = \ self.volume_group_snapshots_mock.get.return_value = (
self.fake_volume_group_snapshot self.fake_volume_group_snapshot
)
self.volume_group_snapshots_mock.delete.return_value = None self.volume_group_snapshots_mock.delete.return_value = None
self.cmd = volume_group_snapshot.DeleteVolumeGroupSnapshot( self.cmd = volume_group_snapshot.DeleteVolumeGroupSnapshot(
self.app, None) self.app, None
)
def test_volume_group_snapshot_delete(self): def test_volume_group_snapshot_delete(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.14') '3.14'
)
arglist = [ arglist = [
self.fake_volume_group_snapshot.id, self.fake_volume_group_snapshot.id,
@ -173,8 +189,9 @@ class TestVolumeGroupSnapshotDelete(TestVolumeGroupSnapshot):
self.assertIsNone(result) self.assertIsNone(result)
def test_volume_group_snapshot_delete_pre_v314(self): def test_volume_group_snapshot_delete_pre_v314(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.13') '3.13'
)
arglist = [ arglist = [
self.fake_volume_group_snapshot.id, self.fake_volume_group_snapshot.id,
@ -185,16 +202,14 @@ class TestVolumeGroupSnapshotDelete(TestVolumeGroupSnapshot):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.14 or greater is required', '--os-volume-api-version 3.14 or greater is required', str(exc)
str(exc)) )
class TestVolumeGroupSnapshotList(TestVolumeGroupSnapshot): class TestVolumeGroupSnapshotList(TestVolumeGroupSnapshot):
fake_volume_group_snapshots = volume_fakes.create_volume_group_snapshots() fake_volume_group_snapshots = volume_fakes.create_volume_group_snapshots()
columns = ( columns = (
@ -207,21 +222,25 @@ class TestVolumeGroupSnapshotList(TestVolumeGroupSnapshot):
fake_volume_group_snapshot.id, fake_volume_group_snapshot.id,
fake_volume_group_snapshot.status, fake_volume_group_snapshot.status,
fake_volume_group_snapshot.name, 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): def setUp(self):
super().setUp() super().setUp()
self.volume_group_snapshots_mock.list.return_value = \ self.volume_group_snapshots_mock.list.return_value = (
self.fake_volume_group_snapshots self.fake_volume_group_snapshots
)
self.cmd = volume_group_snapshot.ListVolumeGroupSnapshot( self.cmd = volume_group_snapshot.ListVolumeGroupSnapshot(
self.app, None) self.app, None
)
def test_volume_group_snapshot_list(self): def test_volume_group_snapshot_list(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.14') '3.14'
)
arglist = [ arglist = [
'--all-projects', '--all-projects',
@ -242,20 +261,19 @@ class TestVolumeGroupSnapshotList(TestVolumeGroupSnapshot):
self.assertCountEqual(tuple(self.data), data) self.assertCountEqual(tuple(self.data), data)
def test_volume_group_snapshot_list_pre_v314(self): def test_volume_group_snapshot_list_pre_v314(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.13') '3.13'
)
arglist = [ arglist = []
]
verifylist = [ verifylist = [
('all_projects', False), ('all_projects', False),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.14 or greater is required', '--os-volume-api-version 3.14 or greater is required', str(exc)
str(exc)) )

View File

@ -21,17 +21,16 @@ from openstackclient.volume.v3 import volume_group_type
class TestVolumeGroupType(volume_fakes.TestVolume): class TestVolumeGroupType(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.volume_group_types_mock = \ self.volume_group_types_mock = (
self.app.client_manager.volume.group_types self.app.client_manager.volume.group_types
)
self.volume_group_types_mock.reset_mock() self.volume_group_types_mock.reset_mock()
class TestVolumeGroupTypeCreate(TestVolumeGroupType): class TestVolumeGroupTypeCreate(TestVolumeGroupType):
maxDiff = 2000 maxDiff = 2000
fake_volume_group_type = volume_fakes.create_one_volume_group_type() fake_volume_group_type = volume_fakes.create_one_volume_group_type()
@ -54,14 +53,16 @@ class TestVolumeGroupTypeCreate(TestVolumeGroupType):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.volume_group_types_mock.create.return_value = \ self.volume_group_types_mock.create.return_value = (
self.fake_volume_group_type self.fake_volume_group_type
)
self.cmd = volume_group_type.CreateVolumeGroupType(self.app, None) self.cmd = volume_group_type.CreateVolumeGroupType(self.app, None)
def test_volume_group_type_create(self): def test_volume_group_type_create(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.11') '3.11'
)
arglist = [ arglist = [
self.fake_volume_group_type.name, self.fake_volume_group_type.name,
@ -76,19 +77,20 @@ class TestVolumeGroupTypeCreate(TestVolumeGroupType):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.volume_group_types_mock.create.assert_called_once_with( self.volume_group_types_mock.create.assert_called_once_with(
self.fake_volume_group_type.name, self.fake_volume_group_type.name, None, True
None, )
True)
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_group_type_create_with_options(self): def test_volume_group_type_create_with_options(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.11') '3.11'
)
arglist = [ arglist = [
self.fake_volume_group_type.name, self.fake_volume_group_type.name,
'--description', 'foo', '--description',
'foo',
'--private', '--private',
] ]
verifylist = [ verifylist = [
@ -101,15 +103,15 @@ class TestVolumeGroupTypeCreate(TestVolumeGroupType):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.volume_group_types_mock.create.assert_called_once_with( self.volume_group_types_mock.create.assert_called_once_with(
self.fake_volume_group_type.name, self.fake_volume_group_type.name, 'foo', False
'foo', )
False)
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_group_type_create_pre_v311(self): def test_volume_group_type_create_pre_v311(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.10') '3.10'
)
arglist = [ arglist = [
self.fake_volume_group_type.name, self.fake_volume_group_type.name,
@ -122,30 +124,30 @@ class TestVolumeGroupTypeCreate(TestVolumeGroupType):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.11 or greater is required', '--os-volume-api-version 3.11 or greater is required', str(exc)
str(exc)) )
class TestVolumeGroupTypeDelete(TestVolumeGroupType): class TestVolumeGroupTypeDelete(TestVolumeGroupType):
fake_volume_group_type = volume_fakes.create_one_volume_group_type() fake_volume_group_type = volume_fakes.create_one_volume_group_type()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.volume_group_types_mock.get.return_value = \ self.volume_group_types_mock.get.return_value = (
self.fake_volume_group_type self.fake_volume_group_type
)
self.volume_group_types_mock.delete.return_value = None self.volume_group_types_mock.delete.return_value = None
self.cmd = volume_group_type.DeleteVolumeGroupType(self.app, None) self.cmd = volume_group_type.DeleteVolumeGroupType(self.app, None)
def test_volume_group_type_delete(self): def test_volume_group_type_delete(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.11') '3.11'
)
arglist = [ arglist = [
self.fake_volume_group_type.id, self.fake_volume_group_type.id,
@ -163,8 +165,9 @@ class TestVolumeGroupTypeDelete(TestVolumeGroupType):
self.assertIsNone(result) self.assertIsNone(result)
def test_volume_group_type_delete_pre_v311(self): def test_volume_group_type_delete_pre_v311(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.10') '3.10'
)
arglist = [ arglist = [
self.fake_volume_group_type.id, self.fake_volume_group_type.id,
@ -175,16 +178,14 @@ class TestVolumeGroupTypeDelete(TestVolumeGroupType):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.11 or greater is required', '--os-volume-api-version 3.11 or greater is required', str(exc)
str(exc)) )
class TestVolumeGroupTypeSet(TestVolumeGroupType): class TestVolumeGroupTypeSet(TestVolumeGroupType):
fake_volume_group_type = volume_fakes.create_one_volume_group_type( fake_volume_group_type = volume_fakes.create_one_volume_group_type(
methods={ methods={
'get_keys': {'foo': 'bar'}, 'get_keys': {'foo': 'bar'},
@ -211,25 +212,31 @@ class TestVolumeGroupTypeSet(TestVolumeGroupType):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.volume_group_types_mock.get.return_value = \ self.volume_group_types_mock.get.return_value = (
self.fake_volume_group_type 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.fake_volume_group_type
)
self.cmd = volume_group_type.SetVolumeGroupType(self.app, None) self.cmd = volume_group_type.SetVolumeGroupType(self.app, None)
def test_volume_group_type_set(self): def test_volume_group_type_set(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.11') '3.11'
)
self.fake_volume_group_type.set_keys.return_value = None self.fake_volume_group_type.set_keys.return_value = None
arglist = [ arglist = [
self.fake_volume_group_type.id, self.fake_volume_group_type.id,
'--name', 'foo', '--name',
'--description', 'hello, world', 'foo',
'--description',
'hello, world',
'--public', '--public',
'--property', 'fizz=buzz', '--property',
'fizz=buzz',
] ]
verifylist = [ verifylist = [
('group_type', self.fake_volume_group_type.id), ('group_type', self.fake_volume_group_type.id),
@ -256,13 +263,15 @@ class TestVolumeGroupTypeSet(TestVolumeGroupType):
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_group_type_with_no_property_option(self): def test_volume_group_type_with_no_property_option(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.11') '3.11'
)
arglist = [ arglist = [
self.fake_volume_group_type.id, self.fake_volume_group_type.id,
'--no-property', '--no-property',
'--property', 'fizz=buzz', '--property',
'fizz=buzz',
] ]
verifylist = [ verifylist = [
('group_type', self.fake_volume_group_type.id), ('group_type', self.fake_volume_group_type.id),
@ -277,21 +286,26 @@ class TestVolumeGroupTypeSet(TestVolumeGroupType):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.volume_group_types_mock.get.assert_called_once_with( 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.get_keys.assert_called_once_with()
self.fake_volume_group_type.unset_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.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_group_type_set_pre_v311(self): def test_volume_group_type_set_pre_v311(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.10') '3.10'
)
arglist = [ arglist = [
self.fake_volume_group_type.id, self.fake_volume_group_type.id,
'--name', 'foo', '--name',
'--description', 'hello, world', 'foo',
'--description',
'hello, world',
] ]
verifylist = [ verifylist = [
('group_type', self.fake_volume_group_type.id), ('group_type', self.fake_volume_group_type.id),
@ -304,16 +318,14 @@ class TestVolumeGroupTypeSet(TestVolumeGroupType):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.11 or greater is required', '--os-volume-api-version 3.11 or greater is required', str(exc)
str(exc)) )
class TestVolumeGroupTypeUnset(TestVolumeGroupType): class TestVolumeGroupTypeUnset(TestVolumeGroupType):
fake_volume_group_type = volume_fakes.create_one_volume_group_type( fake_volume_group_type = volume_fakes.create_one_volume_group_type(
methods={'unset_keys': None}, methods={'unset_keys': None},
) )
@ -336,18 +348,21 @@ class TestVolumeGroupTypeUnset(TestVolumeGroupType):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.volume_group_types_mock.get.return_value = \ self.volume_group_types_mock.get.return_value = (
self.fake_volume_group_type self.fake_volume_group_type
)
self.cmd = volume_group_type.UnsetVolumeGroupType(self.app, None) self.cmd = volume_group_type.UnsetVolumeGroupType(self.app, None)
def test_volume_group_type_unset(self): def test_volume_group_type_unset(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.11') '3.11'
)
arglist = [ arglist = [
self.fake_volume_group_type.id, self.fake_volume_group_type.id,
'--property', 'fizz', '--property',
'fizz',
] ]
verifylist = [ verifylist = [
('group_type', self.fake_volume_group_type.id), ('group_type', self.fake_volume_group_type.id),
@ -357,22 +372,27 @@ class TestVolumeGroupTypeUnset(TestVolumeGroupType):
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.volume_group_types_mock.get.assert_has_calls([ 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), 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( self.fake_volume_group_type.unset_keys.assert_called_once_with(
['fizz']) ['fizz']
)
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_volume_group_type_unset_pre_v311(self): def test_volume_group_type_unset_pre_v311(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.10') '3.10'
)
arglist = [ arglist = [
self.fake_volume_group_type.id, self.fake_volume_group_type.id,
'--property', 'fizz', '--property',
'fizz',
] ]
verifylist = [ verifylist = [
('group_type', self.fake_volume_group_type.id), ('group_type', self.fake_volume_group_type.id),
@ -381,16 +401,14 @@ class TestVolumeGroupTypeUnset(TestVolumeGroupType):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.11 or greater is required', '--os-volume-api-version 3.11 or greater is required', str(exc)
str(exc)) )
class TestVolumeGroupTypeList(TestVolumeGroupType): class TestVolumeGroupTypeList(TestVolumeGroupType):
fake_volume_group_types = volume_fakes.create_volume_group_types() fake_volume_group_types = volume_fakes.create_volume_group_types()
columns = ( columns = (
@ -405,25 +423,28 @@ class TestVolumeGroupTypeList(TestVolumeGroupType):
fake_volume_group_type.name, fake_volume_group_type.name,
fake_volume_group_type.is_public, fake_volume_group_type.is_public,
fake_volume_group_type.group_specs, 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): def setUp(self):
super().setUp() super().setUp()
self.volume_group_types_mock.list.return_value = \ self.volume_group_types_mock.list.return_value = (
self.fake_volume_group_types 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.fake_volume_group_types[0]
)
self.cmd = volume_group_type.ListVolumeGroupType(self.app, None) self.cmd = volume_group_type.ListVolumeGroupType(self.app, None)
def test_volume_group_type_list(self): def test_volume_group_type_list(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.11') '3.11'
)
arglist = [ arglist = []
]
verifylist = [ verifylist = [
('show_default', False), ('show_default', False),
] ]
@ -436,8 +457,9 @@ class TestVolumeGroupTypeList(TestVolumeGroupType):
self.assertCountEqual(tuple(self.data), data) self.assertCountEqual(tuple(self.data), data)
def test_volume_group_type_list_with_default_option(self): def test_volume_group_type_list_with_default_option(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.11') '3.11'
)
arglist = [ arglist = [
'--default', '--default',
@ -454,19 +476,17 @@ class TestVolumeGroupTypeList(TestVolumeGroupType):
self.assertCountEqual(tuple([self.data[0]]), data) self.assertCountEqual(tuple([self.data[0]]), data)
def test_volume_group_type_list_pre_v311(self): def test_volume_group_type_list_pre_v311(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.10') '3.10'
)
arglist = [ arglist = []
] verifylist = []
verifylist = [
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.11 or greater is required', '--os-volume-api-version 3.11 or greater is required', str(exc)
str(exc)) )

View File

@ -21,7 +21,6 @@ from openstackclient.volume.v3 import volume_message
class TestVolumeMessage(volume_fakes.TestVolume): class TestVolumeMessage(volume_fakes.TestVolume):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -33,7 +32,6 @@ class TestVolumeMessage(volume_fakes.TestVolume):
class TestVolumeMessageDelete(TestVolumeMessage): class TestVolumeMessageDelete(TestVolumeMessage):
fake_messages = volume_fakes.create_volume_messages(count=2) fake_messages = volume_fakes.create_volume_messages(count=2)
def setUp(self): def setUp(self):
@ -48,8 +46,9 @@ class TestVolumeMessageDelete(TestVolumeMessage):
self.cmd = volume_message.DeleteMessage(self.app, None) self.cmd = volume_message.DeleteMessage(self.app, None)
def test_message_delete(self): def test_message_delete(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.3') '3.3'
)
arglist = [ arglist = [
self.fake_messages[0].id, self.fake_messages[0].id,
@ -62,12 +61,14 @@ class TestVolumeMessageDelete(TestVolumeMessage):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.volume_messages_mock.delete.assert_called_with( self.volume_messages_mock.delete.assert_called_with(
self.fake_messages[0].id) self.fake_messages[0].id
)
self.assertIsNone(result) self.assertIsNone(result)
def test_message_delete_multiple_messages(self): def test_message_delete_multiple_messages(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.3') '3.3'
)
arglist = [ arglist = [
self.fake_messages[0].id, self.fake_messages[0].id,
@ -87,8 +88,9 @@ class TestVolumeMessageDelete(TestVolumeMessage):
self.assertIsNone(result) self.assertIsNone(result)
def test_message_delete_multiple_messages_with_exception(self): def test_message_delete_multiple_messages_with_exception(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.3') '3.3'
)
arglist = [ arglist = [
self.fake_messages[0].id, self.fake_messages[0].id,
@ -101,22 +103,26 @@ class TestVolumeMessageDelete(TestVolumeMessage):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.volume_messages_mock.delete.side_effect = [ self.volume_messages_mock.delete.side_effect = [
self.fake_messages[0], exceptions.CommandError] self.fake_messages[0],
exceptions.CommandError,
]
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, parsed_args) )
self.assertEqual('Failed to delete 1 of 2 messages.', str(exc)) self.assertEqual('Failed to delete 1 of 2 messages.', str(exc))
self.volume_messages_mock.delete.assert_any_call( 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.volume_messages_mock.delete.assert_any_call('invalid_message')
self.assertEqual(2, self.volume_messages_mock.delete.call_count) self.assertEqual(2, self.volume_messages_mock.delete.call_count)
def test_message_delete_pre_v33(self): def test_message_delete_pre_v33(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.2') '3.2'
)
arglist = [ arglist = [
self.fake_messages[0].id, self.fake_messages[0].id,
@ -127,16 +133,14 @@ class TestVolumeMessageDelete(TestVolumeMessage):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.3 or greater is required', '--os-volume-api-version 3.3 or greater is required', str(exc)
str(exc)) )
class TestVolumeMessageList(TestVolumeMessage): class TestVolumeMessageList(TestVolumeMessage):
fake_project = identity_fakes.FakeProject.create_one_project() fake_project = identity_fakes.FakeProject.create_one_project()
fake_messages = volume_fakes.create_volume_messages(count=3) fake_messages = volume_fakes.create_volume_messages(count=3)
@ -153,17 +157,19 @@ class TestVolumeMessageList(TestVolumeMessage):
) )
data = [] data = []
for fake_message in fake_messages: for fake_message in fake_messages:
data.append(( data.append(
fake_message.id, (
fake_message.event_id, fake_message.id,
fake_message.resource_type, fake_message.event_id,
fake_message.resource_uuid, fake_message.resource_type,
fake_message.message_level, fake_message.resource_uuid,
fake_message.user_message, fake_message.message_level,
fake_message.request_id, fake_message.user_message,
fake_message.created_at, fake_message.request_id,
fake_message.guaranteed_until, fake_message.created_at,
)) fake_message.guaranteed_until,
)
)
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -174,8 +180,9 @@ class TestVolumeMessageList(TestVolumeMessage):
self.cmd = volume_message.ListMessages(self.app, None) self.cmd = volume_message.ListMessages(self.app, None)
def test_message_list(self): def test_message_list(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.3') '3.3'
)
arglist = [] arglist = []
verifylist = [ verifylist = [
@ -199,13 +206,17 @@ class TestVolumeMessageList(TestVolumeMessage):
self.assertCountEqual(self.data, list(data)) self.assertCountEqual(self.data, list(data))
def test_message_list_with_options(self): def test_message_list_with_options(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.3') '3.3'
)
arglist = [ arglist = [
'--project', self.fake_project.name, '--project',
'--marker', self.fake_messages[0].id, self.fake_project.name,
'--limit', '3', '--marker',
self.fake_messages[0].id,
'--limit',
'3',
] ]
verifylist = [ verifylist = [
('project', self.fake_project.name), ('project', self.fake_project.name),
@ -228,8 +239,9 @@ class TestVolumeMessageList(TestVolumeMessage):
self.assertCountEqual(self.data, list(data)) self.assertCountEqual(self.data, list(data))
def test_message_list_pre_v33(self): def test_message_list_pre_v33(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.2') '3.2'
)
arglist = [] arglist = []
verifylist = [ verifylist = [
@ -241,16 +253,14 @@ class TestVolumeMessageList(TestVolumeMessage):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.3 or greater is required', '--os-volume-api-version 3.3 or greater is required', str(exc)
str(exc)) )
class TestVolumeMessageShow(TestVolumeMessage): class TestVolumeMessageShow(TestVolumeMessage):
fake_message = volume_fakes.create_one_volume_message() fake_message = volume_fakes.create_one_volume_message()
columns = ( columns = (
@ -284,15 +294,12 @@ class TestVolumeMessageShow(TestVolumeMessage):
self.cmd = volume_message.ShowMessage(self.app, None) self.cmd = volume_message.ShowMessage(self.app, None)
def test_message_show(self): def test_message_show(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.3') '3.3'
)
arglist = [ arglist = [self.fake_message.id]
self.fake_message.id verifylist = [('message_id', self.fake_message.id)]
]
verifylist = [
('message_id', self.fake_message.id)
]
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) columns, data = self.cmd.take_action(parsed_args)
@ -302,21 +309,17 @@ class TestVolumeMessageShow(TestVolumeMessage):
self.assertEqual(self.data, data) self.assertEqual(self.data, data)
def test_message_show_pre_v33(self): def test_message_show_pre_v33(self):
self.app.client_manager.volume.api_version = \ self.app.client_manager.volume.api_version = api_versions.APIVersion(
api_versions.APIVersion('3.2') '3.2'
)
arglist = [ arglist = [self.fake_message.id]
self.fake_message.id verifylist = [('message_id', self.fake_message.id)]
]
verifylist = [
('message_id', self.fake_message.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
exc = self.assertRaises( exc = self.assertRaises(
exceptions.CommandError, exceptions.CommandError, self.cmd.take_action, parsed_args
self.cmd.take_action, )
parsed_args)
self.assertIn( self.assertIn(
'--os-volume-api-version 3.3 or greater is required', '--os-volume-api-version 3.3 or greater is required', str(exc)
str(exc)) )

View File

@ -60,6 +60,7 @@ def make_client(instance):
else: else:
version = instance._api_version[API_NAME] version = instance._api_version[API_NAME]
from cinderclient import api_versions from cinderclient import api_versions
# convert to APIVersion object # convert to APIVersion object
version = api_versions.get_api_version(version) version = api_versions.get_api_version(version)
@ -69,9 +70,7 @@ def make_client(instance):
volume_snapshots.Snapshot.NAME_ATTR = 'display_name' volume_snapshots.Snapshot.NAME_ATTR = 'display_name'
volume_client = utils.get_client_class( volume_client = utils.get_client_class(
API_NAME, API_NAME, version.ver_major, API_VERSIONS
version.ver_major,
API_VERSIONS
) )
LOG.debug('Instantiating volume client: %s', volume_client) 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) kwargs = utils.build_kwargs_dict('endpoint_type', instance.interface)
endpoint_override = instance.sdk_connection.config.get_endpoint( endpoint_override = instance.sdk_connection.config.get_endpoint(
'block-storage') 'block-storage'
)
client = volume_client( client = volume_client(
session=instance.session, session=instance.session,
@ -105,8 +105,10 @@ def build_option_parser(parser):
'--os-volume-api-version', '--os-volume-api-version',
metavar='<volume-api-version>', metavar='<volume-api-version>',
default=utils.env('OS_VOLUME_API_VERSION'), default=utils.env('OS_VOLUME_API_VERSION'),
help=_('Volume API version, default=%s ' help=_(
'(Env: OS_VOLUME_API_VERSION)') % DEFAULT_API_VERSION 'Volume API version, default=%s ' '(Env: OS_VOLUME_API_VERSION)'
)
% DEFAULT_API_VERSION,
) )
return parser return parser

View File

@ -48,10 +48,12 @@ class AssociateQos(command.Command):
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs, qos_spec = utils.find_resource(
parsed_args.qos_spec) volume_client.qos_specs, parsed_args.qos_spec
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.associate(qos_spec.id, volume_type.id) volume_client.qos_specs.associate(qos_spec.id, volume_type.id)
@ -72,16 +74,22 @@ class CreateQos(command.ShowOne):
metavar='<consumer>', metavar='<consumer>',
choices=consumer_choices, choices=consumer_choices,
default='both', default='both',
help=(_('Consumer of the QoS. Valid consumers: %s ' help=(
"(defaults to 'both')") % _(
utils.format_list(consumer_choices)) 'Consumer of the QoS. Valid consumers: %s '
"(defaults to 'both')"
)
% utils.format_list(consumer_choices)
),
) )
parser.add_argument( parser.add_argument(
'--property', '--property',
metavar='<key=value>', metavar='<key=value>',
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_('Set a QoS specification property ' help=_(
'(repeat option to set multiple properties)'), 'Set a QoS specification property '
'(repeat option to set multiple properties)'
),
) )
return parser return parser
@ -95,8 +103,11 @@ class CreateQos(command.ShowOne):
qos_spec = volume_client.qos_specs.create(parsed_args.name, specs) qos_spec = volume_client.qos_specs.create(parsed_args.name, specs)
qos_spec._info.update( 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())) return zip(*sorted(qos_spec._info.items()))
@ -116,7 +127,7 @@ class DeleteQos(command.Command):
'--force', '--force',
action='store_true', action='store_true',
default=False, default=False,
help=_("Allow to delete in-use QoS specification(s)") help=_("Allow to delete in-use QoS specification(s)"),
) )
return parser return parser
@ -130,14 +141,20 @@ class DeleteQos(command.Command):
volume_client.qos_specs.delete(qos_spec.id, parsed_args.force) volume_client.qos_specs.delete(qos_spec.id, parsed_args.force)
except Exception as e: except Exception as e:
result += 1 result += 1
LOG.error(_("Failed to delete QoS specification with " LOG.error(
"name or ID '%(qos)s': %(e)s"), _(
{'qos': i, 'e': e}) "Failed to delete QoS specification with "
"name or ID '%(qos)s': %(e)s"
),
{'qos': i, 'e': e},
)
if result > 0: if result > 0:
total = len(parsed_args.qos_specs) total = len(parsed_args.qos_specs)
msg = (_("%(result)s of %(total)s QoS specifications failed" msg = _(
" to delete.") % {'result': result, 'total': total}) "%(result)s of %(total)s QoS specifications failed"
" to delete."
) % {'result': result, 'total': total}
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -168,12 +185,14 @@ class DisassociateQos(command.Command):
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs, qos_spec = utils.find_resource(
parsed_args.qos_spec) volume_client.qos_specs, parsed_args.qos_spec
)
if parsed_args.volume_type: if parsed_args.volume_type:
volume_type = utils.find_resource(volume_client.volume_types, volume_type = utils.find_resource(
parsed_args.volume_type) volume_client.volume_types, parsed_args.volume_type
)
volume_client.qos_specs.disassociate(qos_spec.id, volume_type.id) volume_client.qos_specs.disassociate(qos_spec.id, volume_type.id)
elif parsed_args.all: elif parsed_args.all:
volume_client.qos_specs.disassociate_all(qos_spec.id) volume_client.qos_specs.disassociate_all(qos_spec.id)
@ -203,16 +222,27 @@ class ListQos(command.Lister):
raise raise
display_columns = ( display_columns = (
'ID', 'Name', 'Consumer', 'Associations', 'Properties') 'ID',
'Name',
'Consumer',
'Associations',
'Properties',
)
columns = ('ID', 'Name', 'Consumer', 'Associations', 'Specs') columns = ('ID', 'Name', 'Consumer', 'Associations', 'Specs')
return (display_columns, return (
(utils.get_dict_properties( display_columns,
s._info, columns, (
utils.get_dict_properties(
s._info,
columns,
formatters={ formatters={
'Specs': format_columns.DictColumn, '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): class SetQos(command.Command):
@ -229,19 +259,21 @@ class SetQos(command.Command):
'--property', '--property',
metavar='<key=value>', metavar='<key=value>',
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_('Property to add or modify for this QoS specification ' help=_(
'(repeat option to set multiple properties)'), 'Property to add or modify for this QoS specification '
'(repeat option to set multiple properties)'
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs, qos_spec = utils.find_resource(
parsed_args.qos_spec) volume_client.qos_specs, parsed_args.qos_spec
)
if parsed_args.property: if parsed_args.property:
volume_client.qos_specs.set_keys(qos_spec.id, volume_client.qos_specs.set_keys(qos_spec.id, parsed_args.property)
parsed_args.property)
class ShowQos(command.ShowOne): class ShowQos(command.ShowOne):
@ -258,19 +290,25 @@ class ShowQos(command.ShowOne):
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs, qos_spec = utils.find_resource(
parsed_args.qos_spec) volume_client.qos_specs, parsed_args.qos_spec
)
qos_associations = volume_client.qos_specs.get_associations(qos_spec) qos_associations = volume_client.qos_specs.get_associations(qos_spec)
if qos_associations: if qos_associations:
associations = [association.name associations = [
for association in qos_associations] association.name for association in qos_associations
qos_spec._info.update({ ]
'associations': format_columns.ListColumn(associations) qos_spec._info.update(
}) {'associations': format_columns.ListColumn(associations)}
)
qos_spec._info.update( 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())) return zip(*sorted(qos_spec._info.items()))
@ -289,16 +327,20 @@ class UnsetQos(command.Command):
'--property', '--property',
metavar='<key>', metavar='<key>',
action='append', action='append',
help=_('Property to remove from the QoS specification. ' help=_(
'(repeat option to unset multiple properties)'), 'Property to remove from the QoS specification. '
'(repeat option to unset multiple properties)'
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs, qos_spec = utils.find_resource(
parsed_args.qos_spec) volume_client.qos_specs, parsed_args.qos_spec
)
if parsed_args.property: if parsed_args.property:
volume_client.qos_specs.unset_keys(qos_spec.id, volume_client.qos_specs.unset_keys(
parsed_args.property) qos_spec.id, parsed_args.property
)

View File

@ -29,18 +29,18 @@ class ListService(command.Lister):
parser.add_argument( parser.add_argument(
"--host", "--host",
metavar="<host>", metavar="<host>",
help=_("List services on specified host (name only)") help=_("List services on specified host (name only)"),
) )
parser.add_argument( parser.add_argument(
"--service", "--service",
metavar="<service>", metavar="<service>",
help=_("List only specified service (name only)") help=_("List only specified service (name only)"),
) )
parser.add_argument( parser.add_argument(
"--long", "--long",
action="store_true", action="store_true",
default=False, default=False,
help=_("List additional fields in output") help=_("List additional fields in output"),
) )
return parser return parser
@ -55,7 +55,7 @@ class ListService(command.Lister):
"Status", "Status",
"State", "State",
"Updated At", "Updated At",
"Disabled Reason" "Disabled Reason",
] ]
else: else:
columns = [ columns = [
@ -64,15 +64,22 @@ class ListService(command.Lister):
"Zone", "Zone",
"Status", "Status",
"State", "State",
"Updated At" "Updated At",
] ]
data = service_client.services.list(parsed_args.host, data = service_client.services.list(
parsed_args.service) parsed_args.host, parsed_args.service
return (columns, )
(utils.get_item_properties( return (
s, columns, columns,
) for s in data)) (
utils.get_item_properties(
s,
columns,
)
for s in data
),
)
class SetService(command.Command): class SetService(command.Command):
@ -80,51 +87,50 @@ class SetService(command.Command):
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super(SetService, self).get_parser(prog_name) parser = super(SetService, self).get_parser(prog_name)
parser.add_argument( parser.add_argument("host", metavar="<host>", help=_("Name of host"))
"host",
metavar="<host>",
help=_("Name of host")
)
parser.add_argument( parser.add_argument(
"service", "service",
metavar="<service>", metavar="<service>",
help=_("Name of service (Binary name)") help=_("Name of service (Binary name)"),
) )
enabled_group = parser.add_mutually_exclusive_group() enabled_group = parser.add_mutually_exclusive_group()
enabled_group.add_argument( enabled_group.add_argument(
"--enable", "--enable", action="store_true", help=_("Enable volume service")
action="store_true",
help=_("Enable volume service")
) )
enabled_group.add_argument( enabled_group.add_argument(
"--disable", "--disable", action="store_true", help=_("Disable volume service")
action="store_true",
help=_("Disable volume service")
) )
parser.add_argument( parser.add_argument(
"--disable-reason", "--disable-reason",
metavar="<reason>", metavar="<reason>",
help=_("Reason for disabling the service " help=_(
"(should be used with --disable option)") "Reason for disabling the service "
"(should be used with --disable option)"
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
if parsed_args.disable_reason and not parsed_args.disable: if parsed_args.disable_reason and not parsed_args.disable:
msg = _("Cannot specify option --disable-reason without " msg = _(
"--disable specified.") "Cannot specify option --disable-reason without "
"--disable specified."
)
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
service_client = self.app.client_manager.volume service_client = self.app.client_manager.volume
if parsed_args.enable: if parsed_args.enable:
service_client.services.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:
if parsed_args.disable_reason: if parsed_args.disable_reason:
service_client.services.disable_log_reason( service_client.services.disable_log_reason(
parsed_args.host, parsed_args.host,
parsed_args.service, parsed_args.service,
parsed_args.disable_reason) parsed_args.disable_reason,
)
else: else:
service_client.services.disable( service_client.services.disable(
parsed_args.host, parsed_args.service) parsed_args.host, parsed_args.service
)

View File

@ -70,10 +70,11 @@ def _check_size_arg(args):
volume is not specified. volume is not specified.
""" """
if ((args.snapshot or args.source) if (args.snapshot or args.source) is None and args.size is None:
is None and args.size is None): msg = _(
msg = _("--size is a required option if snapshot " "--size is a required option if snapshot "
"or source volume is not specified.") "or source volume is not specified."
)
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -91,8 +92,10 @@ class CreateVolume(command.ShowOne):
'--size', '--size',
metavar='<size>', metavar='<size>',
type=int, type=int,
help=_("Volume size in GB (Required unless --snapshot or " help=_(
"--source is specified)"), "Volume size in GB (Required unless --snapshot or "
"--source is specified)"
),
) )
parser.add_argument( parser.add_argument(
'--type', '--type',
@ -144,30 +147,32 @@ class CreateVolume(command.ShowOne):
'--property', '--property',
metavar='<key=value>', metavar='<key=value>',
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_('Set a property on this volume ' help=_(
'(repeat option to set multiple properties)'), 'Set a property on this volume '
'(repeat option to set multiple properties)'
),
) )
bootable_group = parser.add_mutually_exclusive_group() bootable_group = parser.add_mutually_exclusive_group()
bootable_group.add_argument( bootable_group.add_argument(
"--bootable", "--bootable",
action="store_true", action="store_true",
help=_("Mark volume as bootable") help=_("Mark volume as bootable"),
) )
bootable_group.add_argument( bootable_group.add_argument(
"--non-bootable", "--non-bootable",
action="store_true", 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 = parser.add_mutually_exclusive_group()
readonly_group.add_argument( readonly_group.add_argument(
"--read-only", "--read-only",
action="store_true", action="store_true",
help=_("Set volume to read-only access mode") help=_("Set volume to read-only access mode"),
) )
readonly_group.add_argument( readonly_group.add_argument(
"--read-write", "--read-write",
action="store_true", action="store_true",
help=_("Set volume to read-write access mode (default)") help=_("Set volume to read-write access mode (default)"),
) )
return parser return parser
@ -229,11 +234,10 @@ class CreateVolume(command.ShowOne):
volume.id, volume.id,
success_status=['available'], success_status=['available'],
error_status=['error'], error_status=['error'],
sleep_time=1 sleep_time=1,
): ):
volume_client.volumes.set_bootable( volume_client.volumes.set_bootable(
volume.id, volume.id, parsed_args.bootable
parsed_args.bootable
) )
else: else:
msg = _( msg = _(
@ -250,11 +254,10 @@ class CreateVolume(command.ShowOne):
volume.id, volume.id,
success_status=['available'], success_status=['available'],
error_status=['error'], error_status=['error'],
sleep_time=1 sleep_time=1,
): ):
volume_client.volumes.update_readonly_flag( volume_client.volumes.update_readonly_flag(
volume.id, volume.id, parsed_args.read_only
parsed_args.read_only
) )
else: else:
msg = _( msg = _(
@ -263,14 +266,20 @@ class CreateVolume(command.ShowOne):
) )
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set volume read-only access " LOG.error(
"mode flag: %s"), e) _(
"Failed to set volume read-only access "
"mode flag: %s"
),
e,
)
# Map 'metadata' column to 'properties' # Map 'metadata' column to 'properties'
volume._info.update( volume._info.update(
{ {
'properties': 'properties': format_columns.DictColumn(
format_columns.DictColumn(volume._info.pop('metadata')), volume._info.pop('metadata')
),
'type': volume._info.pop('volume_type'), 'type': volume._info.pop('volume_type'),
}, },
) )
@ -299,8 +308,10 @@ class DeleteVolume(command.Command):
'--force', '--force',
action='store_true', action='store_true',
default=False, default=False,
help=_('Attempt forced removal of volume(s), regardless of state ' help=_(
'(defaults to False)'), 'Attempt forced removal of volume(s), regardless of state '
'(defaults to False)'
),
) )
return parser return parser
@ -310,22 +321,27 @@ class DeleteVolume(command.Command):
for i in parsed_args.volumes: for i in parsed_args.volumes:
try: try:
volume_obj = utils.find_resource( volume_obj = utils.find_resource(volume_client.volumes, i)
volume_client.volumes, i)
if parsed_args.force: if parsed_args.force:
volume_client.volumes.force_delete(volume_obj.id) volume_client.volumes.force_delete(volume_obj.id)
else: else:
volume_client.volumes.delete(volume_obj.id) volume_client.volumes.delete(volume_obj.id)
except Exception as e: except Exception as e:
result += 1 result += 1
LOG.error(_("Failed to delete volume with " LOG.error(
"name or ID '%(volume)s': %(e)s"), _(
{'volume': i, 'e': e}) "Failed to delete volume with "
"name or ID '%(volume)s': %(e)s"
),
{'volume': i, 'e': e},
)
if result > 0: if result > 0:
total = len(parsed_args.volumes) total = len(parsed_args.volumes)
msg = (_("%(result)s of %(total)s volumes failed " msg = _("%(result)s of %(total)s volumes failed " "to delete.") % {
"to delete.") % {'result': result, 'total': total}) 'result': result,
'total': total,
}
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -373,7 +389,6 @@ class ListVolume(command.Lister):
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
compute_client = self.app.client_manager.compute compute_client = self.app.client_manager.compute
@ -423,7 +438,8 @@ class ListVolume(command.Lister):
# Just forget it if there's any trouble # Just forget it if there's any trouble
pass pass
AttachmentsColumnWithCache = functools.partial( AttachmentsColumnWithCache = functools.partial(
AttachmentsColumn, server_cache=server_cache) AttachmentsColumn, server_cache=server_cache
)
search_opts = { search_opts = {
'all_tenants': parsed_args.all_projects, 'all_tenants': parsed_args.all_projects,
@ -439,14 +455,23 @@ class ListVolume(command.Lister):
limit=parsed_args.limit, limit=parsed_args.limit,
) )
column_headers = utils.backward_compat_col_lister( 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, return (
(utils.get_item_properties( column_headers,
s, columns, (
formatters={'Metadata': format_columns.DictColumn, utils.get_item_properties(
'Attachments': AttachmentsColumnWithCache}, s,
) for s in data)) columns,
formatters={
'Metadata': format_columns.DictColumn,
'Attachments': AttachmentsColumnWithCache,
},
)
for s in data
),
)
class MigrateVolume(command.Command): class MigrateVolume(command.Command):
@ -457,27 +482,34 @@ class MigrateVolume(command.Command):
parser.add_argument( parser.add_argument(
'volume', 'volume',
metavar="<volume>", metavar="<volume>",
help=_("Volume to migrate (name or ID)") help=_("Volume to migrate (name or ID)"),
) )
parser.add_argument( parser.add_argument(
'--host', '--host',
metavar="<host>", metavar="<host>",
required=True, 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( parser.add_argument(
'--force-host-copy', '--force-host-copy',
action="store_true", action="store_true",
help=_("Enable generic host-based force-migration, " help=_(
"which bypasses driver optimizations") "Enable generic host-based force-migration, "
"which bypasses driver optimizations"
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume 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)
volume_client.volumes.migrate_volume(volume.id, parsed_args.host, volume_client.volumes.migrate_volume(
parsed_args.force_host_copy,) volume.id,
parsed_args.host,
parsed_args.force_host_copy,
)
class SetVolume(command.Command): class SetVolume(command.Command):
@ -510,39 +542,43 @@ class SetVolume(command.Command):
"--no-property", "--no-property",
dest="no_property", dest="no_property",
action="store_true", action="store_true",
help=_("Remove all properties from <volume> " help=_(
"(specify both --no-property and --property to " "Remove all properties from <volume> "
"remove the current properties before setting " "(specify both --no-property and --property to "
"new properties.)"), "remove the current properties before setting "
"new properties.)"
),
) )
parser.add_argument( parser.add_argument(
'--property', '--property',
metavar='<key=value>', metavar='<key=value>',
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_('Set a property on this volume ' help=_(
'(repeat option to set multiple properties)'), 'Set a property on this volume '
'(repeat option to set multiple properties)'
),
) )
bootable_group = parser.add_mutually_exclusive_group() bootable_group = parser.add_mutually_exclusive_group()
bootable_group.add_argument( bootable_group.add_argument(
"--bootable", "--bootable",
action="store_true", action="store_true",
help=_("Mark volume as bootable") help=_("Mark volume as bootable"),
) )
bootable_group.add_argument( bootable_group.add_argument(
"--non-bootable", "--non-bootable",
action="store_true", action="store_true",
help=_("Mark volume as non-bootable") help=_("Mark volume as non-bootable"),
) )
readonly_group = parser.add_mutually_exclusive_group() readonly_group = parser.add_mutually_exclusive_group()
readonly_group.add_argument( readonly_group.add_argument(
"--read-only", "--read-only",
action="store_true", action="store_true",
help=_("Set volume to read-only access mode") help=_("Set volume to read-only access mode"),
) )
readonly_group.add_argument( readonly_group.add_argument(
"--read-write", "--read-write",
action="store_true", action="store_true",
help=_("Set volume to read-write access mode") help=_("Set volume to read-write access mode"),
) )
return parser return parser
@ -554,12 +590,18 @@ class SetVolume(command.Command):
if parsed_args.size: if parsed_args.size:
try: try:
if volume.status != 'available': if volume.status != 'available':
msg = (_("Volume is in %s state, it must be available " msg = (
"before size can be extended") % volume.status) _(
"Volume is in %s state, it must be available "
"before size can be extended"
)
% volume.status
)
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
if parsed_args.size <= volume.size: if parsed_args.size <= volume.size:
msg = (_("New size must be greater than %s GB") msg = (
% volume.size) _("New size must be greater than %s GB") % volume.size
)
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
volume_client.volumes.extend(volume.id, parsed_args.size) volume_client.volumes.extend(volume.id, parsed_args.size)
except Exception as e: except Exception as e:
@ -569,7 +611,8 @@ class SetVolume(command.Command):
if parsed_args.no_property: if parsed_args.no_property:
try: try:
volume_client.volumes.delete_metadata( volume_client.volumes.delete_metadata(
volume.id, volume.metadata.keys()) volume.id, volume.metadata.keys()
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to clean volume properties: %s"), e) LOG.error(_("Failed to clean volume properties: %s"), e)
result += 1 result += 1
@ -577,26 +620,32 @@ class SetVolume(command.Command):
if parsed_args.property: if parsed_args.property:
try: try:
volume_client.volumes.set_metadata( volume_client.volumes.set_metadata(
volume.id, volume.id, parsed_args.property
parsed_args.property) )
except Exception as e: except Exception as e:
LOG.error(_("Failed to set volume property: %s"), e) LOG.error(_("Failed to set volume property: %s"), e)
result += 1 result += 1
if parsed_args.bootable or parsed_args.non_bootable: if parsed_args.bootable or parsed_args.non_bootable:
try: try:
volume_client.volumes.set_bootable( volume_client.volumes.set_bootable(
volume.id, parsed_args.bootable) volume.id, parsed_args.bootable
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set volume bootable property: %s"), e) LOG.error(_("Failed to set volume bootable property: %s"), e)
result += 1 result += 1
if parsed_args.read_only or parsed_args.read_write: if parsed_args.read_only or parsed_args.read_write:
try: try:
volume_client.volumes.update_readonly_flag( volume_client.volumes.update_readonly_flag(
volume.id, volume.id, parsed_args.read_only
parsed_args.read_only) )
except Exception as e: except Exception as e:
LOG.error(_("Failed to set volume read-only access " LOG.error(
"mode flag: %s"), e) _(
"Failed to set volume read-only access "
"mode flag: %s"
),
e,
)
result += 1 result += 1
kwargs = {} kwargs = {}
if parsed_args.name: if parsed_args.name:
@ -607,13 +656,19 @@ class SetVolume(command.Command):
try: try:
volume_client.volumes.update(volume.id, **kwargs) volume_client.volumes.update(volume.id, **kwargs)
except Exception as e: except Exception as e:
LOG.error(_("Failed to update volume display name " LOG.error(
"or display description: %s"), e) _(
"Failed to update volume display name "
"or display description: %s"
),
e,
)
result += 1 result += 1
if result > 0: if result > 0:
raise exceptions.CommandError(_("One or more of the " raise exceptions.CommandError(
"set operations failed")) _("One or more of the " "set operations failed")
)
class ShowVolume(command.ShowOne): class ShowVolume(command.ShowOne):
@ -634,15 +689,19 @@ class ShowVolume(command.ShowOne):
# Map 'metadata' column to 'properties' # Map 'metadata' column to 'properties'
volume._info.update( volume._info.update(
{ {
'properties': 'properties': format_columns.DictColumn(
format_columns.DictColumn(volume._info.pop('metadata')), volume._info.pop('metadata')
),
'type': volume._info.pop('volume_type'), 'type': volume._info.pop('volume_type'),
}, },
) )
if 'os-vol-tenant-attr:tenant_id' in volume._info: if 'os-vol-tenant-attr:tenant_id' in volume._info:
volume._info.update( 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 # Replace "display_name" by "name", keep consistent in v1 and v2
if 'display_name' in volume._info: if 'display_name' in volume._info:
@ -669,15 +728,16 @@ class UnsetVolume(command.Command):
'--property', '--property',
metavar='<key>', metavar='<key>',
action='append', action='append',
help=_('Remove a property from volume ' help=_(
'(repeat option to remove multiple properties)'), 'Remove a property from volume '
'(repeat option to remove multiple properties)'
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
volume = utils.find_resource( volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
volume_client.volumes, parsed_args.volume)
if parsed_args.property: if parsed_args.property:
volume_client.volumes.delete_metadata( volume_client.volumes.delete_metadata(

View File

@ -87,13 +87,14 @@ class CreateVolumeBackup(command.ShowOne):
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
volume_id = utils.find_resource(volume_client.volumes, volume_id = utils.find_resource(
parsed_args.volume).id volume_client.volumes, parsed_args.volume
).id
backup = volume_client.backups.create( backup = volume_client.backups.create(
volume_id, volume_id,
parsed_args.container, parsed_args.container,
parsed_args.name, parsed_args.name,
parsed_args.description parsed_args.description,
) )
backup._info.pop('links') backup._info.pop('links')
@ -119,19 +120,24 @@ class DeleteVolumeBackup(command.Command):
for i in parsed_args.backups: for i in parsed_args.backups:
try: try:
backup_id = utils.find_resource( backup_id = utils.find_resource(volume_client.backups, i).id
volume_client.backups, i).id
volume_client.backups.delete(backup_id) volume_client.backups.delete(backup_id)
except Exception as e: except Exception as e:
result += 1 result += 1
LOG.error(_("Failed to delete backup with " LOG.error(
"name or ID '%(backup)s': %(e)s"), _(
{'backup': i, 'e': e}) "Failed to delete backup with "
"name or ID '%(backup)s': %(e)s"
),
{'backup': i, 'e': e},
)
if result > 0: if result > 0:
total = len(parsed_args.backups) total = len(parsed_args.backups)
msg = (_("%(result)s of %(total)s backups failed " msg = _("%(result)s of %(total)s backups failed " "to delete.") % {
"to delete.") % {'result': result, 'total': total}) 'result': result,
'total': total,
}
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -149,22 +155,32 @@ class ListVolumeBackup(command.Lister):
parser.add_argument( parser.add_argument(
"--name", "--name",
metavar="<name>", metavar="<name>",
help=_("Filters results by the backup name") help=_("Filters results by the backup name"),
) )
parser.add_argument( parser.add_argument(
"--status", "--status",
metavar="<status>", metavar="<status>",
choices=['creating', 'available', 'deleting', choices=[
'error', 'restoring', 'error_restoring'], 'creating',
help=_("Filters results by the backup status " 'available',
"('creating', 'available', 'deleting', " 'deleting',
"'error', 'restoring' or 'error_restoring')") 'error',
'restoring',
'error_restoring',
],
help=_(
"Filters results by the backup status "
"('creating', 'available', 'deleting', "
"'error', 'restoring' or 'error_restoring')"
),
) )
parser.add_argument( parser.add_argument(
"--volume", "--volume",
metavar="<volume>", metavar="<volume>",
help=_("Filters results by the volume which they " help=_(
"backup (name or ID)") "Filters results by the volume which they "
"backup (name or ID)"
),
) )
parser.add_argument( parser.add_argument(
'--all-projects', '--all-projects',
@ -178,8 +194,16 @@ class ListVolumeBackup(command.Lister):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
if parsed_args.long: if parsed_args.long:
columns = ['ID', 'Name', 'Description', 'Status', 'Size', columns = [
'Availability Zone', 'Volume ID', 'Container'] 'ID',
'Name',
'Description',
'Status',
'Size',
'Availability Zone',
'Volume ID',
'Container',
]
column_headers = copy.deepcopy(columns) column_headers = copy.deepcopy(columns)
column_headers[6] = 'Volume' column_headers[6] = 'Volume'
else: else:
@ -194,13 +218,15 @@ class ListVolumeBackup(command.Lister):
except Exception: except Exception:
# Just forget it if there's any trouble # Just forget it if there's any trouble
pass pass
VolumeIdColumnWithCache = functools.partial(VolumeIdColumn, VolumeIdColumnWithCache = functools.partial(
volume_cache=volume_cache) VolumeIdColumn, volume_cache=volume_cache
)
filter_volume_id = None filter_volume_id = None
if parsed_args.volume: if parsed_args.volume:
filter_volume_id = utils.find_resource(volume_client.volumes, filter_volume_id = utils.find_resource(
parsed_args.volume).id volume_client.volumes, parsed_args.volume
).id
search_opts = { search_opts = {
'name': parsed_args.name, 'name': parsed_args.name,
'status': parsed_args.status, 'status': parsed_args.status,
@ -211,11 +237,17 @@ class ListVolumeBackup(command.Lister):
search_opts=search_opts, search_opts=search_opts,
) )
return (column_headers, return (
(utils.get_item_properties( column_headers,
s, columns, (
utils.get_item_properties(
s,
columns,
formatters={'Volume ID': VolumeIdColumnWithCache}, formatters={'Volume ID': VolumeIdColumnWithCache},
) for s in data)) )
for s in data
),
)
class RestoreVolumeBackup(command.Command): class RestoreVolumeBackup(command.Command):
@ -226,20 +258,21 @@ class RestoreVolumeBackup(command.Command):
parser.add_argument( parser.add_argument(
'backup', 'backup',
metavar='<backup>', metavar='<backup>',
help=_('Backup to restore (name or ID)') help=_('Backup to restore (name or ID)'),
) )
parser.add_argument( parser.add_argument(
'volume', 'volume',
metavar='<volume>', metavar='<volume>',
nargs='?', 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 return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
backup = utils.find_resource( backup = utils.find_resource(
volume_client.backups, parsed_args.backup, volume_client.backups,
parsed_args.backup,
) )
volume_id = None volume_id = None
if parsed_args.volume is not None: if parsed_args.volume is not None:
@ -258,13 +291,12 @@ class ShowVolumeBackup(command.ShowOne):
parser.add_argument( parser.add_argument(
'backup', 'backup',
metavar='<backup>', metavar='<backup>',
help=_('Backup to display (name or ID)') help=_('Backup to display (name or ID)'),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
backup = utils.find_resource(volume_client.backups, backup = utils.find_resource(volume_client.backups, parsed_args.backup)
parsed_args.backup)
backup._info.pop('links') backup._info.pop('links')
return zip(*sorted(backup._info.items())) return zip(*sorted(backup._info.items()))

View File

@ -72,8 +72,10 @@ class CreateVolumeSnapshot(command.ShowOne):
parser.add_argument( parser.add_argument(
'--volume', '--volume',
metavar='<volume>', metavar='<volume>',
help=_('Volume to snapshot (name or ID) ' help=_(
'(default is <snapshot-name>)'), 'Volume to snapshot (name or ID) '
'(default is <snapshot-name>)'
),
) )
parser.add_argument( parser.add_argument(
'--description', '--description',
@ -85,8 +87,10 @@ class CreateVolumeSnapshot(command.ShowOne):
dest='force', dest='force',
action='store_true', action='store_true',
default=False, default=False,
help=_('Create a snapshot attached to an instance. ' help=_(
'Default is False'), 'Create a snapshot attached to an instance. '
'Default is False'
),
) )
return parser return parser
@ -95,18 +99,20 @@ class CreateVolumeSnapshot(command.ShowOne):
volume = parsed_args.volume volume = parsed_args.volume
if not parsed_args.volume: if not parsed_args.volume:
volume = parsed_args.snapshot_name volume = parsed_args.snapshot_name
volume_id = utils.find_resource(volume_client.volumes, volume_id = utils.find_resource(volume_client.volumes, volume).id
volume).id
snapshot = volume_client.volume_snapshots.create( snapshot = volume_client.volume_snapshots.create(
volume_id, volume_id,
parsed_args.force, parsed_args.force,
parsed_args.snapshot_name, parsed_args.snapshot_name,
parsed_args.description parsed_args.description,
) )
snapshot._info.update( 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())) return zip(*sorted(snapshot._info.items()))
@ -132,18 +138,24 @@ class DeleteVolumeSnapshot(command.Command):
for i in parsed_args.snapshots: for i in parsed_args.snapshots:
try: try:
snapshot_id = utils.find_resource( snapshot_id = utils.find_resource(
volume_client.volume_snapshots, i).id volume_client.volume_snapshots, i
).id
volume_client.volume_snapshots.delete(snapshot_id) volume_client.volume_snapshots.delete(snapshot_id)
except Exception as e: except Exception as e:
result += 1 result += 1
LOG.error(_("Failed to delete snapshot with " LOG.error(
"name or ID '%(snapshot)s': %(e)s"), _(
{'snapshot': i, 'e': e}) "Failed to delete snapshot with "
"name or ID '%(snapshot)s': %(e)s"
),
{'snapshot': i, 'e': e},
)
if result > 0: if result > 0:
total = len(parsed_args.snapshots) total = len(parsed_args.snapshots)
msg = (_("%(result)s of %(total)s snapshots failed " msg = _(
"to delete.") % {'result': result, 'total': total}) "%(result)s of %(total)s snapshots failed " "to delete."
) % {'result': result, 'total': total}
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -168,22 +180,29 @@ class ListVolumeSnapshot(command.Lister):
'--name', '--name',
metavar='<name>', metavar='<name>',
default=None, default=None,
help=_('Filters results by a name.') help=_('Filters results by a name.'),
) )
parser.add_argument( parser.add_argument(
'--status', '--status',
metavar='<status>', metavar='<status>',
choices=['available', 'error', 'creating', 'deleting', choices=[
'error_deleting'], 'available',
help=_("Filters results by a status. " 'error',
"('available', 'error', 'creating', 'deleting'" 'creating',
" or 'error_deleting')") 'deleting',
'error_deleting',
],
help=_(
"Filters results by a status. "
"('available', 'error', 'creating', 'deleting'"
" or 'error_deleting')"
),
) )
parser.add_argument( parser.add_argument(
'--volume', '--volume',
metavar='<volume>', metavar='<volume>',
default=None, default=None,
help=_('Filters results by a volume (name or ID).') help=_('Filters results by a volume (name or ID).'),
) )
return parser return parser
@ -191,14 +210,27 @@ class ListVolumeSnapshot(command.Lister):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
if parsed_args.long: if parsed_args.long:
columns = ['ID', 'Display Name', 'Display Description', 'Status', columns = [
'Size', 'Created At', 'Volume ID', 'Metadata'] 'ID',
'Display Name',
'Display Description',
'Status',
'Size',
'Created At',
'Volume ID',
'Metadata',
]
column_headers = copy.deepcopy(columns) column_headers = copy.deepcopy(columns)
column_headers[6] = 'Volume' column_headers[6] = 'Volume'
column_headers[7] = 'Properties' column_headers[7] = 'Properties'
else: else:
columns = ['ID', 'Display Name', 'Display Description', 'Status', columns = [
'Size'] 'ID',
'Display Name',
'Display Description',
'Status',
'Size',
]
column_headers = copy.deepcopy(columns) column_headers = copy.deepcopy(columns)
# Always update Name and Description # Always update Name and Description
@ -213,13 +245,15 @@ class ListVolumeSnapshot(command.Lister):
except Exception: except Exception:
# Just forget it if there's any trouble # Just forget it if there's any trouble
pass pass
VolumeIdColumnWithCache = functools.partial(VolumeIdColumn, VolumeIdColumnWithCache = functools.partial(
volume_cache=volume_cache) VolumeIdColumn, volume_cache=volume_cache
)
volume_id = None volume_id = None
if parsed_args.volume: if parsed_args.volume:
volume_id = utils.find_resource( volume_id = utils.find_resource(
volume_client.volumes, parsed_args.volume).id volume_client.volumes, parsed_args.volume
).id
search_opts = { search_opts = {
'all_tenants': parsed_args.all_projects, 'all_tenants': parsed_args.all_projects,
@ -228,14 +262,21 @@ class ListVolumeSnapshot(command.Lister):
'volume_id': volume_id, 'volume_id': volume_id,
} }
data = volume_client.volume_snapshots.list( data = volume_client.volume_snapshots.list(search_opts=search_opts)
search_opts=search_opts) return (
return (column_headers, column_headers,
(utils.get_item_properties( (
s, columns, utils.get_item_properties(
formatters={'Metadata': format_columns.DictColumn, s,
'Volume ID': VolumeIdColumnWithCache}, columns,
) for s in data)) formatters={
'Metadata': format_columns.DictColumn,
'Volume ID': VolumeIdColumnWithCache,
},
)
for s in data
),
)
class SetVolumeSnapshot(command.Command): class SetVolumeSnapshot(command.Command):
@ -246,40 +287,43 @@ class SetVolumeSnapshot(command.Command):
parser.add_argument( parser.add_argument(
'snapshot', 'snapshot',
metavar='<snapshot>', metavar='<snapshot>',
help=_('Snapshot to modify (name or ID)') help=_('Snapshot to modify (name or ID)'),
) )
parser.add_argument( parser.add_argument(
'--name', '--name', metavar='<name>', help=_('New snapshot name')
metavar='<name>',
help=_('New snapshot name')
) )
parser.add_argument( parser.add_argument(
'--description', '--description',
metavar='<description>', metavar='<description>',
help=_('New snapshot description') help=_('New snapshot description'),
) )
parser.add_argument( parser.add_argument(
"--no-property", "--no-property",
dest="no_property", dest="no_property",
action="store_true", action="store_true",
help=_("Remove all properties from <snapshot> " help=_(
"(specify both --no-property and --property to " "Remove all properties from <snapshot> "
"remove the current properties before setting " "(specify both --no-property and --property to "
"new properties.)"), "remove the current properties before setting "
"new properties.)"
),
) )
parser.add_argument( parser.add_argument(
'--property', '--property',
metavar='<key=value>', metavar='<key=value>',
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_('Property to add/change for this snapshot ' help=_(
'(repeat option to set multiple properties)'), 'Property to add/change for this snapshot '
'(repeat option to set multiple properties)'
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
snapshot = utils.find_resource(volume_client.volume_snapshots, snapshot = utils.find_resource(
parsed_args.snapshot) volume_client.volume_snapshots, parsed_args.snapshot
)
result = 0 result = 0
if parsed_args.no_property: if parsed_args.no_property:
@ -296,7 +340,8 @@ class SetVolumeSnapshot(command.Command):
if parsed_args.property: if parsed_args.property:
try: try:
volume_client.volume_snapshots.set_metadata( volume_client.volume_snapshots.set_metadata(
snapshot.id, parsed_args.property) snapshot.id, parsed_args.property
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set snapshot property: %s"), e) LOG.error(_("Failed to set snapshot property: %s"), e)
result += 1 result += 1
@ -310,13 +355,19 @@ class SetVolumeSnapshot(command.Command):
try: try:
snapshot.update(**kwargs) snapshot.update(**kwargs)
except Exception as e: except Exception as e:
LOG.error(_("Failed to update snapshot display name " LOG.error(
"or display description: %s"), e) _(
"Failed to update snapshot display name "
"or display description: %s"
),
e,
)
result += 1 result += 1
if result > 0: if result > 0:
raise exceptions.CommandError(_("One or more of the " raise exceptions.CommandError(
"set operations failed")) _("One or more of the " "set operations failed")
)
class ShowVolumeSnapshot(command.ShowOne): class ShowVolumeSnapshot(command.ShowOne):
@ -327,18 +378,22 @@ class ShowVolumeSnapshot(command.ShowOne):
parser.add_argument( parser.add_argument(
'snapshot', 'snapshot',
metavar='<snapshot>', metavar='<snapshot>',
help=_('Snapshot to display (name or ID)') help=_('Snapshot to display (name or ID)'),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
snapshot = utils.find_resource(volume_client.volume_snapshots, snapshot = utils.find_resource(
parsed_args.snapshot) volume_client.volume_snapshots, parsed_args.snapshot
)
snapshot._info.update( 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())) return zip(*sorted(snapshot._info.items()))
@ -358,15 +413,18 @@ class UnsetVolumeSnapshot(command.Command):
'--property', '--property',
metavar='<key>', metavar='<key>',
action='append', action='append',
help=_('Property to remove from snapshot ' help=_(
'(repeat option to remove multiple properties)'), 'Property to remove from snapshot '
'(repeat option to remove multiple properties)'
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
snapshot = utils.find_resource( snapshot = utils.find_resource(
volume_client.volume_snapshots, parsed_args.snapshot) volume_client.volume_snapshots, parsed_args.snapshot
)
if parsed_args.property: if parsed_args.property:
volume_client.volume_snapshots.delete_metadata( volume_client.volume_snapshots.delete_metadata(

View File

@ -48,8 +48,7 @@ class AcceptTransferRequest(command.ShowOne):
try: try:
transfer_request_id = utils.find_resource( transfer_request_id = utils.find_resource(
volume_client.transfers, volume_client.transfers, parsed_args.transfer_request
parsed_args.transfer_request
).id ).id
except exceptions.CommandError: except exceptions.CommandError:
# Non-admin users will fail to lookup name -> ID so we just # Non-admin users will fail to lookup name -> ID so we just
@ -77,12 +76,12 @@ class CreateTransferRequest(command.ShowOne):
parser.add_argument( parser.add_argument(
'--name', '--name',
metavar="<name>", metavar="<name>",
help=_('New transfer request name (default to None)') help=_('New transfer request name (default to None)'),
) )
parser.add_argument( parser.add_argument(
'volume', 'volume',
metavar="<volume>", metavar="<volume>",
help=_('Volume to transfer (name or ID)') help=_('Volume to transfer (name or ID)'),
) )
return parser return parser
@ -127,14 +126,20 @@ class DeleteTransferRequest(command.Command):
volume_client.transfers.delete(transfer_request_id) volume_client.transfers.delete(transfer_request_id)
except Exception as e: except Exception as e:
result += 1 result += 1
LOG.error(_("Failed to delete volume transfer request " LOG.error(
"with name or ID '%(transfer)s': %(e)s") _(
% {'transfer': t, 'e': e}) "Failed to delete volume transfer request "
"with name or ID '%(transfer)s': %(e)s"
)
% {'transfer': t, 'e': e}
)
if result > 0: if result > 0:
total = len(parsed_args.transfer_request) total = len(parsed_args.transfer_request)
msg = (_("%(result)s of %(total)s volume transfer requests failed" msg = _(
" to delete") % {'result': result, 'total': total}) "%(result)s of %(total)s volume transfer requests failed"
" to delete"
) % {'result': result, 'total': total}
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -163,9 +168,13 @@ class ListTransferRequest(command.Lister):
search_opts={'all_tenants': parsed_args.all_projects}, search_opts={'all_tenants': parsed_args.all_projects},
) )
return (column_headers, ( return (
utils.get_item_properties(s, columns) column_headers,
for s in volume_transfer_result)) (
utils.get_item_properties(s, columns)
for s in volume_transfer_result
),
)
class ShowTransferRequest(command.ShowOne): class ShowTransferRequest(command.ShowOne):

View File

@ -63,8 +63,10 @@ class EncryptionInfoColumn(cliff_columns.FormattableColumn):
def _create_encryption_type(volume_client, volume_type, parsed_args): def _create_encryption_type(volume_client, volume_type, parsed_args):
if not parsed_args.encryption_provider: if not parsed_args.encryption_provider:
msg = _("'--encryption-provider' should be specified while " msg = _(
"creating a new encryption type") "'--encryption-provider' should be specified while "
"creating a new encryption type"
)
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
# set the default of control location while creating # set the default of control location while creating
control_location = 'front-end' control_location = 'front-end'
@ -74,10 +76,11 @@ def _create_encryption_type(volume_client, volume_type, parsed_args):
'provider': parsed_args.encryption_provider, 'provider': parsed_args.encryption_provider,
'cipher': parsed_args.encryption_cipher, 'cipher': parsed_args.encryption_cipher,
'key_size': parsed_args.encryption_key_size, 'key_size': parsed_args.encryption_key_size,
'control_location': control_location 'control_location': control_location,
} }
encryption = volume_client.volume_encryption_types.create( encryption = volume_client.volume_encryption_types.create(
volume_type, body) volume_type, body
)
return encryption return encryption
@ -95,44 +98,54 @@ class CreateVolumeType(command.ShowOne):
'--property', '--property',
metavar='<key=value>', metavar='<key=value>',
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_('Set a property on this volume type ' help=_(
'(repeat option to set multiple properties)'), 'Set a property on this volume type '
'(repeat option to set multiple properties)'
),
) )
# TODO(Huanxuan Ao): Add choices for each "--encryption-*" option. # TODO(Huanxuan Ao): Add choices for each "--encryption-*" option.
parser.add_argument( parser.add_argument(
'--encryption-provider', '--encryption-provider',
metavar='<provider>', metavar='<provider>',
help=_('Set the encryption provider format for ' help=_(
'this volume type (e.g "luks" or "plain") (admin only) ' 'Set the encryption provider format for '
'(This option is required when setting encryption type ' 'this volume type (e.g "luks" or "plain") (admin only) '
'of a volume. Consider using other encryption options ' '(This option is required when setting encryption type '
'such as: "--encryption-cipher", "--encryption-key-size" ' 'of a volume. Consider using other encryption options '
'and "--encryption-control-location")'), 'such as: "--encryption-cipher", "--encryption-key-size" '
'and "--encryption-control-location")'
),
) )
parser.add_argument( parser.add_argument(
'--encryption-cipher', '--encryption-cipher',
metavar='<cipher>', metavar='<cipher>',
help=_('Set the encryption algorithm or mode for this ' help=_(
'volume type (e.g "aes-xts-plain64") (admin only)'), 'Set the encryption algorithm or mode for this '
'volume type (e.g "aes-xts-plain64") (admin only)'
),
) )
parser.add_argument( parser.add_argument(
'--encryption-key-size', '--encryption-key-size',
metavar='<key-size>', metavar='<key-size>',
type=int, type=int,
help=_('Set the size of the encryption key of this ' help=_(
'volume type (e.g "128" or "256") (admin only)'), 'Set the size of the encryption key of this '
'volume type (e.g "128" or "256") (admin only)'
),
) )
parser.add_argument( parser.add_argument(
'--encryption-control-location', '--encryption-control-location',
metavar='<control-location>', metavar='<control-location>',
choices=['front-end', 'back-end'], choices=['front-end', 'back-end'],
help=_('Set the notional service where the encryption is ' help=_(
'performed ("front-end" or "back-end") (admin only) ' 'Set the notional service where the encryption is '
'(The default value for this option is "front-end" ' 'performed ("front-end" or "back-end") (admin only) '
'when setting encryption type of a volume. Consider ' '(The default value for this option is "front-end" '
'using other encryption options such as: ' 'when setting encryption type of a volume. Consider '
'"--encryption-cipher", "--encryption-key-size" and ' 'using other encryption options such as: '
'"--encryption-provider")'), '"--encryption-cipher", "--encryption-key-size" and '
'"--encryption-provider")'
),
) )
return parser return parser
@ -143,22 +156,32 @@ class CreateVolumeType(command.ShowOne):
if parsed_args.property: if parsed_args.property:
result = volume_type.set_keys(parsed_args.property) result = volume_type.set_keys(parsed_args.property)
volume_type._info.update( volume_type._info.update(
{'properties': format_columns.DictColumn(result)}) {'properties': format_columns.DictColumn(result)}
if (parsed_args.encryption_provider or )
parsed_args.encryption_cipher or if (
parsed_args.encryption_key_size or parsed_args.encryption_provider
parsed_args.encryption_control_location): or parsed_args.encryption_cipher
or parsed_args.encryption_key_size
or parsed_args.encryption_control_location
):
try: try:
# create new encryption # create new encryption
encryption = _create_encryption_type( encryption = _create_encryption_type(
volume_client, volume_type, parsed_args) volume_client, volume_type, parsed_args
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set encryption information for this " LOG.error(
"volume type: %s"), e) _(
"Failed to set encryption information for this "
"volume type: %s"
),
e,
)
# add encryption info in result # add encryption info in result
encryption._info.pop("volume_type_id", None) encryption._info.pop("volume_type_id", None)
volume_type._info.update( 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) volume_type._info.pop("os-volume-type-access:is_public", None)
return zip(*sorted(volume_type._info.items())) return zip(*sorted(volume_type._info.items()))
@ -183,20 +206,26 @@ class DeleteVolumeType(command.Command):
for volume_type in parsed_args.volume_types: for volume_type in parsed_args.volume_types:
try: try:
vol_type = utils.find_resource(volume_client.volume_types, vol_type = utils.find_resource(
volume_type) volume_client.volume_types, volume_type
)
volume_client.volume_types.delete(vol_type) volume_client.volume_types.delete(vol_type)
except Exception as e: except Exception as e:
result += 1 result += 1
LOG.error(_("Failed to delete volume type with " LOG.error(
"name or ID '%(volume_type)s': %(e)s") _(
% {'volume_type': volume_type, 'e': e}) "Failed to delete volume type with "
"name or ID '%(volume_type)s': %(e)s"
)
% {'volume_type': volume_type, 'e': e}
)
if result > 0: if result > 0:
total = len(parsed_args.volume_types) total = len(parsed_args.volume_types)
msg = (_("%(result)s of %(total)s volume types failed " msg = _(
"to delete.") % {'result': result, 'total': total}) "%(result)s of %(total)s volume types failed " "to delete."
) % {'result': result, 'total': total}
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -209,13 +238,15 @@ class ListVolumeType(command.Lister):
'--long', '--long',
action='store_true', action='store_true',
default=False, default=False,
help=_('List additional fields in output') help=_('List additional fields in output'),
) )
parser.add_argument( parser.add_argument(
"--encryption-type", "--encryption-type",
action="store_true", action="store_true",
help=_("Display encryption information for each volume type " help=_(
"(admin only)"), "Display encryption information for each volume type "
"(admin only)"
),
) )
return parser return parser
@ -241,7 +272,7 @@ class ListVolumeType(command.Lister):
'created_at', 'created_at',
'updated_at', 'updated_at',
'deleted_at', 'deleted_at',
'volume_type_id' 'volume_type_id',
] ]
for key in del_key: for key in del_key:
d._info.pop(key, None) d._info.pop(key, None)
@ -254,14 +285,21 @@ class ListVolumeType(command.Lister):
column_headers += ['Encryption'] column_headers += ['Encryption']
_EncryptionInfoColumn = functools.partial( _EncryptionInfoColumn = functools.partial(
EncryptionInfoColumn, encryption_data=encryption) EncryptionInfoColumn, encryption_data=encryption
)
formatters['id'] = _EncryptionInfoColumn formatters['id'] = _EncryptionInfoColumn
return (column_headers, return (
(utils.get_item_properties( column_headers,
s, columns, (
utils.get_item_properties(
s,
columns,
formatters=formatters, formatters=formatters,
) for s in data)) )
for s in data
),
)
class SetVolumeType(command.Command): class SetVolumeType(command.Command):
@ -278,51 +316,62 @@ class SetVolumeType(command.Command):
'--property', '--property',
metavar='<key=value>', metavar='<key=value>',
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_('Set a property on this volume type ' help=_(
'(repeat option to set multiple properties)'), 'Set a property on this volume type '
'(repeat option to set multiple properties)'
),
) )
# TODO(Huanxuan Ao): Add choices for each "--encryption-*" option. # TODO(Huanxuan Ao): Add choices for each "--encryption-*" option.
parser.add_argument( parser.add_argument(
'--encryption-provider', '--encryption-provider',
metavar='<provider>', metavar='<provider>',
help=_('Set the encryption provider format for ' help=_(
'this volume type (e.g "luks" or "plain") (admin only) ' 'Set the encryption provider format for '
'(This option is required when setting encryption type ' 'this volume type (e.g "luks" or "plain") (admin only) '
'of a volume. Consider using other encryption options ' '(This option is required when setting encryption type '
'such as: "--encryption-cipher", "--encryption-key-size" ' 'of a volume. Consider using other encryption options '
'and "--encryption-control-location")'), 'such as: "--encryption-cipher", "--encryption-key-size" '
'and "--encryption-control-location")'
),
) )
parser.add_argument( parser.add_argument(
'--encryption-cipher', '--encryption-cipher',
metavar='<cipher>', metavar='<cipher>',
help=_('Set the encryption algorithm or mode for this ' help=_(
'volume type (e.g "aes-xts-plain64") (admin only)'), 'Set the encryption algorithm or mode for this '
'volume type (e.g "aes-xts-plain64") (admin only)'
),
) )
parser.add_argument( parser.add_argument(
'--encryption-key-size', '--encryption-key-size',
metavar='<key-size>', metavar='<key-size>',
type=int, type=int,
help=_('Set the size of the encryption key of this ' help=_(
'volume type (e.g "128" or "256") (admin only)'), 'Set the size of the encryption key of this '
'volume type (e.g "128" or "256") (admin only)'
),
) )
parser.add_argument( parser.add_argument(
'--encryption-control-location', '--encryption-control-location',
metavar='<control-location>', metavar='<control-location>',
choices=['front-end', 'back-end'], choices=['front-end', 'back-end'],
help=_('Set the notional service where the encryption is ' help=_(
'performed ("front-end" or "back-end") (admin only) ' 'Set the notional service where the encryption is '
'(The default value for this option is "front-end" ' 'performed ("front-end" or "back-end") (admin only) '
'when setting encryption type of a volume. Consider ' '(The default value for this option is "front-end" '
'using other encryption options such as: ' 'when setting encryption type of a volume. Consider '
'"--encryption-cipher", "--encryption-key-size" and ' 'using other encryption options such as: '
'"--encryption-provider")'), '"--encryption-cipher", "--encryption-key-size" and '
'"--encryption-provider")'
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
volume_type = utils.find_resource( volume_type = utils.find_resource(
volume_client.volume_types, parsed_args.volume_type) volume_client.volume_types, parsed_args.volume_type
)
result = 0 result = 0
if parsed_args.property: if parsed_args.property:
@ -332,21 +381,30 @@ class SetVolumeType(command.Command):
LOG.error(_("Failed to set volume type property: %s"), e) LOG.error(_("Failed to set volume type property: %s"), e)
result += 1 result += 1
if (parsed_args.encryption_provider or if (
parsed_args.encryption_cipher or parsed_args.encryption_provider
parsed_args.encryption_key_size or or parsed_args.encryption_cipher
parsed_args.encryption_control_location): or parsed_args.encryption_key_size
or parsed_args.encryption_control_location
):
try: try:
_create_encryption_type( _create_encryption_type(
volume_client, volume_type, parsed_args) volume_client, volume_type, parsed_args
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set encryption information for this " LOG.error(
"volume type: %s"), e) _(
"Failed to set encryption information for this "
"volume type: %s"
),
e,
)
result += 1 result += 1
if result > 0: if result > 0:
raise exceptions.CommandError(_("Command Failed: One or more of" raise exceptions.CommandError(
" the operations failed")) _("Command Failed: One or more of" " the operations failed")
)
class ShowVolumeType(command.ShowOne): class ShowVolumeType(command.ShowOne):
@ -357,35 +415,45 @@ class ShowVolumeType(command.ShowOne):
parser.add_argument( parser.add_argument(
"volume_type", "volume_type",
metavar="<volume-type>", metavar="<volume-type>",
help=_("Volume type to display (name or ID)") help=_("Volume type to display (name or ID)"),
) )
parser.add_argument( parser.add_argument(
"--encryption-type", "--encryption-type",
action="store_true", action="store_true",
help=_("Display encryption information of this volume type " help=_(
"(admin only)"), "Display encryption information of this volume type "
"(admin only)"
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
volume_type = utils.find_resource( 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( properties = format_columns.DictColumn(
volume_type._info.pop('extra_specs')) volume_type._info.pop('extra_specs')
)
volume_type._info.update({'properties': properties}) volume_type._info.update({'properties': properties})
if parsed_args.encryption_type: if parsed_args.encryption_type:
# show encryption type information for this volume type # show encryption type information for this volume type
try: try:
encryption = volume_client.volume_encryption_types.get( encryption = volume_client.volume_encryption_types.get(
volume_type.id) volume_type.id
)
encryption._info.pop("volume_type_id", None) encryption._info.pop("volume_type_id", None)
volume_type._info.update( volume_type._info.update(
{'encryption': {'encryption': format_columns.DictColumn(encryption._info)}
format_columns.DictColumn(encryption._info)}) )
except Exception as e: except Exception as e:
LOG.error(_("Failed to display the encryption information " LOG.error(
"of this volume type: %s"), e) _(
"Failed to display the encryption information "
"of this volume type: %s"
),
e,
)
volume_type._info.pop("os-volume-type-access:is_public", None) volume_type._info.pop("os-volume-type-access:is_public", None)
return zip(*sorted(volume_type._info.items())) return zip(*sorted(volume_type._info.items()))
@ -404,14 +472,18 @@ class UnsetVolumeType(command.Command):
'--property', '--property',
metavar='<key>', metavar='<key>',
action='append', action='append',
help=_('Remove a property from this volume type ' help=_(
'(repeat option to remove multiple properties)'), 'Remove a property from this volume type '
'(repeat option to remove multiple properties)'
),
) )
parser.add_argument( parser.add_argument(
"--encryption-type", "--encryption-type",
action="store_true", action="store_true",
help=_("Remove the encryption type for this volume type " help=_(
"(admin only)"), "Remove the encryption type for this volume type "
"(admin only)"
),
) )
return parser return parser
@ -433,10 +505,16 @@ class UnsetVolumeType(command.Command):
try: try:
volume_client.volume_encryption_types.delete(volume_type) volume_client.volume_encryption_types.delete(volume_type)
except Exception as e: except Exception as e:
LOG.error(_("Failed to remove the encryption type for this " LOG.error(
"volume type: %s"), e) _(
"Failed to remove the encryption type for this "
"volume type: %s"
),
e,
)
result += 1 result += 1
if result > 0: if result > 0:
raise exceptions.CommandError(_("Command Failed: One or more of" raise exceptions.CommandError(
" the operations failed")) _("Command Failed: One or more of" " the operations failed")
)

View File

@ -26,17 +26,19 @@ LOG = logging.getLogger(__name__)
class ExportBackupRecord(command.ShowOne): 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 Backup information can be imported into a new service instance to be able to
restore.""") restore."""
)
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super(ExportBackupRecord, self).get_parser(prog_name) parser = super(ExportBackupRecord, self).get_parser(prog_name)
parser.add_argument( parser.add_argument(
"backup", "backup",
metavar="<backup>", metavar="<backup>",
help=_("Backup to export (name or ID)") help=_("Backup to export (name or ID)"),
) )
return parser return parser
@ -55,29 +57,31 @@ restore.""")
class ImportBackupRecord(command.ShowOne): 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 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): def get_parser(self, prog_name):
parser = super(ImportBackupRecord, self).get_parser(prog_name) parser = super(ImportBackupRecord, self).get_parser(prog_name)
parser.add_argument( parser.add_argument(
"backup_service", "backup_service",
metavar="<backup_service>", metavar="<backup_service>",
help=_("Backup service containing the backup.") help=_("Backup service containing the backup."),
) )
parser.add_argument( parser.add_argument(
"backup_metadata", "backup_metadata",
metavar="<backup_metadata>", metavar="<backup_metadata>",
help=_("Encoded backup metadata from export.") help=_("Encoded backup metadata from export."),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
backup_data = volume_client.backups.import_record( backup_data = volume_client.backups.import_record(
parsed_args.backup_service, parsed_args.backup_service, parsed_args.backup_metadata
parsed_args.backup_metadata) )
backup_data.pop('links', None) backup_data.pop('links', None)
return zip(*sorted(backup_data.items())) return zip(*sorted(backup_data.items()))

View File

@ -33,14 +33,17 @@ def _find_volumes(parsed_args_volumes, volume_client):
uuid = '' uuid = ''
for volume in parsed_args_volumes: for volume in parsed_args_volumes:
try: try:
volume_id = utils.find_resource( volume_id = utils.find_resource(volume_client.volumes, volume).id
volume_client.volumes, volume).id
uuid += volume_id + ',' uuid += volume_id + ','
except Exception as e: except Exception as e:
result += 1 result += 1
LOG.error(_("Failed to find volume with " LOG.error(
"name or ID '%(volume)s':%(e)s") _(
% {'volume': volume, 'e': e}) "Failed to find volume with "
"name or ID '%(volume)s':%(e)s"
)
% {'volume': volume, 'e': e}
)
return result, uuid return result, uuid
@ -59,8 +62,10 @@ class AddVolumeToConsistencyGroup(command.Command):
'volumes', 'volumes',
metavar='<volume>', metavar='<volume>',
nargs='+', nargs='+',
help=_('Volume(s) to add to <consistency-group> (name or ID) ' help=_(
'(repeat option to add multiple volumes)'), 'Volume(s) to add to <consistency-group> (name or ID) '
'(repeat option to add multiple volumes)'
),
) )
return parser return parser
@ -70,16 +75,19 @@ class AddVolumeToConsistencyGroup(command.Command):
if result > 0: if result > 0:
total = len(parsed_args.volumes) total = len(parsed_args.volumes)
LOG.error(_("%(result)s of %(total)s volumes failed " LOG.error(
"to add.") % {'result': result, 'total': total}) _("%(result)s of %(total)s volumes failed " "to add.")
% {'result': result, 'total': total}
)
if add_uuid: if add_uuid:
add_uuid = add_uuid.rstrip(',') add_uuid = add_uuid.rstrip(',')
consistency_group_id = utils.find_resource( consistency_group_id = utils.find_resource(
volume_client.consistencygroups, volume_client.consistencygroups, parsed_args.consistency_group
parsed_args.consistency_group).id ).id
volume_client.consistencygroups.update( volume_client.consistencygroups.update(
consistency_group_id, add_volumes=add_uuid) consistency_group_id, add_volumes=add_uuid
)
class CreateConsistencyGroup(command.ShowOne): class CreateConsistencyGroup(command.ShowOne):
@ -143,18 +151,20 @@ class CreateConsistencyGroup(command.ShowOne):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
if parsed_args.volume_type: if parsed_args.volume_type:
volume_type_id = utils.find_resource( volume_type_id = utils.find_resource(
volume_client.volume_types, volume_client.volume_types, parsed_args.volume_type
parsed_args.volume_type).id ).id
consistency_group = volume_client.consistencygroups.create( consistency_group = volume_client.consistencygroups.create(
volume_type_id, volume_type_id,
name=parsed_args.name, name=parsed_args.name,
description=parsed_args.description, description=parsed_args.description,
availability_zone=parsed_args.availability_zone availability_zone=parsed_args.availability_zone,
) )
else: else:
if parsed_args.availability_zone: if parsed_args.availability_zone:
msg = _("'--availability-zone' option will not work " msg = _(
"if creating consistency group from source") "'--availability-zone' option will not work "
"if creating consistency group from source"
)
LOG.warning(msg) LOG.warning(msg)
consistency_group_id = None consistency_group_id = None
@ -208,19 +218,27 @@ class DeleteConsistencyGroup(command.Command):
for i in parsed_args.consistency_groups: for i in parsed_args.consistency_groups:
try: try:
consistency_group_id = utils.find_resource( consistency_group_id = utils.find_resource(
volume_client.consistencygroups, i).id volume_client.consistencygroups, i
).id
volume_client.consistencygroups.delete( volume_client.consistencygroups.delete(
consistency_group_id, parsed_args.force) consistency_group_id, parsed_args.force
)
except Exception as e: except Exception as e:
result += 1 result += 1
LOG.error(_("Failed to delete consistency group with " LOG.error(
"name or ID '%(consistency_group)s':%(e)s") _(
% {'consistency_group': i, 'e': e}) "Failed to delete consistency group with "
"name or ID '%(consistency_group)s':%(e)s"
)
% {'consistency_group': i, 'e': e}
)
if result > 0: if result > 0:
total = len(parsed_args.consistency_groups) total = len(parsed_args.consistency_groups)
msg = (_("%(result)s of %(total)s consistency groups failed " msg = _(
"to delete.") % {'result': result, 'total': total}) "%(result)s of %(total)s consistency groups failed "
"to delete."
) % {'result': result, 'total': total}
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -232,41 +250,56 @@ class ListConsistencyGroup(command.Lister):
parser.add_argument( parser.add_argument(
'--all-projects', '--all-projects',
action="store_true", action="store_true",
help=_('Show details for all projects. Admin only. ' help=_(
'(defaults to False)') 'Show details for all projects. Admin only. '
'(defaults to False)'
),
) )
parser.add_argument( parser.add_argument(
'--long', '--long',
action="store_true", action="store_true",
help=_('List additional fields in output') help=_('List additional fields in output'),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
if parsed_args.long: if parsed_args.long:
columns = ['ID', 'Status', 'Availability Zone', columns = [
'Name', 'Description', 'Volume Types'] 'ID',
'Status',
'Availability Zone',
'Name',
'Description',
'Volume Types',
]
else: else:
columns = ['ID', 'Status', 'Name'] columns = ['ID', 'Status', 'Name']
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
consistency_groups = volume_client.consistencygroups.list( consistency_groups = volume_client.consistencygroups.list(
detailed=True, detailed=True,
search_opts={'all_tenants': parsed_args.all_projects} search_opts={'all_tenants': parsed_args.all_projects},
) )
return (columns, ( return (
utils.get_item_properties( columns,
s, columns, (
formatters={'Volume Types': format_columns.ListColumn}) utils.get_item_properties(
for s in consistency_groups)) s,
columns,
formatters={'Volume Types': format_columns.ListColumn},
)
for s in consistency_groups
),
)
class RemoveVolumeFromConsistencyGroup(command.Command): class RemoveVolumeFromConsistencyGroup(command.Command):
_description = _("Remove volume(s) from consistency group") _description = _("Remove volume(s) from consistency group")
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = \ parser = super(RemoveVolumeFromConsistencyGroup, self).get_parser(
super(RemoveVolumeFromConsistencyGroup, self).get_parser(prog_name) prog_name
)
parser.add_argument( parser.add_argument(
'consistency_group', 'consistency_group',
metavar="<consistency-group>", metavar="<consistency-group>",
@ -276,8 +309,10 @@ class RemoveVolumeFromConsistencyGroup(command.Command):
'volumes', 'volumes',
metavar='<volume>', metavar='<volume>',
nargs='+', nargs='+',
help=_('Volume(s) to remove from <consistency-group> (name or ID) ' help=_(
'(repeat option to remove multiple volumes)'), 'Volume(s) to remove from <consistency-group> (name or ID) '
'(repeat option to remove multiple volumes)'
),
) )
return parser return parser
@ -287,16 +322,19 @@ class RemoveVolumeFromConsistencyGroup(command.Command):
if result > 0: if result > 0:
total = len(parsed_args.volumes) total = len(parsed_args.volumes)
LOG.error(_("%(result)s of %(total)s volumes failed " LOG.error(
"to remove.") % {'result': result, 'total': total}) _("%(result)s of %(total)s volumes failed " "to remove.")
% {'result': result, 'total': total}
)
if remove_uuid: if remove_uuid:
remove_uuid = remove_uuid.rstrip(',') remove_uuid = remove_uuid.rstrip(',')
consistency_group_id = utils.find_resource( consistency_group_id = utils.find_resource(
volume_client.consistencygroups, volume_client.consistencygroups, parsed_args.consistency_group
parsed_args.consistency_group).id ).id
volume_client.consistencygroups.update( volume_client.consistencygroups.update(
consistency_group_id, remove_volumes=remove_uuid) consistency_group_id, remove_volumes=remove_uuid
)
class SetConsistencyGroup(command.Command): class SetConsistencyGroup(command.Command):
@ -307,7 +345,7 @@ class SetConsistencyGroup(command.Command):
parser.add_argument( parser.add_argument(
'consistency_group', 'consistency_group',
metavar='<consistency-group>', metavar='<consistency-group>',
help=_('Consistency group to modify (name or ID)') help=_('Consistency group to modify (name or ID)'),
) )
parser.add_argument( parser.add_argument(
'--name', '--name',
@ -330,10 +368,11 @@ class SetConsistencyGroup(command.Command):
kwargs['description'] = parsed_args.description kwargs['description'] = parsed_args.description
if kwargs: if kwargs:
consistency_group_id = utils.find_resource( consistency_group_id = utils.find_resource(
volume_client.consistencygroups, volume_client.consistencygroups, parsed_args.consistency_group
parsed_args.consistency_group).id ).id
volume_client.consistencygroups.update( volume_client.consistencygroups.update(
consistency_group_id, **kwargs) consistency_group_id, **kwargs
)
class ShowConsistencyGroup(command.ShowOne): class ShowConsistencyGroup(command.ShowOne):
@ -344,13 +383,13 @@ class ShowConsistencyGroup(command.ShowOne):
parser.add_argument( parser.add_argument(
"consistency_group", "consistency_group",
metavar="<consistency-group>", metavar="<consistency-group>",
help=_("Consistency group to display (name or ID)") help=_("Consistency group to display (name or ID)"),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
consistency_group = utils.find_resource( consistency_group = utils.find_resource(
volume_client.consistencygroups, volume_client.consistencygroups, parsed_args.consistency_group
parsed_args.consistency_group) )
return zip(*sorted(consistency_group._info.items())) return zip(*sorted(consistency_group._info.items()))

View File

@ -30,24 +30,27 @@ class CreateConsistencyGroupSnapshot(command.ShowOne):
_description = _("Create new consistency group snapshot.") _description = _("Create new consistency group snapshot.")
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super( parser = super(CreateConsistencyGroupSnapshot, self).get_parser(
CreateConsistencyGroupSnapshot, self).get_parser(prog_name) prog_name
)
parser.add_argument( parser.add_argument(
"snapshot_name", "snapshot_name",
metavar="<snapshot-name>", metavar="<snapshot-name>",
nargs="?", nargs="?",
help=_("Name of new consistency group snapshot (default to None)") help=_("Name of new consistency group snapshot (default to None)"),
) )
parser.add_argument( parser.add_argument(
"--consistency-group", "--consistency-group",
metavar="<consistency-group>", metavar="<consistency-group>",
help=_("Consistency group to snapshot (name or ID) " help=_(
"(default to be the same as <snapshot-name>)") "Consistency group to snapshot (name or ID) "
"(default to be the same as <snapshot-name>)"
),
) )
parser.add_argument( parser.add_argument(
"--description", "--description",
metavar="<description>", metavar="<description>",
help=_("Description of this consistency group snapshot") help=_("Description of this consistency group snapshot"),
) )
return parser return parser
@ -59,8 +62,8 @@ class CreateConsistencyGroupSnapshot(command.ShowOne):
# will be the same as the new consistency group snapshot name # will be the same as the new consistency group snapshot name
consistency_group = parsed_args.snapshot_name consistency_group = parsed_args.snapshot_name
consistency_group_id = utils.find_resource( consistency_group_id = utils.find_resource(
volume_client.consistencygroups, volume_client.consistencygroups, consistency_group
consistency_group).id ).id
consistency_group_snapshot = volume_client.cgsnapshots.create( consistency_group_snapshot = volume_client.cgsnapshots.create(
consistency_group_id, consistency_group_id,
name=parsed_args.snapshot_name, name=parsed_args.snapshot_name,
@ -74,13 +77,14 @@ class DeleteConsistencyGroupSnapshot(command.Command):
_description = _("Delete consistency group snapshot(s).") _description = _("Delete consistency group snapshot(s).")
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super( parser = super(DeleteConsistencyGroupSnapshot, self).get_parser(
DeleteConsistencyGroupSnapshot, self).get_parser(prog_name) prog_name
)
parser.add_argument( parser.add_argument(
"consistency_group_snapshot", "consistency_group_snapshot",
metavar="<consistency-group-snapshot>", metavar="<consistency-group-snapshot>",
nargs="+", nargs="+",
help=_("Consistency group snapshot(s) to delete (name or ID)") help=_("Consistency group snapshot(s) to delete (name or ID)"),
) )
return parser return parser
@ -90,20 +94,27 @@ class DeleteConsistencyGroupSnapshot(command.Command):
for snapshot in parsed_args.consistency_group_snapshot: for snapshot in parsed_args.consistency_group_snapshot:
try: try:
snapshot_id = utils.find_resource(volume_client.cgsnapshots, snapshot_id = utils.find_resource(
snapshot).id volume_client.cgsnapshots, snapshot
).id
volume_client.cgsnapshots.delete(snapshot_id) volume_client.cgsnapshots.delete(snapshot_id)
except Exception as e: except Exception as e:
result += 1 result += 1
LOG.error(_("Failed to delete consistency group snapshot " LOG.error(
"with name or ID '%(snapshot)s': %(e)s") _(
% {'snapshot': snapshot, 'e': e}) "Failed to delete consistency group snapshot "
"with name or ID '%(snapshot)s': %(e)s"
)
% {'snapshot': snapshot, 'e': e}
)
if result > 0: if result > 0:
total = len(parsed_args.consistency_group_snapshot) total = len(parsed_args.consistency_group_snapshot)
msg = (_("%(result)s of %(total)s consistency group snapshots " msg = _(
"failed to delete.") % {'result': result, 'total': total}) "%(result)s of %(total)s consistency group snapshots "
"failed to delete."
) % {'result': result, 'total': total}
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -111,38 +122,54 @@ class ListConsistencyGroupSnapshot(command.Lister):
_description = _("List consistency group snapshots.") _description = _("List consistency group snapshots.")
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super( parser = super(ListConsistencyGroupSnapshot, self).get_parser(
ListConsistencyGroupSnapshot, self).get_parser(prog_name) prog_name
)
parser.add_argument( parser.add_argument(
'--all-projects', '--all-projects',
action="store_true", action="store_true",
help=_('Show detail for all projects (admin only) ' help=_(
'(defaults to False)') 'Show detail for all projects (admin only) '
'(defaults to False)'
),
) )
parser.add_argument( parser.add_argument(
'--long', '--long',
action="store_true", action="store_true",
help=_('List additional fields in output') help=_('List additional fields in output'),
) )
parser.add_argument( parser.add_argument(
'--status', '--status',
metavar="<status>", metavar="<status>",
choices=['available', 'error', 'creating', 'deleting', choices=[
'error_deleting'], 'available',
help=_('Filters results by a status ("available", "error", ' 'error',
'"creating", "deleting" or "error_deleting")') 'creating',
'deleting',
'error_deleting',
],
help=_(
'Filters results by a status ("available", "error", '
'"creating", "deleting" or "error_deleting")'
),
) )
parser.add_argument( parser.add_argument(
'--consistency-group', '--consistency-group',
metavar="<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 return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
if parsed_args.long: if parsed_args.long:
columns = ['ID', 'Status', 'ConsistencyGroup ID', columns = [
'Name', 'Description', 'Created At'] 'ID',
'Status',
'ConsistencyGroup ID',
'Name',
'Description',
'Created At',
]
else: else:
columns = ['ID', 'Status', 'Name'] columns = ['ID', 'Status', 'Name']
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
@ -162,28 +189,32 @@ class ListConsistencyGroupSnapshot(command.Lister):
search_opts=search_opts, search_opts=search_opts,
) )
return (columns, ( return (
utils.get_item_properties( columns,
s, columns) (
for s in consistency_group_snapshots)) utils.get_item_properties(s, columns)
for s in consistency_group_snapshots
),
)
class ShowConsistencyGroupSnapshot(command.ShowOne): class ShowConsistencyGroupSnapshot(command.ShowOne):
_description = _("Display consistency group snapshot details") _description = _("Display consistency group snapshot details")
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super( parser = super(ShowConsistencyGroupSnapshot, self).get_parser(
ShowConsistencyGroupSnapshot, self).get_parser(prog_name) prog_name
)
parser.add_argument( parser.add_argument(
"consistency_group_snapshot", "consistency_group_snapshot",
metavar="<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 return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
consistency_group_snapshot = utils.find_resource( consistency_group_snapshot = utils.find_resource(
volume_client.cgsnapshots, volume_client.cgsnapshots, parsed_args.consistency_group_snapshot
parsed_args.consistency_group_snapshot) )
return zip(*sorted(consistency_group_snapshot._info.items())) return zip(*sorted(consistency_group_snapshot._info.items()))

View File

@ -48,10 +48,12 @@ class AssociateQos(command.Command):
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs, qos_spec = utils.find_resource(
parsed_args.qos_spec) volume_client.qos_specs, parsed_args.qos_spec
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.associate(qos_spec.id, volume_type.id) volume_client.qos_specs.associate(qos_spec.id, volume_type.id)
@ -72,16 +74,22 @@ class CreateQos(command.ShowOne):
metavar='<consumer>', metavar='<consumer>',
choices=consumer_choices, choices=consumer_choices,
default='both', default='both',
help=(_('Consumer of the QoS. Valid consumers: %s ' help=(
"(defaults to 'both')") % _(
utils.format_list(consumer_choices)) 'Consumer of the QoS. Valid consumers: %s '
"(defaults to 'both')"
)
% utils.format_list(consumer_choices)
),
) )
parser.add_argument( parser.add_argument(
'--property', '--property',
metavar='<key=value>', metavar='<key=value>',
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_('Set a QoS specification property ' help=_(
'(repeat option to set multiple properties)'), 'Set a QoS specification property '
'(repeat option to set multiple properties)'
),
) )
return parser return parser
@ -96,8 +104,11 @@ class CreateQos(command.ShowOne):
qos_spec = volume_client.qos_specs.create(parsed_args.name, specs) qos_spec = volume_client.qos_specs.create(parsed_args.name, specs)
qos_spec._info.update( 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())) return zip(*sorted(qos_spec._info.items()))
@ -117,7 +128,7 @@ class DeleteQos(command.Command):
'--force', '--force',
action='store_true', action='store_true',
default=False, default=False,
help=_("Allow to delete in-use QoS specification(s)") help=_("Allow to delete in-use QoS specification(s)"),
) )
return parser return parser
@ -131,14 +142,20 @@ class DeleteQos(command.Command):
volume_client.qos_specs.delete(qos_spec.id, parsed_args.force) volume_client.qos_specs.delete(qos_spec.id, parsed_args.force)
except Exception as e: except Exception as e:
result += 1 result += 1
LOG.error(_("Failed to delete QoS specification with " LOG.error(
"name or ID '%(qos)s': %(e)s") _(
% {'qos': i, 'e': e}) "Failed to delete QoS specification with "
"name or ID '%(qos)s': %(e)s"
)
% {'qos': i, 'e': e}
)
if result > 0: if result > 0:
total = len(parsed_args.qos_specs) total = len(parsed_args.qos_specs)
msg = (_("%(result)s of %(total)s QoS specifications failed" msg = _(
" to delete.") % {'result': result, 'total': total}) "%(result)s of %(total)s QoS specifications failed"
" to delete."
) % {'result': result, 'total': total}
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -169,12 +186,14 @@ class DisassociateQos(command.Command):
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs, qos_spec = utils.find_resource(
parsed_args.qos_spec) volume_client.qos_specs, parsed_args.qos_spec
)
if parsed_args.volume_type: if parsed_args.volume_type:
volume_type = utils.find_resource(volume_client.volume_types, volume_type = utils.find_resource(
parsed_args.volume_type) volume_client.volume_types, parsed_args.volume_type
)
volume_client.qos_specs.disassociate(qos_spec.id, volume_type.id) volume_client.qos_specs.disassociate(qos_spec.id, volume_type.id)
elif parsed_args.all: elif parsed_args.all:
volume_client.qos_specs.disassociate_all(qos_spec.id) volume_client.qos_specs.disassociate_all(qos_spec.id)
@ -204,17 +223,28 @@ class ListQos(command.Lister):
raise raise
display_columns = ( display_columns = (
'ID', 'Name', 'Consumer', 'Associations', 'Properties') 'ID',
'Name',
'Consumer',
'Associations',
'Properties',
)
columns = ('ID', 'Name', 'Consumer', 'Associations', 'Specs') columns = ('ID', 'Name', 'Consumer', 'Associations', 'Specs')
return (display_columns, return (
(utils.get_dict_properties( display_columns,
s._info, columns, (
utils.get_dict_properties(
s._info,
columns,
formatters={ formatters={
'Specs': format_columns.DictColumn, '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): class SetQos(command.Command):
@ -231,19 +261,21 @@ class SetQos(command.Command):
'--property', '--property',
metavar='<key=value>', metavar='<key=value>',
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_('Property to add or modify for this QoS specification ' help=_(
'(repeat option to set multiple properties)'), 'Property to add or modify for this QoS specification '
'(repeat option to set multiple properties)'
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs, qos_spec = utils.find_resource(
parsed_args.qos_spec) volume_client.qos_specs, parsed_args.qos_spec
)
if parsed_args.property: if parsed_args.property:
volume_client.qos_specs.set_keys(qos_spec.id, volume_client.qos_specs.set_keys(qos_spec.id, parsed_args.property)
parsed_args.property)
class ShowQos(command.ShowOne): class ShowQos(command.ShowOne):
@ -260,19 +292,25 @@ class ShowQos(command.ShowOne):
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs, qos_spec = utils.find_resource(
parsed_args.qos_spec) volume_client.qos_specs, parsed_args.qos_spec
)
qos_associations = volume_client.qos_specs.get_associations(qos_spec) qos_associations = volume_client.qos_specs.get_associations(qos_spec)
if qos_associations: if qos_associations:
associations = [association.name associations = [
for association in qos_associations] association.name for association in qos_associations
qos_spec._info.update({ ]
'associations': format_columns.ListColumn(associations) qos_spec._info.update(
}) {'associations': format_columns.ListColumn(associations)}
)
qos_spec._info.update( 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())) return zip(*sorted(qos_spec._info.items()))
@ -292,16 +330,20 @@ class UnsetQos(command.Command):
metavar='<key>', metavar='<key>',
action='append', action='append',
default=[], default=[],
help=_('Property to remove from the QoS specification. ' help=_(
'(repeat option to unset multiple properties)'), 'Property to remove from the QoS specification. '
'(repeat option to unset multiple properties)'
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
qos_spec = utils.find_resource(volume_client.qos_specs, qos_spec = utils.find_resource(
parsed_args.qos_spec) volume_client.qos_specs, parsed_args.qos_spec
)
if parsed_args.property: if parsed_args.property:
volume_client.qos_specs.unset_keys(qos_spec.id, volume_client.qos_specs.unset_keys(
parsed_args.property) qos_spec.id, parsed_args.property
)

View File

@ -29,18 +29,18 @@ class ListService(command.Lister):
parser.add_argument( parser.add_argument(
"--host", "--host",
metavar="<host>", metavar="<host>",
help=_("List services on specified host (name only)") help=_("List services on specified host (name only)"),
) )
parser.add_argument( parser.add_argument(
"--service", "--service",
metavar="<service>", metavar="<service>",
help=_("List only specified service (name only)") help=_("List only specified service (name only)"),
) )
parser.add_argument( parser.add_argument(
"--long", "--long",
action="store_true", action="store_true",
default=False, default=False,
help=_("List additional fields in output") help=_("List additional fields in output"),
) )
return parser return parser
@ -55,7 +55,7 @@ class ListService(command.Lister):
"Status", "Status",
"State", "State",
"Updated At", "Updated At",
"Disabled Reason" "Disabled Reason",
] ]
else: else:
columns = [ columns = [
@ -64,15 +64,22 @@ class ListService(command.Lister):
"Zone", "Zone",
"Status", "Status",
"State", "State",
"Updated At" "Updated At",
] ]
data = service_client.services.list(parsed_args.host, data = service_client.services.list(
parsed_args.service) parsed_args.host, parsed_args.service
return (columns, )
(utils.get_item_properties( return (
s, columns, columns,
) for s in data)) (
utils.get_item_properties(
s,
columns,
)
for s in data
),
)
class SetService(command.Command): class SetService(command.Command):
@ -80,51 +87,50 @@ class SetService(command.Command):
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super(SetService, self).get_parser(prog_name) parser = super(SetService, self).get_parser(prog_name)
parser.add_argument( parser.add_argument("host", metavar="<host>", help=_("Name of host"))
"host",
metavar="<host>",
help=_("Name of host")
)
parser.add_argument( parser.add_argument(
"service", "service",
metavar="<service>", metavar="<service>",
help=_("Name of service (Binary name)") help=_("Name of service (Binary name)"),
) )
enabled_group = parser.add_mutually_exclusive_group() enabled_group = parser.add_mutually_exclusive_group()
enabled_group.add_argument( enabled_group.add_argument(
"--enable", "--enable", action="store_true", help=_("Enable volume service")
action="store_true",
help=_("Enable volume service")
) )
enabled_group.add_argument( enabled_group.add_argument(
"--disable", "--disable", action="store_true", help=_("Disable volume service")
action="store_true",
help=_("Disable volume service")
) )
parser.add_argument( parser.add_argument(
"--disable-reason", "--disable-reason",
metavar="<reason>", metavar="<reason>",
help=_("Reason for disabling the service " help=_(
"(should be used with --disable option)") "Reason for disabling the service "
"(should be used with --disable option)"
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
if parsed_args.disable_reason and not parsed_args.disable: if parsed_args.disable_reason and not parsed_args.disable:
msg = _("Cannot specify option --disable-reason without " msg = _(
"--disable specified.") "Cannot specify option --disable-reason without "
"--disable specified."
)
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
service_client = self.app.client_manager.volume service_client = self.app.client_manager.volume
if parsed_args.enable: if parsed_args.enable:
service_client.services.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:
if parsed_args.disable_reason: if parsed_args.disable_reason:
service_client.services.disable_log_reason( service_client.services.disable_log_reason(
parsed_args.host, parsed_args.host,
parsed_args.service, parsed_args.service,
parsed_args.disable_reason) parsed_args.disable_reason,
)
else: else:
service_client.services.disable( service_client.services.disable(
parsed_args.host, parsed_args.service) parsed_args.host, parsed_args.service
)

View File

@ -71,10 +71,13 @@ def _check_size_arg(args):
volume is not specified. volume is not specified.
""" """
if ((args.snapshot or args.source or args.backup) if (
is None and args.size is None): args.snapshot or args.source or args.backup
msg = _("--size is a required option if snapshot, backup " ) is None and args.size is None:
"or source volume are not specified.") msg = _(
"--size is a required option if snapshot, backup "
"or source volume are not specified."
)
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -93,8 +96,10 @@ class CreateVolume(command.ShowOne):
"--size", "--size",
metavar="<size>", metavar="<size>",
type=int, type=int,
help=_("Volume size in GB (required unless --snapshot, " help=_(
"--source or --backup is specified)"), "Volume size in GB (required unless --snapshot, "
"--source or --backup is specified)"
),
) )
parser.add_argument( parser.add_argument(
"--type", "--type",
@ -120,8 +125,10 @@ class CreateVolume(command.ShowOne):
source_group.add_argument( source_group.add_argument(
"--backup", "--backup",
metavar="<backup>", metavar="<backup>",
help=_("Restore backup to a volume (name or ID) " help=_(
"(supported by --os-volume-api-version 3.47 or later)"), "Restore backup to a volume (name or ID) "
"(supported by --os-volume-api-version 3.47 or later)"
),
) )
source_group.add_argument( source_group.add_argument(
"--source-replicated", "--source-replicated",
@ -147,37 +154,41 @@ class CreateVolume(command.ShowOne):
"--property", "--property",
metavar="<key=value>", metavar="<key=value>",
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_("Set a property to this volume " help=_(
"(repeat option to set multiple properties)"), "Set a property to this volume "
"(repeat option to set multiple properties)"
),
) )
parser.add_argument( parser.add_argument(
"--hint", "--hint",
metavar="<key=value>", metavar="<key=value>",
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_("Arbitrary scheduler hint key-value pairs to help boot " help=_(
"an instance (repeat option to set multiple hints)"), "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 = parser.add_mutually_exclusive_group()
bootable_group.add_argument( bootable_group.add_argument(
"--bootable", "--bootable",
action="store_true", action="store_true",
help=_("Mark volume as bootable") help=_("Mark volume as bootable"),
) )
bootable_group.add_argument( bootable_group.add_argument(
"--non-bootable", "--non-bootable",
action="store_true", 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 = parser.add_mutually_exclusive_group()
readonly_group.add_argument( readonly_group.add_argument(
"--read-only", "--read-only",
action="store_true", action="store_true",
help=_("Set volume to read-only access mode") help=_("Set volume to read-only access mode"),
) )
readonly_group.add_argument( readonly_group.add_argument(
"--read-write", "--read-write",
action="store_true", action="store_true",
help=_("Set volume to read-write access mode (default)") help=_("Set volume to read-write access mode (default)"),
) )
return parser return parser
@ -193,35 +204,39 @@ class CreateVolume(command.ShowOne):
image_client = self.app.client_manager.image image_client = self.app.client_manager.image
if parsed_args.backup and not ( if parsed_args.backup and not (
volume_client.api_version.matches('3.47')): volume_client.api_version.matches('3.47')
msg = _("--os-volume-api-version 3.47 or greater is required " ):
"to create a volume from backup.") msg = _(
"--os-volume-api-version 3.47 or greater is required "
"to create a volume from backup."
)
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
source_volume = None source_volume = None
if parsed_args.source: if parsed_args.source:
source_volume_obj = utils.find_resource( source_volume_obj = utils.find_resource(
volume_client.volumes, volume_client.volumes, parsed_args.source
parsed_args.source) )
source_volume = source_volume_obj.id source_volume = source_volume_obj.id
size = max(size or 0, source_volume_obj.size) size = max(size or 0, source_volume_obj.size)
consistency_group = None consistency_group = None
if parsed_args.consistency_group: if parsed_args.consistency_group:
consistency_group = utils.find_resource( consistency_group = utils.find_resource(
volume_client.consistencygroups, volume_client.consistencygroups, parsed_args.consistency_group
parsed_args.consistency_group).id ).id
image = None image = None
if parsed_args.image: if parsed_args.image:
image = image_client.find_image(parsed_args.image, image = image_client.find_image(
ignore_missing=False).id parsed_args.image, ignore_missing=False
).id
snapshot = None snapshot = None
if parsed_args.snapshot: if parsed_args.snapshot:
snapshot_obj = utils.find_resource( snapshot_obj = utils.find_resource(
volume_client.volume_snapshots, volume_client.volume_snapshots, parsed_args.snapshot
parsed_args.snapshot) )
snapshot = snapshot_obj.id snapshot = snapshot_obj.id
# Cinder requires a value for size when creating a volume # Cinder requires a value for size when creating a volume
# even if creating from a snapshot. Cinder will create the # even if creating from a snapshot. Cinder will create the
@ -234,8 +249,8 @@ class CreateVolume(command.ShowOne):
backup = None backup = None
if parsed_args.backup: if parsed_args.backup:
backup_obj = utils.find_resource( backup_obj = utils.find_resource(
volume_client.backups, volume_client.backups, parsed_args.backup
parsed_args.backup) )
backup = backup_obj.id backup = backup_obj.id
# As above # As above
size = max(size or 0, backup_obj.size) size = max(size or 0, backup_obj.size)
@ -262,11 +277,10 @@ class CreateVolume(command.ShowOne):
volume.id, volume.id,
success_status=['available'], success_status=['available'],
error_status=['error'], error_status=['error'],
sleep_time=1 sleep_time=1,
): ):
volume_client.volumes.set_bootable( volume_client.volumes.set_bootable(
volume.id, volume.id, parsed_args.bootable
parsed_args.bootable
) )
else: else:
msg = _( msg = _(
@ -283,11 +297,10 @@ class CreateVolume(command.ShowOne):
volume.id, volume.id,
success_status=['available'], success_status=['available'],
error_status=['error'], error_status=['error'],
sleep_time=1 sleep_time=1,
): ):
volume_client.volumes.update_readonly_flag( volume_client.volumes.update_readonly_flag(
volume.id, volume.id, parsed_args.read_only
parsed_args.read_only
) )
else: else:
msg = _( msg = _(
@ -296,15 +309,21 @@ class CreateVolume(command.ShowOne):
) )
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set volume read-only access " LOG.error(
"mode flag: %s"), e) _(
"Failed to set volume read-only access "
"mode flag: %s"
),
e,
)
# Remove key links from being displayed # Remove key links from being displayed
volume._info.update( volume._info.update(
{ {
'properties': 'properties': format_columns.DictColumn(
format_columns.DictColumn(volume._info.pop('metadata')), volume._info.pop('metadata')
'type': volume._info.pop('volume_type') ),
'type': volume._info.pop('volume_type'),
} }
) )
volume._info.pop("links", None) volume._info.pop("links", None)
@ -320,20 +339,24 @@ class DeleteVolume(command.Command):
"volumes", "volumes",
metavar="<volume>", metavar="<volume>",
nargs="+", nargs="+",
help=_("Volume(s) to delete (name or ID)") help=_("Volume(s) to delete (name or ID)"),
) )
group = parser.add_mutually_exclusive_group() group = parser.add_mutually_exclusive_group()
group.add_argument( group.add_argument(
"--force", "--force",
action="store_true", action="store_true",
help=_("Attempt forced removal of volume(s), regardless of state " help=_(
"(defaults to False)") "Attempt forced removal of volume(s), regardless of state "
"(defaults to False)"
),
) )
group.add_argument( group.add_argument(
"--purge", "--purge",
action="store_true", action="store_true",
help=_("Remove any snapshots along with volume(s) " help=_(
"(defaults to False)") "Remove any snapshots along with volume(s) "
"(defaults to False)"
),
) )
return parser return parser
@ -343,23 +366,29 @@ class DeleteVolume(command.Command):
for i in parsed_args.volumes: for i in parsed_args.volumes:
try: try:
volume_obj = utils.find_resource( volume_obj = utils.find_resource(volume_client.volumes, i)
volume_client.volumes, i)
if parsed_args.force: if parsed_args.force:
volume_client.volumes.force_delete(volume_obj.id) volume_client.volumes.force_delete(volume_obj.id)
else: else:
volume_client.volumes.delete(volume_obj.id, volume_client.volumes.delete(
cascade=parsed_args.purge) volume_obj.id, cascade=parsed_args.purge
)
except Exception as e: except Exception as e:
result += 1 result += 1
LOG.error(_("Failed to delete volume with " LOG.error(
"name or ID '%(volume)s': %(e)s"), _(
{'volume': i, 'e': e}) "Failed to delete volume with "
"name or ID '%(volume)s': %(e)s"
),
{'volume': i, 'e': e},
)
if result > 0: if result > 0:
total = len(parsed_args.volumes) total = len(parsed_args.volumes)
msg = (_("%(result)s of %(total)s volumes failed " msg = _("%(result)s of %(total)s volumes failed " "to delete.") % {
"to delete.") % {'result': result, 'total': total}) 'result': result,
'total': total,
}
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -371,13 +400,13 @@ class ListVolume(command.Lister):
parser.add_argument( parser.add_argument(
'--project', '--project',
metavar='<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) identity_common.add_project_domain_option_to_parser(parser)
parser.add_argument( parser.add_argument(
'--user', '--user',
metavar='<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) identity_common.add_user_domain_option_to_parser(parser)
parser.add_argument( parser.add_argument(
@ -417,7 +446,6 @@ class ListVolume(command.Lister):
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
identity_client = self.app.client_manager.identity identity_client = self.app.client_manager.identity
@ -457,20 +485,22 @@ class ListVolume(command.Lister):
# Just forget it if there's any trouble # Just forget it if there's any trouble
pass pass
AttachmentsColumnWithCache = functools.partial( AttachmentsColumnWithCache = functools.partial(
AttachmentsColumn, server_cache=server_cache) AttachmentsColumn, server_cache=server_cache
)
project_id = None project_id = None
if parsed_args.project: if parsed_args.project:
project_id = identity_common.find_project( project_id = identity_common.find_project(
identity_client, identity_client,
parsed_args.project, parsed_args.project,
parsed_args.project_domain).id parsed_args.project_domain,
).id
user_id = None user_id = None
if parsed_args.user: if parsed_args.user:
user_id = identity_common.find_user(identity_client, user_id = identity_common.find_user(
parsed_args.user, identity_client, parsed_args.user, parsed_args.user_domain
parsed_args.user_domain).id ).id
# set value of 'all_tenants' when using project option # set value of 'all_tenants' when using project option
all_projects = bool(parsed_args.project) or parsed_args.all_projects all_projects = bool(parsed_args.project) or parsed_args.all_projects
@ -489,14 +519,23 @@ class ListVolume(command.Lister):
limit=parsed_args.limit, limit=parsed_args.limit,
) )
column_headers = utils.backward_compat_col_lister( 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, return (
(utils.get_item_properties( column_headers,
s, columns, (
formatters={'Metadata': format_columns.DictColumn, utils.get_item_properties(
'Attachments': AttachmentsColumnWithCache}, s,
) for s in data)) columns,
formatters={
'Metadata': format_columns.DictColumn,
'Attachments': AttachmentsColumnWithCache,
},
)
for s in data
),
)
class MigrateVolume(command.Command): class MigrateVolume(command.Command):
@ -507,35 +546,44 @@ class MigrateVolume(command.Command):
parser.add_argument( parser.add_argument(
'volume', 'volume',
metavar="<volume>", metavar="<volume>",
help=_("Volume to migrate (name or ID)") help=_("Volume to migrate (name or ID)"),
) )
parser.add_argument( parser.add_argument(
'--host', '--host',
metavar="<host>", metavar="<host>",
required=True, 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( parser.add_argument(
'--force-host-copy', '--force-host-copy',
action="store_true", action="store_true",
help=_("Enable generic host-based force-migration, " help=_(
"which bypasses driver optimizations") "Enable generic host-based force-migration, "
"which bypasses driver optimizations"
),
) )
parser.add_argument( parser.add_argument(
'--lock-volume', '--lock-volume',
action="store_true", action="store_true",
help=_("If specified, the volume state will be locked " help=_(
"and will not allow a migration to be aborted " "If specified, the volume state will be locked "
"(possibly by another operation)") "and will not allow a migration to be aborted "
"(possibly by another operation)"
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume 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)
volume_client.volumes.migrate_volume(volume.id, parsed_args.host, volume_client.volumes.migrate_volume(
parsed_args.force_host_copy, volume.id,
parsed_args.lock_volume,) parsed_args.host,
parsed_args.force_host_copy,
parsed_args.lock_volume,
)
class SetVolume(command.Command): class SetVolume(command.Command):
@ -568,56 +616,76 @@ class SetVolume(command.Command):
"--no-property", "--no-property",
dest="no_property", dest="no_property",
action="store_true", action="store_true",
help=_("Remove all properties from <volume> " help=_(
"(specify both --no-property and --property to " "Remove all properties from <volume> "
"remove the current properties before setting " "(specify both --no-property and --property to "
"new properties.)"), "remove the current properties before setting "
"new properties.)"
),
) )
parser.add_argument( parser.add_argument(
'--property', '--property',
metavar='<key=value>', metavar='<key=value>',
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_('Set a property on this volume ' help=_(
'(repeat option to set multiple properties)'), 'Set a property on this volume '
'(repeat option to set multiple properties)'
),
) )
parser.add_argument( parser.add_argument(
'--image-property', '--image-property',
metavar='<key=value>', metavar='<key=value>',
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_('Set an image property on this volume ' help=_(
'(repeat option to set multiple image properties)'), 'Set an image property on this volume '
'(repeat option to set multiple image properties)'
),
) )
parser.add_argument( parser.add_argument(
"--state", "--state",
metavar="<state>", metavar="<state>",
choices=['available', 'error', 'creating', 'deleting', choices=[
'in-use', 'attaching', 'detaching', 'error_deleting', 'available',
'maintenance'], 'error',
help=_('New volume state ("available", "error", "creating", ' 'creating',
'"deleting", "in-use", "attaching", "detaching", ' 'deleting',
'"error_deleting" or "maintenance") (admin only) ' 'in-use',
'(This option simply changes the state of the volume ' 'attaching',
'in the database with no regard to actual status, ' 'detaching',
'exercise caution when using)'), '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 = parser.add_mutually_exclusive_group()
attached_group.add_argument( attached_group.add_argument(
"--attached", "--attached",
action="store_true", action="store_true",
help=_('Set volume attachment status to "attached" ' help=_(
'(admin only) ' 'Set volume attachment status to "attached" '
'(This option simply changes the state of the volume ' '(admin only) '
'in the database with no regard to actual status, ' '(This option simply changes the state of the volume '
'exercise caution when using)'), 'in the database with no regard to actual status, '
'exercise caution when using)'
),
) )
attached_group.add_argument( attached_group.add_argument(
"--detached", "--detached",
action="store_true", action="store_true",
help=_('Set volume attachment status to "detached" ' help=_(
'(admin only) ' 'Set volume attachment status to "detached" '
'(This option simply changes the state of the volume ' '(admin only) '
'in the database with no regard to actual status, ' '(This option simply changes the state of the volume '
'exercise caution when using)'), 'in the database with no regard to actual status, '
'exercise caution when using)'
),
) )
parser.add_argument( parser.add_argument(
'--type', '--type',
@ -628,31 +696,33 @@ class SetVolume(command.Command):
'--retype-policy', '--retype-policy',
metavar='<retype-policy>', metavar='<retype-policy>',
choices=['never', 'on-demand'], choices=['never', 'on-demand'],
help=_('Migration policy while re-typing volume ' help=_(
'("never" or "on-demand", default is "never" ) ' 'Migration policy while re-typing volume '
'(available only when --type option is specified)'), '("never" or "on-demand", default is "never" ) '
'(available only when --type option is specified)'
),
) )
bootable_group = parser.add_mutually_exclusive_group() bootable_group = parser.add_mutually_exclusive_group()
bootable_group.add_argument( bootable_group.add_argument(
"--bootable", "--bootable",
action="store_true", action="store_true",
help=_("Mark volume as bootable") help=_("Mark volume as bootable"),
) )
bootable_group.add_argument( bootable_group.add_argument(
"--non-bootable", "--non-bootable",
action="store_true", action="store_true",
help=_("Mark volume as non-bootable") help=_("Mark volume as non-bootable"),
) )
readonly_group = parser.add_mutually_exclusive_group() readonly_group = parser.add_mutually_exclusive_group()
readonly_group.add_argument( readonly_group.add_argument(
"--read-only", "--read-only",
action="store_true", action="store_true",
help=_("Set volume to read-only access mode") help=_("Set volume to read-only access mode"),
) )
readonly_group.add_argument( readonly_group.add_argument(
"--read-write", "--read-write",
action="store_true", action="store_true",
help=_("Set volume to read-write access mode") help=_("Set volume to read-write access mode"),
) )
return parser return parser
@ -664,14 +734,21 @@ class SetVolume(command.Command):
if parsed_args.size: if parsed_args.size:
try: try:
if parsed_args.size <= volume.size: if parsed_args.size <= volume.size:
msg = (_("New size must be greater than %s GB") msg = (
% volume.size) _("New size must be greater than %s GB") % volume.size
)
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
if volume.status != 'available' and \ if (
not volume_client.api_version.matches('3.42'): 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) msg = (
_(
"Volume is in %s state, it must be available "
"before size can be extended"
)
% volume.status
)
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
volume_client.volumes.extend(volume.id, parsed_args.size) volume_client.volumes.extend(volume.id, parsed_args.size)
except Exception as e: except Exception as e:
@ -681,7 +758,8 @@ class SetVolume(command.Command):
if parsed_args.no_property: if parsed_args.no_property:
try: try:
volume_client.volumes.delete_metadata( volume_client.volumes.delete_metadata(
volume.id, volume.metadata.keys()) volume.id, volume.metadata.keys()
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to clean volume properties: %s"), e) LOG.error(_("Failed to clean volume properties: %s"), e)
result += 1 result += 1
@ -689,55 +767,62 @@ class SetVolume(command.Command):
if parsed_args.property: if parsed_args.property:
try: try:
volume_client.volumes.set_metadata( volume_client.volumes.set_metadata(
volume.id, parsed_args.property) volume.id, parsed_args.property
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set volume property: %s"), e) LOG.error(_("Failed to set volume property: %s"), e)
result += 1 result += 1
if parsed_args.image_property: if parsed_args.image_property:
try: try:
volume_client.volumes.set_image_metadata( volume_client.volumes.set_image_metadata(
volume.id, parsed_args.image_property) volume.id, parsed_args.image_property
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set image property: %s"), e) LOG.error(_("Failed to set image property: %s"), e)
result += 1 result += 1
if parsed_args.state: if parsed_args.state:
try: try:
volume_client.volumes.reset_state( volume_client.volumes.reset_state(volume.id, parsed_args.state)
volume.id, parsed_args.state)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set volume state: %s"), e) LOG.error(_("Failed to set volume state: %s"), e)
result += 1 result += 1
if parsed_args.attached: if parsed_args.attached:
try: try:
volume_client.volumes.reset_state( volume_client.volumes.reset_state(
volume.id, state=None, volume.id, state=None, attach_status="attached"
attach_status="attached") )
except Exception as e: except Exception as e:
LOG.error(_("Failed to set volume attach-status: %s"), e) LOG.error(_("Failed to set volume attach-status: %s"), e)
result += 1 result += 1
if parsed_args.detached: if parsed_args.detached:
try: try:
volume_client.volumes.reset_state( volume_client.volumes.reset_state(
volume.id, state=None, volume.id, state=None, attach_status="detached"
attach_status="detached") )
except Exception as e: except Exception as e:
LOG.error(_("Failed to set volume attach-status: %s"), e) LOG.error(_("Failed to set volume attach-status: %s"), e)
result += 1 result += 1
if parsed_args.bootable or parsed_args.non_bootable: if parsed_args.bootable or parsed_args.non_bootable:
try: try:
volume_client.volumes.set_bootable( volume_client.volumes.set_bootable(
volume.id, parsed_args.bootable) volume.id, parsed_args.bootable
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set volume bootable property: %s"), e) LOG.error(_("Failed to set volume bootable property: %s"), e)
result += 1 result += 1
if parsed_args.read_only or parsed_args.read_write: if parsed_args.read_only or parsed_args.read_write:
try: try:
volume_client.volumes.update_readonly_flag( volume_client.volumes.update_readonly_flag(
volume.id, volume.id, parsed_args.read_only
parsed_args.read_only) )
except Exception as e: except Exception as e:
LOG.error(_("Failed to set volume read-only access " LOG.error(
"mode flag: %s"), e) _(
"Failed to set volume read-only access "
"mode flag: %s"
),
e,
)
result += 1 result += 1
if parsed_args.type: if parsed_args.type:
# get the migration policy # get the migration policy
@ -747,20 +832,23 @@ class SetVolume(command.Command):
try: try:
# find the volume type # find the volume type
volume_type = utils.find_resource( volume_type = utils.find_resource(
volume_client.volume_types, volume_client.volume_types, parsed_args.type
parsed_args.type) )
# reset to the new volume type # reset to the new volume type
volume_client.volumes.retype( volume_client.volumes.retype(
volume.id, volume.id, volume_type.id, migration_policy
volume_type.id, )
migration_policy)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set volume type: %s"), e) LOG.error(_("Failed to set volume type: %s"), e)
result += 1 result += 1
elif parsed_args.retype_policy: elif parsed_args.retype_policy:
# If the "--retype-policy" is specified without "--type" # If the "--retype-policy" is specified without "--type"
LOG.warning(_("'--retype-policy' option will not work " LOG.warning(
"without '--type' option")) _(
"'--retype-policy' option will not work "
"without '--type' option"
)
)
kwargs = {} kwargs = {}
if parsed_args.name: if parsed_args.name:
@ -771,13 +859,19 @@ class SetVolume(command.Command):
try: try:
volume_client.volumes.update(volume.id, **kwargs) volume_client.volumes.update(volume.id, **kwargs)
except Exception as e: except Exception as e:
LOG.error(_("Failed to update volume display name " LOG.error(
"or display description: %s"), e) _(
"Failed to update volume display name "
"or display description: %s"
),
e,
)
result += 1 result += 1
if result > 0: if result > 0:
raise exceptions.CommandError(_("One or more of the " raise exceptions.CommandError(
"set operations failed")) _("One or more of the " "set operations failed")
)
class ShowVolume(command.ShowOne): class ShowVolume(command.ShowOne):
@ -788,7 +882,7 @@ class ShowVolume(command.ShowOne):
parser.add_argument( parser.add_argument(
'volume', 'volume',
metavar="<volume>", metavar="<volume>",
help=_("Volume to display (name or ID)") help=_("Volume to display (name or ID)"),
) )
return parser return parser
@ -801,8 +895,9 @@ class ShowVolume(command.ShowOne):
# 'volume_type' --> 'type' # 'volume_type' --> 'type'
volume._info.update( volume._info.update(
{ {
'properties': 'properties': format_columns.DictColumn(
format_columns.DictColumn(volume._info.pop('metadata')), volume._info.pop('metadata')
),
'type': volume._info.pop('volume_type'), 'type': volume._info.pop('volume_type'),
}, },
) )
@ -826,28 +921,32 @@ class UnsetVolume(command.Command):
'--property', '--property',
metavar='<key>', metavar='<key>',
action='append', action='append',
help=_('Remove a property from volume ' help=_(
'(repeat option to remove multiple properties)'), 'Remove a property from volume '
'(repeat option to remove multiple properties)'
),
) )
parser.add_argument( parser.add_argument(
'--image-property', '--image-property',
metavar='<key>', metavar='<key>',
action='append', action='append',
help=_('Remove an image property from volume ' help=_(
'(repeat option to remove multiple image properties)'), 'Remove an image property from volume '
'(repeat option to remove multiple image properties)'
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
volume = utils.find_resource( volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
volume_client.volumes, parsed_args.volume)
result = 0 result = 0
if parsed_args.property: if parsed_args.property:
try: try:
volume_client.volumes.delete_metadata( volume_client.volumes.delete_metadata(
volume.id, parsed_args.property) volume.id, parsed_args.property
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to unset volume property: %s"), e) LOG.error(_("Failed to unset volume property: %s"), e)
result += 1 result += 1
@ -855,11 +954,13 @@ class UnsetVolume(command.Command):
if parsed_args.image_property: if parsed_args.image_property:
try: try:
volume_client.volumes.delete_image_metadata( volume_client.volumes.delete_image_metadata(
volume.id, parsed_args.image_property) volume.id, parsed_args.image_property
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to unset image property: %s"), e) LOG.error(_("Failed to unset image property: %s"), e)
result += 1 result += 1
if result > 0: if result > 0:
raise exceptions.CommandError(_("One or more of the " raise exceptions.CommandError(
"unset operations failed")) _("One or more of the " "unset operations failed")
)

View File

@ -28,7 +28,7 @@ class ShowCapability(command.Lister):
parser.add_argument( parser.add_argument(
"host", "host",
metavar="<host>", metavar="<host>",
help=_("List capabilities of specified host (host@backend-name)") help=_("List capabilities of specified host (host@backend-name)"),
) )
return parser return parser
@ -55,10 +55,16 @@ class ShowCapability(command.Lister):
capability_data['key'] = key capability_data['key'] = key
print_data.append(capability_data) print_data.append(capability_data)
return (columns, return (
(utils.get_dict_properties( columns,
s, columns, (
) for s in print_data)) utils.get_dict_properties(
s,
columns,
)
for s in print_data
),
)
class ListPool(command.Lister): class ListPool(command.Lister):
@ -70,7 +76,7 @@ class ListPool(command.Lister):
"--long", "--long",
action="store_true", action="store_true",
default=False, 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 # TODO(smcginnis): Starting with Cinder microversion 3.33, user is also
# able to pass in --filters with a <key>=<value> pair to filter on. # able to pass in --filters with a <key>=<value> pair to filter on.
@ -98,7 +104,7 @@ class ListPool(command.Lister):
'Volumes', 'Volumes',
'Capacity', 'Capacity',
'Allocated', 'Allocated',
'Max Over Ratio' 'Max Over Ratio',
] ]
else: else:
columns = [ columns = [
@ -107,7 +113,13 @@ class ListPool(command.Lister):
headers = columns headers = columns
data = volume_client.pools.list(detailed=parsed_args.long) data = volume_client.pools.list(detailed=parsed_args.long)
return (headers, return (
(utils.get_item_properties( headers,
s, columns, (
) for s in data)) utils.get_item_properties(
s,
columns,
)
for s in data
),
)

View File

@ -66,44 +66,42 @@ class CreateVolumeBackup(command.ShowOne):
parser.add_argument( parser.add_argument(
"volume", "volume",
metavar="<volume>", metavar="<volume>",
help=_("Volume to backup (name or ID)") help=_("Volume to backup (name or ID)"),
) )
parser.add_argument( parser.add_argument(
"--name", "--name", metavar="<name>", help=_("Name of the backup")
metavar="<name>",
help=_("Name of the backup")
) )
parser.add_argument( parser.add_argument(
"--description", "--description",
metavar="<description>", metavar="<description>",
help=_("Description of the backup") help=_("Description of the backup"),
) )
parser.add_argument( parser.add_argument(
"--container", "--container",
metavar="<container>", metavar="<container>",
help=_("Optional backup container name") help=_("Optional backup container name"),
) )
parser.add_argument( parser.add_argument(
"--snapshot", "--snapshot",
metavar="<snapshot>", metavar="<snapshot>",
help=_("Snapshot to backup (name or ID)") help=_("Snapshot to backup (name or ID)"),
) )
parser.add_argument( parser.add_argument(
'--force', '--force',
action='store_true', action='store_true',
default=False, default=False,
help=_("Allow to back up an in-use volume") help=_("Allow to back up an in-use volume"),
) )
parser.add_argument( parser.add_argument(
'--incremental', '--incremental',
action='store_true', action='store_true',
default=False, default=False,
help=_("Perform an incremental backup") help=_("Perform an incremental backup"),
) )
parser.add_argument( parser.add_argument(
'--no-incremental', '--no-incremental',
action='store_false', action='store_false',
help=_("Do not perform an incremental backup") help=_("Do not perform an incremental backup"),
) )
parser.add_argument( parser.add_argument(
'--property', '--property',
@ -131,14 +129,16 @@ class CreateVolumeBackup(command.ShowOne):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
volume_id = utils.find_resource( volume_id = utils.find_resource(
volume_client.volumes, parsed_args.volume, volume_client.volumes,
parsed_args.volume,
).id ).id
kwargs = {} kwargs = {}
if parsed_args.snapshot: if parsed_args.snapshot:
kwargs['snapshot_id'] = utils.find_resource( kwargs['snapshot_id'] = utils.find_resource(
volume_client.volume_snapshots, parsed_args.snapshot, volume_client.volume_snapshots,
parsed_args.snapshot,
).id ).id
if parsed_args.properties: if parsed_args.properties:
@ -183,13 +183,13 @@ class DeleteVolumeBackup(command.Command):
"backups", "backups",
metavar="<backup>", metavar="<backup>",
nargs="+", nargs="+",
help=_("Backup(s) to delete (name or ID)") help=_("Backup(s) to delete (name or ID)"),
) )
parser.add_argument( parser.add_argument(
'--force', '--force',
action='store_true', action='store_true',
default=False, default=False,
help=_("Allow delete in state other than error or available") help=_("Allow delete in state other than error or available"),
) )
return parser return parser
@ -200,19 +200,25 @@ class DeleteVolumeBackup(command.Command):
for i in parsed_args.backups: for i in parsed_args.backups:
try: try:
backup_id = utils.find_resource( backup_id = utils.find_resource(
volume_client.backups, i, volume_client.backups,
i,
).id ).id
volume_client.backups.delete(backup_id, parsed_args.force) volume_client.backups.delete(backup_id, parsed_args.force)
except Exception as e: except Exception as e:
result += 1 result += 1
LOG.error(_("Failed to delete backup with " LOG.error(
"name or ID '%(backup)s': %(e)s") _(
% {'backup': i, 'e': e}) "Failed to delete backup with "
"name or ID '%(backup)s': %(e)s"
)
% {'backup': i, 'e': e}
)
if result > 0: if result > 0:
total = len(parsed_args.backups) total = len(parsed_args.backups)
msg = _("%(result)s of %(total)s backups failed to delete.") % { msg = _("%(result)s of %(total)s backups failed to delete.") % {
'result': result, 'total': total, 'result': result,
'total': total,
} }
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -226,19 +232,23 @@ class ListVolumeBackup(command.Lister):
"--long", "--long",
action="store_true", action="store_true",
default=False, default=False,
help=_("List additional fields in output") help=_("List additional fields in output"),
) )
parser.add_argument( parser.add_argument(
"--name", "--name",
metavar="<name>", metavar="<name>",
help=_("Filters results by the backup name") help=_("Filters results by the backup name"),
) )
parser.add_argument( parser.add_argument(
"--status", "--status",
metavar="<status>", metavar="<status>",
choices=[ choices=[
'creating', 'available', 'deleting', 'creating',
'error', 'restoring', 'error_restoring', 'available',
'deleting',
'error',
'restoring',
'error_restoring',
], ],
help=_( help=_(
"Filters results by the backup status, one of: " "Filters results by the backup status, one of: "
@ -306,26 +316,31 @@ class ListVolumeBackup(command.Lister):
pass pass
_VolumeIdColumn = functools.partial( _VolumeIdColumn = functools.partial(
VolumeIdColumn, volume_cache=volume_cache) VolumeIdColumn, volume_cache=volume_cache
)
filter_volume_id = None filter_volume_id = None
if parsed_args.volume: if parsed_args.volume:
try: try:
filter_volume_id = utils.find_resource( filter_volume_id = utils.find_resource(
volume_client.volumes, parsed_args.volume, volume_client.volumes,
parsed_args.volume,
).id ).id
except exceptions.CommandError: except exceptions.CommandError:
# Volume with that ID does not exist, but search for backups # Volume with that ID does not exist, but search for backups
# for that volume nevertheless # for that volume nevertheless
LOG.debug("No volume with ID %s existing, continuing to " LOG.debug(
"search for backups for that volume ID", "No volume with ID %s existing, continuing to "
parsed_args.volume) "search for backups for that volume ID",
parsed_args.volume,
)
filter_volume_id = parsed_args.volume filter_volume_id = parsed_args.volume
marker_backup_id = None marker_backup_id = None
if parsed_args.marker: if parsed_args.marker:
marker_backup_id = utils.find_resource( marker_backup_id = utils.find_resource(
volume_client.backups, parsed_args.marker, volume_client.backups,
parsed_args.marker,
).id ).id
search_opts = { search_opts = {
@ -344,8 +359,11 @@ class ListVolumeBackup(command.Lister):
column_headers, column_headers,
( (
utils.get_item_properties( utils.get_item_properties(
s, columns, formatters={'volume_id': _VolumeIdColumn}, s,
) for s in data columns,
formatters={'volume_id': _VolumeIdColumn},
)
for s in data
), ),
) )
@ -358,7 +376,7 @@ class RestoreVolumeBackup(command.ShowOne):
parser.add_argument( parser.add_argument(
"backup", "backup",
metavar="<backup>", metavar="<backup>",
help=_("Backup to restore (name or ID)") help=_("Backup to restore (name or ID)"),
) )
parser.add_argument( parser.add_argument(
"volume", "volume",
@ -368,7 +386,7 @@ class RestoreVolumeBackup(command.ShowOne):
"Volume to restore to " "Volume to restore to "
"(name or ID for existing volume, name only for new volume) " "(name or ID for existing volume, name only for new volume) "
"(default to None)" "(default to None)"
) ),
) )
parser.add_argument( parser.add_argument(
"--force", "--force",
@ -376,7 +394,7 @@ class RestoreVolumeBackup(command.ShowOne):
help=_( help=_(
"Restore the backup to an existing volume " "Restore the backup to an existing volume "
"(default to False)" "(default to False)"
) ),
) )
return parser return parser
@ -401,11 +419,13 @@ class RestoreVolumeBackup(command.ShowOne):
msg = _( msg = _(
"Volume '%s' already exists; if you want to restore the " "Volume '%s' already exists; if you want to restore the "
"backup to it you need to specify the '--force' option" "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( 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( parser.add_argument(
"backup", "backup",
metavar="<backup>", metavar="<backup>",
help=_("Backup to modify (name or ID)") help=_("Backup to modify (name or ID)"),
) )
parser.add_argument( parser.add_argument(
'--name', '--name',
@ -471,14 +491,12 @@ class SetVolumeBackup(command.Command):
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
backup = utils.find_resource( backup = utils.find_resource(volume_client.backups, parsed_args.backup)
volume_client.backups, parsed_args.backup)
result = 0 result = 0
if parsed_args.state: if parsed_args.state:
try: try:
volume_client.backups.reset_state( volume_client.backups.reset_state(backup.id, parsed_args.state)
backup.id, parsed_args.state)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set backup state: %s"), e) LOG.error(_("Failed to set backup state: %s"), e)
result += 1 result += 1
@ -553,7 +571,7 @@ class UnsetVolumeBackup(command.Command):
parser.add_argument( parser.add_argument(
'backup', 'backup',
metavar='<backup>', metavar='<backup>',
help=_('Backup to modify (name or ID)') help=_('Backup to modify (name or ID)'),
) )
parser.add_argument( parser.add_argument(
'--property', '--property',
@ -577,8 +595,7 @@ class UnsetVolumeBackup(command.Command):
) )
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
backup = utils.find_resource( backup = utils.find_resource(volume_client.backups, parsed_args.backup)
volume_client.backups, parsed_args.backup)
metadata = copy.deepcopy(backup.metadata) metadata = copy.deepcopy(backup.metadata)
for key in parsed_args.properties: for key in parsed_args.properties:
@ -586,7 +603,8 @@ class UnsetVolumeBackup(command.Command):
# ignore invalid properties but continue # ignore invalid properties but continue
LOG.warning( LOG.warning(
"'%s' is not a valid property for backup '%s'", "'%s' is not a valid property for backup '%s'",
key, parsed_args.backup, key,
parsed_args.backup,
) )
continue continue
@ -607,13 +625,12 @@ class ShowVolumeBackup(command.ShowOne):
parser.add_argument( parser.add_argument(
"backup", "backup",
metavar="<backup>", metavar="<backup>",
help=_("Backup to display (name or ID)") help=_("Backup to display (name or ID)"),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
backup = utils.find_resource(volume_client.backups, backup = utils.find_resource(volume_client.backups, parsed_args.backup)
parsed_args.backup)
backup._info.pop("links", None) backup._info.pop("links", None)
return zip(*sorted(backup._info.items())) return zip(*sorted(backup._info.items()))

View File

@ -25,23 +25,24 @@ class FailoverVolumeHost(command.Command):
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super(FailoverVolumeHost, self).get_parser(prog_name) parser = super(FailoverVolumeHost, self).get_parser(prog_name)
parser.add_argument( parser.add_argument(
"host", "host", metavar="<host-name>", help=_("Name of volume host")
metavar="<host-name>",
help=_("Name of volume host")
) )
parser.add_argument( parser.add_argument(
"--volume-backend", "--volume-backend",
metavar="<backend-id>", metavar="<backend-id>",
required=True, required=True,
help=_("The ID of the volume backend replication " help=_(
"target where the host will failover to (required)") "The ID of the volume backend replication "
"target where the host will failover to (required)"
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
service_client = self.app.client_manager.volume service_client = self.app.client_manager.volume
service_client.services.failover_host(parsed_args.host, service_client.services.failover_host(
parsed_args.volume_backend) parsed_args.host, parsed_args.volume_backend
)
class SetVolumeHost(command.Command): class SetVolumeHost(command.Command):
@ -50,20 +51,18 @@ class SetVolumeHost(command.Command):
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super(SetVolumeHost, self).get_parser(prog_name) parser = super(SetVolumeHost, self).get_parser(prog_name)
parser.add_argument( parser.add_argument(
"host", "host", metavar="<host-name>", help=_("Name of volume host")
metavar="<host-name>",
help=_("Name of volume host")
) )
enabled_group = parser.add_mutually_exclusive_group() enabled_group = parser.add_mutually_exclusive_group()
enabled_group.add_argument( enabled_group.add_argument(
"--disable", "--disable",
action="store_true", action="store_true",
help=_("Freeze and disable the specified volume host") help=_("Freeze and disable the specified volume host"),
) )
enabled_group.add_argument( enabled_group.add_argument(
"--enable", "--enable",
action="store_true", action="store_true",
help=_("Thaw and enable the specified volume host") help=_("Thaw and enable the specified volume host"),
) )
return parser return parser

View File

@ -72,36 +72,44 @@ class CreateVolumeSnapshot(command.ShowOne):
parser.add_argument( parser.add_argument(
"--volume", "--volume",
metavar="<volume>", metavar="<volume>",
help=_("Volume to snapshot (name or ID) " help=_(
"(default is <snapshot-name>)") "Volume to snapshot (name or ID) "
"(default is <snapshot-name>)"
),
) )
parser.add_argument( parser.add_argument(
"--description", "--description",
metavar="<description>", metavar="<description>",
help=_("Description of the snapshot") help=_("Description of the snapshot"),
) )
parser.add_argument( parser.add_argument(
"--force", "--force",
action="store_true", action="store_true",
default=False, default=False,
help=_("Create a snapshot attached to an instance. " help=_(
"Default is False") "Create a snapshot attached to an instance. "
"Default is False"
),
) )
parser.add_argument( parser.add_argument(
"--property", "--property",
metavar="<key=value>", metavar="<key=value>",
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_("Set a property to this snapshot " help=_(
"(repeat option to set multiple properties)"), "Set a property to this snapshot "
"(repeat option to set multiple properties)"
),
) )
parser.add_argument( parser.add_argument(
"--remote-source", "--remote-source",
metavar="<key=value>", metavar="<key=value>",
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_("The attribute(s) of the existing remote volume snapshot " help=_(
"(admin required) (repeat option to specify multiple " "The attribute(s) of the existing remote volume snapshot "
"attributes) e.g.: '--remote-source source-name=test_name " "(admin required) (repeat option to specify multiple "
"--remote-source source-id=test_id'"), "attributes) e.g.: '--remote-source source-name=test_name "
"--remote-source source-id=test_id'"
),
) )
return parser return parser
@ -110,14 +118,15 @@ class CreateVolumeSnapshot(command.ShowOne):
volume = parsed_args.volume volume = parsed_args.volume
if not parsed_args.volume: if not parsed_args.volume:
volume = parsed_args.snapshot_name volume = parsed_args.snapshot_name
volume_id = utils.find_resource( volume_id = utils.find_resource(volume_client.volumes, volume).id
volume_client.volumes, volume).id
if parsed_args.remote_source: if parsed_args.remote_source:
# Create a new snapshot from an existing remote snapshot source # Create a new snapshot from an existing remote snapshot source
if parsed_args.force: if parsed_args.force:
msg = (_("'--force' option will not work when you create " msg = _(
"new volume snapshot from an existing remote " "'--force' option will not work when you create "
"volume snapshot")) "new volume snapshot from an existing remote "
"volume snapshot"
)
LOG.warning(msg) LOG.warning(msg)
snapshot = volume_client.volume_snapshots.manage( snapshot = volume_client.volume_snapshots.manage(
volume_id=volume_id, volume_id=volume_id,
@ -136,8 +145,11 @@ class CreateVolumeSnapshot(command.ShowOne):
metadata=parsed_args.property, metadata=parsed_args.property,
) )
snapshot._info.update( 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())) return zip(*sorted(snapshot._info.items()))
@ -151,13 +163,15 @@ class DeleteVolumeSnapshot(command.Command):
"snapshots", "snapshots",
metavar="<snapshot>", metavar="<snapshot>",
nargs="+", nargs="+",
help=_("Snapshot(s) to delete (name or ID)") help=_("Snapshot(s) to delete (name or ID)"),
) )
parser.add_argument( parser.add_argument(
'--force', '--force',
action='store_true', action='store_true',
help=_("Attempt forced removal of snapshot(s), " help=_(
"regardless of state (defaults to False)") "Attempt forced removal of snapshot(s), "
"regardless of state (defaults to False)"
),
) )
return parser return parser
@ -168,19 +182,26 @@ class DeleteVolumeSnapshot(command.Command):
for i in parsed_args.snapshots: for i in parsed_args.snapshots:
try: try:
snapshot_id = utils.find_resource( snapshot_id = utils.find_resource(
volume_client.volume_snapshots, i).id volume_client.volume_snapshots, i
).id
volume_client.volume_snapshots.delete( volume_client.volume_snapshots.delete(
snapshot_id, parsed_args.force) snapshot_id, parsed_args.force
)
except Exception as e: except Exception as e:
result += 1 result += 1
LOG.error(_("Failed to delete snapshot with " LOG.error(
"name or ID '%(snapshot)s': %(e)s") _(
% {'snapshot': i, 'e': e}) "Failed to delete snapshot with "
"name or ID '%(snapshot)s': %(e)s"
)
% {'snapshot': i, 'e': e}
)
if result > 0: if result > 0:
total = len(parsed_args.snapshots) total = len(parsed_args.snapshots)
msg = (_("%(result)s of %(total)s snapshots failed " msg = _(
"to delete.") % {'result': result, 'total': total}) "%(result)s of %(total)s snapshots failed " "to delete."
) % {'result': result, 'total': total}
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -198,7 +219,7 @@ class ListVolumeSnapshot(command.Lister):
parser.add_argument( parser.add_argument(
'--project', '--project',
metavar='<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) identity_common.add_project_domain_option_to_parser(parser)
parser.add_argument( parser.add_argument(
@ -223,22 +244,29 @@ class ListVolumeSnapshot(command.Lister):
'--name', '--name',
metavar='<name>', metavar='<name>',
default=None, default=None,
help=_('Filters results by a name.') help=_('Filters results by a name.'),
) )
parser.add_argument( parser.add_argument(
'--status', '--status',
metavar='<status>', metavar='<status>',
choices=['available', 'error', 'creating', 'deleting', choices=[
'error_deleting'], 'available',
help=_("Filters results by a status. " 'error',
"('available', 'error', 'creating', 'deleting'" 'creating',
" or 'error_deleting')") 'deleting',
'error_deleting',
],
help=_(
"Filters results by a status. "
"('available', 'error', 'creating', 'deleting'"
" or 'error_deleting')"
),
) )
parser.add_argument( parser.add_argument(
'--volume', '--volume',
metavar='<volume>', metavar='<volume>',
default=None, default=None,
help=_('Filters results by a volume (name or ID).') help=_('Filters results by a volume (name or ID).'),
) )
return parser return parser
@ -247,8 +275,16 @@ class ListVolumeSnapshot(command.Lister):
identity_client = self.app.client_manager.identity identity_client = self.app.client_manager.identity
if parsed_args.long: if parsed_args.long:
columns = ['ID', 'Name', 'Description', 'Status', columns = [
'Size', 'Created At', 'Volume ID', 'Metadata'] 'ID',
'Name',
'Description',
'Status',
'Size',
'Created At',
'Volume ID',
'Metadata',
]
column_headers = copy.deepcopy(columns) column_headers = copy.deepcopy(columns)
column_headers[6] = 'Volume' column_headers[6] = 'Volume'
column_headers[7] = 'Properties' column_headers[7] = 'Properties'
@ -264,24 +300,28 @@ class ListVolumeSnapshot(command.Lister):
except Exception: except Exception:
# Just forget it if there's any trouble # Just forget it if there's any trouble
pass pass
_VolumeIdColumn = functools.partial(VolumeIdColumn, _VolumeIdColumn = functools.partial(
volume_cache=volume_cache) VolumeIdColumn, volume_cache=volume_cache
)
volume_id = None volume_id = None
if parsed_args.volume: if parsed_args.volume:
volume_id = utils.find_resource( volume_id = utils.find_resource(
volume_client.volumes, parsed_args.volume).id volume_client.volumes, parsed_args.volume
).id
project_id = None project_id = None
if parsed_args.project: if parsed_args.project:
project_id = identity_common.find_project( project_id = identity_common.find_project(
identity_client, identity_client,
parsed_args.project, parsed_args.project,
parsed_args.project_domain).id parsed_args.project_domain,
).id
# set value of 'all_tenants' when using project option # set value of 'all_tenants' when using project option
all_projects = True if parsed_args.project else \ all_projects = (
parsed_args.all_projects True if parsed_args.project else parsed_args.all_projects
)
search_opts = { search_opts = {
'all_tenants': all_projects, 'all_tenants': all_projects,
@ -296,12 +336,20 @@ class ListVolumeSnapshot(command.Lister):
marker=parsed_args.marker, marker=parsed_args.marker,
limit=parsed_args.limit, limit=parsed_args.limit,
) )
return (column_headers, return (
(utils.get_item_properties( column_headers,
s, columns, (
formatters={'Metadata': format_columns.DictColumn, utils.get_item_properties(
'Volume ID': _VolumeIdColumn}, s,
) for s in data)) columns,
formatters={
'Metadata': format_columns.DictColumn,
'Volume ID': _VolumeIdColumn,
},
)
for s in data
),
)
class SetVolumeSnapshot(command.Command): class SetVolumeSnapshot(command.Command):
@ -312,51 +360,61 @@ class SetVolumeSnapshot(command.Command):
parser.add_argument( parser.add_argument(
'snapshot', 'snapshot',
metavar='<snapshot>', metavar='<snapshot>',
help=_('Snapshot to modify (name or ID)') help=_('Snapshot to modify (name or ID)'),
) )
parser.add_argument( parser.add_argument(
'--name', '--name', metavar='<name>', help=_('New snapshot name')
metavar='<name>',
help=_('New snapshot name')
) )
parser.add_argument( parser.add_argument(
'--description', '--description',
metavar='<description>', metavar='<description>',
help=_('New snapshot description') help=_('New snapshot description'),
) )
parser.add_argument( parser.add_argument(
"--no-property", "--no-property",
dest="no_property", dest="no_property",
action="store_true", action="store_true",
help=_("Remove all properties from <snapshot> " help=_(
"(specify both --no-property and --property to " "Remove all properties from <snapshot> "
"remove the current properties before setting " "(specify both --no-property and --property to "
"new properties.)"), "remove the current properties before setting "
"new properties.)"
),
) )
parser.add_argument( parser.add_argument(
'--property', '--property',
metavar='<key=value>', metavar='<key=value>',
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_('Property to add/change for this snapshot ' help=_(
'(repeat option to set multiple properties)'), 'Property to add/change for this snapshot '
'(repeat option to set multiple properties)'
),
) )
parser.add_argument( parser.add_argument(
'--state', '--state',
metavar='<state>', metavar='<state>',
choices=['available', 'error', 'creating', 'deleting', choices=[
'error_deleting'], 'available',
help=_('New snapshot state. ("available", "error", "creating", ' 'error',
'"deleting", or "error_deleting") (admin only) ' 'creating',
'(This option simply changes the state of the snapshot ' 'deleting',
'in the database with no regard to actual status, ' 'error_deleting',
'exercise caution when using)'), ],
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 return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
snapshot = utils.find_resource(volume_client.volume_snapshots, snapshot = utils.find_resource(
parsed_args.snapshot) volume_client.volume_snapshots, parsed_args.snapshot
)
result = 0 result = 0
if parsed_args.no_property: if parsed_args.no_property:
@ -373,7 +431,8 @@ class SetVolumeSnapshot(command.Command):
if parsed_args.property: if parsed_args.property:
try: try:
volume_client.volume_snapshots.set_metadata( volume_client.volume_snapshots.set_metadata(
snapshot.id, parsed_args.property) snapshot.id, parsed_args.property
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set snapshot property: %s"), e) LOG.error(_("Failed to set snapshot property: %s"), e)
result += 1 result += 1
@ -381,7 +440,8 @@ class SetVolumeSnapshot(command.Command):
if parsed_args.state: if parsed_args.state:
try: try:
volume_client.volume_snapshots.reset_state( volume_client.volume_snapshots.reset_state(
snapshot.id, parsed_args.state) snapshot.id, parsed_args.state
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set snapshot state: %s"), e) LOG.error(_("Failed to set snapshot state: %s"), e)
result += 1 result += 1
@ -393,16 +453,18 @@ class SetVolumeSnapshot(command.Command):
kwargs['description'] = parsed_args.description kwargs['description'] = parsed_args.description
if kwargs: if kwargs:
try: try:
volume_client.volume_snapshots.update( volume_client.volume_snapshots.update(snapshot.id, **kwargs)
snapshot.id, **kwargs)
except Exception as e: except Exception as e:
LOG.error(_("Failed to update snapshot name " LOG.error(
"or description: %s"), e) _("Failed to update snapshot name " "or description: %s"),
e,
)
result += 1 result += 1
if result > 0: if result > 0:
raise exceptions.CommandError(_("One or more of the " raise exceptions.CommandError(
"set operations failed")) _("One or more of the " "set operations failed")
)
class ShowVolumeSnapshot(command.ShowOne): class ShowVolumeSnapshot(command.ShowOne):
@ -413,17 +475,21 @@ class ShowVolumeSnapshot(command.ShowOne):
parser.add_argument( parser.add_argument(
"snapshot", "snapshot",
metavar="<snapshot>", metavar="<snapshot>",
help=_("Snapshot to display (name or ID)") help=_("Snapshot to display (name or ID)"),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
snapshot = utils.find_resource( snapshot = utils.find_resource(
volume_client.volume_snapshots, parsed_args.snapshot) volume_client.volume_snapshots, parsed_args.snapshot
)
snapshot._info.update( 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())) return zip(*sorted(snapshot._info.items()))
@ -443,15 +509,18 @@ class UnsetVolumeSnapshot(command.Command):
metavar='<key>', metavar='<key>',
action='append', action='append',
default=[], default=[],
help=_('Property to remove from snapshot ' help=_(
'(repeat option to remove multiple properties)'), 'Property to remove from snapshot '
'(repeat option to remove multiple properties)'
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
snapshot = utils.find_resource( snapshot = utils.find_resource(
volume_client.volume_snapshots, parsed_args.snapshot) volume_client.volume_snapshots, parsed_args.snapshot
)
if parsed_args.property: if parsed_args.property:
volume_client.volume_snapshots.delete_metadata( volume_client.volume_snapshots.delete_metadata(

View File

@ -50,8 +50,7 @@ class AcceptTransferRequest(command.ShowOne):
try: try:
transfer_request_id = utils.find_resource( transfer_request_id = utils.find_resource(
volume_client.transfers, volume_client.transfers, parsed_args.transfer_request
parsed_args.transfer_request
).id ).id
except exceptions.CommandError: except exceptions.CommandError:
# Non-admin users will fail to lookup name -> ID so we just # 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) volume_client.transfers.delete(transfer_request_id)
except Exception as e: except Exception as e:
result += 1 result += 1
LOG.error(_("Failed to delete volume transfer request " LOG.error(
"with name or ID '%(transfer)s': %(e)s") _(
% {'transfer': t, 'e': e}) "Failed to delete volume transfer request "
"with name or ID '%(transfer)s': %(e)s"
)
% {'transfer': t, 'e': e}
)
if result > 0: if result > 0:
total = len(parsed_args.transfer_request) total = len(parsed_args.transfer_request)
msg = (_("%(result)s of %(total)s volume transfer requests failed" msg = _(
" to delete") % {'result': result, 'total': total}) "%(result)s of %(total)s volume transfer requests failed"
" to delete"
) % {'result': result, 'total': total}
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -196,9 +201,13 @@ class ListTransferRequest(command.Lister):
search_opts={'all_tenants': parsed_args.all_projects}, search_opts={'all_tenants': parsed_args.all_projects},
) )
return (column_headers, ( return (
utils.get_item_properties(s, columns) column_headers,
for s in volume_transfer_result)) (
utils.get_item_properties(s, columns)
for s in volume_transfer_result
),
)
class ShowTransferRequest(command.ShowOne): class ShowTransferRequest(command.ShowOne):

View File

@ -63,8 +63,10 @@ class EncryptionInfoColumn(cliff_columns.FormattableColumn):
def _create_encryption_type(volume_client, volume_type, parsed_args): def _create_encryption_type(volume_client, volume_type, parsed_args):
if not parsed_args.encryption_provider: if not parsed_args.encryption_provider:
msg = _("'--encryption-provider' should be specified while " msg = _(
"creating a new encryption type") "'--encryption-provider' should be specified while "
"creating a new encryption type"
)
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
# set the default of control location while creating # set the default of control location while creating
control_location = 'front-end' control_location = 'front-end'
@ -74,10 +76,11 @@ def _create_encryption_type(volume_client, volume_type, parsed_args):
'provider': parsed_args.encryption_provider, 'provider': parsed_args.encryption_provider,
'cipher': parsed_args.encryption_cipher, 'cipher': parsed_args.encryption_cipher,
'key_size': parsed_args.encryption_key_size, 'key_size': parsed_args.encryption_key_size,
'control_location': control_location 'control_location': control_location,
} }
encryption = volume_client.volume_encryption_types.create( encryption = volume_client.volume_encryption_types.create(
volume_type, body) volume_type, body
)
return encryption return encryption
@ -93,10 +96,13 @@ def _set_encryption_type(volume_client, volume_type, parsed_args):
except Exception as e: except Exception as e:
if type(e).__name__ == 'NotFound': if type(e).__name__ == 'NotFound':
# create new encryption type # create new encryption type
LOG.warning(_("No existing encryption type found, creating " LOG.warning(
"new encryption type for this volume type ...")) _(
_create_encryption_type( "No existing encryption type found, creating "
volume_client, volume_type, parsed_args) "new encryption type for this volume type ..."
)
)
_create_encryption_type(volume_client, volume_type, parsed_args)
class CreateVolumeType(command.ShowOne): class CreateVolumeType(command.ShowOne):
@ -131,50 +137,62 @@ class CreateVolumeType(command.ShowOne):
'--property', '--property',
metavar='<key=value>', metavar='<key=value>',
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_('Set a property on this volume type ' help=_(
'(repeat option to set multiple properties)'), 'Set a property on this volume type '
'(repeat option to set multiple properties)'
),
) )
parser.add_argument( parser.add_argument(
'--project', '--project',
metavar='<project>', metavar='<project>',
help=_("Allow <project> to access private type (name or ID) " help=_(
"(Must be used with --private option)"), "Allow <project> to access private type (name or ID) "
"(Must be used with --private option)"
),
) )
# TODO(Huanxuan Ao): Add choices for each "--encryption-*" option. # TODO(Huanxuan Ao): Add choices for each "--encryption-*" option.
parser.add_argument( parser.add_argument(
'--encryption-provider', '--encryption-provider',
metavar='<provider>', metavar='<provider>',
help=_('Set the encryption provider format for ' help=_(
'this volume type (e.g "luks" or "plain") (admin only) ' 'Set the encryption provider format for '
'(This option is required when setting encryption type ' 'this volume type (e.g "luks" or "plain") (admin only) '
'of a volume. Consider using other encryption options ' '(This option is required when setting encryption type '
'such as: "--encryption-cipher", "--encryption-key-size" ' 'of a volume. Consider using other encryption options '
'and "--encryption-control-location")'), 'such as: "--encryption-cipher", "--encryption-key-size" '
'and "--encryption-control-location")'
),
) )
parser.add_argument( parser.add_argument(
'--encryption-cipher', '--encryption-cipher',
metavar='<cipher>', metavar='<cipher>',
help=_('Set the encryption algorithm or mode for this ' help=_(
'volume type (e.g "aes-xts-plain64") (admin only)'), 'Set the encryption algorithm or mode for this '
'volume type (e.g "aes-xts-plain64") (admin only)'
),
) )
parser.add_argument( parser.add_argument(
'--encryption-key-size', '--encryption-key-size',
metavar='<key-size>', metavar='<key-size>',
type=int, type=int,
help=_('Set the size of the encryption key of this ' help=_(
'volume type (e.g "128" or "256") (admin only)'), 'Set the size of the encryption key of this '
'volume type (e.g "128" or "256") (admin only)'
),
) )
parser.add_argument( parser.add_argument(
'--encryption-control-location', '--encryption-control-location',
metavar='<control-location>', metavar='<control-location>',
choices=['front-end', 'back-end'], choices=['front-end', 'back-end'],
help=_('Set the notional service where the encryption is ' help=_(
'performed ("front-end" or "back-end") (admin only) ' 'Set the notional service where the encryption is '
'(The default value for this option is "front-end" ' 'performed ("front-end" or "back-end") (admin only) '
'when setting encryption type of a volume. Consider ' '(The default value for this option is "front-end" '
'using other encryption options such as: ' 'when setting encryption type of a volume. Consider '
'"--encryption-cipher", "--encryption-key-size" and ' 'using other encryption options such as: '
'"--encryption-provider")'), '"--encryption-cipher", "--encryption-key-size" and '
'"--encryption-provider")'
),
) )
identity_common.add_project_domain_option_to_parser(parser) identity_common.add_project_domain_option_to_parser(parser)
return parser return parser
@ -194,9 +212,7 @@ class CreateVolumeType(command.ShowOne):
kwargs['is_public'] = False kwargs['is_public'] = False
volume_type = volume_client.volume_types.create( volume_type = volume_client.volume_types.create(
parsed_args.name, parsed_args.name, description=parsed_args.description, **kwargs
description=parsed_args.description,
**kwargs
) )
volume_type._info.pop('extra_specs') volume_type._info.pop('extra_specs')
@ -208,30 +224,43 @@ class CreateVolumeType(command.ShowOne):
parsed_args.project_domain, parsed_args.project_domain,
).id ).id
volume_client.volume_type_access.add_project_access( volume_client.volume_type_access.add_project_access(
volume_type.id, project_id) volume_type.id, project_id
)
except Exception as e: except Exception as e:
msg = _("Failed to add project %(project)s access to " msg = _(
"type: %(e)s") "Failed to add project %(project)s access to "
"type: %(e)s"
)
LOG.error(msg % {'project': parsed_args.project, 'e': e}) LOG.error(msg % {'project': parsed_args.project, 'e': e})
if parsed_args.property: if parsed_args.property:
result = volume_type.set_keys(parsed_args.property) result = volume_type.set_keys(parsed_args.property)
volume_type._info.update( volume_type._info.update(
{'properties': format_columns.DictColumn(result)}) {'properties': format_columns.DictColumn(result)}
if (parsed_args.encryption_provider or )
parsed_args.encryption_cipher or if (
parsed_args.encryption_key_size or parsed_args.encryption_provider
parsed_args.encryption_control_location): or parsed_args.encryption_cipher
or parsed_args.encryption_key_size
or parsed_args.encryption_control_location
):
try: try:
# create new encryption # create new encryption
encryption = _create_encryption_type( encryption = _create_encryption_type(
volume_client, volume_type, parsed_args) volume_client, volume_type, parsed_args
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set encryption information for this " LOG.error(
"volume type: %s"), e) _(
"Failed to set encryption information for this "
"volume type: %s"
),
e,
)
# add encryption info in result # add encryption info in result
encryption._info.pop("volume_type_id", None) encryption._info.pop("volume_type_id", None)
volume_type._info.update( 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) volume_type._info.pop("os-volume-type-access:is_public", None)
return zip(*sorted(volume_type._info.items())) return zip(*sorted(volume_type._info.items()))
@ -246,7 +275,7 @@ class DeleteVolumeType(command.Command):
"volume_types", "volume_types",
metavar="<volume-type>", metavar="<volume-type>",
nargs="+", nargs="+",
help=_("Volume type(s) to delete (name or ID)") help=_("Volume type(s) to delete (name or ID)"),
) )
return parser return parser
@ -256,20 +285,26 @@ class DeleteVolumeType(command.Command):
for volume_type in parsed_args.volume_types: for volume_type in parsed_args.volume_types:
try: try:
vol_type = utils.find_resource(volume_client.volume_types, vol_type = utils.find_resource(
volume_type) volume_client.volume_types, volume_type
)
volume_client.volume_types.delete(vol_type) volume_client.volume_types.delete(vol_type)
except Exception as e: except Exception as e:
result += 1 result += 1
LOG.error(_("Failed to delete volume type with " LOG.error(
"name or ID '%(volume_type)s': %(e)s") _(
% {'volume_type': volume_type, 'e': e}) "Failed to delete volume type with "
"name or ID '%(volume_type)s': %(e)s"
)
% {'volume_type': volume_type, 'e': e}
)
if result > 0: if result > 0:
total = len(parsed_args.volume_types) total = len(parsed_args.volume_types)
msg = (_("%(result)s of %(total)s volume types failed " msg = _(
"to delete.") % {'result': result, 'total': total}) "%(result)s of %(total)s volume types failed " "to delete."
) % {'result': result, 'total': total}
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -282,30 +317,30 @@ class ListVolumeType(command.Lister):
'--long', '--long',
action='store_true', action='store_true',
default=False, default=False,
help=_('List additional fields in output') help=_('List additional fields in output'),
) )
public_group = parser.add_mutually_exclusive_group() public_group = parser.add_mutually_exclusive_group()
public_group.add_argument( public_group.add_argument(
"--default", "--default",
action='store_true', action='store_true',
default=False, default=False,
help=_('List the default volume type') help=_('List the default volume type'),
) )
public_group.add_argument( public_group.add_argument(
"--public", "--public", action="store_true", help=_("List only public types")
action="store_true",
help=_("List only public types")
) )
public_group.add_argument( public_group.add_argument(
"--private", "--private",
action="store_true", action="store_true",
help=_("List only private types (admin only)") help=_("List only private types (admin only)"),
) )
parser.add_argument( parser.add_argument(
"--encryption-type", "--encryption-type",
action="store_true", action="store_true",
help=_("Display encryption information for each volume type " help=_(
"(admin only)"), "Display encryption information for each volume type "
"(admin only)"
),
) )
return parser return parser
@ -314,7 +349,12 @@ class ListVolumeType(command.Lister):
if parsed_args.long: if parsed_args.long:
columns = ['ID', 'Name', 'Is Public', 'Description', 'Extra Specs'] columns = ['ID', 'Name', 'Is Public', 'Description', 'Extra Specs']
column_headers = [ column_headers = [
'ID', 'Name', 'Is Public', 'Description', 'Properties'] 'ID',
'Name',
'Is Public',
'Description',
'Properties',
]
else: else:
columns = ['ID', 'Name', 'Is Public'] columns = ['ID', 'Name', 'Is Public']
column_headers = ['ID', 'Name', 'Is Public'] column_headers = ['ID', 'Name', 'Is Public']
@ -326,8 +366,7 @@ class ListVolumeType(command.Lister):
is_public = True is_public = True
if parsed_args.private: if parsed_args.private:
is_public = False is_public = False
data = volume_client.volume_types.list( data = volume_client.volume_types.list(is_public=is_public)
is_public=is_public)
formatters = {'Extra Specs': format_columns.DictColumn} formatters = {'Extra Specs': format_columns.DictColumn}
@ -341,7 +380,7 @@ class ListVolumeType(command.Lister):
'created_at', 'created_at',
'updated_at', 'updated_at',
'deleted_at', 'deleted_at',
'volume_type_id' 'volume_type_id',
] ]
for key in del_key: for key in del_key:
d._info.pop(key, None) d._info.pop(key, None)
@ -354,14 +393,21 @@ class ListVolumeType(command.Lister):
column_headers += ['Encryption'] column_headers += ['Encryption']
_EncryptionInfoColumn = functools.partial( _EncryptionInfoColumn = functools.partial(
EncryptionInfoColumn, encryption_data=encryption) EncryptionInfoColumn, encryption_data=encryption
)
formatters['id'] = _EncryptionInfoColumn formatters['id'] = _EncryptionInfoColumn
return (column_headers, return (
(utils.get_item_properties( column_headers,
s, columns, (
utils.get_item_properties(
s,
columns,
formatters=formatters, formatters=formatters,
) for s in data)) )
for s in data
),
)
class SetVolumeType(command.Command): class SetVolumeType(command.Command):
@ -388,52 +434,64 @@ class SetVolumeType(command.Command):
'--property', '--property',
metavar='<key=value>', metavar='<key=value>',
action=parseractions.KeyValueAction, action=parseractions.KeyValueAction,
help=_('Set a property on this volume type ' help=_(
'(repeat option to set multiple properties)'), 'Set a property on this volume type '
'(repeat option to set multiple properties)'
),
) )
parser.add_argument( parser.add_argument(
'--project', '--project',
metavar='<project>', metavar='<project>',
help=_('Set volume type access to project (name or ID) ' help=_(
'(admin only)'), 'Set volume type access to project (name or ID) '
'(admin only)'
),
) )
identity_common.add_project_domain_option_to_parser(parser) identity_common.add_project_domain_option_to_parser(parser)
# TODO(Huanxuan Ao): Add choices for each "--encryption-*" option. # TODO(Huanxuan Ao): Add choices for each "--encryption-*" option.
parser.add_argument( parser.add_argument(
'--encryption-provider', '--encryption-provider',
metavar='<provider>', metavar='<provider>',
help=_('Set the encryption provider format for ' help=_(
'this volume type (e.g "luks" or "plain") (admin only) ' 'Set the encryption provider format for '
'(This option is required when setting encryption type ' 'this volume type (e.g "luks" or "plain") (admin only) '
'of a volume for the first time. Consider using other ' '(This option is required when setting encryption type '
'encryption options such as: "--encryption-cipher", ' 'of a volume for the first time. Consider using other '
'"--encryption-key-size" and ' 'encryption options such as: "--encryption-cipher", '
'"--encryption-control-location")'), '"--encryption-key-size" and '
'"--encryption-control-location")'
),
) )
parser.add_argument( parser.add_argument(
'--encryption-cipher', '--encryption-cipher',
metavar='<cipher>', metavar='<cipher>',
help=_('Set the encryption algorithm or mode for this ' help=_(
'volume type (e.g "aes-xts-plain64") (admin only)'), 'Set the encryption algorithm or mode for this '
'volume type (e.g "aes-xts-plain64") (admin only)'
),
) )
parser.add_argument( parser.add_argument(
'--encryption-key-size', '--encryption-key-size',
metavar='<key-size>', metavar='<key-size>',
type=int, type=int,
help=_('Set the size of the encryption key of this ' help=_(
'volume type (e.g "128" or "256") (admin only)'), 'Set the size of the encryption key of this '
'volume type (e.g "128" or "256") (admin only)'
),
) )
parser.add_argument( parser.add_argument(
'--encryption-control-location', '--encryption-control-location',
metavar='<control-location>', metavar='<control-location>',
choices=['front-end', 'back-end'], choices=['front-end', 'back-end'],
help=_('Set the notional service where the encryption is ' help=_(
'performed ("front-end" or "back-end") (admin only) ' 'Set the notional service where the encryption is '
'(The default value for this option is "front-end" ' 'performed ("front-end" or "back-end") (admin only) '
'when setting encryption type of a volume for the ' '(The default value for this option is "front-end" '
'first time. Consider using other encryption options ' 'when setting encryption type of a volume for the '
'such as: "--encryption-cipher", "--encryption-key-size" ' 'first time. Consider using other encryption options '
'and "--encryption-provider")'), 'such as: "--encryption-cipher", "--encryption-key-size" '
'and "--encryption-provider")'
),
) )
return parser return parser
@ -442,7 +500,8 @@ class SetVolumeType(command.Command):
identity_client = self.app.client_manager.identity identity_client = self.app.client_manager.identity
volume_type = utils.find_resource( volume_type = utils.find_resource(
volume_client.volume_types, parsed_args.volume_type) volume_client.volume_types, parsed_args.volume_type
)
result = 0 result = 0
kwargs = {} kwargs = {}
if parsed_args.name: if parsed_args.name:
@ -452,13 +511,15 @@ class SetVolumeType(command.Command):
if kwargs: if kwargs:
try: try:
volume_client.volume_types.update( volume_client.volume_types.update(volume_type.id, **kwargs)
volume_type.id,
**kwargs
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to update volume type name or" LOG.error(
" description: %s"), e) _(
"Failed to update volume type name or"
" description: %s"
),
e,
)
result += 1 result += 1
if parsed_args.property: if parsed_args.property:
@ -474,29 +535,40 @@ class SetVolumeType(command.Command):
project_info = identity_common.find_project( project_info = identity_common.find_project(
identity_client, identity_client,
parsed_args.project, parsed_args.project,
parsed_args.project_domain) parsed_args.project_domain,
)
volume_client.volume_type_access.add_project_access( volume_client.volume_type_access.add_project_access(
volume_type.id, project_info.id) volume_type.id, project_info.id
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set volume type access to " LOG.error(
"project: %s"), e) _("Failed to set volume type access to " "project: %s"), e
)
result += 1 result += 1
if (parsed_args.encryption_provider or if (
parsed_args.encryption_cipher or parsed_args.encryption_provider
parsed_args.encryption_key_size or or parsed_args.encryption_cipher
parsed_args.encryption_control_location): or parsed_args.encryption_key_size
or parsed_args.encryption_control_location
):
try: try:
_set_encryption_type(volume_client, volume_type, parsed_args) _set_encryption_type(volume_client, volume_type, parsed_args)
except Exception as e: except Exception as e:
LOG.error(_("Failed to set encryption information for this " LOG.error(
"volume type: %s"), e) _(
"Failed to set encryption information for this "
"volume type: %s"
),
e,
)
result += 1 result += 1
if result > 0: if result > 0:
raise exceptions.CommandError(_("Command Failed: One or more of" raise exceptions.CommandError(
" the operations failed")) _("Command Failed: One or more of" " the operations failed")
)
class ShowVolumeType(command.ShowOne): class ShowVolumeType(command.ShowOne):
@ -507,50 +579,65 @@ class ShowVolumeType(command.ShowOne):
parser.add_argument( parser.add_argument(
"volume_type", "volume_type",
metavar="<volume-type>", metavar="<volume-type>",
help=_("Volume type to display (name or ID)") help=_("Volume type to display (name or ID)"),
) )
parser.add_argument( parser.add_argument(
"--encryption-type", "--encryption-type",
action="store_true", action="store_true",
help=_("Display encryption information of this volume type " help=_(
"(admin only)"), "Display encryption information of this volume type "
"(admin only)"
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
volume_type = utils.find_resource( 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( properties = format_columns.DictColumn(
volume_type._info.pop('extra_specs', {})) volume_type._info.pop('extra_specs', {})
)
volume_type._info.update({'properties': properties}) volume_type._info.update({'properties': properties})
access_project_ids = None access_project_ids = None
if not volume_type.is_public: if not volume_type.is_public:
try: try:
volume_type_access = volume_client.volume_type_access.list( volume_type_access = volume_client.volume_type_access.list(
volume_type.id) volume_type.id
project_ids = [utils.get_field(item, 'project_id') )
for item in volume_type_access] 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 # TODO(Rui Chen): This format list case can be removed after
# patch https://review.opendev.org/#/c/330223/ merged. # patch https://review.opendev.org/#/c/330223/ merged.
access_project_ids = format_columns.ListColumn(project_ids) access_project_ids = format_columns.ListColumn(project_ids)
except Exception as e: except Exception as e:
msg = _('Failed to get access project list for volume type ' msg = _(
'%(type)s: %(e)s') 'Failed to get access project list for volume type '
'%(type)s: %(e)s'
)
LOG.error(msg % {'type': volume_type.id, 'e': e}) LOG.error(msg % {'type': volume_type.id, 'e': e})
volume_type._info.update({'access_project_ids': access_project_ids}) volume_type._info.update({'access_project_ids': access_project_ids})
if parsed_args.encryption_type: if parsed_args.encryption_type:
# show encryption type information for this volume type # show encryption type information for this volume type
try: try:
encryption = volume_client.volume_encryption_types.get( encryption = volume_client.volume_encryption_types.get(
volume_type.id) volume_type.id
)
encryption._info.pop("volume_type_id", None) encryption._info.pop("volume_type_id", None)
volume_type._info.update( volume_type._info.update(
{'encryption': {'encryption': format_columns.DictColumn(encryption._info)}
format_columns.DictColumn(encryption._info)}) )
except Exception as e: except Exception as e:
LOG.error(_("Failed to display the encryption information " LOG.error(
"of this volume type: %s"), e) _(
"Failed to display the encryption information "
"of this volume type: %s"
),
e,
)
volume_type._info.pop("os-volume-type-access:is_public", None) volume_type._info.pop("os-volume-type-access:is_public", None)
return zip(*sorted(volume_type._info.items())) return zip(*sorted(volume_type._info.items()))
@ -569,21 +656,27 @@ class UnsetVolumeType(command.Command):
'--property', '--property',
metavar='<key>', metavar='<key>',
action='append', action='append',
help=_('Remove a property from this volume type ' help=_(
'(repeat option to remove multiple properties)'), 'Remove a property from this volume type '
'(repeat option to remove multiple properties)'
),
) )
parser.add_argument( parser.add_argument(
'--project', '--project',
metavar='<project>', metavar='<project>',
help=_('Removes volume type access to project (name or ID) ' help=_(
'(admin only)'), 'Removes volume type access to project (name or ID) '
'(admin only)'
),
) )
identity_common.add_project_domain_option_to_parser(parser) identity_common.add_project_domain_option_to_parser(parser)
parser.add_argument( parser.add_argument(
"--encryption-type", "--encryption-type",
action="store_true", action="store_true",
help=_("Remove the encryption type for this volume type " help=_(
"(admin only)"), "Remove the encryption type for this volume type "
"(admin only)"
),
) )
return parser return parser
@ -610,22 +703,35 @@ class UnsetVolumeType(command.Command):
project_info = identity_common.find_project( project_info = identity_common.find_project(
identity_client, identity_client,
parsed_args.project, parsed_args.project,
parsed_args.project_domain) parsed_args.project_domain,
)
volume_client.volume_type_access.remove_project_access( volume_client.volume_type_access.remove_project_access(
volume_type.id, project_info.id) volume_type.id, project_info.id
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to remove volume type access from " LOG.error(
"project: %s"), e) _(
"Failed to remove volume type access from "
"project: %s"
),
e,
)
result += 1 result += 1
if parsed_args.encryption_type: if parsed_args.encryption_type:
try: try:
volume_client.volume_encryption_types.delete(volume_type) volume_client.volume_encryption_types.delete(volume_type)
except Exception as e: except Exception as e:
LOG.error(_("Failed to remove the encryption type for this " LOG.error(
"volume type: %s"), e) _(
"Failed to remove the encryption type for this "
"volume type: %s"
),
e,
)
result += 1 result += 1
if result > 0: if result > 0:
raise exceptions.CommandError(_("Command Failed: One or more of" raise exceptions.CommandError(
" the operations failed")) _("Command Failed: One or more of" " the operations failed")
)

View File

@ -31,8 +31,13 @@ def _format_cleanup_response(cleaning, unavailable):
combined_data.append(details) combined_data.append(details)
for obj in unavailable: for obj in unavailable:
details = (obj.id, obj.cluster_name, obj.host, obj.binary, details = (
'Unavailable') obj.id,
obj.cluster_name,
obj.host,
obj.binary,
'Unavailable',
)
combined_data.append(details) combined_data.append(details)
return (column_headers, combined_data) return (column_headers, combined_data)
@ -49,20 +54,22 @@ class BlockStorageCleanup(command.Lister):
parser.add_argument( parser.add_argument(
'--cluster', '--cluster',
metavar='<cluster>', metavar='<cluster>',
help=_('Name of block storage cluster in which cleanup needs ' help=_(
'to be performed (name only)') 'Name of block storage cluster in which cleanup needs '
'to be performed (name only)'
),
) )
parser.add_argument( parser.add_argument(
"--host", "--host",
metavar="<host>", metavar="<host>",
default=None, default=None,
help=_("Host where the service resides. (name only)") help=_("Host where the service resides. (name only)"),
) )
parser.add_argument( parser.add_argument(
'--binary', '--binary',
metavar='<binary>', metavar='<binary>',
default=None, 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 = parser.add_mutually_exclusive_group()
service_up_parser.add_argument( service_up_parser.add_argument(
@ -72,7 +79,7 @@ class BlockStorageCleanup(command.Lister):
default=None, default=None,
help=_( help=_(
'Filter by up status. If this is set, services need to be up.' 'Filter by up status. If this is set, services need to be up.'
) ),
) )
service_up_parser.add_argument( service_up_parser.add_argument(
'--down', '--down',
@ -81,7 +88,7 @@ class BlockStorageCleanup(command.Lister):
help=_( help=_(
'Filter by down status. If this is set, services need to be ' 'Filter by down status. If this is set, services need to be '
'down.' 'down.'
) ),
) )
service_disabled_parser = parser.add_mutually_exclusive_group() service_disabled_parser = parser.add_mutually_exclusive_group()
service_disabled_parser.add_argument( service_disabled_parser.add_argument(
@ -89,25 +96,25 @@ class BlockStorageCleanup(command.Lister):
dest='disabled', dest='disabled',
action='store_true', action='store_true',
default=None, default=None,
help=_('Filter by disabled status.') help=_('Filter by disabled status.'),
) )
service_disabled_parser.add_argument( service_disabled_parser.add_argument(
'--enabled', '--enabled',
dest='disabled', dest='disabled',
action='store_false', action='store_false',
help=_('Filter by enabled status.') help=_('Filter by enabled status.'),
) )
parser.add_argument( parser.add_argument(
'--resource-id', '--resource-id',
metavar='<resource-id>', metavar='<resource-id>',
default=None, default=None,
help=_('UUID of a resource to cleanup.') help=_('UUID of a resource to cleanup.'),
) )
parser.add_argument( parser.add_argument(
'--resource-type', '--resource-type',
metavar='<Volume|Snapshot>', metavar='<Volume|Snapshot>',
choices=('Volume', 'Snapshot'), choices=('Volume', 'Snapshot'),
help=_('Type of resource to cleanup.') help=_('Type of resource to cleanup.'),
) )
parser.add_argument( parser.add_argument(
'--service-id', '--service-id',
@ -116,7 +123,7 @@ class BlockStorageCleanup(command.Lister):
help=_( help=_(
'The service ID field from the DB, not the UUID of the ' 'The service ID field from the DB, not the UUID of the '
'service.' 'service.'
) ),
) )
return parser return parser
@ -138,7 +145,7 @@ class BlockStorageCleanup(command.Lister):
'disabled': parsed_args.disabled, 'disabled': parsed_args.disabled,
'resource_id': parsed_args.resource_id, 'resource_id': parsed_args.resource_id,
'resource_type': parsed_args.resource_type, '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} filters = {k: v for k, v in filters.items() if v is not None}

View File

@ -76,7 +76,9 @@ class ListBlockStorageCluster(command.Lister):
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super().get_parser(prog_name) parser = super().get_parser(prog_name)
parser.add_argument( parser.add_argument(
'--cluster', metavar='<name>', default=None, '--cluster',
metavar='<name>',
default=None,
help=_( help=_(
'Filter by cluster name, without backend will list ' 'Filter by cluster name, without backend will list '
'all clustered services from the same cluster.' 'all clustered services from the same cluster.'
@ -131,7 +133,7 @@ class ListBlockStorageCluster(command.Lister):
'--long', '--long',
action='store_true', action='store_true',
default=False, default=False,
help=_("List additional fields in output") help=_("List additional fields in output"),
) )
return parser return parser
@ -183,7 +185,7 @@ class SetBlockStorageCluster(command.Command):
parser.add_argument( parser.add_argument(
'cluster', 'cluster',
metavar='<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( parser.add_argument(
'--binary', '--binary',
@ -192,7 +194,7 @@ class SetBlockStorageCluster(command.Command):
help=_( help=_(
"Name of binary to filter by; defaults to 'cinder-volume' " "Name of binary to filter by; defaults to 'cinder-volume' "
"(optional)" "(optional)"
) ),
) )
enabled_group = parser.add_mutually_exclusive_group() enabled_group = parser.add_mutually_exclusive_group()
enabled_group.add_argument( enabled_group.add_argument(
@ -200,13 +202,13 @@ class SetBlockStorageCluster(command.Command):
action='store_false', action='store_false',
dest='disabled', dest='disabled',
default=None, default=None,
help=_('Enable cluster') help=_('Enable cluster'),
) )
enabled_group.add_argument( enabled_group.add_argument(
'--disable', '--disable',
action='store_true', action='store_true',
dest='disabled', dest='disabled',
help=_('Disable cluster') help=_('Disable cluster'),
) )
parser.add_argument( parser.add_argument(
'--disable-reason', '--disable-reason',
@ -215,7 +217,7 @@ class SetBlockStorageCluster(command.Command):
help=_( help=_(
'Reason for disabling the cluster ' 'Reason for disabling the cluster '
'(should be used with --disable option)' '(should be used with --disable option)'
) ),
) )
return parser return parser

View File

@ -34,8 +34,10 @@ class BlockStorageLogLevelList(command.Lister):
"--host", "--host",
metavar="<host>", metavar="<host>",
default="", default="",
help=_("List block storage service log level of specified host " help=_(
"(name only)") "List block storage service log level of specified host "
"(name only)"
),
) )
parser.add_argument( parser.add_argument(
"--service", "--service",
@ -47,15 +49,18 @@ class BlockStorageLogLevelList(command.Lister):
'cinder-api', 'cinder-api',
'cinder-volume', 'cinder-volume',
'cinder-scheduler', 'cinder-scheduler',
'cinder-backup'), 'cinder-backup',
help=_("List block storage service log level of the specified " ),
"service (name only)") help=_(
"List block storage service log level of the specified "
"service (name only)"
),
) )
parser.add_argument( parser.add_argument(
"--log-prefix", "--log-prefix",
metavar="<log-prefix>", metavar="<log-prefix>",
default="", default="",
help="Prefix for the log, e.g. 'sqlalchemy'" help="Prefix for the log, e.g. 'sqlalchemy'",
) )
return parser return parser
@ -78,12 +83,19 @@ class BlockStorageLogLevelList(command.Lister):
data = service_client.services.get_log_levels( data = service_client.services.get_log_levels(
binary=parsed_args.service, binary=parsed_args.service,
server=parsed_args.host, server=parsed_args.host,
prefix=parsed_args.log_prefix) prefix=parsed_args.log_prefix,
)
return (columns, return (
(utils.get_item_properties( columns,
s, columns, (
) for s in data)) utils.get_item_properties(
s,
columns,
)
for s in data
),
)
class BlockStorageLogLevelSet(command.Command): class BlockStorageLogLevelSet(command.Command):
@ -99,14 +111,16 @@ class BlockStorageLogLevelSet(command.Command):
metavar="<log-level>", metavar="<log-level>",
choices=('INFO', 'WARNING', 'ERROR', 'DEBUG'), choices=('INFO', 'WARNING', 'ERROR', 'DEBUG'),
type=str.upper, type=str.upper,
help=_("Desired log level.") help=_("Desired log level."),
) )
parser.add_argument( parser.add_argument(
"--host", "--host",
metavar="<host>", metavar="<host>",
default="", default="",
help=_("Set block storage service log level of specified host " help=_(
"(name only)") "Set block storage service log level of specified host "
"(name only)"
),
) )
parser.add_argument( parser.add_argument(
"--service", "--service",
@ -118,15 +132,18 @@ class BlockStorageLogLevelSet(command.Command):
'cinder-api', 'cinder-api',
'cinder-volume', 'cinder-volume',
'cinder-scheduler', 'cinder-scheduler',
'cinder-backup'), 'cinder-backup',
help=_("Set block storage service log level of specified service " ),
"(name only)") help=_(
"Set block storage service log level of specified service "
"(name only)"
),
) )
parser.add_argument( parser.add_argument(
"--log-prefix", "--log-prefix",
metavar="<log-prefix>", metavar="<log-prefix>",
default="", default="",
help="Prefix for the log, e.g. 'sqlalchemy'" help="Prefix for the log, e.g. 'sqlalchemy'",
) )
return parser return parser
@ -144,4 +161,5 @@ class BlockStorageLogLevelSet(command.Command):
level=parsed_args.level, level=parsed_args.level,
binary=parsed_args.service, binary=parsed_args.service,
server=parsed_args.host, server=parsed_args.host,
prefix=parsed_args.log_prefix) prefix=parsed_args.log_prefix,
)

View File

@ -38,50 +38,61 @@ class BlockStorageManageVolumes(command.Lister):
"host", "host",
metavar="<host>", metavar="<host>",
nargs='?', nargs='?',
help=_('Cinder host on which to list manageable volumes. ' help=_(
'Takes the form: host@backend-name#pool') 'Cinder host on which to list manageable volumes. '
'Takes the form: host@backend-name#pool'
),
) )
host_group.add_argument( host_group.add_argument(
"--cluster", "--cluster",
metavar="<cluster>", metavar="<cluster>",
help=_('Cinder cluster on which to list manageable volumes. ' help=_(
'Takes the form: cluster@backend-name#pool. ' 'Cinder cluster on which to list manageable volumes. '
'(supported by --os-volume-api-version 3.17 or later)') 'Takes the form: cluster@backend-name#pool. '
'(supported by --os-volume-api-version 3.17 or later)'
),
) )
parser.add_argument( parser.add_argument(
'--detailed', '--detailed',
metavar='<detailed>', metavar='<detailed>',
default=True, default=True,
help=_('Returns detailed information (Default=True).') help=_('Returns detailed information (Default=True).'),
) )
parser.add_argument( parser.add_argument(
'--marker', '--marker',
metavar='<marker>', metavar='<marker>',
default=None, default=None,
help=_('Begin returning volumes that appear later in the volume ' help=_(
'list than that represented by this reference. This ' 'Begin returning volumes that appear later in the volume '
'reference should be json like. Default=None.') 'list than that represented by this reference. This '
'reference should be json like. Default=None.'
),
) )
parser.add_argument( parser.add_argument(
'--limit', '--limit',
metavar='<limit>', metavar='<limit>',
default=None, default=None,
help=_('Maximum number of volumes to return. Default=None.') help=_('Maximum number of volumes to return. Default=None.'),
) )
parser.add_argument( parser.add_argument(
'--offset', '--offset',
metavar='<offset>', metavar='<offset>',
default=None, 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( parser.add_argument(
'--sort', '--sort',
metavar='<key>[:<direction>]', metavar='<key>[:<direction>]',
default=None, 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>]. ' 'form of <key>[:<asc|desc>]. '
'Valid keys: %s. ' 'Valid keys: %s. '
'Default=None.') % ', '.join(SORT_MANAGEABLE_KEY_VALUES)) 'Default=None.'
)
% ', '.join(SORT_MANAGEABLE_KEY_VALUES)
),
) )
return parser return parser
@ -119,11 +130,13 @@ class BlockStorageManageVolumes(command.Lister):
'safe_to_manage', 'safe_to_manage',
] ]
if detailed: if detailed:
columns.extend([ columns.extend(
'reason_not_safe', [
'cinder_id', 'reason_not_safe',
'extra_info', 'cinder_id',
]) 'extra_info',
]
)
data = volume_client.volumes.list_manageable( data = volume_client.volumes.list_manageable(
host=parsed_args.host, host=parsed_args.host,
@ -132,12 +145,19 @@ class BlockStorageManageVolumes(command.Lister):
limit=parsed_args.limit, limit=parsed_args.limit,
offset=parsed_args.offset, offset=parsed_args.offset,
sort=parsed_args.sort, sort=parsed_args.sort,
cluster=cluster) cluster=cluster,
)
return (columns, return (
(utils.get_item_properties( columns,
s, columns, (
) for s in data)) utils.get_item_properties(
s,
columns,
)
for s in data
),
)
class BlockStorageManageSnapshots(command.Lister): class BlockStorageManageSnapshots(command.Lister):
@ -153,50 +173,61 @@ class BlockStorageManageSnapshots(command.Lister):
"host", "host",
metavar="<host>", metavar="<host>",
nargs='?', nargs='?',
help=_('Cinder host on which to list manageable snapshots. ' help=_(
'Takes the form: host@backend-name#pool') 'Cinder host on which to list manageable snapshots. '
'Takes the form: host@backend-name#pool'
),
) )
host_group.add_argument( host_group.add_argument(
"--cluster", "--cluster",
metavar="<cluster>", metavar="<cluster>",
help=_('Cinder cluster on which to list manageable snapshots. ' help=_(
'Takes the form: cluster@backend-name#pool. ' 'Cinder cluster on which to list manageable snapshots. '
'(supported by --os-volume-api-version 3.17 or later)') 'Takes the form: cluster@backend-name#pool. '
'(supported by --os-volume-api-version 3.17 or later)'
),
) )
parser.add_argument( parser.add_argument(
'--detailed', '--detailed',
metavar='<detailed>', metavar='<detailed>',
default=True, default=True,
help=_('Returns detailed information (Default=True).') help=_('Returns detailed information (Default=True).'),
) )
parser.add_argument( parser.add_argument(
'--marker', '--marker',
metavar='<marker>', metavar='<marker>',
default=None, default=None,
help=_('Begin returning snapshots that appear later in the ' help=_(
'snapshot list than that represented by this reference. ' 'Begin returning snapshots that appear later in the '
'This reference should be json like. Default=None.') 'snapshot list than that represented by this reference. '
'This reference should be json like. Default=None.'
),
) )
parser.add_argument( parser.add_argument(
'--limit', '--limit',
metavar='<limit>', metavar='<limit>',
default=None, default=None,
help=_('Maximum number of snapshots to return. Default=None.') help=_('Maximum number of snapshots to return. Default=None.'),
) )
parser.add_argument( parser.add_argument(
'--offset', '--offset',
metavar='<offset>', metavar='<offset>',
default=None, 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( parser.add_argument(
'--sort', '--sort',
metavar='<key>[:<direction>]', metavar='<key>[:<direction>]',
default=None, 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>]. ' 'form of <key>[:<asc|desc>]. '
'Valid keys: %s. ' 'Valid keys: %s. '
'Default=None.') % ', '.join(SORT_MANAGEABLE_KEY_VALUES)) 'Default=None.'
)
% ', '.join(SORT_MANAGEABLE_KEY_VALUES)
),
) )
return parser return parser
@ -237,11 +268,13 @@ class BlockStorageManageSnapshots(command.Lister):
'source_reference', 'source_reference',
] ]
if detailed: if detailed:
columns.extend([ columns.extend(
'reason_not_safe', [
'cinder_id', 'reason_not_safe',
'extra_info', 'cinder_id',
]) 'extra_info',
]
)
data = volume_client.volume_snapshots.list_manageable( data = volume_client.volume_snapshots.list_manageable(
host=parsed_args.host, host=parsed_args.host,
@ -250,9 +283,16 @@ class BlockStorageManageSnapshots(command.Lister):
limit=parsed_args.limit, limit=parsed_args.limit,
offset=parsed_args.offset, offset=parsed_args.offset,
sort=parsed_args.sort, sort=parsed_args.sort,
cluster=cluster) cluster=cluster,
)
return (columns, return (
(utils.get_item_properties( columns,
s, columns, (
) for s in data)) utils.get_item_properties(
s,
columns,
)
for s in data
),
)

View File

@ -42,7 +42,7 @@ class ListBlockStorageResourceFilter(command.Lister):
return ( return (
column_headers, 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( parser.add_argument(
'resource', 'resource',
metavar='<resource>', metavar='<resource>',
help=_('Resource to show filters for (name).') help=_('Resource to show filters for (name).'),
) )
return parser return parser

View File

@ -42,7 +42,6 @@ class VolumeSummary(command.ShowOne):
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
if volume_client.api_version < api_versions.APIVersion('3.12'): if volume_client.api_version < api_versions.APIVersion('3.12'):
@ -89,13 +88,14 @@ class VolumeRevertToSnapshot(command.Command):
parser.add_argument( parser.add_argument(
'snapshot', 'snapshot',
metavar="<snapshot>", metavar="<snapshot>",
help=_('Name or ID of the snapshot to restore. The snapshot must ' help=_(
'be the most recent one known to cinder.'), 'Name or ID of the snapshot to restore. The snapshot must '
'be the most recent one known to cinder.'
),
) )
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume volume_client = self.app.client_manager.volume
if volume_client.api_version < api_versions.APIVersion('3.40'): if volume_client.api_version < api_versions.APIVersion('3.40'):
@ -106,9 +106,10 @@ class VolumeRevertToSnapshot(command.Command):
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
snapshot = utils.find_resource( snapshot = utils.find_resource(
volume_client.volume_snapshots, parsed_args.snapshot) volume_client.volume_snapshots, parsed_args.snapshot
volume = utils.find_resource( )
volume_client.volumes, snapshot.volume_id) volume = utils.find_resource(volume_client.volumes, snapshot.volume_id)
volume_client.volumes.revert_to_snapshot( volume_client.volumes.revert_to_snapshot(
volume=volume, snapshot=snapshot) volume=volume, snapshot=snapshot
)

View File

@ -199,15 +199,17 @@ class CreateVolumeAttachment(command.ShowOne):
'mountpoint': parsed_args.mountpoint, 'mountpoint': parsed_args.mountpoint,
} }
else: else:
if any({ if any(
parsed_args.initiator, {
parsed_args.ip, parsed_args.initiator,
parsed_args.platform, parsed_args.ip,
parsed_args.host, parsed_args.platform,
parsed_args.host, parsed_args.host,
parsed_args.multipath, parsed_args.host,
parsed_args.mountpoint, parsed_args.multipath,
}): parsed_args.mountpoint,
}
):
msg = _( msg = _(
'You must specify the --connect option for any of the ' 'You must specify the --connect option for any of the '
'connection-specific options such as --initiator to be ' 'connection-specific options such as --initiator to be '
@ -225,7 +227,8 @@ class CreateVolumeAttachment(command.ShowOne):
) )
attachment = volume_client.attachments.create( 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) return _format_attachment(attachment)
@ -346,7 +349,8 @@ class SetVolumeAttachment(command.ShowOne):
} }
attachment = volume_client.attachments.update( attachment = volume_client.attachments.update(
parsed_args.attachment, connector) parsed_args.attachment, connector
)
return _format_attachment(attachment) return _format_attachment(attachment)
@ -469,7 +473,8 @@ class ListVolumeAttachment(command.Lister):
attachments = volume_client.attachments.list( attachments = volume_client.attachments.list(
search_opts=search_opts, search_opts=search_opts,
marker=parsed_args.marker, marker=parsed_args.marker,
limit=parsed_args.limit) limit=parsed_args.limit,
)
column_headers = ( column_headers = (
'ID', 'ID',
@ -486,10 +491,7 @@ class ListVolumeAttachment(command.Lister):
return ( return (
column_headers, column_headers,
( (utils.get_item_properties(a, columns) for a in attachments),
utils.get_item_properties(a, columns)
for a in attachments
),
) )

View File

@ -155,7 +155,7 @@ class CreateVolumeGroup(command.ShowOne):
parser.add_argument( parser.add_argument(
'--description', '--description',
metavar='<description>', metavar='<description>',
help=_('Description of a volume group.') help=_('Description of a volume group.'),
) )
parser.add_argument( parser.add_argument(
'--availability-zone', '--availability-zone',
@ -178,8 +178,10 @@ class CreateVolumeGroup(command.ShowOne):
) )
self.log.warning(msg) self.log.warning(msg)
volume_group_type = parsed_args.volume_group_type or \ volume_group_type = (
parsed_args.volume_group_type_legacy parsed_args.volume_group_type
or parsed_args.volume_group_type_legacy
)
volume_types = parsed_args.volume_types[:] volume_types = parsed_args.volume_types[:]
volume_types.extend(parsed_args.volume_types_legacy) volume_types.extend(parsed_args.volume_types_legacy)
@ -229,8 +231,10 @@ class CreateVolumeGroup(command.ShowOne):
"[--source-group|--group-snapshot]' command" "[--source-group|--group-snapshot]' command"
) )
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
if (parsed_args.source_group is None and if (
parsed_args.group_snapshot is None): parsed_args.source_group is None
and parsed_args.group_snapshot is None
):
msg = _( msg = _(
"Either --source-group <source_group> or " "Either --source-group <source_group> or "
"'--group-snapshot <group_snapshot>' needs to be " "'--group-snapshot <group_snapshot>' needs to be "
@ -239,24 +243,28 @@ class CreateVolumeGroup(command.ShowOne):
) )
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
if parsed_args.availability_zone: if parsed_args.availability_zone:
msg = _("'--availability-zone' option will not work " msg = _(
"if creating group from source.") "'--availability-zone' option will not work "
"if creating group from source."
)
self.log.warning(msg) self.log.warning(msg)
source_group = None source_group = None
if parsed_args.source_group: if parsed_args.source_group:
source_group = utils.find_resource(volume_client.groups, source_group = utils.find_resource(
parsed_args.source_group) volume_client.groups, parsed_args.source_group
)
group_snapshot = None group_snapshot = None
if parsed_args.group_snapshot: if parsed_args.group_snapshot:
group_snapshot = utils.find_resource( group_snapshot = utils.find_resource(
volume_client.group_snapshots, volume_client.group_snapshots, parsed_args.group_snapshot
parsed_args.group_snapshot) )
group = volume_client.groups.create_from_src( group = volume_client.groups.create_from_src(
group_snapshot.id if group_snapshot else None, group_snapshot.id if group_snapshot else None,
source_group.id if source_group else None, source_group.id if source_group else None,
parsed_args.name, parsed_args.name,
parsed_args.description) parsed_args.description,
)
group = volume_client.groups.get(group.id) group = volume_client.groups.get(group.id)
return _format_group(group) return _format_group(group)
@ -281,7 +289,7 @@ class DeleteVolumeGroup(command.Command):
help=_( help=_(
'Delete the volume group even if it contains volumes. ' 'Delete the volume group even if it contains volumes. '
'This will delete any remaining volumes in the group.', 'This will delete any remaining volumes in the group.',
) ),
) )
return parser return parser
@ -300,8 +308,7 @@ class DeleteVolumeGroup(command.Command):
parsed_args.group, parsed_args.group,
) )
volume_client.groups.delete( volume_client.groups.delete(group.id, delete_volumes=parsed_args.force)
group.id, delete_volumes=parsed_args.force)
class SetVolumeGroup(command.ShowOne): class SetVolumeGroup(command.ShowOne):
@ -436,8 +443,7 @@ class ListVolumeGroup(command.Lister):
'all_tenants': parsed_args.all_projects, 'all_tenants': parsed_args.all_projects,
} }
groups = volume_client.groups.list( groups = volume_client.groups.list(search_opts=search_opts)
search_opts=search_opts)
column_headers = ( column_headers = (
'ID', 'ID',
@ -452,10 +458,7 @@ class ListVolumeGroup(command.Lister):
return ( return (
column_headers, 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) group = volume_client.groups.show(group.id, **kwargs)
if parsed_args.show_replication_targets: if parsed_args.show_replication_targets:
replication_targets = \ replication_targets = (
volume_client.groups.list_replication_targets(group.id) volume_client.groups.list_replication_targets(group.id)
)
group.replication_targets = replication_targets group.replication_targets = replication_targets
@ -580,7 +584,7 @@ class FailoverVolumeGroup(command.Command):
default=False, default=False,
help=_( help=_(
'Allow group with attached volumes to be failed over.', 'Allow group with attached volumes to be failed over.',
) ),
) )
parser.add_argument( parser.add_argument(
'--disallow-attached-volume', '--disallow-attached-volume',
@ -589,7 +593,7 @@ class FailoverVolumeGroup(command.Command):
default=False, default=False,
help=_( help=_(
'Disallow group with attached volumes to be failed over.', 'Disallow group with attached volumes to be failed over.',
) ),
) )
parser.add_argument( parser.add_argument(
'--secondary-backend-id', '--secondary-backend-id',

View File

@ -70,7 +70,7 @@ class CreateVolumeGroupSnapshot(command.ShowOne):
parser.add_argument( parser.add_argument(
'--description', '--description',
metavar='<description>', metavar='<description>',
help=_('Description of a volume group snapshot.') help=_('Description of a volume group snapshot.'),
) )
return parser return parser
@ -90,9 +90,8 @@ class CreateVolumeGroupSnapshot(command.ShowOne):
) )
snapshot = volume_client.group_snapshots.create( snapshot = volume_client.group_snapshots.create(
volume_group.id, volume_group.id, parsed_args.name, parsed_args.description
parsed_args.name, )
parsed_args.description)
return _format_group_snapshot(snapshot) return _format_group_snapshot(snapshot)
@ -175,8 +174,7 @@ class ListVolumeGroupSnapshot(command.Lister):
'all_tenants': parsed_args.all_projects, 'all_tenants': parsed_args.all_projects,
} }
groups = volume_client.group_snapshots.list( groups = volume_client.group_snapshots.list(search_opts=search_opts)
search_opts=search_opts)
column_headers = ( column_headers = (
'ID', 'ID',
@ -191,10 +189,7 @@ class ListVolumeGroupSnapshot(command.Lister):
return ( return (
column_headers, column_headers,
( (utils.get_item_properties(a, columns) for a in groups),
utils.get_item_properties(a, columns)
for a in groups
),
) )

View File

@ -70,7 +70,7 @@ class CreateVolumeGroupType(command.ShowOne):
parser.add_argument( parser.add_argument(
'--description', '--description',
metavar='<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 = parser.add_mutually_exclusive_group()
type_group.add_argument( type_group.add_argument(
@ -86,7 +86,7 @@ class CreateVolumeGroupType(command.ShowOne):
'--private', '--private',
dest='is_public', dest='is_public',
action='store_false', 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 return parser
@ -101,9 +101,8 @@ class CreateVolumeGroupType(command.ShowOne):
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
group_type = volume_client.group_types.create( group_type = volume_client.group_types.create(
parsed_args.name, parsed_args.name, parsed_args.description, parsed_args.is_public
parsed_args.description, )
parsed_args.is_public)
return _format_group_type(group_type) return _format_group_type(group_type)
@ -176,7 +175,7 @@ class SetVolumeGroupType(command.ShowOne):
'--private', '--private',
dest='is_public', dest='is_public',
action='store_false', action='store_false',
help=_('Make volume group type unavailable to other projects.') help=_('Make volume group type unavailable to other projects.'),
) )
parser.add_argument( parser.add_argument(
'--no-property', '--no-property',
@ -230,7 +229,8 @@ class SetVolumeGroupType(command.ShowOne):
if kwargs: if kwargs:
try: try:
group_type = volume_client.group_types.update( group_type = volume_client.group_types.update(
group_type.id, **kwargs) group_type.id, **kwargs
)
except Exception as e: except Exception as e:
LOG.error(_("Failed to update group type: %s"), e) LOG.error(_("Failed to update group type: %s"), e)
errors += 1 errors += 1
@ -251,9 +251,7 @@ class SetVolumeGroupType(command.ShowOne):
errors += 1 errors += 1
if errors > 0: if errors > 0:
msg = _( msg = _("Command Failed: One or more of the operations failed")
"Command Failed: One or more of the operations failed"
)
raise exceptions.CommandError() raise exceptions.CommandError()
return _format_group_type(group_type) return _format_group_type(group_type)
@ -370,10 +368,7 @@ class ListVolumeGroupType(command.Lister):
return ( return (
column_headers, column_headers,
( (utils.get_item_properties(a, columns) for a in group_types),
utils.get_item_properties(a, columns)
for a in group_types
),
) )

View File

@ -34,7 +34,7 @@ class DeleteMessage(command.Command):
'message_ids', 'message_ids',
metavar='<message-id>', metavar='<message-id>',
nargs='+', nargs='+',
help=_('Message(s) to delete (ID)') help=_('Message(s) to delete (ID)'),
) )
return parser return parser
@ -60,7 +60,8 @@ class DeleteMessage(command.Command):
if errors > 0: if errors > 0:
total = len(parsed_args.message_ids) total = len(parsed_args.message_ids)
msg = _('Failed to delete %(errors)s of %(total)s messages.') % { msg = _('Failed to delete %(errors)s of %(total)s messages.') % {
'errors': errors, 'total': total, 'errors': errors,
'total': total,
} }
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
@ -121,7 +122,8 @@ class ListMessages(command.Lister):
project_id = identity_common.find_project( project_id = identity_common.find_project(
identity_client, identity_client,
parsed_args.project, parsed_args.project,
parsed_args.project_domain).id parsed_args.project_domain,
).id
search_opts = { search_opts = {
'project_id': project_id, 'project_id': project_id,
@ -129,11 +131,12 @@ class ListMessages(command.Lister):
data = volume_client.messages.list( data = volume_client.messages.list(
search_opts=search_opts, search_opts=search_opts,
marker=parsed_args.marker, marker=parsed_args.marker,
limit=parsed_args.limit) limit=parsed_args.limit,
)
return ( return (
column_headers, 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( parser.add_argument(
'message_id', 'message_id',
metavar='<message-id>', metavar='<message-id>',
help=_('Message to show (ID).') help=_('Message to show (ID).'),
) )
return parser return parser