diff --git a/keystoneauth1/extras/kerberos.py b/keystoneauth1/extras/kerberos/__init__.py similarity index 78% rename from keystoneauth1/extras/kerberos.py rename to keystoneauth1/extras/kerberos/__init__.py index 5a4c4f47..1092910c 100644 --- a/keystoneauth1/extras/kerberos.py +++ b/keystoneauth1/extras/kerberos/__init__.py @@ -18,11 +18,13 @@ not installed by default. Without the extra package an import error will occur. The extra package can be installed using:: - $ pip install keystoneauth['kerberos'] - + $ pip install keystoneauth1[kerberos] """ -import requests_kerberos +try: + import requests_kerberos +except ImportError: + requests_kerberos = None from keystoneauth1 import access from keystoneauth1.identity import v3 @@ -37,10 +39,24 @@ def _requests_auth(): mutual_authentication=requests_kerberos.OPTIONAL) +def _dependency_check(): + if requests_kerberos is None: + raise ImportError(""" +Using the kerberos authentication plugin requires installation of additional +packages. These can be installed with:: + + $ pip install keystoneauth1[kerberos] +""") + + class KerberosMethod(v3.AuthMethod): _method_parameters = [] + def __init__(self, *args, **kwargs): + _dependency_check() + super(KerberosMethod, self).__init__(*args, **kwargs) + def get_auth_data(self, session, auth, headers, request_kwargs, **kwargs): # NOTE(jamielennox): request_kwargs is passed as a kwarg however it is # required and always present when called from keystoneclient. @@ -59,6 +75,10 @@ class MappedKerberos(federation.FederationBaseAuth): use the standard keystone auth process to scope that to any given project. """ + def __init__(self, *args, **kwargs): + _dependency_check() + super(MappedKerberos, self).__init__(*args, **kwargs) + def get_unscoped_auth_ref(self, session, **kwargs): resp = session.get(self.federated_token_url, requests_auth=_requests_auth(), diff --git a/keystoneauth1/extras/kerberos/_loading.py b/keystoneauth1/extras/kerberos/_loading.py new file mode 100644 index 00000000..b66c9880 --- /dev/null +++ b/keystoneauth1/extras/kerberos/_loading.py @@ -0,0 +1,25 @@ +# 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 keystoneauth1.extras import kerberos +from keystoneauth1 import loading + + +class Kerberos(loading.BaseV3Loader): + + @property + def plugin_class(self): + return kerberos.Kerberos + + @property + def available(self): + return kerberos.kerberos_requests is not None diff --git a/keystoneauth1/tests/unit/extras/kerberos/test_kerberos_loading.py b/keystoneauth1/tests/unit/extras/kerberos/test_kerberos_loading.py new file mode 100644 index 00000000..e4da3070 --- /dev/null +++ b/keystoneauth1/tests/unit/extras/kerberos/test_kerberos_loading.py @@ -0,0 +1,33 @@ +# 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 keystoneauth1 import loading +from keystoneauth1.tests.unit import utils as test_utils + + +class KerberosLoadingTests(test_utils.TestCase): + + def test_options(self): + opts = [o.name for o in + loading.get_plugin_loader('v3kerberos').get_options()] + + allowed_opts = ['domain-id', + 'domain-name', + 'project-id', + 'project-name', + 'project-domain-id', + 'project-domain-name', + 'trust-id', + 'auth-url', + ] + + self.assertItemsEqual(allowed_opts, opts) diff --git a/keystoneauth1/tests/unit/extras/kerberos/test_mapped.py b/keystoneauth1/tests/unit/extras/kerberos/test_mapped.py index 9ba7fbbb..a5fa41c7 100644 --- a/keystoneauth1/tests/unit/extras/kerberos/test_mapped.py +++ b/keystoneauth1/tests/unit/extras/kerberos/test_mapped.py @@ -12,29 +12,16 @@ import uuid -import six - +from keystoneauth1.extras import kerberos from keystoneauth1 import fixture as ks_fixture from keystoneauth1 import session from keystoneauth1.tests.unit.extras.kerberos import base -try: - # Until requests_kerberos gets py3 support, this is going to fail to import - from keystoneauth1.extras import kerberos - -except ImportError: - if six.PY2: - # requests_kerberos is expected to be there on py2, so don't ignore. - raise - - # requests_kerberos isn't available - kerberos = False - class TestMappedAuth(base.TestCase): def setUp(self): - if not kerberos: + if kerberos.requests_kerberos is None: self.skipTest("Kerberos support isn't available.") super(TestMappedAuth, self).setUp() diff --git a/keystoneauth1/tests/unit/extras/kerberos/test_v3.py b/keystoneauth1/tests/unit/extras/kerberos/test_v3.py index 40df22f7..1d6e5e91 100644 --- a/keystoneauth1/tests/unit/extras/kerberos/test_v3.py +++ b/keystoneauth1/tests/unit/extras/kerberos/test_v3.py @@ -10,29 +10,15 @@ # License for the specific language governing permissions and limitations # under the License. - -import six - +from keystoneauth1.extras import kerberos from keystoneauth1 import session from keystoneauth1.tests.unit.extras.kerberos import base -try: - # Until requests_kerberos gets py3 support, this is going to fail to import - from keystoneauth1.extras import kerberos - -except ImportError: - if six.PY2: - # requests_kerberos is expected to be there on py2, so don't ignore. - raise - - # requests_kerberos isn't available - kerberos = None - class TestKerberosAuth(base.TestCase): def setUp(self): - if not kerberos: + if kerberos.requests_kerberos is None: self.skipTest("Kerberos support isn't available.") super(TestKerberosAuth, self).setUp() diff --git a/keystoneauth1/tests/unit/extras/kerberos/utils.py b/keystoneauth1/tests/unit/extras/kerberos/utils.py index 8c35292f..f955cc8e 100644 --- a/keystoneauth1/tests/unit/extras/kerberos/utils.py +++ b/keystoneauth1/tests/unit/extras/kerberos/utils.py @@ -36,6 +36,9 @@ class KerberosMock(fixtures.Fixture): def setUp(self): super(KerberosMock, self).setUp() + if requests_kerberos is None: + return + m = mockpatch.PatchObject(requests_kerberos.HTTPKerberosAuth, 'generate_request_header', self._generate_request_header) diff --git a/setup.cfg b/setup.cfg index 06cb522e..827c8dae 100644 --- a/setup.cfg +++ b/setup.cfg @@ -48,6 +48,7 @@ keystoneauth1.plugin = v3oidcauthcode = keystoneauth1.loading._plugins.identity.v3:OpenIDConnectAuthorizationCode v3oidcaccesstoken = keystoneauth1.loading._plugins.identity.v3:OpenIDConnectAccessToken v3oauth1 = keystoneauth1.extras.oauth1._loading:V3OAuth1 + v3kerberos = keystoneauth1.extras.kerberos._loading:Kerberos [build_sphinx] source-dir = doc/source