diff options
author | Nathaniel Potter <nathaniel.potter@intel.com> | 2015-10-02 14:37:28 -0500 |
---|---|---|
committer | Nate Potter <nathaniel.potter@intel.com> | 2016-04-21 17:51:43 +0000 |
commit | 7590fe4b7d8a0b75b3257f6676c773052c8019c0 (patch) | |
tree | 4469c43b3a13fb4305943a3a65886d4b8ae5d6b8 | |
parent | 8d79acda0f5ff0e33ece7c84e65f5168b9b465bf (diff) | |
download | python-cinderclient-7590fe4b7d8a0b75b3257f6676c773052c8019c0.tar.gz |
Add options when uploading images to Glance
Added --visibility and --protected options
when uploading volumes to the image service.
DocImpact
Change-Id: Ie639179c5bbbaca4de62b42b368830afcfd8f7ac
Closes-Bug: #1288131
Depends-On: I6e6b2276af22b7809ea88289427c6873211b3faf
Signed-off-by: Nathaniel Potter <nathaniel.potter@intel.com>
-rw-r--r-- | cinderclient/api_versions.py | 2 | ||||
-rw-r--r-- | cinderclient/tests/unit/v2/fakes.py | 3 | ||||
-rw-r--r-- | cinderclient/tests/unit/v2/test_shell.py | 37 | ||||
-rw-r--r-- | cinderclient/v3/shell.py | 12 | ||||
-rw-r--r-- | cinderclient/v3/volumes.py | 25 |
5 files changed, 74 insertions, 5 deletions
diff --git a/cinderclient/api_versions.py b/cinderclient/api_versions.py index 7235d00..a74f3af 100644 --- a/cinderclient/api_versions.py +++ b/cinderclient/api_versions.py @@ -32,7 +32,7 @@ if not LOG.handlers: # key is a deprecated version and value is an alternative version. DEPRECATED_VERSIONS = {"1": "2"} -MAX_VERSION = "3.0" +MAX_VERSION = "3.1" _SUBSTITUTIONS = {} diff --git a/cinderclient/tests/unit/v2/fakes.py b/cinderclient/tests/unit/v2/fakes.py index 40c57d1..5e4ff3a 100644 --- a/cinderclient/tests/unit/v2/fakes.py +++ b/cinderclient/tests/unit/v2/fakes.py @@ -463,6 +463,9 @@ class FakeHTTPClient(base_client.HTTPClient): assert 'key' in body[action] elif action == 'os-show_image_metadata': assert body[action] is None + elif action == 'os-volume_upload_image': + assert 'image_name' in body[action] + _body = body else: raise AssertionError("Unexpected action: %s" % action) return (resp, {}, _body) diff --git a/cinderclient/tests/unit/v2/test_shell.py b/cinderclient/tests/unit/v2/test_shell.py index 156df53..07f27c1 100644 --- a/cinderclient/tests/unit/v2/test_shell.py +++ b/cinderclient/tests/unit/v2/test_shell.py @@ -355,6 +355,43 @@ class ShellTest(utils.TestCase): self.assert_called_anytime('POST', '/volumes', partial_body=expected) self.assert_called('GET', '/volumes/1234') + def test_upload_to_image(self): + expected = {'os-volume_upload_image': {'force': False, + 'container_format': 'bare', + 'disk_format': 'raw', + 'image_name': 'test-image', + 'protected': False, + 'visibility': 'private'}} + self.run_command('upload-to-image 1234 test-image') + self.assert_called_anytime('GET', '/volumes/1234') + self.assert_called_anytime('POST', '/volumes/1234/action', + body=expected) + + def test_upload_to_image_force(self): + expected = {'os-volume_upload_image': {'force': 'True', + 'container_format': 'bare', + 'disk_format': 'raw', + 'image_name': 'test-image', + 'protected': False, + 'visibility': 'private'}} + self.run_command('upload-to-image --force=True 1234 test-image') + self.assert_called_anytime('GET', '/volumes/1234') + self.assert_called_anytime('POST', '/volumes/1234/action', + body=expected) + + def test_upload_to_image_public_protected(self): + expected = {'os-volume_upload_image': {'force': False, + 'container_format': 'bare', + 'disk_format': 'raw', + 'image_name': 'test-image', + 'protected': 'True', + 'visibility': 'public'}} + self.run_command('upload-to-image --visibility=public ' + '--protected=True 1234 test-image') + self.assert_called_anytime('GET', '/volumes/1234') + self.assert_called_anytime('POST', '/volumes/1234/action', + body=expected) + def test_create_size_required_if_not_snapshot_or_clone(self): self.assertRaises(SystemExit, self.run_command, 'create') diff --git a/cinderclient/v3/shell.py b/cinderclient/v3/shell.py index f28dedb..7f79eff 100644 --- a/cinderclient/v3/shell.py +++ b/cinderclient/v3/shell.py @@ -1256,6 +1256,14 @@ def _find_volume_type(cs, vtype): help='The new image name.') @utils.arg('--image_name', help=argparse.SUPPRESS) +@utils.arg('--visibility', + metavar='<public|private>', + help='Makes image publicly accessible. Default=private.', + default='private') +@utils.arg('--protected', + metavar='<True|False>', + help='Prevents image from being deleted. Default=False.', + default=False) @utils.service_type('volumev3') def do_upload_to_image(cs, args): """Uploads volume to Image Service as an image.""" @@ -1263,7 +1271,9 @@ def do_upload_to_image(cs, args): _print_volume_image(volume.upload_to_image(args.force, args.image_name, args.container_format, - args.disk_format)) + args.disk_format, + args.visibility, + args.protected)) @utils.arg('volume', metavar='<volume>', help='ID of volume to migrate.') diff --git a/cinderclient/v3/volumes.py b/cinderclient/v3/volumes.py index f8d2432..eb9c3bc 100644 --- a/cinderclient/v3/volumes.py +++ b/cinderclient/v3/volumes.py @@ -15,6 +15,7 @@ """Volume interface (v3 extension).""" +from cinderclient import api_versions from cinderclient import base from cinderclient.openstack.common.apiclient import base as common_base @@ -110,10 +111,11 @@ class Volume(base.Resource): return self.manager.show_image_metadata(self) def upload_to_image(self, force, image_name, container_format, - disk_format): + disk_format, visibility, protected): """Upload a volume to image service as an image.""" return self.manager.upload_to_image(self, force, image_name, - container_format, disk_format) + container_format, disk_format, + visibility, protected) def force_delete(self): """Delete the specified volume ignoring its current state. @@ -451,8 +453,9 @@ class VolumeManager(base.ManagerWithFind): """ return self._action("os-show_image_metadata", volume) + @api_versions.wraps("2.0", "3.0") def upload_to_image(self, volume, force, image_name, container_format, - disk_format): + disk_format, visibility, protected): """Upload volume to image service as image. :param volume: The :class:`Volume` to upload. @@ -464,6 +467,22 @@ class VolumeManager(base.ManagerWithFind): 'container_format': container_format, 'disk_format': disk_format}) + @api_versions.wraps("3.1") + def upload_to_image(self, volume, force, image_name, container_format, + disk_format, visibility, protected): + """Upload volume to image service as image. + + :param volume: The :class:`Volume` to upload. + """ + return self._action('os-volume_upload_image', + volume, + {'force': force, + 'image_name': image_name, + 'container_format': container_format, + 'disk_format': disk_format, + 'visibility': visibility, + 'protected': protected}) + def force_delete(self, volume): """Delete the specified volume ignoring its current state. |