summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorHuanxuan Ao <huanxuan.ao@easystack.cn>2016-09-28 09:27:32 +0800
committerHuanxuan Ao <huanxuan.ao@easystack.cn>2016-10-18 14:34:05 +0800
commitdaffce3a6a31ac59ee10e3cc8fe421320da1704a (patch)
tree7c58f76614d5fda6ea154b41623cdef7e8f19b34 /openstackclient
parent5e3ec1b42faf7dc49722b58829b6c2cf5c15da79 (diff)
downloadpython-openstackclient-daffce3a6a31ac59ee10e3cc8fe421320da1704a.tar.gz
Add "--read-only" and "--read-write" options in "volume set"
Add "--read-only" and "--read-write" options in "volume set" command to set volume access mode. Implements: bp cinder-command-support Change-Id: I76ba85c7d3ff0eb026a9cbd794368d8b2b0d17fe
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/tests/unit/volume/v1/test_volume.py65
-rw-r--r--openstackclient/tests/unit/volume/v2/test_volume.py41
-rw-r--r--openstackclient/volume/v1/volume.py64
-rw-r--r--openstackclient/volume/v2/volume.py20
4 files changed, 162 insertions, 28 deletions
diff --git a/openstackclient/tests/unit/volume/v1/test_volume.py b/openstackclient/tests/unit/volume/v1/test_volume.py
index 73c00844..58de6cbd 100644
--- a/openstackclient/tests/unit/volume/v1/test_volume.py
+++ b/openstackclient/tests/unit/volume/v1/test_volume.py
@@ -844,8 +844,7 @@ class TestVolumeSet(TestVolume):
)
self.assertIsNone(result)
- @mock.patch.object(volume.LOG, 'error')
- def test_volume_set_size_smaller(self, mock_log_error):
+ def test_volume_set_size_smaller(self):
self._volume.status = 'available'
arglist = [
'--size', '1',
@@ -860,15 +859,11 @@ class TestVolumeSet(TestVolume):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = self.cmd.take_action(parsed_args)
-
- mock_log_error.assert_called_with("New size must be greater "
- "than %s GB",
- self._volume.size)
- self.assertIsNone(result)
+ self.assertRaises(exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
- @mock.patch.object(volume.LOG, 'error')
- def test_volume_set_size_not_available(self, mock_log_error):
+ def test_volume_set_size_not_available(self):
self._volume.status = 'error'
arglist = [
'--size', '130',
@@ -883,12 +878,9 @@ class TestVolumeSet(TestVolume):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = self.cmd.take_action(parsed_args)
-
- mock_log_error.assert_called_with("Volume is in %s state, it must be "
- "available before size can be "
- "extended", 'error')
- self.assertIsNone(result)
+ self.assertRaises(exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
def test_volume_set_property(self):
arglist = [
@@ -896,6 +888,8 @@ class TestVolumeSet(TestVolume):
self._volume.display_name,
]
verifylist = [
+ ('read_only', False),
+ ('read_write', False),
('name', None),
('description', None),
('size', None),
@@ -916,6 +910,7 @@ class TestVolumeSet(TestVolume):
self._volume.id,
metadata
)
+ self.volumes_mock.update_readonly_flag.assert_not_called()
self.assertIsNone(result)
def test_volume_set_bootable(self):
@@ -943,6 +938,44 @@ class TestVolumeSet(TestVolume):
self.volumes_mock.set_bootable.assert_called_with(
self._volume.id, verifylist[index][0][1])
+ def test_volume_set_readonly(self):
+ arglist = [
+ '--read-only',
+ self._volume.id
+ ]
+ verifylist = [
+ ('read_only', True),
+ ('read_write', False),
+ ('volume', self._volume.id)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.update_readonly_flag.assert_called_once_with(
+ self._volume.id,
+ True)
+ self.assertIsNone(result)
+
+ def test_volume_set_read_write(self):
+ arglist = [
+ '--read-write',
+ self._volume.id
+ ]
+ verifylist = [
+ ('read_only', False),
+ ('read_write', True),
+ ('volume', self._volume.id)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.update_readonly_flag.assert_called_once_with(
+ self._volume.id,
+ False)
+ self.assertIsNone(result)
+
class TestVolumeShow(TestVolume):
diff --git a/openstackclient/tests/unit/volume/v2/test_volume.py b/openstackclient/tests/unit/volume/v2/test_volume.py
index f4a7c142..4e4c233b 100644
--- a/openstackclient/tests/unit/volume/v2/test_volume.py
+++ b/openstackclient/tests/unit/volume/v2/test_volume.py
@@ -1033,6 +1033,8 @@ class TestVolumeSet(TestVolume):
self.new_volume.id
]
verifylist = [
+ ('read_only', False),
+ ('read_write', False),
('state', 'error'),
('volume', self.new_volume.id)
]
@@ -1042,6 +1044,7 @@ class TestVolumeSet(TestVolume):
result = self.cmd.take_action(parsed_args)
self.volumes_mock.reset_state.assert_called_with(
self.new_volume.id, 'error')
+ self.volumes_mock.update_readonly_flag.assert_not_called()
self.assertIsNone(result)
def test_volume_set_state_failed(self):
@@ -1090,6 +1093,44 @@ class TestVolumeSet(TestVolume):
self.volumes_mock.set_bootable.assert_called_with(
self.new_volume.id, verifylist[index][0][1])
+ def test_volume_set_readonly(self):
+ arglist = [
+ '--read-only',
+ self.new_volume.id
+ ]
+ verifylist = [
+ ('read_only', True),
+ ('read_write', False),
+ ('volume', self.new_volume.id)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.update_readonly_flag.assert_called_once_with(
+ self.new_volume.id,
+ True)
+ self.assertIsNone(result)
+
+ def test_volume_set_read_write(self):
+ arglist = [
+ '--read-write',
+ self.new_volume.id
+ ]
+ verifylist = [
+ ('read_only', False),
+ ('read_write', True),
+ ('volume', self.new_volume.id)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.update_readonly_flag.assert_called_once_with(
+ self.new_volume.id,
+ False)
+ self.assertIsNone(result)
+
class TestVolumeShow(TestVolume):
diff --git a/openstackclient/volume/v1/volume.py b/openstackclient/volume/v1/volume.py
index cafe8ce6..5b8219ca 100644
--- a/openstackclient/volume/v1/volume.py
+++ b/openstackclient/volume/v1/volume.py
@@ -388,38 +388,78 @@ class SetVolume(command.Command):
action="store_true",
help=_("Mark volume as non-bootable")
)
+ readonly_group = parser.add_mutually_exclusive_group()
+ readonly_group.add_argument(
+ "--read-only",
+ action="store_true",
+ help=_("Set volume to read-only access mode")
+ )
+ readonly_group.add_argument(
+ "--read-write",
+ action="store_true",
+ help=_("Set volume to read-write access mode")
+ )
return parser
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
+ result = 0
if parsed_args.size:
- if volume.status != 'available':
- LOG.error(_("Volume is in %s state, it must be available "
- "before size can be extended"), volume.status)
- return
- if parsed_args.size <= volume.size:
- LOG.error(_("New size must be greater than %s GB"),
- volume.size)
- return
- volume_client.volumes.extend(volume.id, parsed_args.size)
-
+ try:
+ if volume.status != 'available':
+ msg = (_("Volume is in %s state, it must be available "
+ "before size can be extended") % volume.status)
+ raise exceptions.CommandError(msg)
+ if parsed_args.size <= volume.size:
+ msg = (_("New size must be greater than %s GB")
+ % volume.size)
+ raise exceptions.CommandError(msg)
+ volume_client.volumes.extend(volume.id, parsed_args.size)
+ except Exception as e:
+ LOG.error(_("Failed to set volume size: %s"), e)
+ result += 1
if parsed_args.property:
- volume_client.volumes.set_metadata(volume.id, parsed_args.property)
+ try:
+ volume_client.volumes.set_metadata(
+ volume.id,
+ parsed_args.property)
+ except Exception as e:
+ LOG.error(_("Failed to set volume property: %s"), e)
+ result += 1
if parsed_args.bootable or parsed_args.non_bootable:
try:
volume_client.volumes.set_bootable(
volume.id, parsed_args.bootable)
except Exception as e:
LOG.error(_("Failed to set volume bootable property: %s"), e)
+ result += 1
+ if parsed_args.read_only or parsed_args.read_write:
+ try:
+ volume_client.volumes.update_readonly_flag(
+ volume.id,
+ parsed_args.read_only)
+ except Exception as e:
+ LOG.error(_("Failed to set volume read-only access "
+ "mode flag: %s"), e)
+ result += 1
kwargs = {}
if parsed_args.name:
kwargs['display_name'] = parsed_args.name
if parsed_args.description:
kwargs['display_description'] = parsed_args.description
if kwargs:
- volume_client.volumes.update(volume.id, **kwargs)
+ try:
+ volume_client.volumes.update(volume.id, **kwargs)
+ except Exception as e:
+ LOG.error(_("Failed to update volume display name "
+ "or display description: %s"), e)
+ result += 1
+
+ if result > 0:
+ raise exceptions.CommandError(_("One or more of the "
+ "set operations failed"))
class ShowVolume(command.ShowOne):
diff --git a/openstackclient/volume/v2/volume.py b/openstackclient/volume/v2/volume.py
index cb409711..695139bd 100644
--- a/openstackclient/volume/v2/volume.py
+++ b/openstackclient/volume/v2/volume.py
@@ -473,6 +473,17 @@ class SetVolume(command.Command):
action="store_true",
help=_("Mark volume as non-bootable")
)
+ readonly_group = parser.add_mutually_exclusive_group()
+ readonly_group.add_argument(
+ "--read-only",
+ action="store_true",
+ help=_("Set volume to read-only access mode")
+ )
+ readonly_group.add_argument(
+ "--read-write",
+ action="store_true",
+ help=_("Set volume to read-write access mode")
+ )
return parser
def take_action(self, parsed_args):
@@ -523,6 +534,15 @@ class SetVolume(command.Command):
except Exception as e:
LOG.error(_("Failed to set volume bootable property: %s"), e)
result += 1
+ if parsed_args.read_only or parsed_args.read_write:
+ try:
+ volume_client.volumes.update_readonly_flag(
+ volume.id,
+ parsed_args.read_only)
+ except Exception as e:
+ LOG.error(_("Failed to set volume read-only access "
+ "mode flag: %s"), e)
+ result += 1
kwargs = {}
if parsed_args.name: