From 7ea6c8eb806cbe439a31144921c20433c8023af2 Mon Sep 17 00:00:00 2001 From: Zhi Yan Liu Date: Thu, 5 Sep 2013 13:46:50 +0800 Subject: [PATCH] Adding volume readonly-mode-update interface to Cinder client Adding volume readonly-mode-update interface to shell and client object (v1 and v2) to allow end user update volume read-only access mode flag. blueprint read-only-volumes Related-Id: I4c84614d6541d5f7c358abadb957da7b8c3d9c48 Change-Id: I2d587f301a21c0d42b8940465862da25a70ed5a8 Signed-off-by: Zhi Yan Liu --- cinderclient/tests/v1/fakes.py | 2 ++ cinderclient/tests/v1/test_shell.py | 9 +++++++++ cinderclient/tests/v1/test_volumes.py | 5 +++++ cinderclient/tests/v2/fakes.py | 2 ++ cinderclient/tests/v2/test_shell.py | 9 +++++++++ cinderclient/tests/v2/test_volumes.py | 5 +++++ cinderclient/v1/shell.py | 14 ++++++++++++++ cinderclient/v1/volumes.py | 17 +++++++++++++++-- cinderclient/v2/shell.py | 14 ++++++++++++++ cinderclient/v2/volumes.py | 14 ++++++++++++++ 10 files changed, 89 insertions(+), 2 deletions(-) diff --git a/cinderclient/tests/v1/fakes.py b/cinderclient/tests/v1/fakes.py index 6520da651..a5c34ec26 100644 --- a/cinderclient/tests/v1/fakes.py +++ b/cinderclient/tests/v1/fakes.py @@ -344,6 +344,8 @@ class FakeHTTPClient(base_client.HTTPClient): elif action == 'os-migrate_volume': assert 'host' in body[action] assert 'force_host_copy' in body[action] + elif action == 'os-update_readonly_flag': + assert body[action].keys() == ['readonly'] else: raise AssertionError("Unexpected action: %s" % action) return (resp, {}, _body) diff --git a/cinderclient/tests/v1/test_shell.py b/cinderclient/tests/v1/test_shell.py index edc5d7bf9..3b431b947 100644 --- a/cinderclient/tests/v1/test_shell.py +++ b/cinderclient/tests/v1/test_shell.py @@ -304,3 +304,12 @@ class ShellTest(utils.TestCase): 1234 key1=val1 key2=val2') self.assert_called('PUT', '/snapshots/1234/metadata', {'metadata': {'key1': 'val1', 'key2': 'val2'}}) + + def test_readonly_mode_update(self): + self.run_command('readonly-mode-update 1234 True') + expected = {'os-update_readonly_flag': {'readonly': True}} + self.assert_called('POST', '/volumes/1234/action', body=expected) + + self.run_command('readonly-mode-update 1234 False') + expected = {'os-update_readonly_flag': {'readonly': False}} + self.assert_called('POST', '/volumes/1234/action', body=expected) diff --git a/cinderclient/tests/v1/test_volumes.py b/cinderclient/tests/v1/test_volumes.py index f38fbe6fb..a72e6d848 100644 --- a/cinderclient/tests/v1/test_volumes.py +++ b/cinderclient/tests/v1/test_volumes.py @@ -101,3 +101,8 @@ class VolumesTest(utils.TestCase): cs.volumes.update_all_metadata(1234, {'k1': 'v1'}) cs.assert_called('PUT', '/volumes/1234/metadata', {'metadata': {'k1': 'v1'}}) + + def test_readonly_mode_update(self): + v = cs.volumes.get('1234') + cs.volumes.update_readonly_flag(v, True) + cs.assert_called('POST', '/volumes/1234/action') diff --git a/cinderclient/tests/v2/fakes.py b/cinderclient/tests/v2/fakes.py index 53bb35890..ef59289f1 100644 --- a/cinderclient/tests/v2/fakes.py +++ b/cinderclient/tests/v2/fakes.py @@ -351,6 +351,8 @@ class FakeHTTPClient(base_client.HTTPClient): elif action == 'os-migrate_volume': assert 'host' in body[action] assert 'force_host_copy' in body[action] + elif action == 'os-update_readonly_flag': + assert body[action].keys() == ['readonly'] else: raise AssertionError("Unexpected action: %s" % action) return (resp, {}, _body) diff --git a/cinderclient/tests/v2/test_shell.py b/cinderclient/tests/v2/test_shell.py index 58d8de3f6..cc29113ab 100644 --- a/cinderclient/tests/v2/test_shell.py +++ b/cinderclient/tests/v2/test_shell.py @@ -282,3 +282,12 @@ class ShellTest(utils.TestCase): 1234 key1=val1 key2=val2') self.assert_called('PUT', '/snapshots/1234/metadata', {'metadata': {'key1': 'val1', 'key2': 'val2'}}) + + def test_readonly_mode_update(self): + self.run_command('readonly-mode-update 1234 True') + expected = {'os-update_readonly_flag': {'readonly': True}} + self.assert_called('POST', '/volumes/1234/action', body=expected) + + self.run_command('readonly-mode-update 1234 False') + expected = {'os-update_readonly_flag': {'readonly': False}} + self.assert_called('POST', '/volumes/1234/action', body=expected) diff --git a/cinderclient/tests/v2/test_volumes.py b/cinderclient/tests/v2/test_volumes.py index 7e44f840b..24dd01924 100644 --- a/cinderclient/tests/v2/test_volumes.py +++ b/cinderclient/tests/v2/test_volumes.py @@ -104,3 +104,8 @@ class VolumesTest(utils.TestCase): cs.volumes.update_all_metadata(1234, {'k1': 'v1'}) cs.assert_called('PUT', '/volumes/1234/metadata', {'metadata': {'k1': 'v1'}}) + + def test_readonly_mode_update(self): + v = cs.volumes.get('1234') + cs.volumes.update_readonly_flag(v, True) + cs.assert_called('POST', '/volumes/1234/action') diff --git a/cinderclient/v1/shell.py b/cinderclient/v1/shell.py index 3a40dbf5f..0012388b0 100644 --- a/cinderclient/v1/shell.py +++ b/cinderclient/v1/shell.py @@ -1329,3 +1329,17 @@ def do_snapshot_metadata_update_all(cs, args): metadata = _extract_metadata(args) metadata = snapshot.update_all_metadata(metadata) utils.print_dict(metadata) + + +@utils.arg('volume', metavar='', help='ID of the volume to update.') +@utils.arg('read_only', + metavar='', + choices=['True', 'true', 'False', 'false'], + help='Flag to indicate whether to update volume to ' + 'read-only access mode.') +@utils.service_type('volume') +def do_readonly_mode_update(cs, args): + """Update volume read-only access mode read_only.""" + volume = utils.find_volume(cs, args.volume) + cs.volumes.update_readonly_flag(volume, + strutils.bool_from_string(args.read_only)) diff --git a/cinderclient/v1/volumes.py b/cinderclient/v1/volumes.py index 36758c7b0..7a70d3455 100644 --- a/cinderclient/v1/volumes.py +++ b/cinderclient/v1/volumes.py @@ -108,10 +108,9 @@ class Volume(base.Resource): def extend(self, volume, new_size): """Extend the size of the specified volume. - :param volume: The UUID of the volume to extend + :param volume: The UUID of the volume to extend. :param new_size: The desired size to extend volume to. """ - self.manager.extend(self, volume, new_size) def migrate_volume(self, host, force_host_copy): @@ -127,6 +126,15 @@ class Volume(base.Resource): """Update all metadata of this volume.""" return self.manager.update_all_metadata(self, metadata) + def update_readonly_flag(self, volume, read_only): + """Update the read-only access mode flag of the specified volume. + + :param volume: The UUID of the volume to update. + :param read_only: The value to indicate whether to update volume to + read-only access mode. + """ + self.manager.update_readonly_flag(self, volume, read_only) + class VolumeManager(base.ManagerWithFind): """ @@ -409,3 +417,8 @@ class VolumeManager(base.ManagerWithFind): body = {'metadata': metadata} return self._update("/volumes/%s/metadata" % base.getid(volume), body) + + def update_readonly_flag(self, volume, flag): + return self._action('os-update_readonly_flag', + base.getid(volume), + {'readonly': flag}) diff --git a/cinderclient/v2/shell.py b/cinderclient/v2/shell.py index fdec4cca9..bce7585a0 100644 --- a/cinderclient/v2/shell.py +++ b/cinderclient/v2/shell.py @@ -1408,3 +1408,17 @@ def do_snapshot_metadata_update_all(cs, args): metadata = _extract_metadata(args) metadata = snapshot.update_all_metadata(metadata) utils.print_dict(metadata) + + +@utils.arg('volume', metavar='', help='ID of the volume to update.') +@utils.arg('read_only', + metavar='', + choices=['True', 'true', 'False', 'false'], + help='Flag to indicate whether to update volume to ' + 'read-only access mode.') +@utils.service_type('volumev2') +def do_readonly_mode_update(cs, args): + """Update volume read-only access mode flag.""" + volume = utils.find_volume(cs, args.volume) + cs.volumes.update_readonly_flag(volume, + strutils.bool_from_string(args.read_only)) diff --git a/cinderclient/v2/volumes.py b/cinderclient/v2/volumes.py index e6dae9704..91ae43649 100644 --- a/cinderclient/v2/volumes.py +++ b/cinderclient/v2/volumes.py @@ -125,6 +125,15 @@ class Volume(base.Resource): """Update all metadata of this volume.""" return self.manager.update_all_metadata(self, metadata) + def update_readonly_flag(self, volume, read_only): + """Update the read-only access mode flag of the specified volume. + + :param volume: The UUID of the volume to update. + :param read_only: The value to indicate whether to update volume to + read-only access mode. + """ + self.manager.update_readonly_flag(self, volume, read_only) + class VolumeManager(base.ManagerWithFind): """Manage :class:`Volume` resources.""" @@ -391,3 +400,8 @@ class VolumeManager(base.ManagerWithFind): body = {'metadata': metadata} return self._update("/volumes/%s/metadata" % base.getid(volume), body) + + def update_readonly_flag(self, volume, flag): + return self._action('os-update_readonly_flag', + base.getid(volume), + {'readonly': flag})