diff --git a/.gitignore b/.gitignore index ca16ebd..6da4b4a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /python-openstackclient-0.2.2.tar.gz +/python-openstackclient-0.3.0.tar.gz diff --git a/0001-Add-to-clientmanager-tests.patch b/0001-Add-to-clientmanager-tests.patch deleted file mode 100644 index f0e13b9..0000000 --- a/0001-Add-to-clientmanager-tests.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 05cb895999c0a0811586b02dd61847c57a04793b Mon Sep 17 00:00:00 2001 -From: Dean Troyer -Date: Thu, 5 Sep 2013 12:54:14 -0500 -Subject: [PATCH] Add to clientmanager tests - -Change-Id: Iea59c494f31de9c3e1d662f89e6e2babcc8fbd61 ---- - openstackclient/tests/common/test_clientmanager.py | 25 +++++++++++++++++++++- - 1 file changed, 24 insertions(+), 1 deletion(-) - -diff --git a/openstackclient/tests/common/test_clientmanager.py b/openstackclient/tests/common/test_clientmanager.py -index 395f6ec..6aee711 100644 ---- a/openstackclient/tests/common/test_clientmanager.py -+++ b/openstackclient/tests/common/test_clientmanager.py -@@ -1,4 +1,4 @@ --# Copyright 2012-2013 OpenStack, LLC. -+# Copyright 2012-2013 OpenStack Foundation - # - # Licensed under the Apache License, Version 2.0 (the "License"); you may - # not use this file except in compliance with the License. You may obtain -@@ -17,6 +17,10 @@ from openstackclient.common import clientmanager - from openstackclient.tests import utils - - -+AUTH_TOKEN = "foobar" -+AUTH_URL = "http://0.0.0.0" -+ -+ - class Container(object): - attr = clientmanager.ClientCache(lambda x: object()) - -@@ -28,8 +32,27 @@ class TestClientManager(utils.TestCase): - def setUp(self): - super(TestClientManager, self).setUp() - -+ api_version = {"identity": "2.0"} -+ -+ self.client_manager = clientmanager.ClientManager( -+ token=AUTH_TOKEN, -+ url=AUTH_URL, -+ auth_url=AUTH_URL, -+ api_version=api_version, -+ ) -+ - def test_singleton(self): - # NOTE(dtroyer): Verify that the ClientCache descriptor only invokes - # the factory one time and always returns the same value after that. - c = Container() - self.assertEqual(c.attr, c.attr) -+ -+ def test_make_client_identity_default(self): -+ self.assertEqual( -+ self.client_manager.identity.auth_token, -+ AUTH_TOKEN, -+ ) -+ self.assertEqual( -+ self.client_manager.identity.management_url, -+ AUTH_URL, -+ ) diff --git a/0001-Restore-compatibility-with-older-python-keyring.patch b/0001-Restore-compatibility-with-older-python-keyring.patch new file mode 100644 index 0000000..b1ec835 --- /dev/null +++ b/0001-Restore-compatibility-with-older-python-keyring.patch @@ -0,0 +1,23 @@ +From d9b0ee15ee33d9ca1f3d00aff4b442e5d8b54619 Mon Sep 17 00:00:00 2001 +From: Jakub Ruzicka +Date: Wed, 8 Jan 2014 14:06:39 +0100 +Subject: [PATCH] Restore compatibility with older python-keyring + +EPEL provides python-keyring version 0.7 which requires old usage. +--- + openstackclient/common/openstackkeyring.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/openstackclient/common/openstackkeyring.py b/openstackclient/common/openstackkeyring.py +index 34c994b..e7431e5 100644 +--- a/openstackclient/common/openstackkeyring.py ++++ b/openstackclient/common/openstackkeyring.py +@@ -24,7 +24,7 @@ import os + KEYRING_FILE = os.path.join(os.path.expanduser('~'), '.openstack-keyring.cfg') + + +-class OpenstackKeyring(keyring.backends.file.BaseKeyring): ++class OpenstackKeyring(keyring.backend.BasicFileKeyring): + """Openstack Keyring to store encrypted password.""" + filename = KEYRING_FILE + diff --git a/0002-Add-object-store-show-commands.patch b/0002-Add-object-store-show-commands.patch deleted file mode 100644 index 3c5d4aa..0000000 --- a/0002-Add-object-store-show-commands.patch +++ /dev/null @@ -1,1052 +0,0 @@ -From dcd2d05015828de446932f3d9a7fb70994849934 Mon Sep 17 00:00:00 2001 -From: Dean Troyer -Date: Fri, 30 Aug 2013 17:55:37 -0500 -Subject: [PATCH] Add object-store show commands - -* Add lib.container.show_container() and lib.object.show_object() -* Add container and object show commands - -Change-Id: I963d664c55b59739453345f0f353aa2eaf1bf70e ---- - openstackclient/object/v1/container.py | 29 +- - openstackclient/object/v1/lib/container.py | 36 ++ - openstackclient/object/v1/lib/object.py | 51 +++ - openstackclient/object/v1/object.py | 34 ++ - openstackclient/tests/object/test_container.py | 46 +++ - openstackclient/tests/object/test_object.py | 51 +++ - .../tests/object/v1/lib/test_container.py | 59 ++- - openstackclient/tests/object/v1/lib/test_object.py | 77 +++- - setup.cfg | 452 +++++++++++---------- - 9 files changed, 614 insertions(+), 221 deletions(-) - -diff --git a/openstackclient/object/v1/container.py b/openstackclient/object/v1/container.py -index 8c4db66..68b14fc 100644 ---- a/openstackclient/object/v1/container.py -+++ b/openstackclient/object/v1/container.py -@@ -17,8 +17,10 @@ - - - import logging -+import six - - from cliff import lister -+from cliff import show - - from openstackclient.common import utils - from openstackclient.object.v1.lib import container as lib_container -@@ -91,10 +93,35 @@ class ListContainer(lister.Lister): - self.app.client_manager.object.endpoint, - **kwargs - ) -- #print "data: %s" % data - - return (columns, - (utils.get_dict_properties( - s, columns, - formatters={}, - ) for s in data)) -+ -+ -+class ShowContainer(show.ShowOne): -+ """Show container information""" -+ -+ log = logging.getLogger(__name__ + '.ShowContainer') -+ -+ def get_parser(self, prog_name): -+ parser = super(ShowContainer, self).get_parser(prog_name) -+ parser.add_argument( -+ 'container', -+ metavar='', -+ help='Container name to display', -+ ) -+ return parser -+ -+ def take_action(self, parsed_args): -+ self.log.debug('take_action(%s)' % parsed_args) -+ -+ data = lib_container.show_container( -+ self.app.restapi, -+ self.app.client_manager.object.endpoint, -+ parsed_args.container, -+ ) -+ -+ return zip(*sorted(six.iteritems(data))) -diff --git a/openstackclient/object/v1/lib/container.py b/openstackclient/object/v1/lib/container.py -index f30533c..5103d9d 100644 ---- a/openstackclient/object/v1/lib/container.py -+++ b/openstackclient/object/v1/lib/container.py -@@ -16,6 +16,11 @@ - - """Object v1 API library""" - -+try: -+ from urllib.parse import urlparse -+except ImportError: -+ from urlparse import urlparse -+ - - def list_containers( - api, -@@ -75,3 +80,34 @@ def list_containers( - url = "%s?%s" % (object_url, query) - response = api.request('GET', url) - return response.json() -+ -+ -+def show_container( -+ api, -+ url, -+ container, -+): -+ """Get container details -+ -+ :param api: a restapi object -+ :param url: endpoint -+ :param container: name of container to show -+ :returns: dict of returned headers -+ """ -+ -+ object_url = "%s/%s" % (url, container) -+ url_parts = urlparse(url) -+ response = api.request('HEAD', object_url) -+ data = { -+ 'account': url_parts.path.split('/')[-1], -+ 'container': container, -+ } -+ data['object_count'] = response.headers.get( -+ 'x-container-object-count', None) -+ data['bytes_used'] = response.headers.get('x-container-bytes-used', None) -+ data['read_acl'] = response.headers.get('x-container-read', None) -+ data['write_acl'] = response.headers.get('x-container-write', None) -+ data['sync_to'] = response.headers.get('x-container-sync-to', None) -+ data['sync_key'] = response.headers.get('x-container-sync-key', None) -+ -+ return data -diff --git a/openstackclient/object/v1/lib/object.py b/openstackclient/object/v1/lib/object.py -index d7c4a1c..8ad5e5a 100644 ---- a/openstackclient/object/v1/lib/object.py -+++ b/openstackclient/object/v1/lib/object.py -@@ -16,6 +16,13 @@ - - """Object v1 API library""" - -+import six -+ -+try: -+ from urllib.parse import urlparse -+except ImportError: -+ from urlparse import urlparse -+ - - def list_objects( - api, -@@ -95,3 +102,47 @@ def list_objects( - url = "%s/%s?%s" % (object_url, container, query) - response = api.request('GET', url) - return response.json() -+ -+ -+def show_object( -+ api, -+ url, -+ container, -+ obj, -+): -+ """Get object details -+ -+ :param api: a restapi object -+ :param url: endpoint -+ :param container: container name to get a listing for -+ :returns: dict of object properties -+ """ -+ -+ object_url = "%s/%s/%s" % (url, container, obj) -+ url_parts = urlparse(url) -+ response = api.request('HEAD', object_url) -+ data = { -+ 'account': url_parts.path.split('/')[-1], -+ 'container': container, -+ 'object': obj, -+ } -+ #print "data: %s" % data -+ data['content-type'] = response.headers.get('content-type', None) -+ if 'content-length' in response.headers: -+ data['content-length'] = response.headers.get('content-length', None) -+ if 'last-modified' in response.headers: -+ data['last-modified'] = response.headers.get('last-modified', None) -+ if 'etag' in response.headers: -+ data['etag'] = response.headers.get('etag', None) -+ if 'x-object-manifest' in response.headers: -+ data['x-object-manifest'] = response.headers.get( -+ 'x-object-manifest', None) -+ for key, value in six.iteritems(response.headers): -+ if key.startswith('x-object-meta-'): -+ data[key[len('x-object-meta-'):].title()] = value -+ elif key not in ( -+ 'content-type', 'content-length', 'last-modified', -+ 'etag', 'date', 'x-object-manifest'): -+ data[key.title()] = value -+ -+ return data -diff --git a/openstackclient/object/v1/object.py b/openstackclient/object/v1/object.py -index c6bd755..426a52a 100644 ---- a/openstackclient/object/v1/object.py -+++ b/openstackclient/object/v1/object.py -@@ -17,8 +17,10 @@ - - - import logging -+import six - - from cliff import lister -+from cliff import show - - from openstackclient.common import utils - from openstackclient.object.v1.lib import object as lib_object -@@ -116,3 +118,35 @@ class ListObject(lister.Lister): - s, columns, - formatters={}, - ) for s in data)) -+ -+ -+class ShowObject(show.ShowOne): -+ """Show object information""" -+ -+ log = logging.getLogger(__name__ + '.ShowObject') -+ -+ def get_parser(self, prog_name): -+ parser = super(ShowObject, self).get_parser(prog_name) -+ parser.add_argument( -+ 'container', -+ metavar='', -+ help='Container name for object to display', -+ ) -+ parser.add_argument( -+ 'object', -+ metavar='', -+ help='Object name to display', -+ ) -+ return parser -+ -+ def take_action(self, parsed_args): -+ self.log.debug('take_action(%s)' % parsed_args) -+ -+ data = lib_object.show_object( -+ self.app.restapi, -+ self.app.client_manager.object.endpoint, -+ parsed_args.container, -+ parsed_args.object, -+ ) -+ -+ return zip(*sorted(six.iteritems(data))) -diff --git a/openstackclient/tests/object/test_container.py b/openstackclient/tests/object/test_container.py -index 9b53e36..24d6763 100644 ---- a/openstackclient/tests/object/test_container.py -+++ b/openstackclient/tests/object/test_container.py -@@ -313,3 +313,49 @@ class TestContainerList(TestObject): - (object_fakes.container_name_3, ), - ) - self.assertEqual(tuple(data), datalist) -+ -+ -+@mock.patch( -+ 'openstackclient.object.v1.container.lib_container.show_container' -+) -+class TestContainerShow(TestObject): -+ -+ def setUp(self): -+ super(TestContainerShow, self).setUp() -+ -+ # Get the command object to test -+ self.cmd = container.ShowContainer(self.app, None) -+ -+ def test_container_show(self, c_mock): -+ c_mock.return_value = copy.deepcopy(object_fakes.CONTAINER) -+ -+ arglist = [ -+ object_fakes.container_name, -+ ] -+ verifylist = [ -+ ('container', object_fakes.container_name), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ } -+ # lib.container.show_container(api, url, container) -+ c_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ object_fakes.container_name, -+ **kwargs -+ ) -+ -+ collist = ('bytes', 'count', 'name') -+ self.assertEqual(columns, collist) -+ datalist = ( -+ object_fakes.container_bytes, -+ object_fakes.container_count, -+ object_fakes.container_name, -+ ) -+ self.assertEqual(data, datalist) -diff --git a/openstackclient/tests/object/test_object.py b/openstackclient/tests/object/test_object.py -index ddd5b59..1ceb0a5 100644 ---- a/openstackclient/tests/object/test_object.py -+++ b/openstackclient/tests/object/test_object.py -@@ -360,3 +360,54 @@ class TestObjectList(TestObject): - (object_fakes.object_name_2, ), - ) - self.assertEqual(tuple(data), datalist) -+ -+ -+@mock.patch( -+ 'openstackclient.object.v1.object.lib_object.show_object' -+) -+class TestObjectShow(TestObject): -+ -+ def setUp(self): -+ super(TestObjectShow, self).setUp() -+ -+ # Get the command object to test -+ self.cmd = obj.ShowObject(self.app, None) -+ -+ def test_object_show(self, c_mock): -+ c_mock.return_value = copy.deepcopy(object_fakes.OBJECT) -+ -+ arglist = [ -+ object_fakes.container_name, -+ object_fakes.object_name_1, -+ ] -+ verifylist = [ -+ ('container', object_fakes.container_name), -+ ('object', object_fakes.object_name_1), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ } -+ # lib.container.show_container(api, url, container) -+ c_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ object_fakes.container_name, -+ object_fakes.object_name_1, -+ **kwargs -+ ) -+ -+ collist = ('bytes', 'content_type', 'hash', 'last_modified', 'name') -+ self.assertEqual(columns, collist) -+ datalist = ( -+ object_fakes.object_bytes_1, -+ object_fakes.object_content_type_1, -+ object_fakes.object_hash_1, -+ object_fakes.object_modified_1, -+ object_fakes.object_name_1, -+ ) -+ self.assertEqual(data, datalist) -diff --git a/openstackclient/tests/object/v1/lib/test_container.py b/openstackclient/tests/object/v1/lib/test_container.py -index 1c0112c..3b9976a 100644 ---- a/openstackclient/tests/object/v1/lib/test_container.py -+++ b/openstackclient/tests/object/v1/lib/test_container.py -@@ -15,19 +15,17 @@ - - """Test Object API library module""" - --from __future__ import unicode_literals -- - import mock - -- - from openstackclient.object.v1.lib import container as lib_container - from openstackclient.tests.common import test_restapi as restapi - from openstackclient.tests import fakes - from openstackclient.tests import utils - - -+fake_account = 'q12we34r' - fake_auth = '11223344556677889900' --fake_url = 'http://gopher.com' -+fake_url = 'http://gopher.com/v1/' + fake_account - - fake_container = 'rainbarrel' - -@@ -38,18 +36,18 @@ class FakeClient(object): - self.token = fake_auth - - --class TestObject(utils.TestCommand): -+class TestContainer(utils.TestCommand): - - def setUp(self): -- super(TestObject, self).setUp() -+ super(TestContainer, self).setUp() - self.app.client_manager = fakes.FakeClientManager() - self.app.client_manager.object = FakeClient() - self.app.restapi = mock.MagicMock() - - --class TestObjectListContainers(TestObject): -+class TestContainerList(TestContainer): - -- def test_list_containers_no_options(self): -+ def test_container_list_no_options(self): - resp = [{'name': 'is-name'}] - self.app.restapi.request.return_value = restapi.FakeResponse(data=resp) - -@@ -65,7 +63,7 @@ class TestObjectListContainers(TestObject): - ) - self.assertEqual(data, resp) - -- def test_list_containers_marker(self): -+ def test_container_list_marker(self): - resp = [{'name': 'is-name'}] - self.app.restapi.request.return_value = restapi.FakeResponse(data=resp) - -@@ -82,7 +80,7 @@ class TestObjectListContainers(TestObject): - ) - self.assertEqual(data, resp) - -- def test_list_containers_limit(self): -+ def test_container_list_limit(self): - resp = [{'name': 'is-name'}] - self.app.restapi.request.return_value = restapi.FakeResponse(data=resp) - -@@ -99,7 +97,7 @@ class TestObjectListContainers(TestObject): - ) - self.assertEqual(data, resp) - -- def test_list_containers_end_marker(self): -+ def test_container_list_end_marker(self): - resp = [{'name': 'is-name'}] - self.app.restapi.request.return_value = restapi.FakeResponse(data=resp) - -@@ -116,7 +114,7 @@ class TestObjectListContainers(TestObject): - ) - self.assertEqual(data, resp) - -- def test_list_containers_prefix(self): -+ def test_container_list_prefix(self): - resp = [{'name': 'is-name'}] - self.app.restapi.request.return_value = restapi.FakeResponse(data=resp) - -@@ -133,7 +131,7 @@ class TestObjectListContainers(TestObject): - ) - self.assertEqual(data, resp) - -- def test_list_containers_full_listing(self): -+ def test_container_list_full_listing(self): - - def side_effect(*args, **kwargs): - rv = self.app.restapi.request.return_value -@@ -159,3 +157,38 @@ class TestObjectListContainers(TestObject): - fake_url + '?format=json&marker=is-name', - ) - self.assertEqual(data, resp) -+ -+ -+class TestContainerShow(TestContainer): -+ -+ def test_container_show_no_options(self): -+ resp = { -+ 'x-container-object-count': 1, -+ 'x-container-bytes-used': 577, -+ } -+ self.app.restapi.request.return_value = \ -+ restapi.FakeResponse(headers=resp) -+ -+ data = lib_container.show_container( -+ self.app.restapi, -+ self.app.client_manager.object.endpoint, -+ 'is-name', -+ ) -+ -+ # Check expected values -+ self.app.restapi.request.assert_called_with( -+ 'HEAD', -+ fake_url + '/is-name', -+ ) -+ -+ data_expected = { -+ 'account': fake_account, -+ 'container': 'is-name', -+ 'object_count': 1, -+ 'bytes_used': 577, -+ 'read_acl': None, -+ 'write_acl': None, -+ 'sync_to': None, -+ 'sync_key': None, -+ } -+ self.assertEqual(data, data_expected) -diff --git a/openstackclient/tests/object/v1/lib/test_object.py b/openstackclient/tests/object/v1/lib/test_object.py -index b4793cc..0104183 100644 ---- a/openstackclient/tests/object/v1/lib/test_object.py -+++ b/openstackclient/tests/object/v1/lib/test_object.py -@@ -15,8 +15,6 @@ - - """Test Object API library module""" - --from __future__ import unicode_literals -- - import mock - - from openstackclient.object.v1.lib import object as lib_object -@@ -25,10 +23,12 @@ from openstackclient.tests import fakes - from openstackclient.tests import utils - - -+fake_account = 'q12we34r' - fake_auth = '11223344556677889900' --fake_url = 'http://gopher.com' -+fake_url = 'http://gopher.com/v1/' + fake_account - - fake_container = 'rainbarrel' -+fake_object = 'raindrop' - - - class FakeClient(object): -@@ -203,3 +203,74 @@ class TestObjectListObjects(TestObject): - fake_url + '/' + fake_container + '?format=json&marker=is-name', - ) - self.assertEqual(data, resp) -+ -+ -+class TestObjectShowObjects(TestObject): -+ -+ def test_object_show_no_options(self): -+ resp = { -+ 'content-type': 'text/alpha', -+ } -+ self.app.restapi.request.return_value = \ -+ restapi.FakeResponse(headers=resp) -+ -+ data = lib_object.show_object( -+ self.app.restapi, -+ self.app.client_manager.object.endpoint, -+ fake_container, -+ fake_object, -+ ) -+ -+ # Check expected values -+ self.app.restapi.request.assert_called_with( -+ 'HEAD', -+ fake_url + '/%s/%s' % (fake_container, fake_object), -+ ) -+ -+ data_expected = { -+ 'account': fake_account, -+ 'container': fake_container, -+ 'object': fake_object, -+ 'content-type': 'text/alpha', -+ } -+ self.assertEqual(data, data_expected) -+ -+ def test_object_show_all_options(self): -+ resp = { -+ 'content-type': 'text/alpha', -+ 'content-length': 577, -+ 'last-modified': '20130101', -+ 'etag': 'qaz', -+ 'x-object-manifest': None, -+ 'x-object-meta-wife': 'Wilma', -+ 'x-tra-header': 'yabba-dabba-do', -+ } -+ self.app.restapi.request.return_value = \ -+ restapi.FakeResponse(headers=resp) -+ -+ data = lib_object.show_object( -+ self.app.restapi, -+ self.app.client_manager.object.endpoint, -+ fake_container, -+ fake_object, -+ ) -+ -+ # Check expected values -+ self.app.restapi.request.assert_called_with( -+ 'HEAD', -+ fake_url + '/%s/%s' % (fake_container, fake_object), -+ ) -+ -+ data_expected = { -+ 'account': fake_account, -+ 'container': fake_container, -+ 'object': fake_object, -+ 'content-type': 'text/alpha', -+ 'content-length': 577, -+ 'last-modified': '20130101', -+ 'etag': 'qaz', -+ 'x-object-manifest': None, -+ 'Wife': 'Wilma', -+ 'X-Tra-Header': 'yabba-dabba-do', -+ } -+ self.assertEqual(data, data_expected) -diff --git a/setup.cfg b/setup.cfg -index b36daf3..48f7b76 100644 ---- a/setup.cfg -+++ b/setup.cfg -@@ -22,210 +22,254 @@ packages = - openstackclient - - [entry_points] --console_scripts = -- openstack = openstackclient.shell:main --openstack.cli = --openstack.common = -- limits_show = openstackclient.common.limits:ShowLimits -- quota_set = openstackclient.common.quota:SetQuota -- quota_show = openstackclient.common.quota:ShowQuota --openstack.compute.v2 = -- agent_create = openstackclient.compute.v2.agent:CreateAgent -- agent_delete = openstackclient.compute.v2.agent:DeleteAgent -- agent_list = openstackclient.compute.v2.agent:ListAgent -- agent_set = openstackclient.compute.v2.agent:SetAgent -- aggregate_add_host = openstackclient.compute.v2.aggregate:AddAggregateHost -- aggregate_create = openstackclient.compute.v2.aggregate:CreateAggregate -- aggregate_delete = openstackclient.compute.v2.aggregate:DeleteAggregate -- aggregate_list = openstackclient.compute.v2.aggregate:ListAggregate -- aggregate_remove_host = openstackclient.compute.v2.aggregate:RemoveAggregateHost -- aggregate_set = openstackclient.compute.v2.aggregate:SetAggregate -- aggregate_show = openstackclient.compute.v2.aggregate:ShowAggregate -- compute_service_list = openstackclient.compute.v2.service:ListService -- compute_service_set = openstackclient.compute.v2.service:SetService -- console_log_show = openstackclient.compute.v2.console:ShowConsoleLog -- console_url_show = openstackclient.compute.v2.console:ShowConsoleURL -- flavor_create = openstackclient.compute.v2.flavor:CreateFlavor -- flavor_delete = openstackclient.compute.v2.flavor:DeleteFlavor -- flavor_list = openstackclient.compute.v2.flavor:ListFlavor -- flavor_show = openstackclient.compute.v2.flavor:ShowFlavor -- host_list = openstackclient.compute.v2.host:ListHost -- host_show = openstackclient.compute.v2.host:ShowHost -- hypervisor_list = openstackclient.compute.v2.hypervisor:ListHypervisor -- hypervisor_show = openstackclient.compute.v2.hypervisor:ShowHypervisor -- ip_fixed_add = openstackclient.compute.v2.fixedip:AddFixedIP -- ip_fixed_remove = openstackclient.compute.v2.fixedip:RemoveFixedIP -- ip_floating_add = openstackclient.compute.v2.floatingip:AddFloatingIP -- ip_floating_create = openstackclient.compute.v2.floatingip:CreateFloatingIP -- ip_floating_delete = openstackclient.compute.v2.floatingip:DeleteFloatingIP -- ip_floating_list = openstackclient.compute.v2.floatingip:ListFloatingIP -- ip_floating_remove = openstackclient.compute.v2.floatingip:RemoveFloatingIP -- ip_floating_pool_list = openstackclient.compute.v2.floatingippool:ListFloatingIPPool -- keypair_create = openstackclient.compute.v2.keypair:CreateKeypair -- keypair_delete = openstackclient.compute.v2.keypair:DeleteKeypair -- keypair_list = openstackclient.compute.v2.keypair:ListKeypair -- keypair_show = openstackclient.compute.v2.keypair:ShowKeypair -- project_usage_list = openstackclient.compute.v2.usage:ListUsage -- security_group_create = openstackclient.compute.v2.security_group:CreateSecurityGroup -- security_group_delete = openstackclient.compute.v2.security_group:DeleteSecurityGroup -- security_group_list = openstackclient.compute.v2.security_group:ListSecurityGroup -- security_group_set = openstackclient.compute.v2.security_group:SetSecurityGroup -- security_group_show = openstackclient.compute.v2.security_group:ShowSecurityGroup -- security_group_rule_create = openstackclient.compute.v2.security_group:CreateSecurityGroupRule -- security_group_rule_delete = openstackclient.compute.v2.security_group:DeleteSecurityGroupRule -- security_group_rule_list = openstackclient.compute.v2.security_group:ListSecurityGroupRule -- server_add_security_group = openstackclient.compute.v2.server:AddServerSecurityGroup -- server_add_volume = openstackclient.compute.v2.server:AddServerVolume -- server_create = openstackclient.compute.v2.server:CreateServer -- server_delete = openstackclient.compute.v2.server:DeleteServer -- server_list = openstackclient.compute.v2.server:ListServer -- server_lock = openstackclient.compute.v2.server:LockServer -- server_migrate = openstackclient.compute.v2.server:MigrateServer -- server_pause = openstackclient.compute.v2.server:PauseServer -- server_reboot = openstackclient.compute.v2.server:RebootServer -- server_rebuild = openstackclient.compute.v2.server:RebuildServer -- server_remove_security_group = openstackclient.compute.v2.server:RemoveServerSecurityGroup -- server_remove_volume = openstackclient.compute.v2.server:RemoveServerVolume -- server_rescue = openstackclient.compute.v2.server:RescueServer -- server_resize = openstackclient.compute.v2.server:ResizeServer -- server_resume = openstackclient.compute.v2.server:ResumeServer -- server_set = openstackclient.compute.v2.server:SetServer -- server_show = openstackclient.compute.v2.server:ShowServer -- server_ssh = openstackclient.compute.v2.server:SshServer -- server_suspend = openstackclient.compute.v2.server:SuspendServer -- server_unlock = openstackclient.compute.v2.server:UnlockServer -- server_unpause = openstackclient.compute.v2.server:UnpauseServer -- server_unrescue = openstackclient.compute.v2.server:UnrescueServer -- server_unset = openstackclient.compute.v2.server:UnsetServer --openstack.identity.v2_0 = -- ec2_credentials_create = openstackclient.identity.v2_0.ec2creds:CreateEC2Creds -- ec2_credentials_delete = openstackclient.identity.v2_0.ec2creds:DeleteEC2Creds -- ec2_credentials_list = openstackclient.identity.v2_0.ec2creds:ListEC2Creds -- ec2_credentials_show = openstackclient.identity.v2_0.ec2creds:ShowEC2Creds -- endpoint_create = openstackclient.identity.v2_0.endpoint:CreateEndpoint -- endpoint_delete = openstackclient.identity.v2_0.endpoint:DeleteEndpoint -- endpoint_list = openstackclient.identity.v2_0.endpoint:ListEndpoint -- endpoint_show = openstackclient.identity.v2_0.endpoint:ShowEndpoint -- project_create = openstackclient.identity.v2_0.project:CreateProject -- project_delete = openstackclient.identity.v2_0.project:DeleteProject -- project_list = openstackclient.identity.v2_0.project:ListProject -- project_set = openstackclient.identity.v2_0.project:SetProject -- project_show = openstackclient.identity.v2_0.project:ShowProject -- role_add = openstackclient.identity.v2_0.role:AddRole -- role_create = openstackclient.identity.v2_0.role:CreateRole -- role_delete = openstackclient.identity.v2_0.role:DeleteRole -- role_list =openstackclient.identity.v2_0.role:ListRole -- role_remove = openstackclient.identity.v2_0.role:RemoveRole -- role_show =openstackclient.identity.v2_0.role:ShowRole -- service_create = openstackclient.identity.v2_0.service:CreateService -- service_delete = openstackclient.identity.v2_0.service:DeleteService -- service_list =openstackclient.identity.v2_0.service:ListService -- service_show =openstackclient.identity.v2_0.service:ShowService -- user_role_list = openstackclient.identity.v2_0.role:ListUserRole -- user_create = openstackclient.identity.v2_0.user:CreateUser -- user_delete = openstackclient.identity.v2_0.user:DeleteUser -- user_list = openstackclient.identity.v2_0.user:ListUser -- user_set = openstackclient.identity.v2_0.user:SetUser -- user_show = openstackclient.identity.v2_0.user:ShowUser --openstack.identity.v3 = -- access_token_authenticate = openstackclient.identity.v3.token:AuthenticateAccessToken -- access_token_create = openstackclient.identity.v3.token:CreateAccessToken -- access_token_delete = openstackclient.identity.v3.token:DeleteAccessToken -- access_token_list = openstackclient.identity.v3.token:ListAccessToken -- consumer_create = openstackclient.identity.v3.consumer:CreateConsumer -- consumer_delete = openstackclient.identity.v3.consumer:DeleteConsumer -- consumer_list = openstackclient.identity.v3.consumer:ListConsumer -- consumer_set = openstackclient.identity.v3.consumer:SetConsumer -- consumer_show = openstackclient.identity.v3.consumer:ShowConsumer -- credential_create = openstackclient.identity.v3.credential:CreateCredential -- credential_delete = openstackclient.identity.v3.credential:DeleteCredential -- credential_list = openstackclient.identity.v3.credential:ListCredential -- credential_set = openstackclient.identity.v3.credential:SetCredential -- credential_show = openstackclient.identity.v3.credential:ShowCredential -- domain_create = openstackclient.identity.v3.domain:CreateDomain -- domain_delete = openstackclient.identity.v3.domain:DeleteDomain -- domain_list = openstackclient.identity.v3.domain:ListDomain -- domain_set = openstackclient.identity.v3.domain:SetDomain -- domain_show = openstackclient.identity.v3.domain:ShowDomain -- endpoint_create = openstackclient.identity.v3.endpoint:CreateEndpoint -- endpoint_delete = openstackclient.identity.v3.endpoint:DeleteEndpoint -- endpoint_set = openstackclient.identity.v3.endpoint:SetEndpoint -- endpoint_show = openstackclient.identity.v3.endpoint:ShowEndpoint -- endpoint_list = openstackclient.identity.v3.endpoint:ListEndpoint -- group_add_user = openstackclient.identity.v3.group:AddUserToGroup -- group_contains_user = openstackclient.identity.v3.group:CheckUserInGroup -- group_create = openstackclient.identity.v3.group:CreateGroup -- group_delete = openstackclient.identity.v3.group:DeleteGroup -- group_list = openstackclient.identity.v3.group:ListGroup -- group_remove_user = openstackclient.identity.v3.group:RemoveUserFromGroup -- group_set = openstackclient.identity.v3.group:SetGroup -- group_show = openstackclient.identity.v3.group:ShowGroup -- policy_create = openstackclient.identity.v3.policy:CreatePolicy -- policy_delete = openstackclient.identity.v3.policy:DeletePolicy -- policy_list = openstackclient.identity.v3.policy:ListPolicy -- policy_set = openstackclient.identity.v3.policy:SetPolicy -- policy_show = openstackclient.identity.v3.policy:ShowPolicy -- project_create = openstackclient.identity.v3.project:CreateProject -- project_delete = openstackclient.identity.v3.project:DeleteProject -- project_list = openstackclient.identity.v3.project:ListProject -- project_set = openstackclient.identity.v3.project:SetProject -- project_show = openstackclient.identity.v3.project:ShowProject -- request_token_authorize = openstackclient.identity.v3.token:AuthorizeRequestToken -- request_token_create = openstackclient.identity.v3.token:CreateRequestToken -- role_add = openstackclient.identity.v3.role:AddRole -- role_create = openstackclient.identity.v3.role:CreateRole -- role_delete = openstackclient.identity.v3.role:DeleteRole -- role_list = openstackclient.identity.v3.role:ListRole -- role_remove = openstackclient.identity.v3.role:RemoveRole -- role_show = openstackclient.identity.v3.role:ShowRole -- role_set = openstackclient.identity.v3.role:SetRole -- service_create = openstackclient.identity.v3.service:CreateService -- service_delete = openstackclient.identity.v3.service:DeleteService -- service_list = openstackclient.identity.v3.service:ListService -- service_show = openstackclient.identity.v3.service:ShowService -- service_set = openstackclient.identity.v3.service:SetService -- user_create = openstackclient.identity.v3.user:CreateUser -- user_delete = openstackclient.identity.v3.user:DeleteUser -- user_list = openstackclient.identity.v3.user:ListUser -- user_set = openstackclient.identity.v3.user:SetUser -- user_show = openstackclient.identity.v3.user:ShowUser --openstack.image.v1 = -- image_create = openstackclient.image.v1.image:CreateImage -- image_delete = openstackclient.image.v1.image:DeleteImage -- image_list = openstackclient.image.v1.image:ListImage -- image_save = openstackclient.image.v1.image:SaveImage -- image_set = openstackclient.image.v1.image:SetImage -- image_show = openstackclient.image.v1.image:ShowImage --openstack.image.v2 = -- image_delete = openstackclient.image.v2.image:DeleteImage -- image_list = openstackclient.image.v2.image:ListImage -- image_save = openstackclient.image.v2.image:SaveImage -- image_show = openstackclient.image.v2.image:ShowImage --openstack.object_store.v1 = -- container_list = openstackclient.object.v1.container:ListContainer -- object_list = openstackclient.object.v1.object:ListObject --openstack.volume.v1 = -- snapshot_create = openstackclient.volume.v1.snapshot:CreateSnapshot -- snapshot_delete = openstackclient.volume.v1.snapshot:DeleteSnapshot -- snapshot_list = openstackclient.volume.v1.snapshot:ListSnapshot -- snapshot_set = openstackclient.volume.v1.snapshot:SetSnapshot -- snapshot_show = openstackclient.volume.v1.snapshot:ShowSnapshot -- backup_create = openstackclient.volume.v1.backup:CreateBackup -- backup_delete = openstackclient.volume.v1.backup:DeleteBackup -- backup_list = openstackclient.volume.v1.backup:ListBackup -- backup_restore = openstackclient.volume.v1.backup:RestoreBackup -- backup_show = openstackclient.volume.v1.backup:ShowBackup -- volume_create = openstackclient.volume.v1.volume:CreateVolume -- volume_delete = openstackclient.volume.v1.volume:DeleteVolume -- volume_list = openstackclient.volume.v1.volume:ListVolume -- volume_set = openstackclient.volume.v1.volume:SetVolume -- volume_show = openstackclient.volume.v1.volume:ShowVolume -- volume_unset = openstackclient.volume.v1.volume:UnsetVolume -- volume_type_create = openstackclient.volume.v1.type:CreateVolumeType -- volume_type_delete = openstackclient.volume.v1.type:DeleteVolumeType -- volume_type_list = openstackclient.volume.v1.type:ListVolumeType -- volume_type_set = openstackclient.volume.v1.type:SetVolumeType -- volume_type_unset = openstackclient.volume.v1.type:UnsetVolumeType -+console_scripts = -+ openstack = openstackclient.shell:main -+ -+openstack.cli = -+ -+openstack.common = -+ limits_show = openstackclient.common.limits:ShowLimits -+ quota_set = openstackclient.common.quota:SetQuota -+ quota_show = openstackclient.common.quota:ShowQuota -+ -+openstack.compute.v2 = -+ agent_create = openstackclient.compute.v2.agent:CreateAgent -+ agent_delete = openstackclient.compute.v2.agent:DeleteAgent -+ agent_list = openstackclient.compute.v2.agent:ListAgent -+ agent_set = openstackclient.compute.v2.agent:SetAgent -+ -+ aggregate_add_host = openstackclient.compute.v2.aggregate:AddAggregateHost -+ aggregate_create = openstackclient.compute.v2.aggregate:CreateAggregate -+ aggregate_delete = openstackclient.compute.v2.aggregate:DeleteAggregate -+ aggregate_list = openstackclient.compute.v2.aggregate:ListAggregate -+ aggregate_remove_host = openstackclient.compute.v2.aggregate:RemoveAggregateHost -+ aggregate_set = openstackclient.compute.v2.aggregate:SetAggregate -+ aggregate_show = openstackclient.compute.v2.aggregate:ShowAggregate -+ -+ compute_service_list = openstackclient.compute.v2.service:ListService -+ compute_service_set = openstackclient.compute.v2.service:SetService -+ -+ console_log_show = openstackclient.compute.v2.console:ShowConsoleLog -+ console_url_show = openstackclient.compute.v2.console:ShowConsoleURL -+ -+ flavor_create = openstackclient.compute.v2.flavor:CreateFlavor -+ flavor_delete = openstackclient.compute.v2.flavor:DeleteFlavor -+ flavor_list = openstackclient.compute.v2.flavor:ListFlavor -+ flavor_show = openstackclient.compute.v2.flavor:ShowFlavor -+ -+ host_list = openstackclient.compute.v2.host:ListHost -+ host_show = openstackclient.compute.v2.host:ShowHost -+ -+ hypervisor_list = openstackclient.compute.v2.hypervisor:ListHypervisor -+ hypervisor_show = openstackclient.compute.v2.hypervisor:ShowHypervisor -+ -+ ip_fixed_add = openstackclient.compute.v2.fixedip:AddFixedIP -+ ip_fixed_remove = openstackclient.compute.v2.fixedip:RemoveFixedIP -+ -+ ip_floating_add = openstackclient.compute.v2.floatingip:AddFloatingIP -+ ip_floating_create = openstackclient.compute.v2.floatingip:CreateFloatingIP -+ ip_floating_delete = openstackclient.compute.v2.floatingip:DeleteFloatingIP -+ ip_floating_list = openstackclient.compute.v2.floatingip:ListFloatingIP -+ ip_floating_remove = openstackclient.compute.v2.floatingip:RemoveFloatingIP -+ -+ ip_floating_pool_list = openstackclient.compute.v2.floatingippool:ListFloatingIPPool -+ -+ keypair_create = openstackclient.compute.v2.keypair:CreateKeypair -+ keypair_delete = openstackclient.compute.v2.keypair:DeleteKeypair -+ keypair_list = openstackclient.compute.v2.keypair:ListKeypair -+ keypair_show = openstackclient.compute.v2.keypair:ShowKeypair -+ -+ project_usage_list = openstackclient.compute.v2.usage:ListUsage -+ -+ security_group_create = openstackclient.compute.v2.security_group:CreateSecurityGroup -+ security_group_delete = openstackclient.compute.v2.security_group:DeleteSecurityGroup -+ security_group_list = openstackclient.compute.v2.security_group:ListSecurityGroup -+ security_group_set = openstackclient.compute.v2.security_group:SetSecurityGroup -+ security_group_show = openstackclient.compute.v2.security_group:ShowSecurityGroup -+ security_group_rule_create = openstackclient.compute.v2.security_group:CreateSecurityGroupRule -+ security_group_rule_delete = openstackclient.compute.v2.security_group:DeleteSecurityGroupRule -+ security_group_rule_list = openstackclient.compute.v2.security_group:ListSecurityGroupRule -+ -+ server_add_security_group = openstackclient.compute.v2.server:AddServerSecurityGroup -+ server_add_volume = openstackclient.compute.v2.server:AddServerVolume -+ server_create = openstackclient.compute.v2.server:CreateServer -+ server_delete = openstackclient.compute.v2.server:DeleteServer -+ server_list = openstackclient.compute.v2.server:ListServer -+ server_lock = openstackclient.compute.v2.server:LockServer -+ server_migrate = openstackclient.compute.v2.server:MigrateServer -+ server_pause = openstackclient.compute.v2.server:PauseServer -+ server_reboot = openstackclient.compute.v2.server:RebootServer -+ server_rebuild = openstackclient.compute.v2.server:RebuildServer -+ server_remove_security_group = openstackclient.compute.v2.server:RemoveServerSecurityGroup -+ server_remove_volume = openstackclient.compute.v2.server:RemoveServerVolume -+ server_rescue = openstackclient.compute.v2.server:RescueServer -+ server_resize = openstackclient.compute.v2.server:ResizeServer -+ server_resume = openstackclient.compute.v2.server:ResumeServer -+ server_set = openstackclient.compute.v2.server:SetServer -+ server_show = openstackclient.compute.v2.server:ShowServer -+ server_ssh = openstackclient.compute.v2.server:SshServer -+ server_suspend = openstackclient.compute.v2.server:SuspendServer -+ server_unlock = openstackclient.compute.v2.server:UnlockServer -+ server_unpause = openstackclient.compute.v2.server:UnpauseServer -+ server_unrescue = openstackclient.compute.v2.server:UnrescueServer -+ server_unset = openstackclient.compute.v2.server:UnsetServer -+ -+openstack.identity.v2_0 = -+ ec2_credentials_create = openstackclient.identity.v2_0.ec2creds:CreateEC2Creds -+ ec2_credentials_delete = openstackclient.identity.v2_0.ec2creds:DeleteEC2Creds -+ ec2_credentials_list = openstackclient.identity.v2_0.ec2creds:ListEC2Creds -+ ec2_credentials_show = openstackclient.identity.v2_0.ec2creds:ShowEC2Creds -+ -+ endpoint_create = openstackclient.identity.v2_0.endpoint:CreateEndpoint -+ endpoint_delete = openstackclient.identity.v2_0.endpoint:DeleteEndpoint -+ endpoint_list = openstackclient.identity.v2_0.endpoint:ListEndpoint -+ endpoint_show = openstackclient.identity.v2_0.endpoint:ShowEndpoint -+ -+ project_create = openstackclient.identity.v2_0.project:CreateProject -+ project_delete = openstackclient.identity.v2_0.project:DeleteProject -+ project_list = openstackclient.identity.v2_0.project:ListProject -+ project_set = openstackclient.identity.v2_0.project:SetProject -+ project_show = openstackclient.identity.v2_0.project:ShowProject -+ -+ role_add = openstackclient.identity.v2_0.role:AddRole -+ role_create = openstackclient.identity.v2_0.role:CreateRole -+ role_delete = openstackclient.identity.v2_0.role:DeleteRole -+ role_list =openstackclient.identity.v2_0.role:ListRole -+ role_remove = openstackclient.identity.v2_0.role:RemoveRole -+ role_show =openstackclient.identity.v2_0.role:ShowRole -+ -+ service_create = openstackclient.identity.v2_0.service:CreateService -+ service_delete = openstackclient.identity.v2_0.service:DeleteService -+ service_list =openstackclient.identity.v2_0.service:ListService -+ service_show =openstackclient.identity.v2_0.service:ShowService -+ -+ user_role_list = openstackclient.identity.v2_0.role:ListUserRole -+ -+ user_create = openstackclient.identity.v2_0.user:CreateUser -+ user_delete = openstackclient.identity.v2_0.user:DeleteUser -+ user_list = openstackclient.identity.v2_0.user:ListUser -+ user_set = openstackclient.identity.v2_0.user:SetUser -+ user_show = openstackclient.identity.v2_0.user:ShowUser -+ -+openstack.identity.v3 = -+ access_token_authenticate = openstackclient.identity.v3.token:AuthenticateAccessToken -+ access_token_create = openstackclient.identity.v3.token:CreateAccessToken -+ access_token_delete = openstackclient.identity.v3.token:DeleteAccessToken -+ access_token_list = openstackclient.identity.v3.token:ListAccessToken -+ -+ consumer_create = openstackclient.identity.v3.consumer:CreateConsumer -+ consumer_delete = openstackclient.identity.v3.consumer:DeleteConsumer -+ consumer_list = openstackclient.identity.v3.consumer:ListConsumer -+ consumer_set = openstackclient.identity.v3.consumer:SetConsumer -+ consumer_show = openstackclient.identity.v3.consumer:ShowConsumer -+ -+ credential_create = openstackclient.identity.v3.credential:CreateCredential -+ credential_delete = openstackclient.identity.v3.credential:DeleteCredential -+ credential_list = openstackclient.identity.v3.credential:ListCredential -+ credential_set = openstackclient.identity.v3.credential:SetCredential -+ credential_show = openstackclient.identity.v3.credential:ShowCredential -+ -+ domain_create = openstackclient.identity.v3.domain:CreateDomain -+ domain_delete = openstackclient.identity.v3.domain:DeleteDomain -+ domain_list = openstackclient.identity.v3.domain:ListDomain -+ domain_set = openstackclient.identity.v3.domain:SetDomain -+ domain_show = openstackclient.identity.v3.domain:ShowDomain -+ -+ endpoint_create = openstackclient.identity.v3.endpoint:CreateEndpoint -+ endpoint_delete = openstackclient.identity.v3.endpoint:DeleteEndpoint -+ endpoint_set = openstackclient.identity.v3.endpoint:SetEndpoint -+ endpoint_show = openstackclient.identity.v3.endpoint:ShowEndpoint -+ endpoint_list = openstackclient.identity.v3.endpoint:ListEndpoint -+ -+ group_add_user = openstackclient.identity.v3.group:AddUserToGroup -+ group_contains_user = openstackclient.identity.v3.group:CheckUserInGroup -+ group_create = openstackclient.identity.v3.group:CreateGroup -+ group_delete = openstackclient.identity.v3.group:DeleteGroup -+ group_list = openstackclient.identity.v3.group:ListGroup -+ group_remove_user = openstackclient.identity.v3.group:RemoveUserFromGroup -+ group_set = openstackclient.identity.v3.group:SetGroup -+ group_show = openstackclient.identity.v3.group:ShowGroup -+ -+ policy_create = openstackclient.identity.v3.policy:CreatePolicy -+ policy_delete = openstackclient.identity.v3.policy:DeletePolicy -+ policy_list = openstackclient.identity.v3.policy:ListPolicy -+ policy_set = openstackclient.identity.v3.policy:SetPolicy -+ policy_show = openstackclient.identity.v3.policy:ShowPolicy -+ -+ project_create = openstackclient.identity.v3.project:CreateProject -+ project_delete = openstackclient.identity.v3.project:DeleteProject -+ project_list = openstackclient.identity.v3.project:ListProject -+ project_set = openstackclient.identity.v3.project:SetProject -+ project_show = openstackclient.identity.v3.project:ShowProject -+ -+ request_token_authorize = openstackclient.identity.v3.token:AuthorizeRequestToken -+ request_token_create = openstackclient.identity.v3.token:CreateRequestToken -+ -+ role_add = openstackclient.identity.v3.role:AddRole -+ role_create = openstackclient.identity.v3.role:CreateRole -+ role_delete = openstackclient.identity.v3.role:DeleteRole -+ role_list = openstackclient.identity.v3.role:ListRole -+ role_remove = openstackclient.identity.v3.role:RemoveRole -+ role_show = openstackclient.identity.v3.role:ShowRole -+ role_set = openstackclient.identity.v3.role:SetRole -+ -+ service_create = openstackclient.identity.v3.service:CreateService -+ service_delete = openstackclient.identity.v3.service:DeleteService -+ service_list = openstackclient.identity.v3.service:ListService -+ service_show = openstackclient.identity.v3.service:ShowService -+ service_set = openstackclient.identity.v3.service:SetService -+ -+ user_create = openstackclient.identity.v3.user:CreateUser -+ user_delete = openstackclient.identity.v3.user:DeleteUser -+ user_list = openstackclient.identity.v3.user:ListUser -+ user_set = openstackclient.identity.v3.user:SetUser -+ user_show = openstackclient.identity.v3.user:ShowUser -+ -+openstack.image.v1 = -+ image_create = openstackclient.image.v1.image:CreateImage -+ image_delete = openstackclient.image.v1.image:DeleteImage -+ image_list = openstackclient.image.v1.image:ListImage -+ image_save = openstackclient.image.v1.image:SaveImage -+ image_set = openstackclient.image.v1.image:SetImage -+ image_show = openstackclient.image.v1.image:ShowImage -+ -+openstack.image.v2 = -+ image_delete = openstackclient.image.v2.image:DeleteImage -+ image_list = openstackclient.image.v2.image:ListImage -+ image_save = openstackclient.image.v2.image:SaveImage -+ image_show = openstackclient.image.v2.image:ShowImage -+ -+openstack.object_store.v1 = -+ container_list = openstackclient.object.v1.container:ListContainer -+ container_show = openstackclient.object.v1.container:ShowContainer -+ object_list = openstackclient.object.v1.object:ListObject -+ object_show = openstackclient.object.v1.object:ShowObject -+ -+openstack.volume.v1 = -+ snapshot_create = openstackclient.volume.v1.snapshot:CreateSnapshot -+ snapshot_delete = openstackclient.volume.v1.snapshot:DeleteSnapshot -+ snapshot_list = openstackclient.volume.v1.snapshot:ListSnapshot -+ snapshot_set = openstackclient.volume.v1.snapshot:SetSnapshot -+ snapshot_show = openstackclient.volume.v1.snapshot:ShowSnapshot -+ -+ backup_create = openstackclient.volume.v1.backup:CreateBackup -+ backup_delete = openstackclient.volume.v1.backup:DeleteBackup -+ backup_list = openstackclient.volume.v1.backup:ListBackup -+ backup_restore = openstackclient.volume.v1.backup:RestoreBackup -+ backup_show = openstackclient.volume.v1.backup:ShowBackup -+ -+ volume_create = openstackclient.volume.v1.volume:CreateVolume -+ volume_delete = openstackclient.volume.v1.volume:DeleteVolume -+ volume_list = openstackclient.volume.v1.volume:ListVolume -+ volume_set = openstackclient.volume.v1.volume:SetVolume -+ volume_show = openstackclient.volume.v1.volume:ShowVolume -+ volume_unset = openstackclient.volume.v1.volume:UnsetVolume -+ -+ volume_type_create = openstackclient.volume.v1.type:CreateVolumeType -+ volume_type_delete = openstackclient.volume.v1.type:DeleteVolumeType -+ volume_type_list = openstackclient.volume.v1.type:ListVolumeType -+ volume_type_set = openstackclient.volume.v1.type:SetVolumeType -+ volume_type_unset = openstackclient.volume.v1.type:UnsetVolumeType - - [build_sphinx] - source-dir = doc/source diff --git a/0003-Updated-from-global-requirements.patch b/0003-Updated-from-global-requirements.patch deleted file mode 100644 index 0ef1dc8..0000000 --- a/0003-Updated-from-global-requirements.patch +++ /dev/null @@ -1,37 +0,0 @@ -From cf2aa66e4fde5720b00153d57db4696762e060ac Mon Sep 17 00:00:00 2001 -From: OpenStack Jenkins -Date: Tue, 1 Oct 2013 16:15:07 +0000 -Subject: [PATCH] Updated from global requirements - -Change-Id: Ic3b5de6a54951b4f9a6449f97aa1ab9c395a2f08 ---- - requirements.txt | 4 ++-- - setup.py | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/requirements.txt b/requirements.txt -index d956a9e..d906f1b 100644 ---- a/requirements.txt -+++ b/requirements.txt -@@ -1,8 +1,8 @@ - pbr>=0.5.21,<1.0 --cliff>=1.4 -+cliff>=1.4.3 - keyring>=1.6.1,<2.0 - pycrypto>=2.6 - python-glanceclient>=0.9.0 - python-keystoneclient>=0.3.2 --python-novaclient>=2.12.0 -+python-novaclient>=2.15.0 - python-cinderclient>=1.0.5 -diff --git a/setup.py b/setup.py -index 2a0786a..70c2b3f 100644 ---- a/setup.py -+++ b/setup.py -@@ -18,5 +18,5 @@ - import setuptools - - setuptools.setup( -- setup_requires=['pbr>=0.5.21,<1.0'], -+ setup_requires=['pbr'], - pbr=True) diff --git a/0004-Add-options-to-support-TLS-certificate-verification.patch b/0004-Add-options-to-support-TLS-certificate-verification.patch deleted file mode 100644 index 1a4bf71..0000000 --- a/0004-Add-options-to-support-TLS-certificate-verification.patch +++ /dev/null @@ -1,187 +0,0 @@ -From a768f3be91107bdd303b4e4719e6bc6a69cd0a65 Mon Sep 17 00:00:00 2001 -From: Dean Troyer -Date: Mon, 7 Oct 2013 12:23:00 -0500 -Subject: [PATCH] Add options to support TLS certificate verification - -Add --os-cacert and --verify|--insecure options using the same -sematics as the other project CLIs. --verify is included for -completeness. - -Bug: 1236608 - -Change-Id: I8a116d790db5aa4cb17a2207efedce7cb229eba3 ---- - openstackclient/common/clientmanager.py | 12 +++++++++++- - openstackclient/common/restapi.py | 1 + - openstackclient/compute/client.py | 4 ++-- - openstackclient/identity/client.py | 5 ++++- - openstackclient/image/client.py | 7 ++++++- - openstackclient/shell.py | 29 +++++++++++++++++++++++++++-- - openstackclient/volume/client.py | 2 ++ - 7 files changed, 53 insertions(+), 7 deletions(-) - -diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py -index 24b09be..85f544e 100644 ---- a/openstackclient/common/clientmanager.py -+++ b/openstackclient/common/clientmanager.py -@@ -50,7 +50,7 @@ class ClientManager(object): - - def __init__(self, token=None, url=None, auth_url=None, project_name=None, - project_id=None, username=None, password=None, -- region_name=None, api_version=None): -+ region_name=None, verify=True, api_version=None): - self._token = token - self._url = url - self._auth_url = auth_url -@@ -62,6 +62,16 @@ class ClientManager(object): - self._api_version = api_version - self._service_catalog = None - -+ # verify is the Requests-compatible form -+ self._verify = verify -+ # also store in the form used by the legacy client libs -+ self._cacert = None -+ if verify is True or verify is False: -+ self._insecure = not verify -+ else: -+ self._cacert = verify -+ self._insecure = True -+ - self.auth_ref = None - - if not self._url: -diff --git a/openstackclient/common/restapi.py b/openstackclient/common/restapi.py -index 4cea5a0..a45c842 100644 ---- a/openstackclient/common/restapi.py -+++ b/openstackclient/common/restapi.py -@@ -53,6 +53,7 @@ class RESTApi(object): - os_auth=None, - user_agent=USER_AGENT, - debug=None, -+ verify=True, - **kwargs - ): - self.set_auth(os_auth) -diff --git a/openstackclient/compute/client.py b/openstackclient/compute/client.py -index 9bd40a4..4d3b1b7 100644 ---- a/openstackclient/compute/client.py -+++ b/openstackclient/compute/client.py -@@ -38,8 +38,8 @@ def make_client(instance): - api_key=instance._password, - project_id=instance._project_name, - auth_url=instance._auth_url, -- # FIXME(dhellmann): add constructor argument for this -- insecure=False, -+ cacert=instance._cacert, -+ insecure=instance._insecure, - region_name=instance._region_name, - # FIXME(dhellmann): get endpoint_type from option? - endpoint_type='publicURL', -diff --git a/openstackclient/identity/client.py b/openstackclient/identity/client.py -index 8c9437b..4814bc3 100644 ---- a/openstackclient/identity/client.py -+++ b/openstackclient/identity/client.py -@@ -47,7 +47,10 @@ def make_client(instance): - tenant_name=instance._project_name, - tenant_id=instance._project_id, - auth_url=instance._auth_url, -- region_name=instance._region_name) -+ region_name=instance._region_name, -+ cacert=instance._cacert, -+ insecure=instance._insecure, -+ ) - instance.auth_ref = client.auth_ref - return client - -diff --git a/openstackclient/image/client.py b/openstackclient/image/client.py -index 70bef1c..d56ca3b 100644 ---- a/openstackclient/image/client.py -+++ b/openstackclient/image/client.py -@@ -40,7 +40,12 @@ def make_client(instance): - if not instance._url: - instance._url = instance.get_endpoint_for_service_type(API_NAME) - -- return image_client(instance._url, token=instance._token) -+ return image_client( -+ instance._url, -+ token=instance._token, -+ cacert=instance._cacert, -+ insecure=instance._insecure, -+ ) - - - # NOTE(dtroyer): glanceclient.v1.image.ImageManager() doesn't have a find() -diff --git a/openstackclient/shell.py b/openstackclient/shell.py -index 6797790..d0905fd 100644 ---- a/openstackclient/shell.py -+++ b/openstackclient/shell.py -@@ -79,6 +79,9 @@ class OpenStackShell(app.App): - # password flow auth - self.auth_client = None - -+ # Assume TLS host certificate verification is enabled -+ self.verify = True -+ - # NOTE(dtroyer): This hack changes the help action that Cliff - # automatically adds to the parser so we can defer - # its execution until after the api-versioned commands -@@ -159,6 +162,22 @@ class OpenStackShell(app.App): - default=env('OS_REGION_NAME'), - help='Authentication region name (Env: OS_REGION_NAME)') - parser.add_argument( -+ '--os-cacert', -+ metavar='', -+ default=env('OS_CACERT'), -+ help='CA certificate bundle file (Env: OS_CACERT)') -+ verify_group = parser.add_mutually_exclusive_group() -+ verify_group.add_argument( -+ '--verify', -+ action='store_true', -+ help='Verify server certificate (default)', -+ ) -+ verify_group.add_argument( -+ '--insecure', -+ action='store_true', -+ help='Disable server certificate verification', -+ ) -+ parser.add_argument( - '--os-default-domain', - metavar='', - default=env( -@@ -299,7 +318,9 @@ class OpenStackShell(app.App): - username=self.options.os_username, - password=self.options.os_password, - region_name=self.options.os_region_name, -- api_version=self.api_version) -+ verify=self.verify, -+ api_version=self.api_version, -+ ) - return - - def init_keyring_backend(self): -@@ -387,7 +408,11 @@ class OpenStackShell(app.App): - self.DeferredHelpAction(self.parser, self.parser, None, None) - - # Set up common client session -- self.restapi = restapi.RESTApi() -+ if self.options.os_cacert: -+ self.verify = self.options.os_cacert -+ else: -+ self.verify = not self.options.insecure -+ self.restapi = restapi.RESTApi(verify=self.verify) - - def prepare_to_run_command(self, cmd): - """Set up auth and API versions""" -diff --git a/openstackclient/volume/client.py b/openstackclient/volume/client.py -index 92f3b14..626b23f 100644 ---- a/openstackclient/volume/client.py -+++ b/openstackclient/volume/client.py -@@ -40,6 +40,8 @@ def make_client(instance): - api_key=instance._password, - project_id=instance._project_name, - auth_url=instance._auth_url, -+ cacert=instance._cacert, -+ insecure=instance._insecure, - ) - - return client diff --git a/0005-Sync-oslo-incubator-for-py33-fixes.patch b/0005-Sync-oslo-incubator-for-py33-fixes.patch deleted file mode 100644 index d56f92a..0000000 --- a/0005-Sync-oslo-incubator-for-py33-fixes.patch +++ /dev/null @@ -1,387 +0,0 @@ -From a051c85ebf387326370184238486ca9d2cc87e40 Mon Sep 17 00:00:00 2001 -From: Dean Troyer -Date: Fri, 11 Oct 2013 11:52:37 -0500 -Subject: [PATCH] Sync oslo-incubator for py33 fixes - -Change-Id: I261ec6bb34b29169ba3547305deab051f85a3d4d ---- - openstackclient/openstack/common/gettextutils.py | 198 +++++++++++++++++------ - tools/install_venv_common.py | 46 +----- - 2 files changed, 156 insertions(+), 88 deletions(-) - -diff --git a/openstackclient/openstack/common/gettextutils.py b/openstackclient/openstack/common/gettextutils.py -index 2dd5449..d4c93f4 100644 ---- a/openstackclient/openstack/common/gettextutils.py -+++ b/openstackclient/openstack/common/gettextutils.py -@@ -1,8 +1,8 @@ - # vim: tabstop=4 shiftwidth=4 softtabstop=4 - - # Copyright 2012 Red Hat, Inc. --# All Rights Reserved. - # Copyright 2013 IBM Corp. -+# All Rights Reserved. - # - # Licensed under the Apache License, Version 2.0 (the "License"); you may - # not use this file except in compliance with the License. You may obtain -@@ -26,22 +26,46 @@ Usual usage in an openstack.common module: - - import copy - import gettext --import logging.handlers -+import logging - import os - import re --import UserString -+try: -+ import UserString as _userString -+except ImportError: -+ import collections as _userString - -+from babel import localedata - import six - - _localedir = os.environ.get('openstackclient'.upper() + '_LOCALEDIR') - _t = gettext.translation('openstackclient', localedir=_localedir, fallback=True) - -+_AVAILABLE_LANGUAGES = {} -+USE_LAZY = False -+ -+ -+def enable_lazy(): -+ """Convenience function for configuring _() to use lazy gettext -+ -+ Call this at the start of execution to enable the gettextutils._ -+ function to use lazy gettext functionality. This is useful if -+ your project is importing _ directly instead of using the -+ gettextutils.install() way of importing the _ function. -+ """ -+ global USE_LAZY -+ USE_LAZY = True -+ - - def _(msg): -- return _t.ugettext(msg) -+ if USE_LAZY: -+ return Message(msg, 'openstackclient') -+ else: -+ if six.PY3: -+ return _t.gettext(msg) -+ return _t.ugettext(msg) - - --def install(domain): -+def install(domain, lazy=False): - """Install a _() function using the given translation domain. - - Given a translation domain, install a _() function using gettext's -@@ -51,52 +75,60 @@ def install(domain): - overriding the default localedir (e.g. /usr/share/locale) using - a translation-domain-specific environment variable (e.g. - NOVA_LOCALEDIR). -- """ -- gettext.install(domain, -- localedir=os.environ.get(domain.upper() + '_LOCALEDIR'), -- unicode=True) -- -- --""" --Lazy gettext functionality. -- --The following is an attempt to introduce a deferred way --to do translations on messages in OpenStack. We attempt to --override the standard _() function and % (format string) operation --to build Message objects that can later be translated when we have --more information. Also included is an example LogHandler that --translates Messages to an associated locale, effectively allowing --many logs, each with their own locale. --""" -- -- --def get_lazy_gettext(domain): -- """Assemble and return a lazy gettext function for a given domain. - -- Factory method for a project/module to get a lazy gettext function -- for its own translation domain (i.e. nova, glance, cinder, etc.) -+ :param domain: the translation domain -+ :param lazy: indicates whether or not to install the lazy _() function. -+ The lazy _() introduces a way to do deferred translation -+ of messages by installing a _ that builds Message objects, -+ instead of strings, which can then be lazily translated into -+ any available locale. - """ -- -- def _lazy_gettext(msg): -- """Create and return a Message object. -- -- Message encapsulates a string so that we can translate it later when -- needed. -- """ -- return Message(msg, domain) -- -- return _lazy_gettext -+ if lazy: -+ # NOTE(mrodden): Lazy gettext functionality. -+ # -+ # The following introduces a deferred way to do translations on -+ # messages in OpenStack. We override the standard _() function -+ # and % (format string) operation to build Message objects that can -+ # later be translated when we have more information. -+ # -+ # Also included below is an example LocaleHandler that translates -+ # Messages to an associated locale, effectively allowing many logs, -+ # each with their own locale. -+ -+ def _lazy_gettext(msg): -+ """Create and return a Message object. -+ -+ Lazy gettext function for a given domain, it is a factory method -+ for a project/module to get a lazy gettext function for its own -+ translation domain (i.e. nova, glance, cinder, etc.) -+ -+ Message encapsulates a string so that we can translate -+ it later when needed. -+ """ -+ return Message(msg, domain) -+ -+ from six import moves -+ moves.builtins.__dict__['_'] = _lazy_gettext -+ else: -+ localedir = '%s_LOCALEDIR' % domain.upper() -+ if six.PY3: -+ gettext.install(domain, -+ localedir=os.environ.get(localedir)) -+ else: -+ gettext.install(domain, -+ localedir=os.environ.get(localedir), -+ unicode=True) - - --class Message(UserString.UserString, object): -+class Message(_userString.UserString, object): - """Class used to encapsulate translatable messages.""" - def __init__(self, msg, domain): - # _msg is the gettext msgid and should never change - self._msg = msg - self._left_extra_msg = '' - self._right_extra_msg = '' -+ self._locale = None - self.params = None -- self.locale = None - self.domain = domain - - @property -@@ -116,8 +148,13 @@ class Message(UserString.UserString, object): - localedir=localedir, - fallback=True) - -+ if six.PY3: -+ ugettext = lang.gettext -+ else: -+ ugettext = lang.ugettext -+ - full_msg = (self._left_extra_msg + -- lang.ugettext(self._msg) + -+ ugettext(self._msg) + - self._right_extra_msg) - - if self.params is not None: -@@ -125,12 +162,39 @@ class Message(UserString.UserString, object): - - return six.text_type(full_msg) - -+ @property -+ def locale(self): -+ return self._locale -+ -+ @locale.setter -+ def locale(self, value): -+ self._locale = value -+ if not self.params: -+ return -+ -+ # This Message object may have been constructed with one or more -+ # Message objects as substitution parameters, given as a single -+ # Message, or a tuple or Map containing some, so when setting the -+ # locale for this Message we need to set it for those Messages too. -+ if isinstance(self.params, Message): -+ self.params.locale = value -+ return -+ if isinstance(self.params, tuple): -+ for param in self.params: -+ if isinstance(param, Message): -+ param.locale = value -+ return -+ if isinstance(self.params, dict): -+ for param in self.params.values(): -+ if isinstance(param, Message): -+ param.locale = value -+ - def _save_dictionary_parameter(self, dict_param): - full_msg = self.data - # look for %(blah) fields in string; - # ignore %% and deal with the - # case where % is first character on the line -- keys = re.findall('(?:[^%]|^)%\((\w*)\)[a-z]', full_msg) -+ keys = re.findall('(?:[^%]|^)?%\((\w*)\)[a-z]', full_msg) - - # if we don't find any %(blah) blocks but have a %s - if not keys and re.findall('(?:[^%]|^)%[a-z]', full_msg): -@@ -143,7 +207,7 @@ class Message(UserString.UserString, object): - params[key] = copy.deepcopy(dict_param[key]) - except TypeError: - # cast uncopyable thing to unicode string -- params[key] = unicode(dict_param[key]) -+ params[key] = six.text_type(dict_param[key]) - - return params - -@@ -162,7 +226,7 @@ class Message(UserString.UserString, object): - try: - self.params = copy.deepcopy(other) - except TypeError: -- self.params = unicode(other) -+ self.params = six.text_type(other) - - return self - -@@ -171,11 +235,13 @@ class Message(UserString.UserString, object): - return self.data - - def __str__(self): -+ if six.PY3: -+ return self.__unicode__() - return self.data.encode('utf-8') - - def __getstate__(self): - to_copy = ['_msg', '_right_extra_msg', '_left_extra_msg', -- 'domain', 'params', 'locale'] -+ 'domain', 'params', '_locale'] - new_dict = self.__dict__.fromkeys(to_copy) - for attr in to_copy: - new_dict[attr] = copy.deepcopy(self.__dict__[attr]) -@@ -229,7 +295,47 @@ class Message(UserString.UserString, object): - if name in ops: - return getattr(self.data, name) - else: -- return UserString.UserString.__getattribute__(self, name) -+ return _userString.UserString.__getattribute__(self, name) -+ -+ -+def get_available_languages(domain): -+ """Lists the available languages for the given translation domain. -+ -+ :param domain: the domain to get languages for -+ """ -+ if domain in _AVAILABLE_LANGUAGES: -+ return copy.copy(_AVAILABLE_LANGUAGES[domain]) -+ -+ localedir = '%s_LOCALEDIR' % domain.upper() -+ find = lambda x: gettext.find(domain, -+ localedir=os.environ.get(localedir), -+ languages=[x]) -+ -+ # NOTE(mrodden): en_US should always be available (and first in case -+ # order matters) since our in-line message strings are en_US -+ language_list = ['en_US'] -+ # NOTE(luisg): Babel <1.0 used a function called list(), which was -+ # renamed to locale_identifiers() in >=1.0, the requirements master list -+ # requires >=0.9.6, uncapped, so defensively work with both. We can remove -+ # this check when the master list updates to >=1.0, and all projects udpate -+ list_identifiers = (getattr(localedata, 'list', None) or -+ getattr(localedata, 'locale_identifiers')) -+ locale_identifiers = list_identifiers() -+ for i in locale_identifiers: -+ if find(i) is not None: -+ language_list.append(i) -+ _AVAILABLE_LANGUAGES[domain] = language_list -+ return copy.copy(language_list) -+ -+ -+def get_localized_message(message, user_locale): -+ """Gets a localized version of the given message in the given locale.""" -+ if isinstance(message, Message): -+ if user_locale: -+ message.locale = user_locale -+ return six.text_type(message) -+ else: -+ return message - - - class LocaleHandler(logging.Handler): -diff --git a/tools/install_venv_common.py b/tools/install_venv_common.py -index f428c1e..1bab88a 100644 ---- a/tools/install_venv_common.py -+++ b/tools/install_venv_common.py -@@ -114,15 +114,12 @@ class InstallVenv(object): - print('Installing dependencies with pip (this can take a while)...') - - # First things first, make sure our venv has the latest pip and -- # setuptools. -- self.pip_install('pip>=1.3') -+ # setuptools and pbr -+ self.pip_install('pip>=1.4') - self.pip_install('setuptools') -+ self.pip_install('pbr') - -- self.pip_install('-r', self.requirements) -- self.pip_install('-r', self.test_requirements) -- -- def post_process(self): -- self.get_distro().post_process() -+ self.pip_install('-r', self.requirements, '-r', self.test_requirements) - - def parse_args(self, argv): - """Parses command-line arguments.""" -@@ -156,14 +153,6 @@ class Distro(InstallVenv): - ' requires virtualenv, please install it using your' - ' favorite package management tool' % self.project) - -- def post_process(self): -- """Any distribution-specific post-processing gets done here. -- -- In particular, this is useful for applying patches to code inside -- the venv. -- """ -- pass -- - - class Fedora(Distro): - """This covers all Fedora-based distributions. -@@ -175,10 +164,6 @@ class Fedora(Distro): - return self.run_command_with_code(['rpm', '-q', pkg], - check_exit_code=False)[1] == 0 - -- def apply_patch(self, originalfile, patchfile): -- self.run_command(['patch', '-N', originalfile, patchfile], -- check_exit_code=False) -- - def install_virtualenv(self): - if self.check_cmd('virtualenv'): - return -@@ -187,26 +172,3 @@ class Fedora(Distro): - self.die("Please install 'python-virtualenv'.") - - super(Fedora, self).install_virtualenv() -- -- def post_process(self): -- """Workaround for a bug in eventlet. -- -- This currently affects RHEL6.1, but the fix can safely be -- applied to all RHEL and Fedora distributions. -- -- This can be removed when the fix is applied upstream. -- -- Nova: https://bugs.launchpad.net/nova/+bug/884915 -- Upstream: https://bitbucket.org/eventlet/eventlet/issue/89 -- RHEL: https://bugzilla.redhat.com/958868 -- """ -- -- # Install "patch" program if it's not there -- if not self.check_pkg('patch'): -- self.die("Please install 'patch'.") -- -- # Apply the eventlet patch -- self.apply_patch(os.path.join(self.venv, 'lib', self.py_version, -- 'site-packages', -- 'eventlet/green/subprocess.py'), -- 'contrib/redhat-eventlet.patch') diff --git a/0006-Updated-from-global-requirements.patch b/0006-Updated-from-global-requirements.patch deleted file mode 100644 index de97702..0000000 --- a/0006-Updated-from-global-requirements.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 4c3035f1e71ca6fe11fc3296d5955ed0bd7a491b Mon Sep 17 00:00:00 2001 -From: OpenStack Jenkins -Date: Wed, 16 Oct 2013 12:21:38 +0000 -Subject: [PATCH] Updated from global requirements - -Change-Id: I2a306dd8edc030d3f989e9947dec784f502b3953 ---- - test-requirements.txt | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/test-requirements.txt b/test-requirements.txt -index 27de420..77788e6 100644 ---- a/test-requirements.txt -+++ b/test-requirements.txt -@@ -11,4 +11,4 @@ testrepository>=0.0.17 - testtools>=0.9.32 - WebOb>=1.2.3,<1.3 - --Babel>=0.9.6 -+Babel>=1.3 diff --git a/0007-Do-lookups-for-user-project-in-volume-create.patch b/0007-Do-lookups-for-user-project-in-volume-create.patch deleted file mode 100644 index 3df74c5..0000000 --- a/0007-Do-lookups-for-user-project-in-volume-create.patch +++ /dev/null @@ -1,531 +0,0 @@ -From 31ab3556307e203977bb31fcfa8a8290e5f7d8fc Mon Sep 17 00:00:00 2001 -From: Dean Troyer -Date: Thu, 11 Apr 2013 16:02:53 -0500 -Subject: [PATCH] Do lookups for user, project in volume create - -This required https://review.openstack.org/26323 in keystoneclient, -merged long ago... - -Also adds some tests for 'volume create' - -Change-Id: I55bededbc20b5dcf2833c59eb2b6b069703d8a9a ---- - openstackclient/tests/volume/test_volume.py | 51 ---- - openstackclient/tests/volume/v1/__init__.py | 14 ++ - openstackclient/tests/volume/v1/fakes.py | 44 ++++ - openstackclient/tests/volume/v1/test_volume.py | 37 +++ - openstackclient/tests/volume/v1/test_volumecmd.py | 269 ++++++++++++++++++++++ - openstackclient/volume/v1/volume.py | 27 ++- - 6 files changed, 383 insertions(+), 59 deletions(-) - delete mode 100644 openstackclient/tests/volume/test_volume.py - create mode 100644 openstackclient/tests/volume/v1/__init__.py - create mode 100644 openstackclient/tests/volume/v1/fakes.py - create mode 100644 openstackclient/tests/volume/v1/test_volume.py - create mode 100644 openstackclient/tests/volume/v1/test_volumecmd.py - -diff --git a/openstackclient/tests/volume/test_volume.py b/openstackclient/tests/volume/test_volume.py -deleted file mode 100644 -index 548fbf7..0000000 ---- a/openstackclient/tests/volume/test_volume.py -+++ /dev/null -@@ -1,51 +0,0 @@ --# Copyright 2013 OpenStack, LLC. --# --# Licensed under the Apache License, Version 2.0 (the "License"); you may --# not use this file except in compliance with the License. You may obtain --# a copy of the License at --# --# http://www.apache.org/licenses/LICENSE-2.0 --# --# Unless required by applicable law or agreed to in writing, software --# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT --# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the --# License for the specific language governing permissions and limitations --# under the License. --# -- --import mock -- --from openstackclient.common import clientmanager --from openstackclient.tests import utils --from openstackclient.volume import client as volume_client -- -- --AUTH_TOKEN = "foobar" --AUTH_URL = "http://0.0.0.0" -- -- --class FakeClient(object): -- def __init__(self, endpoint=None, **kwargs): -- self.client = mock.MagicMock() -- self.client.auth_token = AUTH_TOKEN -- self.client.auth_url = AUTH_URL -- -- --class TestVolume(utils.TestCase): -- def setUp(self): -- super(TestVolume, self).setUp() -- -- api_version = {"volume": "1"} -- -- volume_client.API_VERSIONS = { -- "1": "openstackclient.tests.volume.test_volume.FakeClient" -- } -- -- self.cm = clientmanager.ClientManager(token=AUTH_TOKEN, -- url=AUTH_URL, -- auth_url=AUTH_URL, -- api_version=api_version) -- -- def test_make_client(self): -- self.assertEqual(self.cm.volume.client.auth_token, AUTH_TOKEN) -- self.assertEqual(self.cm.volume.client.auth_url, AUTH_URL) -diff --git a/openstackclient/tests/volume/v1/__init__.py b/openstackclient/tests/volume/v1/__init__.py -new file mode 100644 -index 0000000..c534c01 ---- /dev/null -+++ b/openstackclient/tests/volume/v1/__init__.py -@@ -0,0 +1,14 @@ -+# Copyright 2013 OpenStack Foundation -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -diff --git a/openstackclient/tests/volume/v1/fakes.py b/openstackclient/tests/volume/v1/fakes.py -new file mode 100644 -index 0000000..a382dbb ---- /dev/null -+++ b/openstackclient/tests/volume/v1/fakes.py -@@ -0,0 +1,44 @@ -+# Copyright 2013 Nebula Inc. -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -+ -+import mock -+ -+from openstackclient.tests import fakes -+ -+volume_id = 'vvvvvvvv-vvvv-vvvv-vvvvvvvv' -+volume_name = 'nigel' -+volume_description = 'Nigel Tufnel' -+volume_size = 120 -+volume_metadata = {} -+ -+VOLUME = { -+ 'id': volume_id, -+ 'display_name': volume_name, -+ 'display_description': volume_description, -+ 'size': volume_size, -+ 'status': '', -+ 'attach_status': 'detatched', -+ 'metadata': volume_metadata, -+} -+ -+ -+class FakeVolumev1Client(object): -+ def __init__(self, **kwargs): -+ self.volumes = mock.Mock() -+ self.volumes.resource_class = fakes.FakeResource(None, {}) -+ self.services = mock.Mock() -+ self.services.resource_class = fakes.FakeResource(None, {}) -+ self.auth_token = kwargs['token'] -+ self.management_url = kwargs['endpoint'] -diff --git a/openstackclient/tests/volume/v1/test_volume.py b/openstackclient/tests/volume/v1/test_volume.py -new file mode 100644 -index 0000000..58024f0 ---- /dev/null -+++ b/openstackclient/tests/volume/v1/test_volume.py -@@ -0,0 +1,37 @@ -+# Copyright 2013 OpenStack, LLC. -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -+ -+from openstackclient.tests.identity.v2_0 import fakes as identity_fakes -+from openstackclient.tests import utils -+from openstackclient.tests.volume.v1 import fakes -+ -+ -+AUTH_TOKEN = "foobar" -+AUTH_URL = "http://0.0.0.0" -+ -+ -+class TestVolumev1(utils.TestCommand): -+ def setUp(self): -+ super(TestVolumev1, self).setUp() -+ -+ self.app.client_manager.volume = fakes.FakeVolumev1Client( -+ endpoint=AUTH_URL, -+ token=AUTH_TOKEN, -+ ) -+ -+ self.app.client_manager.identity = identity_fakes.FakeIdentityv2Client( -+ endpoint=AUTH_URL, -+ token=AUTH_TOKEN, -+ ) -diff --git a/openstackclient/tests/volume/v1/test_volumecmd.py b/openstackclient/tests/volume/v1/test_volumecmd.py -new file mode 100644 -index 0000000..1f5ed88 ---- /dev/null -+++ b/openstackclient/tests/volume/v1/test_volumecmd.py -@@ -0,0 +1,269 @@ -+# Copyright 2013 Nebula Inc. -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -+ -+import copy -+ -+from openstackclient.tests import fakes -+from openstackclient.tests.identity.v2_0 import fakes as identity_fakes -+from openstackclient.tests.volume.v1 import fakes as volume_fakes -+from openstackclient.tests.volume.v1 import test_volume -+from openstackclient.volume.v1 import volume -+ -+ -+class TestVolume(test_volume.TestVolumev1): -+ -+ def setUp(self): -+ super(TestVolume, self).setUp() -+ -+ # Get a shortcut to the VolumeManager Mock -+ self.volumes_mock = self.app.client_manager.volume.volumes -+ self.volumes_mock.reset_mock() -+ -+ # Get a shortcut to the TenantManager Mock -+ self.projects_mock = self.app.client_manager.identity.tenants -+ self.projects_mock.reset_mock() -+ -+ # Get a shortcut to the UserManager Mock -+ self.users_mock = self.app.client_manager.identity.users -+ self.users_mock.reset_mock() -+ -+ -+# TODO(dtroyer): The volume create tests are incomplete, only the minimal -+# options and the options that require additional processing -+# are implemented at this time. -+ -+class TestVolumeCreate(TestVolume): -+ -+ def setUp(self): -+ super(TestVolumeCreate, self).setUp() -+ -+ self.volumes_mock.create.return_value = fakes.FakeResource( -+ None, -+ copy.deepcopy(volume_fakes.VOLUME), -+ loaded=True, -+ ) -+ -+ # Get the command object to test -+ self.cmd = volume.CreateVolume(self.app, None) -+ -+ def test_volume_create_min_options(self): -+ arglist = [ -+ '--size', str(volume_fakes.volume_size), -+ volume_fakes.volume_name, -+ ] -+ verifylist = [ -+ ('size', volume_fakes.volume_size), -+ ('name', volume_fakes.volume_name), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ #kwargs = { -+ # 'metadata': volume_fakes.volume_metadata, -+ #} -+ # VolumeManager.create(size, snapshot_id=, source_volid=, -+ # display_name=, display_description=, -+ # volume_type=, user_id=, -+ # project_id=, availability_zone=, -+ # metadata=, imageRef=) -+ self.volumes_mock.create.assert_called_with( -+ volume_fakes.volume_size, -+ None, -+ None, -+ volume_fakes.volume_name, -+ None, -+ None, -+ None, -+ None, -+ None, -+ None, -+ None, -+ ) -+ -+ collist = ( -+ 'attach_status', -+ 'display_description', -+ 'display_name', -+ 'id', -+ 'properties', -+ 'size', -+ 'status', -+ ) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ 'detatched', -+ volume_fakes.volume_description, -+ volume_fakes.volume_name, -+ volume_fakes.volume_id, -+ '', -+ volume_fakes.volume_size, -+ '', -+ ) -+ self.assertEqual(data, datalist) -+ -+ def test_volume_create_user_project_id(self): -+ # Return a project -+ self.projects_mock.get.return_value = fakes.FakeResource( -+ None, -+ copy.deepcopy(identity_fakes.PROJECT), -+ loaded=True, -+ ) -+ # Return a user -+ self.users_mock.get.return_value = fakes.FakeResource( -+ None, -+ copy.deepcopy(identity_fakes.USER), -+ loaded=True, -+ ) -+ -+ arglist = [ -+ '--size', str(volume_fakes.volume_size), -+ '--project', identity_fakes.project_id, -+ '--user', identity_fakes.user_id, -+ volume_fakes.volume_name, -+ ] -+ verifylist = [ -+ ('size', volume_fakes.volume_size), -+ ('project', identity_fakes.project_id), -+ ('user', identity_fakes.user_id), -+ ('name', volume_fakes.volume_name), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ #kwargs = { -+ # 'metadata': volume_fakes.volume_metadata, -+ #} -+ # VolumeManager.create(size, snapshot_id=, source_volid=, -+ # display_name=, display_description=, -+ # volume_type=, user_id=, -+ # project_id=, availability_zone=, -+ # metadata=, imageRef=) -+ self.volumes_mock.create.assert_called_with( -+ volume_fakes.volume_size, -+ None, -+ None, -+ volume_fakes.volume_name, -+ #volume_fakes.volume_description, -+ None, -+ None, -+ identity_fakes.user_id, -+ identity_fakes.project_id, -+ None, -+ None, -+ None, -+ ) -+ -+ collist = ( -+ 'attach_status', -+ 'display_description', -+ 'display_name', -+ 'id', -+ 'properties', -+ 'size', -+ 'status', -+ ) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ 'detatched', -+ volume_fakes.volume_description, -+ volume_fakes.volume_name, -+ volume_fakes.volume_id, -+ '', -+ volume_fakes.volume_size, -+ '', -+ ) -+ self.assertEqual(data, datalist) -+ -+ def test_volume_create_user_project_name(self): -+ # Return a project -+ self.projects_mock.get.return_value = fakes.FakeResource( -+ None, -+ copy.deepcopy(identity_fakes.PROJECT), -+ loaded=True, -+ ) -+ # Return a user -+ self.users_mock.get.return_value = fakes.FakeResource( -+ None, -+ copy.deepcopy(identity_fakes.USER), -+ loaded=True, -+ ) -+ -+ arglist = [ -+ '--size', str(volume_fakes.volume_size), -+ '--project', identity_fakes.project_name, -+ '--user', identity_fakes.user_name, -+ volume_fakes.volume_name, -+ ] -+ verifylist = [ -+ ('size', volume_fakes.volume_size), -+ ('project', identity_fakes.project_name), -+ ('user', identity_fakes.user_name), -+ ('name', volume_fakes.volume_name), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ #kwargs = { -+ # 'metadata': volume_fakes.volume_metadata, -+ #} -+ # VolumeManager.create(size, snapshot_id=, source_volid=, -+ # display_name=, display_description=, -+ # volume_type=, user_id=, -+ # project_id=, availability_zone=, -+ # metadata=, imageRef=) -+ self.volumes_mock.create.assert_called_with( -+ volume_fakes.volume_size, -+ None, -+ None, -+ volume_fakes.volume_name, -+ #volume_fakes.volume_description, -+ None, -+ None, -+ identity_fakes.user_id, -+ identity_fakes.project_id, -+ None, -+ None, -+ None, -+ ) -+ -+ collist = ( -+ 'attach_status', -+ 'display_description', -+ 'display_name', -+ 'id', -+ 'properties', -+ 'size', -+ 'status', -+ ) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ 'detatched', -+ volume_fakes.volume_description, -+ volume_fakes.volume_name, -+ volume_fakes.volume_id, -+ '', -+ volume_fakes.volume_size, -+ '', -+ ) -+ self.assertEqual(data, datalist) -diff --git a/openstackclient/volume/v1/volume.py b/openstackclient/volume/v1/volume.py -index c6690fd..0253bc1 100644 ---- a/openstackclient/volume/v1/volume.py -+++ b/openstackclient/volume/v1/volume.py -@@ -61,14 +61,14 @@ class CreateVolume(show.ShowOne): - help='Type of volume', - ) - parser.add_argument( -- '--user-id', -- metavar='', -- help='Override user id derived from context (admin only)', -+ '--user', -+ metavar='', -+ help='Specify a different user (admin only)', - ) - parser.add_argument( -- '--project-id', -- metavar='', -- help='Override project id derived from context (admin only)', -+ '--project', -+ metavar='', -+ help='Specify a diffeent project (admin only)', - ) - parser.add_argument( - '--availability-zone', -@@ -98,6 +98,7 @@ class CreateVolume(show.ShowOne): - def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) - -+ identity_client = self.app.client_manager.identity - volume_client = self.app.client_manager.volume - - source_volume = None -@@ -107,6 +108,16 @@ class CreateVolume(show.ShowOne): - parsed_args.source, - ).id - -+ project = None -+ if parsed_args.project: -+ project = utils.find_resource( -+ identity_client.tenants, parsed_args.project).id -+ -+ user = None -+ if parsed_args.user: -+ user = utils.find_resource( -+ identity_client.users, parsed_args.user).id -+ - volume = volume_client.volumes.create( - parsed_args.size, - parsed_args.snapshot_id, -@@ -114,8 +125,8 @@ class CreateVolume(show.ShowOne): - parsed_args.name, - parsed_args.description, - parsed_args.volume_type, -- parsed_args.user_id, -- parsed_args.project_id, -+ user, -+ project, - parsed_args.availability_zone, - parsed_args.property, - parsed_args.image diff --git a/0008-Updated-from-global-requirements.patch b/0008-Updated-from-global-requirements.patch deleted file mode 100644 index 9769b66..0000000 --- a/0008-Updated-from-global-requirements.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 574fb361ce2b0d322e6932838c4b9fe7e9ef9a06 Mon Sep 17 00:00:00 2001 -From: OpenStack Jenkins -Date: Tue, 5 Nov 2013 09:54:51 +0000 -Subject: [PATCH] Updated from global requirements - -Change-Id: I421ab7a5b0c0224122cc747141956bc1282f2b07 ---- - requirements.txt | 4 ++-- - test-requirements.txt | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/requirements.txt b/requirements.txt -index d906f1b..e515041 100644 ---- a/requirements.txt -+++ b/requirements.txt -@@ -3,6 +3,6 @@ cliff>=1.4.3 - keyring>=1.6.1,<2.0 - pycrypto>=2.6 - python-glanceclient>=0.9.0 --python-keystoneclient>=0.3.2 -+python-keystoneclient>=0.4.1 - python-novaclient>=2.15.0 --python-cinderclient>=1.0.5 -+python-cinderclient>=1.0.6 -diff --git a/test-requirements.txt b/test-requirements.txt -index 77788e6..b2bed22 100644 ---- a/test-requirements.txt -+++ b/test-requirements.txt -@@ -1,4 +1,4 @@ --hacking>=0.5.6,<0.8 -+hacking>=0.8.0,<0.9 - - coverage>=3.6 - discover diff --git a/0009-Remove-httpretty-from-test-requirements.patch b/0009-Remove-httpretty-from-test-requirements.patch deleted file mode 100644 index 5d0fa7c..0000000 --- a/0009-Remove-httpretty-from-test-requirements.patch +++ /dev/null @@ -1,24 +0,0 @@ -From c004537c9f86a24309764eb914c82f6d4adef6f9 Mon Sep 17 00:00:00 2001 -From: Dean Troyer -Date: Thu, 7 Nov 2013 20:56:03 -0600 -Subject: [PATCH] Remove httpretty from test requirements - -We don't use it... - -Change-Id: I41466da5153a8bdd0e4b4dd5774a9711bff3b7f5 ---- - test-requirements.txt | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/test-requirements.txt b/test-requirements.txt -index b2bed22..63de8be 100644 ---- a/test-requirements.txt -+++ b/test-requirements.txt -@@ -3,7 +3,6 @@ hacking>=0.8.0,<0.9 - coverage>=3.6 - discover - fixtures>=0.3.14 --httpretty>=0.6.3 - mock>=1.0 - mox3>=0.7.0 - sphinx>=1.1.2 diff --git a/0010-Update-URL-for-global-hacking-doc-and-fix-typos.patch b/0010-Update-URL-for-global-hacking-doc-and-fix-typos.patch deleted file mode 100644 index 22327f8..0000000 --- a/0010-Update-URL-for-global-hacking-doc-and-fix-typos.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 231f07379e1c090cd61d56e1d8eb383b10bd8943 Mon Sep 17 00:00:00 2001 -From: Joe Gordon -Date: Mon, 11 Nov 2013 11:09:04 -0800 -Subject: [PATCH] Update URL for global hacking doc and fix typos - -* related to I579e7c889f3addc2cd40bce0c584bbc70bf435e2 - -Change-Id: I519155d0a47564ce18a9cd930378a3c4feaa7a77 ---- - HACKING.rst | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/HACKING.rst b/HACKING.rst -index 15dca8f..8744a93 100644 ---- a/HACKING.rst -+++ b/HACKING.rst -@@ -1,9 +1,9 @@ - OpenStack Style Commandments - ============================ - --Step 0: Read https://github.com/openstack-dev/hacking/blob/master/HACKING.rst --Step 1: Read http://www.python.org/dev/peps/pep-0008/ one more time --Step 2: Read on -+- Step 1: Read the OpenStack Style Commandments -+ http://docs.openstack.org/developer/hacking/ -+- Step 2: Read on - - General - ------- -@@ -27,7 +27,7 @@ Calling Methods - --------------- - - Deviation! When breaking up method calls due to the 79 char line length limit, --use the alternate 4 space indent. With the frist argument on the succeeding -+use the alternate 4 space indent. With the first argument on the succeeding - line all arguments will then be vertically aligned. Use the same convention - used with other data structure literals and terminate the method call with - the last argument line ending with a comma and the closing paren on its own -@@ -87,7 +87,7 @@ commandline arguments, etc.) should be presumed to be encoded as utf-8. - Python 3.x Compatibility - ------------------------ - --OpenStackClient strives to be Python 3.3 compatibile. Common guidelines: -+OpenStackClient strives to be Python 3.3 compatible. Common guidelines: - - * Convert print statements to functions: print statements should be converted - to an appropriate log or other output mechanism. -@@ -97,7 +97,7 @@ OpenStackClient strives to be Python 3.3 compatibile. Common guidelines: - Running Tests - ------------- - --Note: Oh boy, are we behing on writing tests. But they are coming! -+Note: Oh boy, are we behind on writing tests. But they are coming! - - The testing system is based on a combination of tox and testr. If you just - want to run the whole suite, run `tox` and all will be fine. However, if diff --git a/0011-change-execute-to-run.patch b/0011-change-execute-to-run.patch deleted file mode 100644 index 118b7ef..0000000 --- a/0011-change-execute-to-run.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 15db304dc23fef69cfe0c56d529826a5b529b789 Mon Sep 17 00:00:00 2001 -From: Terry Howe -Date: Fri, 1 Nov 2013 13:54:44 -0600 -Subject: [PATCH] change execute to run - -Change-Id: I23a210c8771c206df14d2713a2e72ccd92402c43 ---- - openstackclient/shell.py | 24 +++++++++++++++++++----- - 1 file changed, 19 insertions(+), 5 deletions(-) - -diff --git a/openstackclient/shell.py b/openstackclient/shell.py -index d0905fd..78e16cd 100644 ---- a/openstackclient/shell.py -+++ b/openstackclient/shell.py -@@ -20,6 +20,7 @@ import getpass - import logging - import os - import sys -+import traceback - - from cliff import app - from cliff import command -@@ -75,6 +76,9 @@ class OpenStackShell(app.App): - version=openstackclient.__version__, - command_manager=commandmanager.CommandManager('openstack.cli')) - -+ # Until we have command line arguments parsed, dump any stack traces -+ self.dump_stack_trace = True -+ - # This is instantiated in initialize_app() only when using - # password flow auth - self.auth_client = None -@@ -111,6 +115,18 @@ class OpenStackShell(app.App): - help="show this help message and exit", - ) - -+ def run(self, argv): -+ try: -+ super(OpenStackShell, self).run(argv) -+ except Exception as e: -+ if not logging.getLogger('').handlers: -+ logging.basicConfig() -+ if self.dump_stack_trace: -+ self.log.error(traceback.format_exc(e)) -+ else: -+ self.log.error('Exception raised: ' + str(e)) -+ return 1 -+ - def build_option_parser(self, description, version): - parser = super(OpenStackShell, self).build_option_parser( - description, -@@ -365,8 +381,10 @@ class OpenStackShell(app.App): - requests_log = logging.getLogger("requests") - if self.options.debug: - requests_log.setLevel(logging.DEBUG) -+ self.dump_stack_trace = True - else: - requests_log.setLevel(logging.WARNING) -+ self.dump_stack_trace = False - - # Save default domain - self.default_domain = self.options.os_default_domain -@@ -437,11 +455,7 @@ class OpenStackShell(app.App): - - - def main(argv=sys.argv[1:]): -- try: -- return OpenStackShell().run(argv) -- except Exception: -- return 1 -- -+ return OpenStackShell().run(argv) - - if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) diff --git a/0012-Complete-basic-test-infrastructure.patch b/0012-Complete-basic-test-infrastructure.patch deleted file mode 100644 index 37cf643..0000000 --- a/0012-Complete-basic-test-infrastructure.patch +++ /dev/null @@ -1,3199 +0,0 @@ -From 46363c50999bfe6fdfafe4048451f36f0f03c4f0 Mon Sep 17 00:00:00 2001 -From: Dean Troyer -Date: Fri, 15 Nov 2013 17:40:09 -0600 -Subject: [PATCH] Complete basic test infrastructure - -This finally gets all of the API tests into a common framework regarding -test classes and so forth. - -Change-Id: If675347129c50dcba0bfc5b6c58f5a2ca57ff46c ---- - openstackclient/image/v1/image.py | 2 +- - openstackclient/tests/compute/test_compute.py | 50 --- - openstackclient/tests/compute/v2/__init__.py | 14 + - openstackclient/tests/compute/v2/fakes.py | 55 +++ - openstackclient/tests/compute/v2/test_server.py | 63 ++++ - openstackclient/tests/fakes.py | 4 + - openstackclient/tests/identity/v2_0/fakes.py | 12 + - .../tests/identity/v2_0/test_identity.py | 31 -- - .../tests/identity/v2_0/test_project.py | 3 +- - openstackclient/tests/identity/v2_0/test_role.py | 3 +- - .../tests/identity/v2_0/test_service.py | 3 +- - openstackclient/tests/identity/v2_0/test_user.py | 3 +- - openstackclient/tests/identity/v3/fakes.py | 11 + - openstackclient/tests/identity/v3/test_identity.py | 31 -- - openstackclient/tests/identity/v3/test_project.py | 3 +- - openstackclient/tests/identity/v3/test_role.py | 3 +- - openstackclient/tests/identity/v3/test_service.py | 3 +- - openstackclient/tests/identity/v3/test_user.py | 3 +- - openstackclient/tests/image/test_image.py | 51 --- - openstackclient/tests/image/v1/__init__.py | 14 + - openstackclient/tests/image/v1/fakes.py | 46 +++ - openstackclient/tests/image/v1/test_image.py | 63 ++++ - openstackclient/tests/image/v2/__init__.py | 14 + - openstackclient/tests/image/v2/fakes.py | 46 +++ - openstackclient/tests/image/v2/test_image.py | 63 ++++ - openstackclient/tests/object/fakes.py | 67 ---- - openstackclient/tests/object/test_container.py | 361 ------------------ - openstackclient/tests/object/test_object.py | 413 --------------------- - openstackclient/tests/object/v1/fakes.py | 67 ++++ - openstackclient/tests/object/v1/test_container.py | 361 ++++++++++++++++++ - openstackclient/tests/object/v1/test_object.py | 413 +++++++++++++++++++++ - openstackclient/tests/volume/v1/fakes.py | 18 + - openstackclient/tests/volume/v1/test_volume.py | 257 ++++++++++++- - openstackclient/tests/volume/v1/test_volumecmd.py | 269 -------------- - 34 files changed, 1517 insertions(+), 1303 deletions(-) - delete mode 100644 openstackclient/tests/compute/test_compute.py - create mode 100644 openstackclient/tests/compute/v2/__init__.py - create mode 100644 openstackclient/tests/compute/v2/fakes.py - create mode 100644 openstackclient/tests/compute/v2/test_server.py - delete mode 100644 openstackclient/tests/identity/v2_0/test_identity.py - delete mode 100644 openstackclient/tests/identity/v3/test_identity.py - delete mode 100644 openstackclient/tests/image/test_image.py - create mode 100644 openstackclient/tests/image/v1/__init__.py - create mode 100644 openstackclient/tests/image/v1/fakes.py - create mode 100644 openstackclient/tests/image/v1/test_image.py - create mode 100644 openstackclient/tests/image/v2/__init__.py - create mode 100644 openstackclient/tests/image/v2/fakes.py - create mode 100644 openstackclient/tests/image/v2/test_image.py - delete mode 100644 openstackclient/tests/object/fakes.py - delete mode 100644 openstackclient/tests/object/test_container.py - delete mode 100644 openstackclient/tests/object/test_object.py - create mode 100644 openstackclient/tests/object/v1/fakes.py - create mode 100644 openstackclient/tests/object/v1/test_container.py - create mode 100644 openstackclient/tests/object/v1/test_object.py - delete mode 100644 openstackclient/tests/volume/v1/test_volumecmd.py - -diff --git a/openstackclient/image/v1/image.py b/openstackclient/image/v1/image.py -index 8827d07..40f9fce 100644 ---- a/openstackclient/image/v1/image.py -+++ b/openstackclient/image/v1/image.py -@@ -213,7 +213,7 @@ class DeleteImage(command.Command): - image_client.images, - parsed_args.image, - ) -- image_client.images.delete(image) -+ image_client.images.delete(image.id) - - - class ListImage(lister.Lister): -diff --git a/openstackclient/tests/compute/test_compute.py b/openstackclient/tests/compute/test_compute.py -deleted file mode 100644 -index 9d2061d..0000000 ---- a/openstackclient/tests/compute/test_compute.py -+++ /dev/null -@@ -1,50 +0,0 @@ --# Copyright 2013 OpenStack, LLC. --# --# Licensed under the Apache License, Version 2.0 (the "License"); you may --# not use this file except in compliance with the License. You may obtain --# a copy of the License at --# --# http://www.apache.org/licenses/LICENSE-2.0 --# --# Unless required by applicable law or agreed to in writing, software --# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT --# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the --# License for the specific language governing permissions and limitations --# under the License. --# -- --import mock -- --from openstackclient.common import clientmanager --from openstackclient.compute import client as compute_client --from openstackclient.tests import utils -- -- --AUTH_TOKEN = "foobar" --AUTH_URL = "http://0.0.0.0" -- -- --class FakeClient(object): -- def __init__(self, endpoint=None, **kwargs): -- self.client = mock.MagicMock() -- self.client.auth_url = AUTH_URL -- -- --class TestCompute(utils.TestCase): -- def setUp(self): -- super(TestCompute, self).setUp() -- -- api_version = {"compute": "2"} -- -- compute_client.API_VERSIONS = { -- "2": "openstackclient.tests.compute.test_compute.FakeClient" -- } -- -- self.cm = clientmanager.ClientManager(token=AUTH_TOKEN, -- url=AUTH_URL, -- auth_url=AUTH_URL, -- api_version=api_version) -- -- def test_make_client(self): -- self.assertEqual(self.cm.compute.client.auth_token, AUTH_TOKEN) -- self.assertEqual(self.cm.compute.client.auth_url, AUTH_URL) -diff --git a/openstackclient/tests/compute/v2/__init__.py b/openstackclient/tests/compute/v2/__init__.py -new file mode 100644 -index 0000000..c534c01 ---- /dev/null -+++ b/openstackclient/tests/compute/v2/__init__.py -@@ -0,0 +1,14 @@ -+# Copyright 2013 OpenStack Foundation -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -diff --git a/openstackclient/tests/compute/v2/fakes.py b/openstackclient/tests/compute/v2/fakes.py -new file mode 100644 -index 0000000..8154449 ---- /dev/null -+++ b/openstackclient/tests/compute/v2/fakes.py -@@ -0,0 +1,55 @@ -+# Copyright 2013 Nebula Inc. -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -+ -+import mock -+ -+from openstackclient.tests import fakes -+from openstackclient.tests import utils -+ -+ -+image_id = 'im1' -+ -+IMAGE = { -+ 'id': image_id, -+} -+ -+ -+server_id = 'serv1' -+server_name = 'waiter' -+ -+SERVER = { -+ 'id': server_id, -+ 'name': server_name, -+} -+ -+ -+class FakeComputev2Client(object): -+ def __init__(self, **kwargs): -+ self.images = mock.Mock() -+ self.images.resource_class = fakes.FakeResource(None, {}) -+ self.servers = mock.Mock() -+ self.servers.resource_class = fakes.FakeResource(None, {}) -+ self.auth_token = kwargs['token'] -+ self.management_url = kwargs['endpoint'] -+ -+ -+class TestComputev2(utils.TestCommand): -+ def setUp(self): -+ super(TestComputev2, self).setUp() -+ -+ self.app.client_manager.compute = FakeComputev2Client( -+ endpoint=fakes.AUTH_URL, -+ token=fakes.AUTH_TOKEN, -+ ) -diff --git a/openstackclient/tests/compute/v2/test_server.py b/openstackclient/tests/compute/v2/test_server.py -new file mode 100644 -index 0000000..7e68808 ---- /dev/null -+++ b/openstackclient/tests/compute/v2/test_server.py -@@ -0,0 +1,63 @@ -+# Copyright 2013 Nebula Inc. -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -+ -+import copy -+ -+from openstackclient.compute.v2 import server -+from openstackclient.tests.compute.v2 import fakes as compute_fakes -+from openstackclient.tests import fakes -+ -+ -+class TestServer(compute_fakes.TestComputev2): -+ -+ def setUp(self): -+ super(TestServer, self).setUp() -+ -+ # Get a shortcut to the ServerManager Mock -+ self.servers_mock = self.app.client_manager.compute.servers -+ self.servers_mock.reset_mock() -+ -+ -+class TestServerDelete(TestServer): -+ -+ def setUp(self): -+ super(TestServerDelete, self).setUp() -+ -+ # This is the return value for utils.find_resource() -+ self.servers_mock.get.return_value = fakes.FakeResource( -+ None, -+ copy.deepcopy(compute_fakes.SERVER), -+ loaded=True, -+ ) -+ self.servers_mock.delete.return_value = None -+ -+ # Get the command object to test -+ self.cmd = server.DeleteServer(self.app, None) -+ -+ def test_server_delete_no_options(self): -+ arglist = [ -+ compute_fakes.server_id, -+ ] -+ verifylist = [ -+ ('server', compute_fakes.server_id), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ self.cmd.take_action(parsed_args) -+ -+ self.servers_mock.delete.assert_called_with( -+ compute_fakes.server_id, -+ ) -diff --git a/openstackclient/tests/fakes.py b/openstackclient/tests/fakes.py -index d6cf1d7..8ab4546 100644 ---- a/openstackclient/tests/fakes.py -+++ b/openstackclient/tests/fakes.py -@@ -16,6 +16,10 @@ - import sys - - -+AUTH_TOKEN = "foobar" -+AUTH_URL = "http://0.0.0.0" -+ -+ - class FakeStdout: - def __init__(self): - self.content = [] -diff --git a/openstackclient/tests/identity/v2_0/fakes.py b/openstackclient/tests/identity/v2_0/fakes.py -index b1aeabd..80febd2 100644 ---- a/openstackclient/tests/identity/v2_0/fakes.py -+++ b/openstackclient/tests/identity/v2_0/fakes.py -@@ -16,6 +16,8 @@ - import mock - - from openstackclient.tests import fakes -+from openstackclient.tests import utils -+ - - project_id = '8-9-64' - project_name = 'beatles' -@@ -83,3 +85,13 @@ class FakeIdentityv2Client(object): - self.ec2.resource_class = fakes.FakeResource(None, {}) - self.auth_token = kwargs['token'] - self.management_url = kwargs['endpoint'] -+ -+ -+class TestIdentityv2(utils.TestCommand): -+ def setUp(self): -+ super(TestIdentityv2, self).setUp() -+ -+ self.app.client_manager.identity = FakeIdentityv2Client( -+ endpoint=fakes.AUTH_URL, -+ token=fakes.AUTH_TOKEN, -+ ) -diff --git a/openstackclient/tests/identity/v2_0/test_identity.py b/openstackclient/tests/identity/v2_0/test_identity.py -deleted file mode 100644 -index 8a50a48..0000000 ---- a/openstackclient/tests/identity/v2_0/test_identity.py -+++ /dev/null -@@ -1,31 +0,0 @@ --# Copyright 2013 Nebula Inc. --# --# Licensed under the Apache License, Version 2.0 (the "License"); you may --# not use this file except in compliance with the License. You may obtain --# a copy of the License at --# --# http://www.apache.org/licenses/LICENSE-2.0 --# --# Unless required by applicable law or agreed to in writing, software --# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT --# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the --# License for the specific language governing permissions and limitations --# under the License. --# -- --from openstackclient.tests.identity.v2_0 import fakes --from openstackclient.tests import utils -- -- --AUTH_TOKEN = "foobar" --AUTH_URL = "http://0.0.0.0" -- -- --class TestIdentityv2(utils.TestCommand): -- def setUp(self): -- super(TestIdentityv2, self).setUp() -- -- self.app.client_manager.identity = fakes.FakeIdentityv2Client( -- endpoint=AUTH_URL, -- token=AUTH_TOKEN, -- ) -diff --git a/openstackclient/tests/identity/v2_0/test_project.py b/openstackclient/tests/identity/v2_0/test_project.py -index 933bd09..30f4278 100644 ---- a/openstackclient/tests/identity/v2_0/test_project.py -+++ b/openstackclient/tests/identity/v2_0/test_project.py -@@ -18,10 +18,9 @@ import copy - from openstackclient.identity.v2_0 import project - from openstackclient.tests import fakes - from openstackclient.tests.identity.v2_0 import fakes as identity_fakes --from openstackclient.tests.identity.v2_0 import test_identity - - --class TestProject(test_identity.TestIdentityv2): -+class TestProject(identity_fakes.TestIdentityv2): - - def setUp(self): - super(TestProject, self).setUp() -diff --git a/openstackclient/tests/identity/v2_0/test_role.py b/openstackclient/tests/identity/v2_0/test_role.py -index 56e9d4c..d515bd7 100644 ---- a/openstackclient/tests/identity/v2_0/test_role.py -+++ b/openstackclient/tests/identity/v2_0/test_role.py -@@ -20,10 +20,9 @@ from openstackclient.common import exceptions - from openstackclient.identity.v2_0 import role - from openstackclient.tests import fakes - from openstackclient.tests.identity.v2_0 import fakes as identity_fakes --from openstackclient.tests.identity.v2_0 import test_identity - - --class TestRole(test_identity.TestIdentityv2): -+class TestRole(identity_fakes.TestIdentityv2): - - def setUp(self): - super(TestRole, self).setUp() -diff --git a/openstackclient/tests/identity/v2_0/test_service.py b/openstackclient/tests/identity/v2_0/test_service.py -index f09c413..6c93574 100644 ---- a/openstackclient/tests/identity/v2_0/test_service.py -+++ b/openstackclient/tests/identity/v2_0/test_service.py -@@ -18,10 +18,9 @@ import copy - from openstackclient.identity.v2_0 import service - from openstackclient.tests import fakes - from openstackclient.tests.identity.v2_0 import fakes as identity_fakes --from openstackclient.tests.identity.v2_0 import test_identity - - --class TestService(test_identity.TestIdentityv2): -+class TestService(identity_fakes.TestIdentityv2): - - def setUp(self): - super(TestService, self).setUp() -diff --git a/openstackclient/tests/identity/v2_0/test_user.py b/openstackclient/tests/identity/v2_0/test_user.py -index 2fe585e..a18d13d 100644 ---- a/openstackclient/tests/identity/v2_0/test_user.py -+++ b/openstackclient/tests/identity/v2_0/test_user.py -@@ -18,10 +18,9 @@ import copy - from openstackclient.identity.v2_0 import user - from openstackclient.tests import fakes - from openstackclient.tests.identity.v2_0 import fakes as identity_fakes --from openstackclient.tests.identity.v2_0 import test_identity - - --class TestUser(test_identity.TestIdentityv2): -+class TestUser(identity_fakes.TestIdentityv2): - - def setUp(self): - super(TestUser, self).setUp() -diff --git a/openstackclient/tests/identity/v3/fakes.py b/openstackclient/tests/identity/v3/fakes.py -index 1338553..9d40d9d 100644 ---- a/openstackclient/tests/identity/v3/fakes.py -+++ b/openstackclient/tests/identity/v3/fakes.py -@@ -16,6 +16,7 @@ - import mock - - from openstackclient.tests import fakes -+from openstackclient.tests import utils - - - domain_id = 'd1' -@@ -104,3 +105,13 @@ class FakeIdentityv3Client(object): - self.users.resource_class = fakes.FakeResource(None, {}) - self.auth_token = kwargs['token'] - self.management_url = kwargs['endpoint'] -+ -+ -+class TestIdentityv3(utils.TestCommand): -+ def setUp(self): -+ super(TestIdentityv3, self).setUp() -+ -+ self.app.client_manager.identity = FakeIdentityv3Client( -+ endpoint=fakes.AUTH_URL, -+ token=fakes.AUTH_TOKEN, -+ ) -diff --git a/openstackclient/tests/identity/v3/test_identity.py b/openstackclient/tests/identity/v3/test_identity.py -deleted file mode 100644 -index 4b55ee4..0000000 ---- a/openstackclient/tests/identity/v3/test_identity.py -+++ /dev/null -@@ -1,31 +0,0 @@ --# Copyright 2013 Nebula Inc. --# --# Licensed under the Apache License, Version 2.0 (the "License"); you may --# not use this file except in compliance with the License. You may obtain --# a copy of the License at --# --# http://www.apache.org/licenses/LICENSE-2.0 --# --# Unless required by applicable law or agreed to in writing, software --# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT --# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the --# License for the specific language governing permissions and limitations --# under the License. --# -- --from openstackclient.tests.identity.v3 import fakes --from openstackclient.tests import utils -- -- --AUTH_TOKEN = "foobar" --AUTH_URL = "http://0.0.0.0" -- -- --class TestIdentityv3(utils.TestCommand): -- def setUp(self): -- super(TestIdentityv3, self).setUp() -- -- self.app.client_manager.identity = fakes.FakeIdentityv3Client( -- endpoint=AUTH_URL, -- token=AUTH_TOKEN, -- ) -diff --git a/openstackclient/tests/identity/v3/test_project.py b/openstackclient/tests/identity/v3/test_project.py -index 91c15e2..02cb41b 100644 ---- a/openstackclient/tests/identity/v3/test_project.py -+++ b/openstackclient/tests/identity/v3/test_project.py -@@ -18,10 +18,9 @@ import copy - from openstackclient.identity.v3 import project - from openstackclient.tests import fakes - from openstackclient.tests.identity.v3 import fakes as identity_fakes --from openstackclient.tests.identity.v3 import test_identity - - --class TestProject(test_identity.TestIdentityv3): -+class TestProject(identity_fakes.TestIdentityv3): - - def setUp(self): - super(TestProject, self).setUp() -diff --git a/openstackclient/tests/identity/v3/test_role.py b/openstackclient/tests/identity/v3/test_role.py -index ef2b3e0..040c39d 100644 ---- a/openstackclient/tests/identity/v3/test_role.py -+++ b/openstackclient/tests/identity/v3/test_role.py -@@ -18,10 +18,9 @@ import copy - from openstackclient.identity.v3 import role - from openstackclient.tests import fakes - from openstackclient.tests.identity.v3 import fakes as identity_fakes --from openstackclient.tests.identity.v3 import test_identity - - --class TestRole(test_identity.TestIdentityv3): -+class TestRole(identity_fakes.TestIdentityv3): - - def setUp(self): - super(TestRole, self).setUp() -diff --git a/openstackclient/tests/identity/v3/test_service.py b/openstackclient/tests/identity/v3/test_service.py -index 1c3ae21..10d249c 100644 ---- a/openstackclient/tests/identity/v3/test_service.py -+++ b/openstackclient/tests/identity/v3/test_service.py -@@ -18,10 +18,9 @@ import copy - from openstackclient.identity.v3 import service - from openstackclient.tests import fakes - from openstackclient.tests.identity.v3 import fakes as identity_fakes --from openstackclient.tests.identity.v3 import test_identity - - --class TestService(test_identity.TestIdentityv3): -+class TestService(identity_fakes.TestIdentityv3): - - def setUp(self): - super(TestService, self).setUp() -diff --git a/openstackclient/tests/identity/v3/test_user.py b/openstackclient/tests/identity/v3/test_user.py -index 8f19580..4321b04 100644 ---- a/openstackclient/tests/identity/v3/test_user.py -+++ b/openstackclient/tests/identity/v3/test_user.py -@@ -18,10 +18,9 @@ import copy - from openstackclient.identity.v3 import user - from openstackclient.tests import fakes - from openstackclient.tests.identity.v3 import fakes as identity_fakes --from openstackclient.tests.identity.v3 import test_identity - - --class TestUser(test_identity.TestIdentityv3): -+class TestUser(identity_fakes.TestIdentityv3): - - def setUp(self): - super(TestUser, self).setUp() -diff --git a/openstackclient/tests/image/test_image.py b/openstackclient/tests/image/test_image.py -deleted file mode 100644 -index f4c8d72..0000000 ---- a/openstackclient/tests/image/test_image.py -+++ /dev/null -@@ -1,51 +0,0 @@ --# Copyright 2013 OpenStack, LLC. --# --# Licensed under the Apache License, Version 2.0 (the "License"); you may --# not use this file except in compliance with the License. You may obtain --# a copy of the License at --# --# http://www.apache.org/licenses/LICENSE-2.0 --# --# Unless required by applicable law or agreed to in writing, software --# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT --# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the --# License for the specific language governing permissions and limitations --# under the License. --# -- --import mock -- --from openstackclient.common import clientmanager --from openstackclient.image import client as image_client --from openstackclient.tests import utils -- -- --AUTH_TOKEN = "foobar" --AUTH_URL = "http://0.0.0.0" -- -- --class FakeClient(object): -- def __init__(self, endpoint=None, **kwargs): -- self.client = mock.MagicMock() -- self.client.auth_token = AUTH_TOKEN -- self.client.auth_url = AUTH_URL -- -- --class TestImage(utils.TestCase): -- def setUp(self): -- super(TestImage, self).setUp() -- -- api_version = {"image": "2"} -- -- image_client.API_VERSIONS = { -- "2": "openstackclient.tests.image.test_image.FakeClient" -- } -- -- self.cm = clientmanager.ClientManager(token=AUTH_TOKEN, -- url=AUTH_URL, -- auth_url=AUTH_URL, -- api_version=api_version) -- -- def test_make_client(self): -- self.assertEqual(self.cm.image.client.auth_token, AUTH_TOKEN) -- self.assertEqual(self.cm.image.client.auth_url, AUTH_URL) -diff --git a/openstackclient/tests/image/v1/__init__.py b/openstackclient/tests/image/v1/__init__.py -new file mode 100644 -index 0000000..ebf59b3 ---- /dev/null -+++ b/openstackclient/tests/image/v1/__init__.py -@@ -0,0 +1,14 @@ -+# Copyright 2013 OpenStack, LLC. -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -diff --git a/openstackclient/tests/image/v1/fakes.py b/openstackclient/tests/image/v1/fakes.py -new file mode 100644 -index 0000000..ea2af84 ---- /dev/null -+++ b/openstackclient/tests/image/v1/fakes.py -@@ -0,0 +1,46 @@ -+# Copyright 2013 Nebula Inc. -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -+ -+import mock -+ -+from openstackclient.tests import fakes -+from openstackclient.tests import utils -+ -+ -+image_id = 'im1' -+image_name = 'graven' -+ -+IMAGE = { -+ 'id': image_id, -+ 'name': image_name -+} -+ -+ -+class FakeImagev1Client(object): -+ def __init__(self, **kwargs): -+ self.images = mock.Mock() -+ self.images.resource_class = fakes.FakeResource(None, {}) -+ self.auth_token = kwargs['token'] -+ self.management_url = kwargs['endpoint'] -+ -+ -+class TestImagev1(utils.TestCommand): -+ def setUp(self): -+ super(TestImagev1, self).setUp() -+ -+ self.app.client_manager.image = FakeImagev1Client( -+ endpoint=fakes.AUTH_URL, -+ token=fakes.AUTH_TOKEN, -+ ) -diff --git a/openstackclient/tests/image/v1/test_image.py b/openstackclient/tests/image/v1/test_image.py -new file mode 100644 -index 0000000..a410674 ---- /dev/null -+++ b/openstackclient/tests/image/v1/test_image.py -@@ -0,0 +1,63 @@ -+# Copyright 2013 Nebula Inc. -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -+ -+import copy -+ -+from openstackclient.image.v1 import image -+from openstackclient.tests import fakes -+from openstackclient.tests.image.v1 import fakes as image_fakes -+ -+ -+class TestImage(image_fakes.TestImagev1): -+ -+ def setUp(self): -+ super(TestImage, self).setUp() -+ -+ # Get a shortcut to the ServerManager Mock -+ self.images_mock = self.app.client_manager.image.images -+ self.images_mock.reset_mock() -+ -+ -+class TestImageDelete(TestImage): -+ -+ def setUp(self): -+ super(TestImageDelete, self).setUp() -+ -+ # This is the return value for utils.find_resource() -+ self.images_mock.get.return_value = fakes.FakeResource( -+ None, -+ copy.deepcopy(image_fakes.IMAGE), -+ loaded=True, -+ ) -+ self.images_mock.delete.return_value = None -+ -+ # Get the command object to test -+ self.cmd = image.DeleteImage(self.app, None) -+ -+ def test_image_delete_no_options(self): -+ arglist = [ -+ image_fakes.image_id, -+ ] -+ verifylist = [ -+ ('image', image_fakes.image_id), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ self.cmd.take_action(parsed_args) -+ -+ self.images_mock.delete.assert_called_with( -+ image_fakes.image_id, -+ ) -diff --git a/openstackclient/tests/image/v2/__init__.py b/openstackclient/tests/image/v2/__init__.py -new file mode 100644 -index 0000000..ebf59b3 ---- /dev/null -+++ b/openstackclient/tests/image/v2/__init__.py -@@ -0,0 +1,14 @@ -+# Copyright 2013 OpenStack, LLC. -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -diff --git a/openstackclient/tests/image/v2/fakes.py b/openstackclient/tests/image/v2/fakes.py -new file mode 100644 -index 0000000..df6b807 ---- /dev/null -+++ b/openstackclient/tests/image/v2/fakes.py -@@ -0,0 +1,46 @@ -+# Copyright 2013 Nebula Inc. -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -+ -+import mock -+ -+from openstackclient.tests import fakes -+from openstackclient.tests import utils -+ -+ -+image_id = 'im1' -+image_name = 'graven' -+ -+IMAGE = { -+ 'id': image_id, -+ 'name': image_name -+} -+ -+ -+class FakeImagev2Client(object): -+ def __init__(self, **kwargs): -+ self.images = mock.Mock() -+ self.images.resource_class = fakes.FakeResource(None, {}) -+ self.auth_token = kwargs['token'] -+ self.management_url = kwargs['endpoint'] -+ -+ -+class TestImagev2(utils.TestCommand): -+ def setUp(self): -+ super(TestImagev2, self).setUp() -+ -+ self.app.client_manager.image = FakeImagev2Client( -+ endpoint=fakes.AUTH_URL, -+ token=fakes.AUTH_TOKEN, -+ ) -diff --git a/openstackclient/tests/image/v2/test_image.py b/openstackclient/tests/image/v2/test_image.py -new file mode 100644 -index 0000000..ef84e2c ---- /dev/null -+++ b/openstackclient/tests/image/v2/test_image.py -@@ -0,0 +1,63 @@ -+# Copyright 2013 Nebula Inc. -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -+ -+import copy -+ -+from openstackclient.image.v1 import image -+from openstackclient.tests import fakes -+from openstackclient.tests.image.v2 import fakes as image_fakes -+ -+ -+class TestImage(image_fakes.TestImagev2): -+ -+ def setUp(self): -+ super(TestImage, self).setUp() -+ -+ # Get a shortcut to the ServerManager Mock -+ self.images_mock = self.app.client_manager.image.images -+ self.images_mock.reset_mock() -+ -+ -+class TestImageDelete(TestImage): -+ -+ def setUp(self): -+ super(TestImageDelete, self).setUp() -+ -+ # This is the return value for utils.find_resource() -+ self.images_mock.get.return_value = fakes.FakeResource( -+ None, -+ copy.deepcopy(image_fakes.IMAGE), -+ loaded=True, -+ ) -+ self.images_mock.delete.return_value = None -+ -+ # Get the command object to test -+ self.cmd = image.DeleteImage(self.app, None) -+ -+ def test_image_delete_no_options(self): -+ arglist = [ -+ image_fakes.image_id, -+ ] -+ verifylist = [ -+ ('image', image_fakes.image_id), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ self.cmd.take_action(parsed_args) -+ -+ self.images_mock.delete.assert_called_with( -+ image_fakes.image_id, -+ ) -diff --git a/openstackclient/tests/object/fakes.py b/openstackclient/tests/object/fakes.py -deleted file mode 100644 -index fbc784a..0000000 ---- a/openstackclient/tests/object/fakes.py -+++ /dev/null -@@ -1,67 +0,0 @@ --# Copyright 2013 Nebula Inc. --# --# Licensed under the Apache License, Version 2.0 (the "License"); you may --# not use this file except in compliance with the License. You may obtain --# a copy of the License at --# --# http://www.apache.org/licenses/LICENSE-2.0 --# --# Unless required by applicable law or agreed to in writing, software --# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT --# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the --# License for the specific language governing permissions and limitations --# under the License. --# -- --container_name = 'bit-bucket' --container_bytes = 1024 --container_count = 1 -- --container_name_2 = 'archive' --container_name_3 = 'bit-blit' -- --CONTAINER = { -- 'name': container_name, -- 'bytes': container_bytes, -- 'count': container_count, --} -- --CONTAINER_2 = { -- 'name': container_name_2, -- 'bytes': container_bytes * 2, -- 'count': container_count * 2, --} -- --CONTAINER_3 = { -- 'name': container_name_3, -- 'bytes': container_bytes * 3, -- 'count': container_count * 3, --} -- --object_name_1 = 'punch-card' --object_bytes_1 = 80 --object_hash_1 = '1234567890' --object_content_type_1 = 'text' --object_modified_1 = 'today' -- --object_name_2 = 'floppy-disk' --object_bytes_2 = 1440000 --object_hash_2 = '0987654321' --object_content_type_2 = 'text' --object_modified_2 = 'today' -- --OBJECT = { -- 'name': object_name_1, -- 'bytes': object_bytes_1, -- 'hash': object_hash_1, -- 'content_type': object_content_type_1, -- 'last_modified': object_modified_1, --} -- --OBJECT_2 = { -- 'name': object_name_2, -- 'bytes': object_bytes_2, -- 'hash': object_hash_2, -- 'content_type': object_content_type_2, -- 'last_modified': object_modified_2, --} -diff --git a/openstackclient/tests/object/test_container.py b/openstackclient/tests/object/test_container.py -deleted file mode 100644 -index 24d6763..0000000 ---- a/openstackclient/tests/object/test_container.py -+++ /dev/null -@@ -1,361 +0,0 @@ --# Copyright 2013 OpenStack Foundation --# --# Licensed under the Apache License, Version 2.0 (the "License"); you may --# not use this file except in compliance with the License. You may obtain --# a copy of the License at --# --# http://www.apache.org/licenses/LICENSE-2.0 --# --# Unless required by applicable law or agreed to in writing, software --# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT --# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the --# License for the specific language governing permissions and limitations --# under the License. --# -- --import copy --import mock -- --from openstackclient.common import clientmanager --from openstackclient.object.v1 import container --from openstackclient.tests.object import fakes as object_fakes --from openstackclient.tests import utils -- -- --AUTH_TOKEN = "foobar" --AUTH_URL = "http://0.0.0.0" -- -- --class FakeClient(object): -- def __init__(self, endpoint=None, **kwargs): -- self.endpoint = AUTH_URL -- self.token = AUTH_TOKEN -- -- --class TestObject(utils.TestCommand): -- def setUp(self): -- super(TestObject, self).setUp() -- -- api_version = {"object-store": "1"} -- self.app.client_manager = clientmanager.ClientManager( -- token=AUTH_TOKEN, -- url=AUTH_URL, -- auth_url=AUTH_URL, -- api_version=api_version, -- ) -- -- --class TestObjectClient(TestObject): -- -- def test_make_client(self): -- self.assertEqual(self.app.client_manager.object.endpoint, AUTH_URL) -- self.assertEqual(self.app.client_manager.object.token, AUTH_TOKEN) -- -- --@mock.patch( -- 'openstackclient.object.v1.container.lib_container.list_containers' --) --class TestContainerList(TestObject): -- -- def setUp(self): -- super(TestContainerList, self).setUp() -- -- # Get the command object to test -- self.cmd = container.ListContainer(self.app, None) -- -- def test_object_list_containers_no_options(self, c_mock): -- c_mock.return_value = [ -- copy.deepcopy(object_fakes.CONTAINER), -- copy.deepcopy(object_fakes.CONTAINER_3), -- copy.deepcopy(object_fakes.CONTAINER_2), -- ] -- -- arglist = [] -- verifylist = [] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- } -- c_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- **kwargs -- ) -- -- collist = ('Name',) -- self.assertEqual(columns, collist) -- datalist = ( -- (object_fakes.container_name, ), -- (object_fakes.container_name_3, ), -- (object_fakes.container_name_2, ), -- ) -- self.assertEqual(tuple(data), datalist) -- -- def test_object_list_containers_prefix(self, c_mock): -- c_mock.return_value = [ -- copy.deepcopy(object_fakes.CONTAINER), -- copy.deepcopy(object_fakes.CONTAINER_3), -- ] -- -- arglist = [ -- '--prefix', 'bit', -- ] -- verifylist = [ -- ('prefix', 'bit'), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- 'prefix': 'bit', -- } -- c_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- **kwargs -- ) -- -- collist = ('Name',) -- self.assertEqual(columns, collist) -- datalist = ( -- (object_fakes.container_name, ), -- (object_fakes.container_name_3, ), -- ) -- self.assertEqual(tuple(data), datalist) -- -- def test_object_list_containers_marker(self, c_mock): -- c_mock.return_value = [ -- copy.deepcopy(object_fakes.CONTAINER), -- copy.deepcopy(object_fakes.CONTAINER_3), -- ] -- -- arglist = [ -- '--marker', object_fakes.container_name, -- ] -- verifylist = [ -- ('marker', object_fakes.container_name), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- 'marker': object_fakes.container_name, -- } -- c_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- **kwargs -- ) -- -- collist = ('Name',) -- self.assertEqual(columns, collist) -- datalist = ( -- (object_fakes.container_name, ), -- (object_fakes.container_name_3, ), -- ) -- self.assertEqual(tuple(data), datalist) -- -- def test_object_list_containers_end_marker(self, c_mock): -- c_mock.return_value = [ -- copy.deepcopy(object_fakes.CONTAINER), -- copy.deepcopy(object_fakes.CONTAINER_3), -- ] -- -- arglist = [ -- '--end-marker', object_fakes.container_name_3, -- ] -- verifylist = [ -- ('end_marker', object_fakes.container_name_3), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- 'end_marker': object_fakes.container_name_3, -- } -- c_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- **kwargs -- ) -- -- collist = ('Name',) -- self.assertEqual(columns, collist) -- datalist = ( -- (object_fakes.container_name, ), -- (object_fakes.container_name_3, ), -- ) -- self.assertEqual(tuple(data), datalist) -- -- def test_object_list_containers_limit(self, c_mock): -- c_mock.return_value = [ -- copy.deepcopy(object_fakes.CONTAINER), -- copy.deepcopy(object_fakes.CONTAINER_3), -- ] -- -- arglist = [ -- '--limit', '2', -- ] -- verifylist = [ -- ('limit', 2), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- 'limit': 2, -- } -- c_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- **kwargs -- ) -- -- collist = ('Name',) -- self.assertEqual(columns, collist) -- datalist = ( -- (object_fakes.container_name, ), -- (object_fakes.container_name_3, ), -- ) -- self.assertEqual(tuple(data), datalist) -- -- def test_object_list_containers_long(self, c_mock): -- c_mock.return_value = [ -- copy.deepcopy(object_fakes.CONTAINER), -- copy.deepcopy(object_fakes.CONTAINER_3), -- ] -- -- arglist = [ -- '--long', -- ] -- verifylist = [ -- ('long', True), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- } -- c_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- **kwargs -- ) -- -- collist = ('Name', 'Bytes', 'Count') -- self.assertEqual(columns, collist) -- datalist = ( -- ( -- object_fakes.container_name, -- object_fakes.container_bytes, -- object_fakes.container_count, -- ), -- ( -- object_fakes.container_name_3, -- object_fakes.container_bytes * 3, -- object_fakes.container_count * 3, -- ), -- ) -- self.assertEqual(tuple(data), datalist) -- -- def test_object_list_containers_all(self, c_mock): -- c_mock.return_value = [ -- copy.deepcopy(object_fakes.CONTAINER), -- copy.deepcopy(object_fakes.CONTAINER_2), -- copy.deepcopy(object_fakes.CONTAINER_3), -- ] -- -- arglist = [ -- '--all', -- ] -- verifylist = [ -- ('all', True), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- 'full_listing': True, -- } -- c_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- **kwargs -- ) -- -- collist = ('Name',) -- self.assertEqual(columns, collist) -- datalist = ( -- (object_fakes.container_name, ), -- (object_fakes.container_name_2, ), -- (object_fakes.container_name_3, ), -- ) -- self.assertEqual(tuple(data), datalist) -- -- --@mock.patch( -- 'openstackclient.object.v1.container.lib_container.show_container' --) --class TestContainerShow(TestObject): -- -- def setUp(self): -- super(TestContainerShow, self).setUp() -- -- # Get the command object to test -- self.cmd = container.ShowContainer(self.app, None) -- -- def test_container_show(self, c_mock): -- c_mock.return_value = copy.deepcopy(object_fakes.CONTAINER) -- -- arglist = [ -- object_fakes.container_name, -- ] -- verifylist = [ -- ('container', object_fakes.container_name), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- } -- # lib.container.show_container(api, url, container) -- c_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- object_fakes.container_name, -- **kwargs -- ) -- -- collist = ('bytes', 'count', 'name') -- self.assertEqual(columns, collist) -- datalist = ( -- object_fakes.container_bytes, -- object_fakes.container_count, -- object_fakes.container_name, -- ) -- self.assertEqual(data, datalist) -diff --git a/openstackclient/tests/object/test_object.py b/openstackclient/tests/object/test_object.py -deleted file mode 100644 -index 1ceb0a5..0000000 ---- a/openstackclient/tests/object/test_object.py -+++ /dev/null -@@ -1,413 +0,0 @@ --# Copyright 2013 OpenStack Foundation --# --# Licensed under the Apache License, Version 2.0 (the "License"); you may --# not use this file except in compliance with the License. You may obtain --# a copy of the License at --# --# http://www.apache.org/licenses/LICENSE-2.0 --# --# Unless required by applicable law or agreed to in writing, software --# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT --# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the --# License for the specific language governing permissions and limitations --# under the License. --# -- --import copy --import mock -- --from openstackclient.common import clientmanager --from openstackclient.object.v1 import object as obj --from openstackclient.tests.object import fakes as object_fakes --from openstackclient.tests import utils -- -- --AUTH_TOKEN = "foobar" --AUTH_URL = "http://0.0.0.0" -- -- --class FakeClient(object): -- def __init__(self, endpoint=None, **kwargs): -- self.endpoint = AUTH_URL -- self.token = AUTH_TOKEN -- -- --class TestObject(utils.TestCommand): -- def setUp(self): -- super(TestObject, self).setUp() -- -- api_version = {"object-store": "1"} -- self.app.client_manager = clientmanager.ClientManager( -- token=AUTH_TOKEN, -- url=AUTH_URL, -- auth_url=AUTH_URL, -- api_version=api_version, -- ) -- -- --class TestObjectClient(TestObject): -- -- def test_make_client(self): -- self.assertEqual(self.app.client_manager.object.endpoint, AUTH_URL) -- self.assertEqual(self.app.client_manager.object.token, AUTH_TOKEN) -- -- --@mock.patch( -- 'openstackclient.object.v1.object.lib_object.list_objects' --) --class TestObjectList(TestObject): -- -- def setUp(self): -- super(TestObjectList, self).setUp() -- -- # Get the command object to test -- self.cmd = obj.ListObject(self.app, None) -- -- def test_object_list_objects_no_options(self, o_mock): -- o_mock.return_value = [ -- copy.deepcopy(object_fakes.OBJECT), -- copy.deepcopy(object_fakes.OBJECT_2), -- ] -- -- arglist = [ -- object_fakes.container_name, -- ] -- verifylist = [ -- ('container', object_fakes.container_name), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- o_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- object_fakes.container_name, -- ) -- -- collist = ('Name',) -- self.assertEqual(columns, collist) -- datalist = ( -- (object_fakes.object_name_1, ), -- (object_fakes.object_name_2, ), -- ) -- self.assertEqual(tuple(data), datalist) -- -- def test_object_list_objects_prefix(self, o_mock): -- o_mock.return_value = [ -- copy.deepcopy(object_fakes.OBJECT_2), -- ] -- -- arglist = [ -- '--prefix', 'floppy', -- object_fakes.container_name_2, -- ] -- verifylist = [ -- ('prefix', 'floppy'), -- ('container', object_fakes.container_name_2), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- 'prefix': 'floppy', -- } -- o_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- object_fakes.container_name_2, -- **kwargs -- ) -- -- collist = ('Name',) -- self.assertEqual(columns, collist) -- datalist = ( -- (object_fakes.object_name_2, ), -- ) -- self.assertEqual(tuple(data), datalist) -- -- def test_object_list_objects_delimiter(self, o_mock): -- o_mock.return_value = [ -- copy.deepcopy(object_fakes.OBJECT_2), -- ] -- -- arglist = [ -- '--delimiter', '=', -- object_fakes.container_name_2, -- ] -- verifylist = [ -- ('delimiter', '='), -- ('container', object_fakes.container_name_2), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- 'delimiter': '=', -- } -- o_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- object_fakes.container_name_2, -- **kwargs -- ) -- -- collist = ('Name',) -- self.assertEqual(columns, collist) -- datalist = ( -- (object_fakes.object_name_2, ), -- ) -- self.assertEqual(tuple(data), datalist) -- -- def test_object_list_objects_marker(self, o_mock): -- o_mock.return_value = [ -- copy.deepcopy(object_fakes.OBJECT_2), -- ] -- -- arglist = [ -- '--marker', object_fakes.object_name_2, -- object_fakes.container_name_2, -- ] -- verifylist = [ -- ('marker', object_fakes.object_name_2), -- ('container', object_fakes.container_name_2), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- 'marker': object_fakes.object_name_2, -- } -- o_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- object_fakes.container_name_2, -- **kwargs -- ) -- -- collist = ('Name',) -- self.assertEqual(columns, collist) -- datalist = ( -- (object_fakes.object_name_2, ), -- ) -- self.assertEqual(tuple(data), datalist) -- -- def test_object_list_objects_end_marker(self, o_mock): -- o_mock.return_value = [ -- copy.deepcopy(object_fakes.OBJECT_2), -- ] -- -- arglist = [ -- '--end-marker', object_fakes.object_name_2, -- object_fakes.container_name_2, -- ] -- verifylist = [ -- ('end_marker', object_fakes.object_name_2), -- ('container', object_fakes.container_name_2), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- 'end_marker': object_fakes.object_name_2, -- } -- o_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- object_fakes.container_name_2, -- **kwargs -- ) -- -- collist = ('Name',) -- self.assertEqual(columns, collist) -- datalist = ( -- (object_fakes.object_name_2, ), -- ) -- self.assertEqual(tuple(data), datalist) -- -- def test_object_list_objects_limit(self, o_mock): -- o_mock.return_value = [ -- copy.deepcopy(object_fakes.OBJECT_2), -- ] -- -- arglist = [ -- '--limit', '2', -- object_fakes.container_name_2, -- ] -- verifylist = [ -- ('limit', 2), -- ('container', object_fakes.container_name_2), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- 'limit': 2, -- } -- o_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- object_fakes.container_name_2, -- **kwargs -- ) -- -- collist = ('Name',) -- self.assertEqual(columns, collist) -- datalist = ( -- (object_fakes.object_name_2, ), -- ) -- self.assertEqual(tuple(data), datalist) -- -- def test_object_list_objects_long(self, o_mock): -- o_mock.return_value = [ -- copy.deepcopy(object_fakes.OBJECT), -- copy.deepcopy(object_fakes.OBJECT_2), -- ] -- -- arglist = [ -- '--long', -- object_fakes.container_name, -- ] -- verifylist = [ -- ('long', True), -- ('container', object_fakes.container_name), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- } -- o_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- object_fakes.container_name, -- **kwargs -- ) -- -- collist = ('Name', 'Bytes', 'Hash', 'Content Type', 'Last Modified') -- self.assertEqual(columns, collist) -- datalist = ( -- ( -- object_fakes.object_name_1, -- object_fakes.object_bytes_1, -- object_fakes.object_hash_1, -- object_fakes.object_content_type_1, -- object_fakes.object_modified_1, -- ), -- ( -- object_fakes.object_name_2, -- object_fakes.object_bytes_2, -- object_fakes.object_hash_2, -- object_fakes.object_content_type_2, -- object_fakes.object_modified_2, -- ), -- ) -- self.assertEqual(tuple(data), datalist) -- -- def test_object_list_objects_all(self, o_mock): -- o_mock.return_value = [ -- copy.deepcopy(object_fakes.OBJECT), -- copy.deepcopy(object_fakes.OBJECT_2), -- ] -- -- arglist = [ -- '--all', -- object_fakes.container_name, -- ] -- verifylist = [ -- ('all', True), -- ('container', object_fakes.container_name), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- 'full_listing': True, -- } -- o_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- object_fakes.container_name, -- **kwargs -- ) -- -- collist = ('Name',) -- self.assertEqual(columns, collist) -- datalist = ( -- (object_fakes.object_name_1, ), -- (object_fakes.object_name_2, ), -- ) -- self.assertEqual(tuple(data), datalist) -- -- --@mock.patch( -- 'openstackclient.object.v1.object.lib_object.show_object' --) --class TestObjectShow(TestObject): -- -- def setUp(self): -- super(TestObjectShow, self).setUp() -- -- # Get the command object to test -- self.cmd = obj.ShowObject(self.app, None) -- -- def test_object_show(self, c_mock): -- c_mock.return_value = copy.deepcopy(object_fakes.OBJECT) -- -- arglist = [ -- object_fakes.container_name, -- object_fakes.object_name_1, -- ] -- verifylist = [ -- ('container', object_fakes.container_name), -- ('object', object_fakes.object_name_1), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- kwargs = { -- } -- # lib.container.show_container(api, url, container) -- c_mock.assert_called_with( -- self.app.restapi, -- AUTH_URL, -- object_fakes.container_name, -- object_fakes.object_name_1, -- **kwargs -- ) -- -- collist = ('bytes', 'content_type', 'hash', 'last_modified', 'name') -- self.assertEqual(columns, collist) -- datalist = ( -- object_fakes.object_bytes_1, -- object_fakes.object_content_type_1, -- object_fakes.object_hash_1, -- object_fakes.object_modified_1, -- object_fakes.object_name_1, -- ) -- self.assertEqual(data, datalist) -diff --git a/openstackclient/tests/object/v1/fakes.py b/openstackclient/tests/object/v1/fakes.py -new file mode 100644 -index 0000000..fbc784a ---- /dev/null -+++ b/openstackclient/tests/object/v1/fakes.py -@@ -0,0 +1,67 @@ -+# Copyright 2013 Nebula Inc. -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -+ -+container_name = 'bit-bucket' -+container_bytes = 1024 -+container_count = 1 -+ -+container_name_2 = 'archive' -+container_name_3 = 'bit-blit' -+ -+CONTAINER = { -+ 'name': container_name, -+ 'bytes': container_bytes, -+ 'count': container_count, -+} -+ -+CONTAINER_2 = { -+ 'name': container_name_2, -+ 'bytes': container_bytes * 2, -+ 'count': container_count * 2, -+} -+ -+CONTAINER_3 = { -+ 'name': container_name_3, -+ 'bytes': container_bytes * 3, -+ 'count': container_count * 3, -+} -+ -+object_name_1 = 'punch-card' -+object_bytes_1 = 80 -+object_hash_1 = '1234567890' -+object_content_type_1 = 'text' -+object_modified_1 = 'today' -+ -+object_name_2 = 'floppy-disk' -+object_bytes_2 = 1440000 -+object_hash_2 = '0987654321' -+object_content_type_2 = 'text' -+object_modified_2 = 'today' -+ -+OBJECT = { -+ 'name': object_name_1, -+ 'bytes': object_bytes_1, -+ 'hash': object_hash_1, -+ 'content_type': object_content_type_1, -+ 'last_modified': object_modified_1, -+} -+ -+OBJECT_2 = { -+ 'name': object_name_2, -+ 'bytes': object_bytes_2, -+ 'hash': object_hash_2, -+ 'content_type': object_content_type_2, -+ 'last_modified': object_modified_2, -+} -diff --git a/openstackclient/tests/object/v1/test_container.py b/openstackclient/tests/object/v1/test_container.py -new file mode 100644 -index 0000000..2090b88 ---- /dev/null -+++ b/openstackclient/tests/object/v1/test_container.py -@@ -0,0 +1,361 @@ -+# Copyright 2013 OpenStack Foundation -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -+ -+import copy -+import mock -+ -+from openstackclient.common import clientmanager -+from openstackclient.object.v1 import container -+from openstackclient.tests.object.v1 import fakes as object_fakes -+from openstackclient.tests import utils -+ -+ -+AUTH_TOKEN = "foobar" -+AUTH_URL = "http://0.0.0.0" -+ -+ -+class FakeClient(object): -+ def __init__(self, endpoint=None, **kwargs): -+ self.endpoint = AUTH_URL -+ self.token = AUTH_TOKEN -+ -+ -+class TestObject(utils.TestCommand): -+ def setUp(self): -+ super(TestObject, self).setUp() -+ -+ api_version = {"object-store": "1"} -+ self.app.client_manager = clientmanager.ClientManager( -+ token=AUTH_TOKEN, -+ url=AUTH_URL, -+ auth_url=AUTH_URL, -+ api_version=api_version, -+ ) -+ -+ -+class TestObjectClient(TestObject): -+ -+ def test_make_client(self): -+ self.assertEqual(self.app.client_manager.object.endpoint, AUTH_URL) -+ self.assertEqual(self.app.client_manager.object.token, AUTH_TOKEN) -+ -+ -+@mock.patch( -+ 'openstackclient.object.v1.container.lib_container.list_containers' -+) -+class TestContainerList(TestObject): -+ -+ def setUp(self): -+ super(TestContainerList, self).setUp() -+ -+ # Get the command object to test -+ self.cmd = container.ListContainer(self.app, None) -+ -+ def test_object_list_containers_no_options(self, c_mock): -+ c_mock.return_value = [ -+ copy.deepcopy(object_fakes.CONTAINER), -+ copy.deepcopy(object_fakes.CONTAINER_3), -+ copy.deepcopy(object_fakes.CONTAINER_2), -+ ] -+ -+ arglist = [] -+ verifylist = [] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ } -+ c_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ **kwargs -+ ) -+ -+ collist = ('Name',) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ (object_fakes.container_name, ), -+ (object_fakes.container_name_3, ), -+ (object_fakes.container_name_2, ), -+ ) -+ self.assertEqual(tuple(data), datalist) -+ -+ def test_object_list_containers_prefix(self, c_mock): -+ c_mock.return_value = [ -+ copy.deepcopy(object_fakes.CONTAINER), -+ copy.deepcopy(object_fakes.CONTAINER_3), -+ ] -+ -+ arglist = [ -+ '--prefix', 'bit', -+ ] -+ verifylist = [ -+ ('prefix', 'bit'), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ 'prefix': 'bit', -+ } -+ c_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ **kwargs -+ ) -+ -+ collist = ('Name',) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ (object_fakes.container_name, ), -+ (object_fakes.container_name_3, ), -+ ) -+ self.assertEqual(tuple(data), datalist) -+ -+ def test_object_list_containers_marker(self, c_mock): -+ c_mock.return_value = [ -+ copy.deepcopy(object_fakes.CONTAINER), -+ copy.deepcopy(object_fakes.CONTAINER_3), -+ ] -+ -+ arglist = [ -+ '--marker', object_fakes.container_name, -+ ] -+ verifylist = [ -+ ('marker', object_fakes.container_name), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ 'marker': object_fakes.container_name, -+ } -+ c_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ **kwargs -+ ) -+ -+ collist = ('Name',) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ (object_fakes.container_name, ), -+ (object_fakes.container_name_3, ), -+ ) -+ self.assertEqual(tuple(data), datalist) -+ -+ def test_object_list_containers_end_marker(self, c_mock): -+ c_mock.return_value = [ -+ copy.deepcopy(object_fakes.CONTAINER), -+ copy.deepcopy(object_fakes.CONTAINER_3), -+ ] -+ -+ arglist = [ -+ '--end-marker', object_fakes.container_name_3, -+ ] -+ verifylist = [ -+ ('end_marker', object_fakes.container_name_3), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ 'end_marker': object_fakes.container_name_3, -+ } -+ c_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ **kwargs -+ ) -+ -+ collist = ('Name',) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ (object_fakes.container_name, ), -+ (object_fakes.container_name_3, ), -+ ) -+ self.assertEqual(tuple(data), datalist) -+ -+ def test_object_list_containers_limit(self, c_mock): -+ c_mock.return_value = [ -+ copy.deepcopy(object_fakes.CONTAINER), -+ copy.deepcopy(object_fakes.CONTAINER_3), -+ ] -+ -+ arglist = [ -+ '--limit', '2', -+ ] -+ verifylist = [ -+ ('limit', 2), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ 'limit': 2, -+ } -+ c_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ **kwargs -+ ) -+ -+ collist = ('Name',) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ (object_fakes.container_name, ), -+ (object_fakes.container_name_3, ), -+ ) -+ self.assertEqual(tuple(data), datalist) -+ -+ def test_object_list_containers_long(self, c_mock): -+ c_mock.return_value = [ -+ copy.deepcopy(object_fakes.CONTAINER), -+ copy.deepcopy(object_fakes.CONTAINER_3), -+ ] -+ -+ arglist = [ -+ '--long', -+ ] -+ verifylist = [ -+ ('long', True), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ } -+ c_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ **kwargs -+ ) -+ -+ collist = ('Name', 'Bytes', 'Count') -+ self.assertEqual(columns, collist) -+ datalist = ( -+ ( -+ object_fakes.container_name, -+ object_fakes.container_bytes, -+ object_fakes.container_count, -+ ), -+ ( -+ object_fakes.container_name_3, -+ object_fakes.container_bytes * 3, -+ object_fakes.container_count * 3, -+ ), -+ ) -+ self.assertEqual(tuple(data), datalist) -+ -+ def test_object_list_containers_all(self, c_mock): -+ c_mock.return_value = [ -+ copy.deepcopy(object_fakes.CONTAINER), -+ copy.deepcopy(object_fakes.CONTAINER_2), -+ copy.deepcopy(object_fakes.CONTAINER_3), -+ ] -+ -+ arglist = [ -+ '--all', -+ ] -+ verifylist = [ -+ ('all', True), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ 'full_listing': True, -+ } -+ c_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ **kwargs -+ ) -+ -+ collist = ('Name',) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ (object_fakes.container_name, ), -+ (object_fakes.container_name_2, ), -+ (object_fakes.container_name_3, ), -+ ) -+ self.assertEqual(tuple(data), datalist) -+ -+ -+@mock.patch( -+ 'openstackclient.object.v1.container.lib_container.show_container' -+) -+class TestContainerShow(TestObject): -+ -+ def setUp(self): -+ super(TestContainerShow, self).setUp() -+ -+ # Get the command object to test -+ self.cmd = container.ShowContainer(self.app, None) -+ -+ def test_container_show(self, c_mock): -+ c_mock.return_value = copy.deepcopy(object_fakes.CONTAINER) -+ -+ arglist = [ -+ object_fakes.container_name, -+ ] -+ verifylist = [ -+ ('container', object_fakes.container_name), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ } -+ # lib.container.show_container(api, url, container) -+ c_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ object_fakes.container_name, -+ **kwargs -+ ) -+ -+ collist = ('bytes', 'count', 'name') -+ self.assertEqual(columns, collist) -+ datalist = ( -+ object_fakes.container_bytes, -+ object_fakes.container_count, -+ object_fakes.container_name, -+ ) -+ self.assertEqual(data, datalist) -diff --git a/openstackclient/tests/object/v1/test_object.py b/openstackclient/tests/object/v1/test_object.py -new file mode 100644 -index 0000000..52b5ebd ---- /dev/null -+++ b/openstackclient/tests/object/v1/test_object.py -@@ -0,0 +1,413 @@ -+# Copyright 2013 OpenStack Foundation -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); you may -+# not use this file except in compliance with the License. You may obtain -+# a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+# License for the specific language governing permissions and limitations -+# under the License. -+# -+ -+import copy -+import mock -+ -+from openstackclient.common import clientmanager -+from openstackclient.object.v1 import object as obj -+from openstackclient.tests.object.v1 import fakes as object_fakes -+from openstackclient.tests import utils -+ -+ -+AUTH_TOKEN = "foobar" -+AUTH_URL = "http://0.0.0.0" -+ -+ -+class FakeClient(object): -+ def __init__(self, endpoint=None, **kwargs): -+ self.endpoint = AUTH_URL -+ self.token = AUTH_TOKEN -+ -+ -+class TestObject(utils.TestCommand): -+ def setUp(self): -+ super(TestObject, self).setUp() -+ -+ api_version = {"object-store": "1"} -+ self.app.client_manager = clientmanager.ClientManager( -+ token=AUTH_TOKEN, -+ url=AUTH_URL, -+ auth_url=AUTH_URL, -+ api_version=api_version, -+ ) -+ -+ -+class TestObjectClient(TestObject): -+ -+ def test_make_client(self): -+ self.assertEqual(self.app.client_manager.object.endpoint, AUTH_URL) -+ self.assertEqual(self.app.client_manager.object.token, AUTH_TOKEN) -+ -+ -+@mock.patch( -+ 'openstackclient.object.v1.object.lib_object.list_objects' -+) -+class TestObjectList(TestObject): -+ -+ def setUp(self): -+ super(TestObjectList, self).setUp() -+ -+ # Get the command object to test -+ self.cmd = obj.ListObject(self.app, None) -+ -+ def test_object_list_objects_no_options(self, o_mock): -+ o_mock.return_value = [ -+ copy.deepcopy(object_fakes.OBJECT), -+ copy.deepcopy(object_fakes.OBJECT_2), -+ ] -+ -+ arglist = [ -+ object_fakes.container_name, -+ ] -+ verifylist = [ -+ ('container', object_fakes.container_name), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ o_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ object_fakes.container_name, -+ ) -+ -+ collist = ('Name',) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ (object_fakes.object_name_1, ), -+ (object_fakes.object_name_2, ), -+ ) -+ self.assertEqual(tuple(data), datalist) -+ -+ def test_object_list_objects_prefix(self, o_mock): -+ o_mock.return_value = [ -+ copy.deepcopy(object_fakes.OBJECT_2), -+ ] -+ -+ arglist = [ -+ '--prefix', 'floppy', -+ object_fakes.container_name_2, -+ ] -+ verifylist = [ -+ ('prefix', 'floppy'), -+ ('container', object_fakes.container_name_2), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ 'prefix': 'floppy', -+ } -+ o_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ object_fakes.container_name_2, -+ **kwargs -+ ) -+ -+ collist = ('Name',) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ (object_fakes.object_name_2, ), -+ ) -+ self.assertEqual(tuple(data), datalist) -+ -+ def test_object_list_objects_delimiter(self, o_mock): -+ o_mock.return_value = [ -+ copy.deepcopy(object_fakes.OBJECT_2), -+ ] -+ -+ arglist = [ -+ '--delimiter', '=', -+ object_fakes.container_name_2, -+ ] -+ verifylist = [ -+ ('delimiter', '='), -+ ('container', object_fakes.container_name_2), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ 'delimiter': '=', -+ } -+ o_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ object_fakes.container_name_2, -+ **kwargs -+ ) -+ -+ collist = ('Name',) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ (object_fakes.object_name_2, ), -+ ) -+ self.assertEqual(tuple(data), datalist) -+ -+ def test_object_list_objects_marker(self, o_mock): -+ o_mock.return_value = [ -+ copy.deepcopy(object_fakes.OBJECT_2), -+ ] -+ -+ arglist = [ -+ '--marker', object_fakes.object_name_2, -+ object_fakes.container_name_2, -+ ] -+ verifylist = [ -+ ('marker', object_fakes.object_name_2), -+ ('container', object_fakes.container_name_2), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ 'marker': object_fakes.object_name_2, -+ } -+ o_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ object_fakes.container_name_2, -+ **kwargs -+ ) -+ -+ collist = ('Name',) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ (object_fakes.object_name_2, ), -+ ) -+ self.assertEqual(tuple(data), datalist) -+ -+ def test_object_list_objects_end_marker(self, o_mock): -+ o_mock.return_value = [ -+ copy.deepcopy(object_fakes.OBJECT_2), -+ ] -+ -+ arglist = [ -+ '--end-marker', object_fakes.object_name_2, -+ object_fakes.container_name_2, -+ ] -+ verifylist = [ -+ ('end_marker', object_fakes.object_name_2), -+ ('container', object_fakes.container_name_2), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ 'end_marker': object_fakes.object_name_2, -+ } -+ o_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ object_fakes.container_name_2, -+ **kwargs -+ ) -+ -+ collist = ('Name',) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ (object_fakes.object_name_2, ), -+ ) -+ self.assertEqual(tuple(data), datalist) -+ -+ def test_object_list_objects_limit(self, o_mock): -+ o_mock.return_value = [ -+ copy.deepcopy(object_fakes.OBJECT_2), -+ ] -+ -+ arglist = [ -+ '--limit', '2', -+ object_fakes.container_name_2, -+ ] -+ verifylist = [ -+ ('limit', 2), -+ ('container', object_fakes.container_name_2), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ 'limit': 2, -+ } -+ o_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ object_fakes.container_name_2, -+ **kwargs -+ ) -+ -+ collist = ('Name',) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ (object_fakes.object_name_2, ), -+ ) -+ self.assertEqual(tuple(data), datalist) -+ -+ def test_object_list_objects_long(self, o_mock): -+ o_mock.return_value = [ -+ copy.deepcopy(object_fakes.OBJECT), -+ copy.deepcopy(object_fakes.OBJECT_2), -+ ] -+ -+ arglist = [ -+ '--long', -+ object_fakes.container_name, -+ ] -+ verifylist = [ -+ ('long', True), -+ ('container', object_fakes.container_name), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ } -+ o_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ object_fakes.container_name, -+ **kwargs -+ ) -+ -+ collist = ('Name', 'Bytes', 'Hash', 'Content Type', 'Last Modified') -+ self.assertEqual(columns, collist) -+ datalist = ( -+ ( -+ object_fakes.object_name_1, -+ object_fakes.object_bytes_1, -+ object_fakes.object_hash_1, -+ object_fakes.object_content_type_1, -+ object_fakes.object_modified_1, -+ ), -+ ( -+ object_fakes.object_name_2, -+ object_fakes.object_bytes_2, -+ object_fakes.object_hash_2, -+ object_fakes.object_content_type_2, -+ object_fakes.object_modified_2, -+ ), -+ ) -+ self.assertEqual(tuple(data), datalist) -+ -+ def test_object_list_objects_all(self, o_mock): -+ o_mock.return_value = [ -+ copy.deepcopy(object_fakes.OBJECT), -+ copy.deepcopy(object_fakes.OBJECT_2), -+ ] -+ -+ arglist = [ -+ '--all', -+ object_fakes.container_name, -+ ] -+ verifylist = [ -+ ('all', True), -+ ('container', object_fakes.container_name), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ 'full_listing': True, -+ } -+ o_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ object_fakes.container_name, -+ **kwargs -+ ) -+ -+ collist = ('Name',) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ (object_fakes.object_name_1, ), -+ (object_fakes.object_name_2, ), -+ ) -+ self.assertEqual(tuple(data), datalist) -+ -+ -+@mock.patch( -+ 'openstackclient.object.v1.object.lib_object.show_object' -+) -+class TestObjectShow(TestObject): -+ -+ def setUp(self): -+ super(TestObjectShow, self).setUp() -+ -+ # Get the command object to test -+ self.cmd = obj.ShowObject(self.app, None) -+ -+ def test_object_show(self, c_mock): -+ c_mock.return_value = copy.deepcopy(object_fakes.OBJECT) -+ -+ arglist = [ -+ object_fakes.container_name, -+ object_fakes.object_name_1, -+ ] -+ verifylist = [ -+ ('container', object_fakes.container_name), -+ ('object', object_fakes.object_name_1), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ kwargs = { -+ } -+ # lib.container.show_container(api, url, container) -+ c_mock.assert_called_with( -+ self.app.restapi, -+ AUTH_URL, -+ object_fakes.container_name, -+ object_fakes.object_name_1, -+ **kwargs -+ ) -+ -+ collist = ('bytes', 'content_type', 'hash', 'last_modified', 'name') -+ self.assertEqual(columns, collist) -+ datalist = ( -+ object_fakes.object_bytes_1, -+ object_fakes.object_content_type_1, -+ object_fakes.object_hash_1, -+ object_fakes.object_modified_1, -+ object_fakes.object_name_1, -+ ) -+ self.assertEqual(data, datalist) -diff --git a/openstackclient/tests/volume/v1/fakes.py b/openstackclient/tests/volume/v1/fakes.py -index a382dbb..b25dfaf 100644 ---- a/openstackclient/tests/volume/v1/fakes.py -+++ b/openstackclient/tests/volume/v1/fakes.py -@@ -16,6 +16,9 @@ - import mock - - from openstackclient.tests import fakes -+from openstackclient.tests.identity.v2_0 import fakes as identity_fakes -+from openstackclient.tests import utils -+ - - volume_id = 'vvvvvvvv-vvvv-vvvv-vvvvvvvv' - volume_name = 'nigel' -@@ -42,3 +45,18 @@ class FakeVolumev1Client(object): - self.services.resource_class = fakes.FakeResource(None, {}) - self.auth_token = kwargs['token'] - self.management_url = kwargs['endpoint'] -+ -+ -+class TestVolumev1(utils.TestCommand): -+ def setUp(self): -+ super(TestVolumev1, self).setUp() -+ -+ self.app.client_manager.volume = FakeVolumev1Client( -+ endpoint=fakes.AUTH_URL, -+ token=fakes.AUTH_TOKEN, -+ ) -+ -+ self.app.client_manager.identity = identity_fakes.FakeIdentityv2Client( -+ endpoint=fakes.AUTH_URL, -+ token=fakes.AUTH_TOKEN, -+ ) -diff --git a/openstackclient/tests/volume/v1/test_volume.py b/openstackclient/tests/volume/v1/test_volume.py -index 58024f0..4e033df 100644 ---- a/openstackclient/tests/volume/v1/test_volume.py -+++ b/openstackclient/tests/volume/v1/test_volume.py -@@ -1,4 +1,4 @@ --# Copyright 2013 OpenStack, LLC. -+# Copyright 2013 Nebula Inc. - # - # Licensed under the Apache License, Version 2.0 (the "License"); you may - # not use this file except in compliance with the License. You may obtain -@@ -13,25 +13,256 @@ - # under the License. - # - -+import copy -+ -+from openstackclient.tests import fakes - from openstackclient.tests.identity.v2_0 import fakes as identity_fakes --from openstackclient.tests import utils --from openstackclient.tests.volume.v1 import fakes -+from openstackclient.tests.volume.v1 import fakes as volume_fakes -+from openstackclient.volume.v1 import volume -+ -+ -+class TestVolume(volume_fakes.TestVolumev1): -+ -+ def setUp(self): -+ super(TestVolume, self).setUp() - -+ # Get a shortcut to the VolumeManager Mock -+ self.volumes_mock = self.app.client_manager.volume.volumes -+ self.volumes_mock.reset_mock() - --AUTH_TOKEN = "foobar" --AUTH_URL = "http://0.0.0.0" -+ # Get a shortcut to the TenantManager Mock -+ self.projects_mock = self.app.client_manager.identity.tenants -+ self.projects_mock.reset_mock() - -+ # Get a shortcut to the UserManager Mock -+ self.users_mock = self.app.client_manager.identity.users -+ self.users_mock.reset_mock() -+ -+ -+# TODO(dtroyer): The volume create tests are incomplete, only the minimal -+# options and the options that require additional processing -+# are implemented at this time. -+ -+class TestVolumeCreate(TestVolume): - --class TestVolumev1(utils.TestCommand): - def setUp(self): -- super(TestVolumev1, self).setUp() -+ super(TestVolumeCreate, self).setUp() -+ -+ self.volumes_mock.create.return_value = fakes.FakeResource( -+ None, -+ copy.deepcopy(volume_fakes.VOLUME), -+ loaded=True, -+ ) -+ -+ # Get the command object to test -+ self.cmd = volume.CreateVolume(self.app, None) -+ -+ def test_volume_create_min_options(self): -+ arglist = [ -+ '--size', str(volume_fakes.volume_size), -+ volume_fakes.volume_name, -+ ] -+ verifylist = [ -+ ('size', volume_fakes.volume_size), -+ ('name', volume_fakes.volume_name), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ #kwargs = { -+ # 'metadata': volume_fakes.volume_metadata, -+ #} -+ # VolumeManager.create(size, snapshot_id=, source_volid=, -+ # display_name=, display_description=, -+ # volume_type=, user_id=, -+ # project_id=, availability_zone=, -+ # metadata=, imageRef=) -+ self.volumes_mock.create.assert_called_with( -+ volume_fakes.volume_size, -+ None, -+ None, -+ volume_fakes.volume_name, -+ None, -+ None, -+ None, -+ None, -+ None, -+ None, -+ None, -+ ) -+ -+ collist = ( -+ 'attach_status', -+ 'display_description', -+ 'display_name', -+ 'id', -+ 'properties', -+ 'size', -+ 'status', -+ ) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ 'detatched', -+ volume_fakes.volume_description, -+ volume_fakes.volume_name, -+ volume_fakes.volume_id, -+ '', -+ volume_fakes.volume_size, -+ '', -+ ) -+ self.assertEqual(data, datalist) -+ -+ def test_volume_create_user_project_id(self): -+ # Return a project -+ self.projects_mock.get.return_value = fakes.FakeResource( -+ None, -+ copy.deepcopy(identity_fakes.PROJECT), -+ loaded=True, -+ ) -+ # Return a user -+ self.users_mock.get.return_value = fakes.FakeResource( -+ None, -+ copy.deepcopy(identity_fakes.USER), -+ loaded=True, -+ ) -+ -+ arglist = [ -+ '--size', str(volume_fakes.volume_size), -+ '--project', identity_fakes.project_id, -+ '--user', identity_fakes.user_id, -+ volume_fakes.volume_name, -+ ] -+ verifylist = [ -+ ('size', volume_fakes.volume_size), -+ ('project', identity_fakes.project_id), -+ ('user', identity_fakes.user_id), -+ ('name', volume_fakes.volume_name), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) - -- self.app.client_manager.volume = fakes.FakeVolumev1Client( -- endpoint=AUTH_URL, -- token=AUTH_TOKEN, -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ #kwargs = { -+ # 'metadata': volume_fakes.volume_metadata, -+ #} -+ # VolumeManager.create(size, snapshot_id=, source_volid=, -+ # display_name=, display_description=, -+ # volume_type=, user_id=, -+ # project_id=, availability_zone=, -+ # metadata=, imageRef=) -+ self.volumes_mock.create.assert_called_with( -+ volume_fakes.volume_size, -+ None, -+ None, -+ volume_fakes.volume_name, -+ #volume_fakes.volume_description, -+ None, -+ None, -+ identity_fakes.user_id, -+ identity_fakes.project_id, -+ None, -+ None, -+ None, -+ ) -+ -+ collist = ( -+ 'attach_status', -+ 'display_description', -+ 'display_name', -+ 'id', -+ 'properties', -+ 'size', -+ 'status', -+ ) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ 'detatched', -+ volume_fakes.volume_description, -+ volume_fakes.volume_name, -+ volume_fakes.volume_id, -+ '', -+ volume_fakes.volume_size, -+ '', - ) -+ self.assertEqual(data, datalist) - -- self.app.client_manager.identity = identity_fakes.FakeIdentityv2Client( -- endpoint=AUTH_URL, -- token=AUTH_TOKEN, -+ def test_volume_create_user_project_name(self): -+ # Return a project -+ self.projects_mock.get.return_value = fakes.FakeResource( -+ None, -+ copy.deepcopy(identity_fakes.PROJECT), -+ loaded=True, -+ ) -+ # Return a user -+ self.users_mock.get.return_value = fakes.FakeResource( -+ None, -+ copy.deepcopy(identity_fakes.USER), -+ loaded=True, -+ ) -+ -+ arglist = [ -+ '--size', str(volume_fakes.volume_size), -+ '--project', identity_fakes.project_name, -+ '--user', identity_fakes.user_name, -+ volume_fakes.volume_name, -+ ] -+ verifylist = [ -+ ('size', volume_fakes.volume_size), -+ ('project', identity_fakes.project_name), -+ ('user', identity_fakes.user_name), -+ ('name', volume_fakes.volume_name), -+ ] -+ parsed_args = self.check_parser(self.cmd, arglist, verifylist) -+ -+ # DisplayCommandBase.take_action() returns two tuples -+ columns, data = self.cmd.take_action(parsed_args) -+ -+ # Set expected values -+ #kwargs = { -+ # 'metadata': volume_fakes.volume_metadata, -+ #} -+ # VolumeManager.create(size, snapshot_id=, source_volid=, -+ # display_name=, display_description=, -+ # volume_type=, user_id=, -+ # project_id=, availability_zone=, -+ # metadata=, imageRef=) -+ self.volumes_mock.create.assert_called_with( -+ volume_fakes.volume_size, -+ None, -+ None, -+ volume_fakes.volume_name, -+ #volume_fakes.volume_description, -+ None, -+ None, -+ identity_fakes.user_id, -+ identity_fakes.project_id, -+ None, -+ None, -+ None, -+ ) -+ -+ collist = ( -+ 'attach_status', -+ 'display_description', -+ 'display_name', -+ 'id', -+ 'properties', -+ 'size', -+ 'status', -+ ) -+ self.assertEqual(columns, collist) -+ datalist = ( -+ 'detatched', -+ volume_fakes.volume_description, -+ volume_fakes.volume_name, -+ volume_fakes.volume_id, -+ '', -+ volume_fakes.volume_size, -+ '', - ) -+ self.assertEqual(data, datalist) -diff --git a/openstackclient/tests/volume/v1/test_volumecmd.py b/openstackclient/tests/volume/v1/test_volumecmd.py -deleted file mode 100644 -index 1f5ed88..0000000 ---- a/openstackclient/tests/volume/v1/test_volumecmd.py -+++ /dev/null -@@ -1,269 +0,0 @@ --# Copyright 2013 Nebula Inc. --# --# Licensed under the Apache License, Version 2.0 (the "License"); you may --# not use this file except in compliance with the License. You may obtain --# a copy of the License at --# --# http://www.apache.org/licenses/LICENSE-2.0 --# --# Unless required by applicable law or agreed to in writing, software --# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT --# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the --# License for the specific language governing permissions and limitations --# under the License. --# -- --import copy -- --from openstackclient.tests import fakes --from openstackclient.tests.identity.v2_0 import fakes as identity_fakes --from openstackclient.tests.volume.v1 import fakes as volume_fakes --from openstackclient.tests.volume.v1 import test_volume --from openstackclient.volume.v1 import volume -- -- --class TestVolume(test_volume.TestVolumev1): -- -- def setUp(self): -- super(TestVolume, self).setUp() -- -- # Get a shortcut to the VolumeManager Mock -- self.volumes_mock = self.app.client_manager.volume.volumes -- self.volumes_mock.reset_mock() -- -- # Get a shortcut to the TenantManager Mock -- self.projects_mock = self.app.client_manager.identity.tenants -- self.projects_mock.reset_mock() -- -- # Get a shortcut to the UserManager Mock -- self.users_mock = self.app.client_manager.identity.users -- self.users_mock.reset_mock() -- -- --# TODO(dtroyer): The volume create tests are incomplete, only the minimal --# options and the options that require additional processing --# are implemented at this time. -- --class TestVolumeCreate(TestVolume): -- -- def setUp(self): -- super(TestVolumeCreate, self).setUp() -- -- self.volumes_mock.create.return_value = fakes.FakeResource( -- None, -- copy.deepcopy(volume_fakes.VOLUME), -- loaded=True, -- ) -- -- # Get the command object to test -- self.cmd = volume.CreateVolume(self.app, None) -- -- def test_volume_create_min_options(self): -- arglist = [ -- '--size', str(volume_fakes.volume_size), -- volume_fakes.volume_name, -- ] -- verifylist = [ -- ('size', volume_fakes.volume_size), -- ('name', volume_fakes.volume_name), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- #kwargs = { -- # 'metadata': volume_fakes.volume_metadata, -- #} -- # VolumeManager.create(size, snapshot_id=, source_volid=, -- # display_name=, display_description=, -- # volume_type=, user_id=, -- # project_id=, availability_zone=, -- # metadata=, imageRef=) -- self.volumes_mock.create.assert_called_with( -- volume_fakes.volume_size, -- None, -- None, -- volume_fakes.volume_name, -- None, -- None, -- None, -- None, -- None, -- None, -- None, -- ) -- -- collist = ( -- 'attach_status', -- 'display_description', -- 'display_name', -- 'id', -- 'properties', -- 'size', -- 'status', -- ) -- self.assertEqual(columns, collist) -- datalist = ( -- 'detatched', -- volume_fakes.volume_description, -- volume_fakes.volume_name, -- volume_fakes.volume_id, -- '', -- volume_fakes.volume_size, -- '', -- ) -- self.assertEqual(data, datalist) -- -- def test_volume_create_user_project_id(self): -- # Return a project -- self.projects_mock.get.return_value = fakes.FakeResource( -- None, -- copy.deepcopy(identity_fakes.PROJECT), -- loaded=True, -- ) -- # Return a user -- self.users_mock.get.return_value = fakes.FakeResource( -- None, -- copy.deepcopy(identity_fakes.USER), -- loaded=True, -- ) -- -- arglist = [ -- '--size', str(volume_fakes.volume_size), -- '--project', identity_fakes.project_id, -- '--user', identity_fakes.user_id, -- volume_fakes.volume_name, -- ] -- verifylist = [ -- ('size', volume_fakes.volume_size), -- ('project', identity_fakes.project_id), -- ('user', identity_fakes.user_id), -- ('name', volume_fakes.volume_name), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- #kwargs = { -- # 'metadata': volume_fakes.volume_metadata, -- #} -- # VolumeManager.create(size, snapshot_id=, source_volid=, -- # display_name=, display_description=, -- # volume_type=, user_id=, -- # project_id=, availability_zone=, -- # metadata=, imageRef=) -- self.volumes_mock.create.assert_called_with( -- volume_fakes.volume_size, -- None, -- None, -- volume_fakes.volume_name, -- #volume_fakes.volume_description, -- None, -- None, -- identity_fakes.user_id, -- identity_fakes.project_id, -- None, -- None, -- None, -- ) -- -- collist = ( -- 'attach_status', -- 'display_description', -- 'display_name', -- 'id', -- 'properties', -- 'size', -- 'status', -- ) -- self.assertEqual(columns, collist) -- datalist = ( -- 'detatched', -- volume_fakes.volume_description, -- volume_fakes.volume_name, -- volume_fakes.volume_id, -- '', -- volume_fakes.volume_size, -- '', -- ) -- self.assertEqual(data, datalist) -- -- def test_volume_create_user_project_name(self): -- # Return a project -- self.projects_mock.get.return_value = fakes.FakeResource( -- None, -- copy.deepcopy(identity_fakes.PROJECT), -- loaded=True, -- ) -- # Return a user -- self.users_mock.get.return_value = fakes.FakeResource( -- None, -- copy.deepcopy(identity_fakes.USER), -- loaded=True, -- ) -- -- arglist = [ -- '--size', str(volume_fakes.volume_size), -- '--project', identity_fakes.project_name, -- '--user', identity_fakes.user_name, -- volume_fakes.volume_name, -- ] -- verifylist = [ -- ('size', volume_fakes.volume_size), -- ('project', identity_fakes.project_name), -- ('user', identity_fakes.user_name), -- ('name', volume_fakes.volume_name), -- ] -- parsed_args = self.check_parser(self.cmd, arglist, verifylist) -- -- # DisplayCommandBase.take_action() returns two tuples -- columns, data = self.cmd.take_action(parsed_args) -- -- # Set expected values -- #kwargs = { -- # 'metadata': volume_fakes.volume_metadata, -- #} -- # VolumeManager.create(size, snapshot_id=, source_volid=, -- # display_name=, display_description=, -- # volume_type=, user_id=, -- # project_id=, availability_zone=, -- # metadata=, imageRef=) -- self.volumes_mock.create.assert_called_with( -- volume_fakes.volume_size, -- None, -- None, -- volume_fakes.volume_name, -- #volume_fakes.volume_description, -- None, -- None, -- identity_fakes.user_id, -- identity_fakes.project_id, -- None, -- None, -- None, -- ) -- -- collist = ( -- 'attach_status', -- 'display_description', -- 'display_name', -- 'id', -- 'properties', -- 'size', -- 'status', -- ) -- self.assertEqual(columns, collist) -- datalist = ( -- 'detatched', -- volume_fakes.volume_description, -- volume_fakes.volume_name, -- volume_fakes.volume_id, -- '', -- volume_fakes.volume_size, -- '', -- ) -- self.assertEqual(data, datalist) diff --git a/0013-Add-server-image-create-command.patch b/0013-Add-server-image-create-command.patch deleted file mode 100644 index fe9c360..0000000 --- a/0013-Add-server-image-create-command.patch +++ /dev/null @@ -1,269 +0,0 @@ -From 03267c4afadd093f66cc01141b7a36c389d3cb69 Mon Sep 17 00:00:00 2001 -From: Dean Troyer -Date: Mon, 18 Nov 2013 17:10:39 -0600 -Subject: [PATCH] Add server image create command - -Translation of 'nova image-create', with tests! - -Change-Id: I8a833aeff6f291e4774063ed235876eb2ba9c13c ---- - openstackclient/compute/v2/server.py | 67 ++++++++++++++++++ - openstackclient/tests/compute/v2/fakes.py | 13 ++-- - openstackclient/tests/compute/v2/test_server.py | 91 +++++++++++++++++++++++++ - openstackclient/tests/image/v2/fakes.py | 5 +- - setup.cfg | 1 + - 5 files changed, 169 insertions(+), 8 deletions(-) - -diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py -index 1de9f1b..87f5f68 100644 ---- a/openstackclient/compute/v2/server.py -+++ b/openstackclient/compute/v2/server.py -@@ -384,6 +384,73 @@ class CreateServer(show.ShowOne): - return zip(*sorted(six.iteritems(details))) - - -+class CreateServerImage(show.ShowOne): -+ """Create a new disk image from a running server""" -+ -+ log = logging.getLogger(__name__ + '.CreateServerImage') -+ -+ def get_parser(self, prog_name): -+ parser = super(CreateServerImage, self).get_parser(prog_name) -+ parser.add_argument( -+ 'server', -+ metavar=' -Date: Tue, 19 Nov 2013 10:10:54 +0100 -Subject: [PATCH] Support building wheels (PEP-427) - -With that, building and uploading wheels to PyPI is only one "python -setup.py bdist_wheel" away. - -Change-Id: I8c8565f55e7a3434e1a1972a797a6cd7dba8a581 ---- - setup.cfg | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - -diff --git a/setup.cfg b/setup.cfg -index 2ee47c0..1f84c1e 100644 ---- a/setup.cfg -+++ b/setup.cfg -@@ -280,8 +280,5 @@ all_files = 1 - [upload_sphinx] - upload-dir = doc/build/html - --[egg_info] --tag_build = --tag_date = 0 --tag_svn_revision = 0 -- -+[wheel] -+universal = 1 diff --git a/0015-Fix-typo.patch b/0015-Fix-typo.patch deleted file mode 100644 index 549d1a8..0000000 --- a/0015-Fix-typo.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 58d058ae3030b928529e7fb39b88bd2eeaeda013 Mon Sep 17 00:00:00 2001 -From: Noorul Islam K M -Date: Tue, 19 Nov 2013 19:57:02 +0530 -Subject: [PATCH] Fix typo - -Change-Id: I7bca8b76c6746121314e688e9ed3825e04350b8d ---- - openstackclient/common/commandmanager.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/openstackclient/common/commandmanager.py b/openstackclient/common/commandmanager.py -index e366034..06073d9 100644 ---- a/openstackclient/common/commandmanager.py -+++ b/openstackclient/common/commandmanager.py -@@ -25,7 +25,7 @@ LOG = logging.getLogger(__name__) - - - class CommandManager(cliff.commandmanager.CommandManager): -- """Alters Cliff's default CommandManager behaviour to load additiona -+ """Alters Cliff's default CommandManager behaviour to load additional - command groups after initialization. - """ - def _load_commands(self, group=None): diff --git a/python-openstackclient.spec b/python-openstackclient.spec index 1f5dc2e..db3efc8 100644 --- a/python-openstackclient.spec +++ b/python-openstackclient.spec @@ -1,6 +1,6 @@ Name: python-openstackclient -Version: 0.2.2 -Release: 4%{?dist} +Version: 0.3.0 +Release: 1%{?dist} Summary: OpenStack Command-line Client Group: Development/Languages @@ -9,23 +9,10 @@ URL: http://github.com/openstack/python-openstackclient Source0: http://pypi.python.org/packages/source/p/%{name}/%{name}-%{version}.tar.gz # -# patches_base=0.2.2+1 +# patches_base=0.3.0 # -Patch0001: 0001-Add-to-clientmanager-tests.patch -Patch0002: 0002-Add-object-store-show-commands.patch -Patch0003: 0003-Updated-from-global-requirements.patch -Patch0004: 0004-Add-options-to-support-TLS-certificate-verification.patch -Patch0005: 0005-Sync-oslo-incubator-for-py33-fixes.patch -Patch0006: 0006-Updated-from-global-requirements.patch -Patch0007: 0007-Do-lookups-for-user-project-in-volume-create.patch -Patch0008: 0008-Updated-from-global-requirements.patch -Patch0009: 0009-Remove-httpretty-from-test-requirements.patch -Patch0010: 0010-Update-URL-for-global-hacking-doc-and-fix-typos.patch -Patch0011: 0011-change-execute-to-run.patch -Patch0012: 0012-Complete-basic-test-infrastructure.patch -Patch0013: 0013-Add-server-image-create-command.patch -Patch0014: 0014-Support-building-wheels-PEP-427.patch -Patch0015: 0015-Fix-typo.patch +Patch0001: 0001-Restore-compatibility-with-older-python-keyring.patch + BuildArch: noarch BuildRequires: python2-devel @@ -42,6 +29,8 @@ Requires: python-glanceclient Requires: python-keystoneclient Requires: python-novaclient Requires: python-cinderclient +Requires: python-six +Requires: python-requests %description python-openstackclient is a unified command-line client for the OpenStack APIs. @@ -68,20 +57,6 @@ This package contains auto-generated documentation. %setup -q %patch0001 -p1 -%patch0002 -p1 -%patch0003 -p1 -%patch0004 -p1 -%patch0005 -p1 -%patch0006 -p1 -%patch0007 -p1 -%patch0008 -p1 -%patch0009 -p1 -%patch0010 -p1 -%patch0011 -p1 -%patch0012 -p1 -%patch0013 -p1 -%patch0014 -p1 -%patch0015 -p1 # Remove bundled egg-info rm -rf python_openstackclient.egg-info @@ -118,6 +93,11 @@ rm -fr html/.doctrees html/.buildinfo %doc html %changelog +* Tue Jan 07 2014 Jakub Ruzicka 0.3.0-1 +- Update to upstream 0.3.0 +- New dependencies: python-six, python-requests +- Restore compatibility with old EPEL python-keyring + * Fri Nov 22 2013 Jakub Ruzicka 0.2.2-4 - Update with patches from upstream master diff --git a/sources b/sources index 6ff9e11..91005d2 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -5ad5f3ad0e84c83ec623265420de79d4 python-openstackclient-0.2.2.tar.gz +bc0f86d23d706d3a36aba47398fad03b python-openstackclient-0.3.0.tar.gz