]> Frank Brehm's Git Trees - pixelpark/pp-admin-tools.git/commitdiff
Adding config parameter 'sync-source' for a LDAP server instance.
authorFrank Brehm <frank@brehm-online.com>
Tue, 18 Oct 2022 12:37:10 +0000 (14:37 +0200)
committerFrank Brehm <frank@brehm-online.com>
Tue, 18 Oct 2022 12:37:10 +0000 (14:37 +0200)
etc/ldap.yaml.default
lib/pp_admintools/config/ldap.py

index 47c885a445e8fbaa1be503d138bf1685edce718d..f7f55a67b079282389ae3e761787b14e74916351 100644 (file)
@@ -20,6 +20,7 @@ ldap:
     # bind_pw: ******
     is_admin: true
     readonly: false
+    sync-source: 'dpx-prod'
     tier: 'dev'
   dpx-dev-ro:
     host: 'dev-ldap2.pixelpark.com'
@@ -80,4 +81,7 @@ ldap:
     # bind_pw: ******
     is_admin: true
     readonly: false
+    sync-source: 'spk-live'
     tier: 'test'
+
+# vim: filetype=yaml
index 50bd96883cbc4d0732a4eefd6e12195b8f9539c0..3e09977ab332f2624036ddc0ab4492bb9e34e592 100644 (file)
@@ -32,7 +32,7 @@ from . import VALID_TIERS, DEFAULT_TIER
 
 from ..xlate import XLATOR
 
-__version__ = '0.4.2'
+__version__ = '0.6.0'
 LOG = logging.getLogger(__name__)
 
 _ = XLATOR.gettext
@@ -53,12 +53,22 @@ class LdapConfigError(PpConfigurationError):
 class LdapConnectionInfo(FbBaseObject):
     """Encapsulating all necessary data to connect to a LDAP server."""
 
+    re_ldap_host_key = re.compile(r'^\s*(?:host|server)\s*$', re.IGNORECASE)
+    re_ldap_ldaps_key = re.compile(r'^\s*(?:use[_-]?)?(?:ldaps|ssl)\s*$', re.IGNORECASE)
+    re_ldap_port_key = re.compile(r'^\s*port\s*$', re.IGNORECASE)
+    re_ldap_base_dn_key = re.compile(r'^\s*base[_-]*dn\s*$', re.IGNORECASE)
+    re_ldap_bind_dn_key = re.compile(r'^\s*bind[_-]*dn\s*$', re.IGNORECASE)
+    re_ldap_bind_pw_key = re.compile(r'^\s*bind[_-]*pw\s*$', re.IGNORECASE)
+    re_ldap_is_admin_key = re.compile(r'^\s*(?:is[_-]*)?admin\s*$', re.IGNORECASE)
+    re_ldap_readonly_key = re.compile(r'^\s*read[_-]*only\s*$', re.IGNORECASE)
+    re_ldap_sync_source_key = re.compile(r'^\s*sync[_-]*source\s*$', re.IGNORECASE)
+
     # -------------------------------------------------------------------------
     def __init__(
         self, appname=None, verbose=0, version=__version__, base_dir=None,
             host=None, use_ldaps=False, port=DEFAULT_PORT_LDAP, base_dn=None,
             bind_dn=None, bind_pw=None, is_admin=None, readonly=None, tier=None,
-            initialized=False):
+            sync_source=None, initialized=False):
 
         self._host = None
         self._use_ldaps = False
@@ -69,6 +79,7 @@ class LdapConnectionInfo(FbBaseObject):
         self._is_admin = False
         self._readonly = True
         self._tier = DEFAULT_TIER
+        self._sync_source = None
 
         super(LdapConnectionInfo, self).__init__(
             appname=appname, verbose=verbose, version=version, base_dir=base_dir,
@@ -87,6 +98,7 @@ class LdapConnectionInfo(FbBaseObject):
         self.is_admin = is_admin
         self.readonly = readonly
         self.tier = tier
+        self.sync_source = sync_source
 
         if initialized:
             self.initialized = True
@@ -105,17 +117,18 @@ class LdapConnectionInfo(FbBaseObject):
 
         res = super(LdapConnectionInfo, self).as_dict(short=short)
 
-        res['host'] = self.host
-        res['use_ldaps'] = self.use_ldaps
-        res['port'] = self.port
         res['base_dn'] = self.base_dn
         res['bind_dn'] = self.bind_dn
         res['bind_pw'] = None
-        res['schema'] = self.schema
-        res['url'] = self.url
         res['is_admin'] = self.is_admin
+        res['host'] = self.host
+        res['port'] = self.port
         res['readonly'] = self.readonly
+        res['schema'] = self.schema
+        res['sync_source'] = self.sync_source
         res['tier'] = self.tier
+        res['url'] = self.url
+        res['use_ldaps'] = self.use_ldaps
 
         if self.bind_pw:
             if self.verbose > 4:
@@ -265,6 +278,19 @@ class LdapConnectionInfo(FbBaseObject):
             raise LdapConfigError(msg)
         self._tier = val_lc
 
+    # -----------------------------------------------------------
+    @property
+    def sync_source(self):
+        """The host name (or IP address) of the LDAP server."""
+        return self._sync_source
+
+    @sync_source.setter
+    def sync_source(self, value):
+        if value is None or str(value).strip() == '':
+            self._sync_source = None
+            return
+        self._sync_source = str(value).strip()
+
     # -------------------------------------------------------------------------
     def __repr__(self):
         """Typecasting into a string for reproduction."""
@@ -282,6 +308,7 @@ class LdapConnectionInfo(FbBaseObject):
         fields.append("is_admin={!r}".format(self.is_admin))
         fields.append("readonly={!r}".format(self.readonly))
         fields.append("tier={!r}".format(self.tier))
+        fields.append("sync_source={!r}".format(self.sync_source))
         fields.append("initialized={!r}".format(self.initialized))
 
         out += ", ".join(fields) + ")>"
@@ -294,10 +321,89 @@ class LdapConnectionInfo(FbBaseObject):
             appname=self.appname, verbose=self.verbose, base_dir=self.base_dir, host=self.host,
             use_ldaps=self.use_ldaps, port=self.port, base_dn=self.base_dn, bind_dn=self.bind_dn,
             bind_pw=self.bind_pw, is_admin=self.is_admin, readonly=self.readonly, tier=self.tier,
-            initialized=self.initialized)
+            sync_source=self.sync_source, initialized=self.initialized)
 
         return new
 
+    # -------------------------------------------------------------------------
+    @classmethod
+    def from_config(cls, section, connection_name, appname=None, verbose=0, base_dir=None):
+
+        msg_invalid = _("Invalid value {val!r} in section {sec!r} for a LDAP {what}.")
+        section_name = "ldap:" + connection_name
+
+        new = cls(appname=appname, verbose=verbose, base_dir=base_dir, initialized=False)
+
+        for key in section.keys():
+
+            value = section[key]
+
+            if cls.re_ldap_host_key.match(key):
+                if value.strip():
+                    new.host = value
+                else:
+                    msg = msg_invalid.format(val=value, sec=section_name, what='host')
+                    LOG.error(msg)
+                continue
+
+            if cls.re_ldap_ldaps_key.match(key):
+                new.use_ldaps = value
+                continue
+
+            if cls.re_ldap_port_key.match(key):
+                port = DEFAULT_PORT_LDAP
+                try:
+                    port = int(value)
+                except (ValueError, TypeError) as e:
+                    msg = msg_invalid.format(val=value, sec=section_name, what='port')
+                    msg += ' ' + str(e)
+                    LOG.error(msg)
+                    continue
+                if port <= 0 or port > MAX_PORT_NUMBER:
+                    msg = msg_invalid.format(val=value, sec=section_name, what='port')
+                    LOG.error(msg)
+                    continue
+                new.port = port
+                continue
+
+            if cls.re_ldap_base_dn_key.match(key):
+                if value.strip():
+                    new.base_dn = value
+                else:
+                    msg = msg_invalid.format(val=value, sec=section_name, what='base_dn')
+                    LOG.error(msg)
+                continue
+
+            if cls.re_ldap_bind_dn_key.match(key):
+                new.bind_dn = value
+                continue
+
+            if cls.re_ldap_bind_pw_key.match(key):
+                new.bind_pw = value
+                continue
+
+            if cls.re_ldap_is_admin_key.match(key):
+                new.is_admin = value
+                continue
+
+            if cls.re_ldap_readonly_key.match(key):
+                new.readonly = value
+                continue
+
+            if key.strip().lower() == 'tier':
+                new.tier = value
+                continue
+
+            if cls.re_ldap_sync_source_key.match(key):
+                new.sync_source = value
+
+            msg = _("Unknown LDAP configuration key {key} found in section {sec!r}.").format(
+                key=key, sec=section_name)
+            LOG.error(msg)
+
+        new.initialized = True
+        return new
+
 
 # =============================================================================
 class LdapConnectionDict(dict, FbGenericBaseObject):
@@ -348,15 +454,6 @@ class LdapConfiguration(PpBaseConfiguration):
 
     re_ldap_section_w_name = re.compile(r'^\s*ldap\s*:\s*(\S+)')
 
-    re_ldap_host_key = re.compile(r'^\s*(?:host|server)\s*$', re.IGNORECASE)
-    re_ldap_ldaps_key = re.compile(r'^\s*(?:use[_-]?)?(?:ldaps|ssl)\s*$', re.IGNORECASE)
-    re_ldap_port_key = re.compile(r'^\s*port\s*$', re.IGNORECASE)
-    re_ldap_base_dn_key = re.compile(r'^\s*base[_-]*dn\s*$', re.IGNORECASE)
-    re_ldap_bind_dn_key = re.compile(r'^\s*bind[_-]*dn\s*$', re.IGNORECASE)
-    re_ldap_bind_pw_key = re.compile(r'^\s*bind[_-]*pw\s*$', re.IGNORECASE)
-    re_ldap_is_admin_key = re.compile(r'^\s*(?:is[_-]*)?admin\s*$', re.IGNORECASE)
-    re_ldap_readonly_key = re.compile(r'^\s*read[_-]*only\s*$', re.IGNORECASE)
-
     # -------------------------------------------------------------------------
     def __init__(
         self, appname=None, verbose=0, version=__version__, base_dir=None,
@@ -448,76 +545,9 @@ class LdapConfiguration(PpBaseConfiguration):
             msg = _("Reading configuration of LDAP instance {!r} ...").format(connection_name)
             LOG.debug(msg)
 
-        connection = LdapConnectionInfo(
-            appname=self.appname, verbose=self.verbose, base_dir=self.base_dir,
-            initialized=False)
-
-        section_name = "ldap:" + connection_name
-        msg_invalid = _("Invalid value {val!r} in section {sec!r} for a LDAP {what}.")
-
-        for key in section.keys():
-
-            value = section[key]
-
-            if self.re_ldap_host_key.match(key):
-                if value.strip():
-                    connection.host = value
-                else:
-                    msg = msg_invalid.format(val=value, sec=section_name, what='host')
-                    LOG.error(msg)
-                continue
-
-            if self.re_ldap_ldaps_key.match(key):
-                connection.use_ldaps = value
-                continue
-
-            if self.re_ldap_port_key.match(key):
-                port = DEFAULT_PORT_LDAP
-                try:
-                    port = int(value)
-                except (ValueError, TypeError) as e:
-                    msg = msg_invalid.format(val=value, sec=section_name, what='port')
-                    msg += ' ' + str(e)
-                    LOG.error(msg)
-                    continue
-                if port <= 0 or port > MAX_PORT_NUMBER:
-                    msg = msg_invalid.format(val=value, sec=section_name, what='port')
-                    LOG.error(msg)
-                    continue
-                connection.port = port
-                continue
-
-            if self.re_ldap_base_dn_key.match(key):
-                if value.strip():
-                    connection.base_dn = value
-                else:
-                    msg = msg_invalid.format(val=value, sec=section_name, what='base_dn')
-                    LOG.error(msg)
-                continue
-
-            if self.re_ldap_bind_dn_key.match(key):
-                connection.bind_dn = value
-                continue
-
-            if self.re_ldap_bind_pw_key.match(key):
-                connection.bind_pw = value
-                continue
-
-            if self.re_ldap_is_admin_key.match(key):
-                connection.is_admin = value
-                continue
-
-            if self.re_ldap_readonly_key.match(key):
-                connection.readonly = value
-                continue
-
-            if key.strip().lower() == 'tier':
-                connection.tier = value
-                continue
-
-            msg = _("Unknown LDAP configuration key {key} found in section {sec!r}.").format(
-                key=key, sec=section_name)
-            LOG.error(msg)
+        connection = LdapConnectionInfo.from_config(
+            section, connection_name, appname=self.appname,
+            verbose=self.verbose, base_dir=self.base_dir)
 
         self.ldap_connection[connection_name] = connection