]> Frank Brehm's Git Trees - pixelpark/pp-admin-tools.git/commitdiff
Retries on connecting to and disconnecting from a LDAP instance
authorFrank Brehm <frank.brehm@pixelpark.com>
Fri, 2 Feb 2024 10:14:00 +0000 (11:14 +0100)
committerFrank Brehm <frank.brehm@pixelpark.com>
Fri, 2 Feb 2024 10:14:00 +0000 (11:14 +0100)
lib/pp_admintools/app/ldap.py

index 416601390ab2282b3bfa38e741d139796c24d0bc..c382f477e1438aaa9230dfadeba4103e7f437e8e 100644 (file)
@@ -61,7 +61,7 @@ from ..errors import DpxLdapSessionError
 from ..errors import DpxWriteLdapItemError
 from ..xlate import XLATOR, format_list
 
-__version__ = '1.3.6'
+__version__ = '1.3.7'
 LOG = logging.getLogger(__name__)
 
 _ = XLATOR.gettext
@@ -821,24 +821,49 @@ class BaseLdapApplication(BaseDPXApplication):
         if single:
             min_verb_level = 1
 
+        retries = self.retries_on_conn_error
+        wait_on_error = self.wait_on_conn_error
+        cur_try = 0
+
         if self.verbose > min_verb_level:
             msg = _('Connecting to LDAP server {url} as {dn!r} ...').format(
                 url=connect_info.url, dn=bind_dn)
             LOG.debug(msg)
 
-        try:
-            ldap_connection = Connection(
-                ldap_server, bind_dn, bind_pw, client_strategy=SAFE_SYNC, auto_bind=True)
-        except LDAPBindError as e:
-            msg = _('Could not connect to LDAP server {url!r} as {user!r}: {e}').format(
-                url=connect_info.url, user=bind_dn, e=e)
-            LOG.error(msg)
-            self.exit(8)
-        except LDAPException as e:
-            msg = _('{c} on connecting to LDAP server {url!r} as {user!r}: {e}').format(
-                c=e.__class__.__name__, url=connect_info.url, user=bind_dn, e=e)
-            LOG.error(msg)
-            self.exit(9)
+        while True:
+            cur_try += 1
+            if self.verbose > 2:
+                LOG.debug(_(
+                    'Try number {nr} for connecting to LDAP server instance {i!r} ...').format(
+                    cur_try))
+
+            try:
+                ldap_connection = Connection(
+                    ldap_server, bind_dn, bind_pw, client_strategy=SAFE_SYNC, auto_bind=True)
+                break
+            except LDAPCommunicationError as e:
+                e_msg = str(e)
+                e_cls = e.__class__.__name__
+                if cur_try >= retries:
+                    msg = _('Got a {cls} on connecting to LDAP instance {i!r}:').format(
+                        cls=e_cls, i=inst) + ' ' + e_msg
+                    LOG.error(msg)
+                    self.exit(9)
+                LOG.warn(_(
+                    'Waiting #{nr} on connecting to instance {i!r} because of a '
+                    '{cls}:').format(nr=cur_try, i=inst, cls=e_cls) + ' ' + e_msg)
+                time.sleep(wait_on_error)
+                continue
+            except LDAPBindError as e:
+                msg = _('Could not connect to LDAP server {url!r} as {user!r}: {e}').format(
+                    url=connect_info.url, user=bind_dn, e=e)
+                LOG.error(msg)
+                self.exit(8)
+            except LDAPException as e:
+                msg = _('{c} on connecting to LDAP server {url!r} as {user!r}: {e}').format(
+                    c=e.__class__.__name__, url=connect_info.url, user=bind_dn, e=e)
+                LOG.error(msg)
+                self.exit(9)
 
         return ldap_connection
 
@@ -866,6 +891,10 @@ class BaseLdapApplication(BaseDPXApplication):
         """Disconnect from the given instance."""
         connect_info = self.cfg.ldap_connection[inst]
 
+        retries = self.retries_on_conn_error
+        wait_on_error = self.wait_on_conn_error
+        cur_try = 0
+
         min_verb_level = 2
         if single:
             min_verb_level = 1
@@ -874,9 +903,36 @@ class BaseLdapApplication(BaseDPXApplication):
             ldap_connection = self.ldap_connection[inst]
             if self.verbose > min_verb_level:
                 LOG.debug(_('Unbinding from LDAP server {!r} ...').format(connect_info.url))
-            ldap_connection.unbind()
-            ldap_connection = None
-            del self.ldap_connection[inst]
+            while True:
+                cur_try += 1
+                if self.verbose > 2:
+                    LOG.debug(_(
+                        'Try number {nr} for disconnecting from LDAP server '
+                        'instance {i!r} ...').format( cur_try))
+                try:
+                    ldap_connection.unbind()
+                    ldap_connection = None
+                    del self.ldap_connection[inst]
+                    break
+                except LDAPCommunicationError as e:
+                    e_msg = str(e)
+                    e_cls = e.__class__.__name__
+                    if cur_try >= retries:
+                        msg = _('Got a {cls} on disconnecting from LDAP instance {i!r}:').format(
+                            cls=e_cls, i=inst) + ' ' + e_msg
+                        LOG.error(msg)
+                        self.exit(12)
+                    LOG.warn(_(
+                        'Waiting #{nr} on disconnecting from instance {i!r} because of a '
+                        '{cls}:').format(nr=cur_try, i=inst, cls=e_cls) + ' ' + e_msg)
+                    time.sleep(wait_on_error)
+                    continue
+                except LDAPException as e:
+                    msg = _(
+                        '{c} on disconnecting from LDAP server instance {i!r}: {e}').format(
+                        c=e.__class__.__name__, i=inst, e=e)
+                    LOG.error(msg)
+                    self.exit(9)
 
         if inst in self.ldap_server and single:
             if self.verbose > min_verb_level: