A simple connector pool for python-ldap and related LDAP libraries.
Go to file
Nathan Kinder 3f0ea8533a Handle retry logic for timeouts with multiple LDAP servers
It is currently possible to specify multiple LDAP server URIs
for failover purposes when using LDAP connection pooling, as this
functionality is provided in the underlying python-ldap module.
Unfortunately, failover does not work properly if LDAP timeout
issue are encountered due to the way python-LDAP works.  If multiple
URLs are provided, the first URL that results in a successful TCP
connection is considered to be a successful LDAP connection.  If the
initial bind operation fails due to a timeout waiting for an LDAP
response from the server, it will never failover to additional
URIs.  It is easy to demonstrate this behavior by forcing an LDAP
server to hang (attach with gdb to halt the process), then using
that server as the first URI when creating a connection pool.

This patch adds proper failover logic to ldappool.  If multiple URIs
are provided, we split them and attempt to connect to them one-by-one
until we have either had a successful LDAP bind operation, or we have
exhausted the list of URIs.  The connection retry logic is processed
per-URI as well, meaning we will attempt to reconnect to the first
URI up to the requested retry limit, then we will failover to the
next URI and reset the retry count.

The ldap.TIMEOUT exception was not raised to the caller like some
of the other common LDAP exceptions we might encounter.  We should
raise the TIMEOUT exception instead of the more generic BackendError
exception to provide more detail to the calling code.

Change-Id: Iabc13363d2425e70a53163249e5389d336274533
2018-10-31 12:39:26 -07:00
doc Switch from oslosphinx to openstackdocstheme 2017-06-30 15:37:13 +07:00
ldappool Handle retry logic for timeouts with multiple LDAP servers 2018-10-31 12:39:26 -07:00
.gitignore Switch to stestr 2018-07-17 08:17:25 +07:00
.gitreview add .gitreview and fix ldappool gate 2016-05-12 13:50:05 -07:00
.stestr.conf Switch to stestr 2018-07-17 08:17:25 +07:00
.zuul.yaml add python 3.6 unit test job 2018-08-29 16:04:56 -04:00
CHANGES.rst starting 1.1 2012-02-27 23:08:32 +01:00
CONTRIBUTORS preparing 1.0 2012-02-27 23:05:12 +01:00
MANIFEST.in preparing 1.0 2012-02-27 23:05:12 +01:00
README.rst Handle retry logic for timeouts with multiple LDAP servers 2018-10-31 12:39:26 -07:00
lower-constraints.txt Switch to python-ldap again 2018-07-18 20:25:01 +00:00
requirements.txt Switch to python-ldap again 2018-07-18 20:25:01 +00:00
setup.cfg Removed older version of python added 3.5 2018-09-29 16:30:04 +08:00
setup.py Updated from global requirements 2017-03-10 03:31:33 +00:00
test-requirements.txt Bump to hacking 1.1.x 2018-07-17 10:52:49 +02:00
tox.ini Removed older version of python added 3.5 2018-09-29 16:30:04 +08:00

README.rst

ldappool

A simple connector pool for python-ldap.

The pool keeps LDAP connectors alive and let you reuse them, drastically reducing the time spent to initiate a ldap connection.

The pool has useful features like:

  • transparent reconnection on failures or server restarts
  • configurable pool size and connectors timeouts
  • configurable max lifetime for connectors
  • a context manager to simplify acquiring and releasing a connector

You need python-ldap in order to use this library

Quickstart

To work with the pool, you just need to create it, then use it as a context manager with the connection method:

from ldappool import ConnectionManager

cm = ConnectionManager('ldap://localhost')

with cm.connection('uid=adminuser,ou=logins,dc=mozilla', 'password') as conn:
    .. do something with conn ..

The connector returned by connection is a LDAPObject, that's binded to the server. See https://pypi.org/project/python-ldap/ for details on how to use a connector.

ConnectionManager options

Here are the options you can use when instanciating the pool:

  • uri: ldap server uri [mandatory]
  • bind: default bind that will be used to bind a connector. default: None
  • passwd: default password that will be used to bind a connector. default: None
  • size: pool size. default: 10
  • retry_max: number of attempts when a server is down. default: 3
  • retry_delay: delay in seconds before a retry. default: .1
  • use_tls: activate TLS when connecting. default: False
  • timeout: connector timeout. default: -1
  • use_pool: activates the pool. If False, will recreate a connector each time. default: True

The uri option will accept a comma or whitespace separated list of LDAP server URIs to allow for failover behavior when connection errors are encountered. Connections will be attempted against the servers in order, with retry_max attempts per URI before failing over to the next server.

The connection method takes two options:

  • bind: bind used to connect. If None, uses the pool default's. default: None
  • passwd: password used to connect. If None, uses the pool default's. default: None