diff --git a/novaclient/auth_plugin.py b/novaclient/auth_plugin.py index da2c07b26..d729c4d5a 100644 --- a/novaclient/auth_plugin.py +++ b/novaclient/auth_plugin.py @@ -37,7 +37,14 @@ def discover_auth_systems(): ep_name = 'openstack.client.auth_plugin' for ep in pkg_resources.iter_entry_points(ep_name): try: - auth_plugin = ep.load() + # FIXME(dhellmann): It would be better to use stevedore + # here, since it abstracts this difference in behavior + # between versions of setuptools, but this seemed like a + # more expedient fix. + if hasattr(ep, 'resolve') and hasattr(ep, 'require'): + auth_plugin = ep.resolve() + else: + auth_plugin = ep.load(require=False) except (ImportError, pkg_resources.UnknownExtra, AttributeError) as e: logger.debug("ERROR: Cannot load auth plugin %s" % ep.name) logger.debug(e, exc_info=1) diff --git a/novaclient/tests/unit/test_auth_plugins.py b/novaclient/tests/unit/test_auth_plugins.py index 675102ca3..9dc02b02a 100644 --- a/novaclient/tests/unit/test_auth_plugins.py +++ b/novaclient/tests/unit/test_auth_plugins.py @@ -58,7 +58,10 @@ def requested_headers(cs): class DeprecatedAuthPluginTest(utils.TestCase): def test_auth_system_success(self): class MockEntrypoint(pkg_resources.EntryPoint): - def load(self): + def load(self, require=False): + return self.authenticate + + def resolve(self): return self.authenticate def authenticate(self, cls, auth_url): @@ -117,14 +120,20 @@ class DeprecatedAuthPluginTest(utils.TestCase): def test_auth_system_defining_auth_url(self): class MockAuthUrlEntrypoint(pkg_resources.EntryPoint): - def load(self): + def load(self, require=False): + return self.auth_url + + def resolve(self): return self.auth_url def auth_url(self): return "http://faked/v2.0" class MockAuthenticateEntrypoint(pkg_resources.EntryPoint): - def load(self): + def load(self, require=False): + return self.authenticate + + def resolve(self): return self.authenticate def authenticate(self, cls, auth_url): @@ -160,7 +169,10 @@ class DeprecatedAuthPluginTest(utils.TestCase): @mock.patch.object(pkg_resources, "iter_entry_points") def test_client_raises_exc_without_auth_url(self, mock_iter_entry_points): class MockAuthUrlEntrypoint(pkg_resources.EntryPoint): - def load(self): + def load(self, require=False): + return self.auth_url + + def resolve(self): return self.auth_url def auth_url(self): @@ -184,14 +196,17 @@ class AuthPluginTest(utils.TestCase): def test_auth_system_success(self, mock_iter_entry_points, mock_request): """Test that we can authenticate using the auth system.""" class MockEntrypoint(pkg_resources.EntryPoint): - def load(self): + def load(self, require=False): + return FakePlugin + + def resolve(self): return FakePlugin class FakePlugin(auth_plugin.BaseAuthPlugin): def authenticate(self, cls, auth_url): cls._authenticate(auth_url, {"fake": "me"}) - mock_iter_entry_points.side_effect = lambda _t: [ + mock_iter_entry_points.side_effect = lambda _t, name=None: [ MockEntrypoint("fake", "fake", ["FakePlugin"])] mock_request.side_effect = mock_http_request() @@ -227,10 +242,13 @@ class AuthPluginTest(utils.TestCase): return parser class MockEntrypoint(pkg_resources.EntryPoint): - def load(self): + def load(self, require=False): return FakePlugin - mock_iter_entry_points.side_effect = lambda _t: [ + def resolve(self): + return FakePlugin + + mock_iter_entry_points.side_effect = lambda _t, name=None: [ MockEntrypoint("fake", "fake", ["FakePlugin"])] parser = argparse.ArgumentParser() @@ -244,7 +262,10 @@ class AuthPluginTest(utils.TestCase): def test_parse_auth_system_options(self, mock_iter_entry_points): """Test that we can parse the auth system options.""" class MockEntrypoint(pkg_resources.EntryPoint): - def load(self): + def load(self, require=False): + return FakePlugin + + def resolve(self): return FakePlugin class FakePlugin(auth_plugin.BaseAuthPlugin): @@ -254,7 +275,7 @@ class AuthPluginTest(utils.TestCase): def parse_opts(self, args): return self.opts - mock_iter_entry_points.side_effect = lambda _t: [ + mock_iter_entry_points.side_effect = lambda _t, name=None: [ MockEntrypoint("fake", "fake", ["FakePlugin"])] auth_plugin.discover_auth_systems() @@ -267,14 +288,17 @@ class AuthPluginTest(utils.TestCase): def test_auth_system_defining_url(self, mock_iter_entry_points): """Test the auth_system defining an url.""" class MockEntrypoint(pkg_resources.EntryPoint): - def load(self): + def load(self, require=False): + return FakePlugin + + def resolve(self): return FakePlugin class FakePlugin(auth_plugin.BaseAuthPlugin): def get_auth_url(self): return "http://faked/v2.0" - mock_iter_entry_points.side_effect = lambda _t: [ + mock_iter_entry_points.side_effect = lambda _t, name=None: [ MockEntrypoint("fake", "fake", ["FakePlugin"])] auth_plugin.discover_auth_systems() @@ -289,13 +313,16 @@ class AuthPluginTest(utils.TestCase): def test_exception_if_no_authenticate(self, mock_iter_entry_points): """Test that no authenticate raises a proper exception.""" class MockEntrypoint(pkg_resources.EntryPoint): - def load(self): + def load(self, require=False): + return FakePlugin + + def resolve(self): return FakePlugin class FakePlugin(auth_plugin.BaseAuthPlugin): pass - mock_iter_entry_points.side_effect = lambda _t: [ + mock_iter_entry_points.side_effect = lambda _t, name=None: [ MockEntrypoint("fake", "fake", ["FakePlugin"])] auth_plugin.discover_auth_systems() @@ -310,13 +337,16 @@ class AuthPluginTest(utils.TestCase): def test_exception_if_no_url(self, mock_iter_entry_points): """Test that no auth_url at all raises exception.""" class MockEntrypoint(pkg_resources.EntryPoint): - def load(self): + def load(self, require=False): + return FakePlugin + + def resolve(self): return FakePlugin class FakePlugin(auth_plugin.BaseAuthPlugin): pass - mock_iter_entry_points.side_effect = lambda _t: [ + mock_iter_entry_points.side_effect = lambda _t, name=None: [ MockEntrypoint("fake", "fake", ["FakePlugin"])] auth_plugin.discover_auth_systems() diff --git a/novaclient/utils.py b/novaclient/utils.py index 50310bfdb..1f4df7a57 100644 --- a/novaclient/utils.py +++ b/novaclient/utils.py @@ -319,7 +319,14 @@ def _load_entry_point(ep_name, name=None): """Try to load the entry point ep_name that matches name.""" for ep in pkg_resources.iter_entry_points(ep_name, name=name): try: - return ep.load() + # FIXME(dhellmann): It would be better to use stevedore + # here, since it abstracts this difference in behavior + # between versions of setuptools, but this seemed like a + # more expedient fix. + if hasattr(ep, 'resolve') and hasattr(ep, 'require'): + return ep.resolve() + else: + return ep.load(require=False) except (ImportError, pkg_resources.UnknownExtra, AttributeError): continue