Module: check_mk
Branch: master
Commit: 791d611d84799572d60800a2ad61ed0d45625838
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=791d611d847995…
Author: Andreas Boesl <ab(a)mathias-kettner.de>
Date: Mon Oct 22 16:22:22 2018 +0200
added WK6669
Change-Id: I31a5be36e05f9b1f8e4b967b9512761224f7d2c5
---
.werks/6669 | 15 +++++++
cmk/gui/plugins/userdb/ldap_connector.py | 71 ++++++++++++++++++++++++++++++--
cmk/gui/plugins/userdb/utils.py | 4 ++
cmk/gui/userdb.py | 3 ++
4 files changed, 89 insertions(+), 4 deletions(-)
diff --git a/.werks/6669 b/.werks/6669
new file mode 100644
index 0000000..314ec3b
--- /dev/null
+++ b/.werks/6669
@@ -0,0 +1,15 @@
+Title: LDAP connections: Improved performance for "Automatically discover LDAP
server"
+Level: 1
+Component: multisite
+Class: feature
+Compatible: compat
+Edition: cre
+State: unknown
+Version: 1.6.0i1
+Date: 1540209516
+
+The discovery process for the fastet LDAP server could take a large amount of time.
+The result of this discovery is now cached, which can considerably increase the
performance
+during user login and other ldap related queries.
+
+
diff --git a/cmk/gui/plugins/userdb/ldap_connector.py
b/cmk/gui/plugins/userdb/ldap_connector.py
index b93d433..a359558 100644
--- a/cmk/gui/plugins/userdb/ldap_connector.py
+++ b/cmk/gui/plugins/userdb/ldap_connector.py
@@ -52,6 +52,7 @@ import os
import time
import copy
import sys
+import shutil
# docs:
http://www.python-ldap.org/doc/html/index.html
import ldap
@@ -254,6 +255,7 @@ class LDAPUserConnector(UserConnector):
return conn, None
except (ldap.SERVER_DOWN, ldap.TIMEOUT, ldap.LOCAL_ERROR, ldap.LDAPError), e:
+ self.clear_nearest_dc_cache()
if type(e[0]) == dict:
msg = e[0].get('info', e[0].get('desc', ''))
else:
@@ -262,6 +264,7 @@ class LDAPUserConnector(UserConnector):
return None, "%s: %s" % (uri, msg)
except MKLDAPException, e:
+ self.clear_nearest_dc_cache()
return None, "%s" % e
@@ -331,11 +334,17 @@ class LDAPUserConnector(UserConnector):
def _discover_nearest_dc(self, domain):
+ cached_server = self._get_nearest_dc_from_cache()
+ if cached_server:
+ self._logger.info(_('Using cached DC %s') % cached_server)
+ return cached_server
+
import ad # pylint: disable=import-error
locator = ad.Locator()
locator.m_logger = self._logger
try:
server = locator.locate(domain)
+ self._cache_nearest_dc(server)
self._logger.info(' DISCOVERY: Discovered server %r from %r' %
(server, domain))
return server
except Exception:
@@ -345,6 +354,50 @@ class LDAPUserConnector(UserConnector):
return domain
+ def _get_nearest_dc_from_cache(self):
+ try:
+ return file(self._nearest_dc_cache_filepath()).read()
+ except IOError:
+ pass
+
+
+ def _cache_nearest_dc(self, server):
+ self._logger.debug(_('Caching nearest DC %s') % server)
+ cmk.store.save_file(self._nearest_dc_cache_filepath(), server)
+
+
+ def clear_nearest_dc_cache(self):
+ if not self._uses_discover_nearest_server():
+ return
+
+ try:
+ os.unlink(self._nearest_dc_cache_filepath())
+ except OSError:
+ pass
+
+ def _nearest_dc_cache_filepath(self):
+ return os.path.join(self._ldap_caches_filepath(), "nearest_server.%s" %
self.id())
+
+
+ @classmethod
+ def _ldap_caches_filepath(cls):
+ return os.path.join(cmk.paths.tmp_dir, "ldap_caches")
+
+
+ @classmethod
+ def config_changed(cls):
+ cls.clear_all_ldap_caches()
+
+
+ @classmethod
+ def clear_all_ldap_caches(cls):
+ try:
+ shutil.rmtree(cls._ldap_caches_filepath())
+ except OSError, e:
+ if e.errno != 2:
+ raise
+
+
# Bind with the default credentials
def _default_bind(self, conn):
try:
@@ -375,10 +428,8 @@ class LDAPUserConnector(UserConnector):
def servers(self):
- # 'directory_type': ('ad', {'connect_to':
('discover', {'domain': 'corp.de'})}),
- connect_method, connect_params =
self._config['directory_type'][1]["connect_to"]
-
- if connect_method == "discover":
+ connect_params = self._get_connect_params()
+ if self._uses_discover_nearest_server():
servers = [ self._discover_nearest_dc(connect_params["domain"]) ]
else:
servers = [ connect_params['server'] ] +
connect_params.get('failover_servers', [])
@@ -386,6 +437,16 @@ class LDAPUserConnector(UserConnector):
return servers
+ def _uses_discover_nearest_server(self):
+ # 'directory_type': ('ad', {'connect_to':
('discover', {'domain': 'corp.de'})}),
+ return self._config['directory_type'][1]["connect_to"][0] ==
"discover"
+
+
+ def _get_connect_params(self):
+ # 'directory_type': ('ad', {'connect_to':
('discover', {'domain': 'corp.de'})}),
+ return self._config['directory_type'][1]["connect_to"][1]
+
+
def use_ssl(self):
return 'use_ssl' in self._config
@@ -563,6 +624,8 @@ class LDAPUserConnector(UserConnector):
'incomplete results. You should change
the scope of operation '
'within the ldap or adapt the limit
settings of the LDAP server.'))
except (ldap.SERVER_DOWN, ldap.TIMEOUT, MKLDAPException), e:
+ self.clear_nearest_dc_cache()
+
last_exc = e
if implicit_connect and tries_left:
self._logger.info(' Received %r. Retrying with clean
connection...' % e)
diff --git a/cmk/gui/plugins/userdb/utils.py b/cmk/gui/plugins/userdb/utils.py
index 6364b77..224114b 100644
--- a/cmk/gui/plugins/userdb/utils.py
+++ b/cmk/gui/plugins/userdb/utils.py
@@ -69,6 +69,10 @@ class UserConnector(object):
raise NotImplementedError()
+ @classmethod
+ def config_changed(cls):
+ return
+
#
# USERDB API METHODS
#
diff --git a/cmk/gui/userdb.py b/cmk/gui/userdb.py
index b5831f5..8b4c8ec 100644
--- a/cmk/gui/userdb.py
+++ b/cmk/gui/userdb.py
@@ -1158,6 +1158,9 @@ def save_connection_config(connections, base_dir=None):
store.save_to_mk_file(os.path.join(base_dir, "user_connections.mk"),
"user_connections", connections)
+ for connector_id, connector_class in user_connector_registry.items():
+ connector_class.config_changed()
+
#.