diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py index a2f85af..4dcec8e 100644 --- a/openstackclient/common/clientmanager.py +++ b/openstackclient/common/clientmanager.py @@ -19,6 +19,7 @@ import logging import pkg_resources import sys +from openstackclient.common import restapi from openstackclient.identity import client as identity_client @@ -77,7 +78,18 @@ class ClientManager(object): self._insecure = not verify else: self._cacert = verify - self._insecure = True + self._insecure = False + + self.session = restapi.RESTApi( + verify=verify, + debug=True, + ) + + # Get logging from root logger + root_logger = logging.getLogger('') + LOG.setLevel(root_logger.getEffectiveLevel()) + restapi_logger = logging.getLogger('restapi') + restapi_logger.setLevel(root_logger.getEffectiveLevel()) self.auth_ref = None diff --git a/openstackclient/shell.py b/openstackclient/shell.py index 6fe5ba7..2480434 100644 --- a/openstackclient/shell.py +++ b/openstackclient/shell.py @@ -31,7 +31,6 @@ import openstackclient from openstackclient.common import clientmanager from openstackclient.common import commandmanager from openstackclient.common import exceptions as exc -from openstackclient.common import restapi from openstackclient.common import timing from openstackclient.common import utils @@ -467,10 +466,6 @@ class OpenStackShell(app.App): self.verify = self.options.os_cacert else: self.verify = not self.options.insecure - self.restapi = restapi.RESTApi( - verify=self.verify, - debug=self.options.debug, - ) def prepare_to_run_command(self, cmd): """Set up auth and API versions""" @@ -481,12 +476,10 @@ class OpenStackShell(app.App): if cmd.best_effort: try: self.authenticate_user() - self.restapi.set_auth(self.client_manager.identity.auth_token) except Exception: pass else: self.authenticate_user() - self.restapi.set_auth(self.client_manager.identity.auth_token) return def clean_up(self, cmd, result, err): @@ -522,7 +515,6 @@ class OpenStackShell(app.App): # NOTE(dtroyer): Maintain the old behaviour for interactive use as # this path does not call prepare_to_run_command() self.authenticate_user() - self.restapi.set_auth(self.client_manager.identity.auth_token) super(OpenStackShell, self).interact() diff --git a/openstackclient/tests/common/test_clientmanager.py b/openstackclient/tests/common/test_clientmanager.py index 6aee711..5a25fa2 100644 --- a/openstackclient/tests/common/test_clientmanager.py +++ b/openstackclient/tests/common/test_clientmanager.py @@ -14,11 +14,26 @@ # from openstackclient.common import clientmanager +from openstackclient.common import restapi from openstackclient.tests import utils +AUTH_REF = {'a': 1} AUTH_TOKEN = "foobar" AUTH_URL = "http://0.0.0.0" +USERNAME = "itchy" +PASSWORD = "scratchy" +SERVICE_CATALOG = {'sc': '123'} + + +def FakeMakeClient(instance): + return FakeClient() + + +class FakeClient(object): + auth_ref = AUTH_REF + auth_token = AUTH_TOKEN + service_catalog = SERVICE_CATALOG class Container(object): @@ -28,18 +43,7 @@ class Container(object): pass -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, - ) +class TestClientCache(utils.TestCase): def test_singleton(self): # NOTE(dtroyer): Verify that the ClientCache descriptor only invokes @@ -47,12 +51,88 @@ class TestClientManager(utils.TestCase): c = Container() self.assertEqual(c.attr, c.attr) - def test_make_client_identity_default(self): + +class TestClientManager(utils.TestCase): + def setUp(self): + super(TestClientManager, self).setUp() + + clientmanager.ClientManager.identity = \ + clientmanager.ClientCache(FakeMakeClient) + + def test_client_manager_token(self): + + client_manager = clientmanager.ClientManager( + token=AUTH_TOKEN, + url=AUTH_URL, + verify=True, + ) + self.assertEqual( - self.client_manager.identity.auth_token, AUTH_TOKEN, + client_manager._token, ) self.assertEqual( - self.client_manager.identity.management_url, AUTH_URL, + client_manager._url, ) + self.assertIsInstance( + client_manager.session, + restapi.RESTApi, + ) + self.assertFalse(client_manager._insecure) + self.assertTrue(client_manager._verify) + + def test_client_manager_password(self): + + client_manager = clientmanager.ClientManager( + auth_url=AUTH_URL, + username=USERNAME, + password=PASSWORD, + verify=False, + ) + + self.assertEqual( + AUTH_URL, + client_manager._auth_url, + ) + self.assertEqual( + USERNAME, + client_manager._username, + ) + self.assertEqual( + PASSWORD, + client_manager._password, + ) + self.assertIsInstance( + client_manager.session, + restapi.RESTApi, + ) + self.assertTrue(client_manager._insecure) + self.assertFalse(client_manager._verify) + + # These need to stick around until the old-style clients are gone + self.assertEqual( + AUTH_REF, + client_manager.auth_ref, + ) + self.assertEqual( + AUTH_TOKEN, + client_manager._token, + ) + self.assertEqual( + SERVICE_CATALOG, + client_manager._service_catalog, + ) + + def test_client_manager_password_verify_ca(self): + + client_manager = clientmanager.ClientManager( + auth_url=AUTH_URL, + username=USERNAME, + password=PASSWORD, + verify='cafile', + ) + + self.assertFalse(client_manager._insecure) + self.assertTrue(client_manager._verify) + self.assertEqual('cafile', client_manager._cacert) diff --git a/openstackclient/tests/fakes.py b/openstackclient/tests/fakes.py index fb27ef9..263640e 100644 --- a/openstackclient/tests/fakes.py +++ b/openstackclient/tests/fakes.py @@ -13,9 +13,12 @@ # under the License. # +import json import six import sys +import requests + AUTH_TOKEN = "foobar" AUTH_URL = "http://0.0.0.0" @@ -42,7 +45,6 @@ class FakeApp(object): self.stdin = sys.stdin self.stdout = _stdout or sys.stdout self.stderr = sys.stderr - self.restapi = None class FakeClientManager(object): @@ -53,6 +55,7 @@ class FakeClientManager(object): self.object = None self.volume = None self.network = None + self.session = None self.auth_ref = None @@ -78,3 +81,15 @@ class FakeResource(object): k != 'manager') info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys) return "<%s %s>" % (self.__class__.__name__, info) + + +class FakeResponse(requests.Response): + def __init__(self, headers={}, status_code=200, data=None, encoding=None): + super(FakeResponse, self).__init__() + + self.status_code = status_code + + self.headers.update(headers) + self._content = json.dumps(data) + if not isinstance(self._content, six.binary_type): + self._content = self._content.encode()