Repository: aurora Updated Branches: refs/heads/master f41938d36 -> 745869cfb
Adding help message in case kerberos auth fails. Bugs closed: AURORA-1364 Reviewed at https://reviews.apache.org/r/39797/ Project: http://git-wip-us.apache.org/repos/asf/aurora/repo Commit: http://git-wip-us.apache.org/repos/asf/aurora/commit/745869cf Tree: http://git-wip-us.apache.org/repos/asf/aurora/tree/745869cf Diff: http://git-wip-us.apache.org/repos/asf/aurora/diff/745869cf Branch: refs/heads/master Commit: 745869cfb8ae5d6bcf4389ede323b493dd8fec8c Parents: f41938d Author: Maxim Khutornenko <[email protected]> Authored: Tue Nov 3 17:00:23 2015 -0800 Committer: Maxim Khutornenko <[email protected]> Committed: Tue Nov 3 17:00:23 2015 -0800 ---------------------------------------------------------------------- .../apache/aurora/client/api/scheduler_client.py | 8 ++++++-- src/main/python/apache/aurora/client/cli/client.py | 11 +++++++++++ .../apache/aurora/common/auth/auth_module.py | 10 ++++++++++ .../aurora/common/auth/auth_module_manager.py | 2 +- .../python/apache/aurora/kerberos/auth_module.py | 11 ++++------- .../aurora/client/api/test_scheduler_client.py | 17 +++++++++++------ .../python/apache/aurora/client/cli/test_client.py | 2 ++ 7 files changed, 45 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/aurora/blob/745869cf/src/main/python/apache/aurora/client/api/scheduler_client.py ---------------------------------------------------------------------- diff --git a/src/main/python/apache/aurora/client/api/scheduler_client.py b/src/main/python/apache/aurora/client/api/scheduler_client.py index a469eec..c973da1 100644 --- a/src/main/python/apache/aurora/client/api/scheduler_client.py +++ b/src/main/python/apache/aurora/client/api/scheduler_client.py @@ -73,7 +73,7 @@ class SchedulerClient(object): def __init__(self, auth, user_agent, verbose=False): self._client = None - self._auth = auth + self._auth_handler = auth self._user_agent = user_agent self._verbose = verbose @@ -82,13 +82,16 @@ class SchedulerClient(object): self._client = self._connect() return self._client + def get_failed_auth_message(self): + return self._auth_handler.failed_auth_message + # per-class implementation -- mostly meant to set up a valid host/port # pair and then delegate the opening to SchedulerClient._connect_scheduler def _connect(self): return None def _connect_scheduler(self, uri, clock=time): - transport = TRequestsTransport(uri, auth=self._auth, user_agent=self._user_agent) + transport = TRequestsTransport(uri, auth=self._auth_handler.auth(), user_agent=self._user_agent) protocol = TJSONProtocol.TJSONProtocol(transport) schedulerClient = AuroraAdmin.Client(protocol) for _ in range(self.THRIFT_RETRIES): @@ -299,6 +302,7 @@ class SchedulerProxy(object): [m.message for m in resp.details] if resp.details else [])) return resp except TRequestsTransport.AuthError as e: + log.error(self.scheduler_client().get_failed_auth_message()) raise self.AuthError(e) except (TTransport.TTransportException, self.TimeoutError, self.TransientError) as e: if not self._terminating.is_set(): http://git-wip-us.apache.org/repos/asf/aurora/blob/745869cf/src/main/python/apache/aurora/client/cli/client.py ---------------------------------------------------------------------- diff --git a/src/main/python/apache/aurora/client/cli/client.py b/src/main/python/apache/aurora/client/cli/client.py index c17f857..297fb58 100644 --- a/src/main/python/apache/aurora/client/cli/client.py +++ b/src/main/python/apache/aurora/client/cli/client.py @@ -46,6 +46,7 @@ class AuroraLogConfigurationPlugin(ConfigurationPlugin): handler = logging.StreamHandler() handler.setFormatter(PlainFormatter()) logging.getLogger().addHandler(handler) + self._configure_lib_logging(loglevel) return raw_args def before_execution(self, context): @@ -54,6 +55,16 @@ class AuroraLogConfigurationPlugin(ConfigurationPlugin): def after_execution(self, context, result_code): pass + def _configure_lib_logging(self, loglevel): + """Sets logging level for "chatty" third party libs. + + Some dependencies have low default logging threshold thus generating messages that could + be confusing to users under normal conditions. To mitigate, we set the default loglevel + to CRITICAL to filter out the noise and re-enable logging when verbose output is requested. + """ + lib_loglevel = logging.DEBUG if loglevel == logging.DEBUG else logging.CRITICAL + logging.getLogger("requests_kerberos").setLevel(lib_loglevel) + class AuroraAuthConfigurationPlugin(ConfigurationPlugin): """Plugin for configuring aurora client authentication.""" http://git-wip-us.apache.org/repos/asf/aurora/blob/745869cf/src/main/python/apache/aurora/common/auth/auth_module.py ---------------------------------------------------------------------- diff --git a/src/main/python/apache/aurora/common/auth/auth_module.py b/src/main/python/apache/aurora/common/auth/auth_module.py index e655cad..28cea15 100644 --- a/src/main/python/apache/aurora/common/auth/auth_module.py +++ b/src/main/python/apache/aurora/common/auth/auth_module.py @@ -29,6 +29,12 @@ class AuthModule(Interface): :rtype: requests.auth.AuthBase. """ + @abstractproperty + def failed_auth_message(self): + """Default help message to log on failed auth attempt. + :rtype: string + """ + class InsecureAuthModule(AuthModule): @property @@ -37,3 +43,7 @@ class InsecureAuthModule(AuthModule): def auth(self): return None + + @property + def failed_auth_message(self): + return '' http://git-wip-us.apache.org/repos/asf/aurora/blob/745869cf/src/main/python/apache/aurora/common/auth/auth_module_manager.py ---------------------------------------------------------------------- diff --git a/src/main/python/apache/aurora/common/auth/auth_module_manager.py b/src/main/python/apache/aurora/common/auth/auth_module_manager.py index 2d785e7..3ae0e0a 100644 --- a/src/main/python/apache/aurora/common/auth/auth_module_manager.py +++ b/src/main/python/apache/aurora/common/auth/auth_module_manager.py @@ -46,4 +46,4 @@ def get_auth_handler(auth_mechanism=DEFAULT_AUTH_MECHANISM): auth_module = _AUTH_MODULES.get(auth_mechanism) or _INSECURE_AUTH_MODULE log.debug('Using auth module: %r' % auth_module) - return auth_module.auth() + return auth_module http://git-wip-us.apache.org/repos/asf/aurora/blob/745869cf/src/main/python/apache/aurora/kerberos/auth_module.py ---------------------------------------------------------------------- diff --git a/src/main/python/apache/aurora/kerberos/auth_module.py b/src/main/python/apache/aurora/kerberos/auth_module.py index fade005..6d3ade4 100644 --- a/src/main/python/apache/aurora/kerberos/auth_module.py +++ b/src/main/python/apache/aurora/kerberos/auth_module.py @@ -21,13 +21,6 @@ class KerberosAuthModule(AuthModule): def mechanism(self): return 'KERBEROS' - def payload(self): - """NOTE: until AURORA-1229 is addressed, using "Kerberized" client in production in a backwards - compatible way will require a new custom module that will override this method to - return the currently used payload (security blob used in SessionKey). - """ - return '' - def auth(self): # While SPNEGO supports mutual authentication of the response, it does not assert the validity # of the response payload, only the identity of the server. Thus the scheduler will not set @@ -36,3 +29,7 @@ class KerberosAuthModule(AuthModule): # constraints the client must connect to the scheduler API via HTTPS. Kerberos is thus only # used to authenticate the client to the server. return HTTPKerberosAuth(mutual_authentication=DISABLED) + + @property + def failed_auth_message(self): + return 'Communication with Aurora scheduler is kerberized. Did you forget to run "kinit"?' http://git-wip-us.apache.org/repos/asf/aurora/blob/745869cf/src/test/python/apache/aurora/client/api/test_scheduler_client.py ---------------------------------------------------------------------- diff --git a/src/test/python/apache/aurora/client/api/test_scheduler_client.py b/src/test/python/apache/aurora/client/api/test_scheduler_client.py index 5a17ab6..44671fa 100644 --- a/src/test/python/apache/aurora/client/api/test_scheduler_client.py +++ b/src/test/python/apache/aurora/client/api/test_scheduler_client.py @@ -26,6 +26,7 @@ from twitter.common.zookeeper.kazoo_client import TwitterKazooClient from twitter.common.zookeeper.serverset.endpoint import ServiceInstance import apache.aurora.client.api.scheduler_client as scheduler_client +from apache.aurora.common.auth.auth_module import AuthModule from apache.aurora.common.cluster import Cluster from apache.aurora.common.transport import TRequestsTransport @@ -227,6 +228,7 @@ class TestSchedulerProxyInjection(unittest.TestCase): def test_raise_auth_error(self): self.mock_thrift_client.killTasks(TaskQuery(), None, None, SESSION).AndRaise( TRequestsTransport.AuthError()) + self.mock_scheduler_client.get_failed_auth_message().AndReturn('failed auth') self.mox.ReplayAll() with pytest.raises(scheduler_client.SchedulerProxy.AuthError): self.make_scheduler_proxy().killTasks(TaskQuery(), None, None) @@ -328,7 +330,9 @@ class TestSchedulerProxyAdminInjection(TestSchedulerProxyInjection): def mock_auth(): - return mock.create_autospec(spec=AuthBase, instance=True) + auth_mock = mock.create_autospec(spec=AuthModule, instance=True) + auth_mock.auth.return_value = mock.create_autospec(AuthBase) + return auth_mock @pytest.mark.parametrize('scheme', ('http', 'https')) @@ -411,7 +415,7 @@ def test_connect_scheduler_with_user_agent(mock_transport): uri = 'https://scheduler.example.com:1337' client._connect_scheduler(uri, mock_time) - mock_transport.assert_called_once_with(uri, auth=auth, user_agent=user_agent) + mock_transport.assert_called_once_with(uri, auth=auth.auth(), user_agent=user_agent) @mock.patch('apache.aurora.client.api.scheduler_client.SchedulerClient', @@ -460,18 +464,19 @@ def test_connect_direct_scheduler_with_user_agent(mock_transport): mock_transport.return_value.open.side_effect = [TTransport.TTransportException, True] mock_time = mock.create_autospec(spec=time, instance=True) + auth = mock_auth() user_agent = 'Some-User-Agent' uri = 'https://scheduler.example.com:1337' client = scheduler_client.DirectSchedulerClient( uri, - auth=None, + auth=auth, verbose=True, user_agent=user_agent) client._connect_scheduler(uri, mock_time) - mock_transport.assert_called_once_with(uri, auth=None, user_agent=user_agent) + mock_transport.assert_called_once_with(uri, auth=auth.auth(), user_agent=user_agent) @mock.patch('apache.aurora.client.api.scheduler_client.TRequestsTransport', spec=TRequestsTransport) @@ -494,7 +499,7 @@ def test_connect_zookeeper_client_with_auth(mock_transport): client._connect_scheduler(uri, mock_time) - mock_transport.assert_called_once_with(uri, auth=auth, user_agent=user_agent) + mock_transport.assert_called_once_with(uri, auth=auth.auth(), user_agent=user_agent) @mock.patch('apache.aurora.client.api.scheduler_client.TRequestsTransport', spec=TRequestsTransport) @@ -517,4 +522,4 @@ def test_connect_direct_client_with_auth(mock_transport): client._connect_scheduler(uri, mock_time) - mock_transport.assert_called_once_with(uri, auth=auth, user_agent=user_agent) + mock_transport.assert_called_once_with(uri, auth=auth.auth(), user_agent=user_agent) http://git-wip-us.apache.org/repos/asf/aurora/blob/745869cf/src/test/python/apache/aurora/client/cli/test_client.py ---------------------------------------------------------------------- diff --git a/src/test/python/apache/aurora/client/cli/test_client.py b/src/test/python/apache/aurora/client/cli/test_client.py index 49f050c..54b429a 100644 --- a/src/test/python/apache/aurora/client/cli/test_client.py +++ b/src/test/python/apache/aurora/client/cli/test_client.py @@ -23,6 +23,7 @@ def test_log_plugin_enabled(): plugin.before_dispatch(["aurora", "version", "--verbose"]) assert logging.getLogger().getEffectiveLevel() == logging.DEBUG + assert logging.getLogger('requests_kerberos').getEffectiveLevel() == logging.DEBUG def test_log_plugin_disabled(): @@ -31,3 +32,4 @@ def test_log_plugin_disabled(): plugin.before_dispatch(["aurora", "version"]) assert logging.getLogger().getEffectiveLevel() == logging.INFO + assert logging.getLogger('requests_kerberos').getEffectiveLevel() == logging.CRITICAL
