3f0ea8533a
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 |
||
---|---|---|
doc | ||
ldappool | ||
.gitignore | ||
.gitreview | ||
.stestr.conf | ||
.zuul.yaml | ||
CHANGES.rst | ||
CONTRIBUTORS | ||
MANIFEST.in | ||
README.rst | ||
lower-constraints.txt | ||
requirements.txt | ||
setup.cfg | ||
setup.py | ||
test-requirements.txt | ||
tox.ini |
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