]> Frank Brehm's Git Trees - pixelpark/pp-admin-tools.git/commitdiff
Adding and using role 389ds-config-plugins
authorFrank Brehm <frank.brehm@pixelpark.com>
Mon, 2 Dec 2024 17:13:34 +0000 (18:13 +0100)
committerFrank Brehm <frank.brehm@pixelpark.com>
Mon, 2 Dec 2024 17:13:34 +0000 (18:13 +0100)
filter_plugins/cfg_389ds_to_dict.py
filter_plugins/compare_lc_list.py [new file with mode: 0644]
playbooks/configure-ldap-servers.yaml
roles/389ds-config-plugins/tasks/main.yaml [new file with mode: 0644]
roles/389ds-config-plugins/tasks/memberof.yaml [new file with mode: 0644]
roles/389ds-config-plugins/vars/main.yaml [new file with mode: 0644]

index 71c7715196b0bd0eaa1cf7bed2e473bbe1b2be8e..b13430d137d885958426c35f37f518b4f21431fe 100644 (file)
@@ -1,19 +1,38 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+@summary: Ansible filter module of filter 'compare_lc_list'.
+
+@author: Frank Brehm
+@contact: frank@brehm-online.com
+@copyright: © 2024 by Frank Brehm, Berlin
+"""
+
 import re
 
 # =============================================================================
 class FilterModule(object):
+    """A filter module object."""
 
-    re_key = re.compile(r'nsslapd-', re.IGNORECASE)
-    re_sep = re.compile(r':\s+')
-    re_int = re.compile('^[+-]?\d+$')
-    re_float = re.compile('^[+-]?\d+\.\d*$')
+    re_key = re.compile(r'nsslapd-', re.IGNORECASE)                     # noqa: W605
+    re_sep = re.compile(r':\s+')                                        # noqa: W605
+    re_int = re.compile('^[+-]?\d+$')                                   # noqa: W605
+    re_float = re.compile('^[+-]?\d+\.\d*$')                            # noqa: W605
 
     # ------------------
     def filters(self):
-        return {'cfg_389ds_to_dict': self.cfg_389ds_to_dict }
+        """Return all usable filter methods from this class."""
+        return {'cfg_389ds_to_dict': self.cfg_389ds_to_dict}
 
     # ------------------
     def cfg_389ds_to_dict(self, the_list):
+        """
+        Translate a list of strings of the form 'key: value' into a dictionary.
+
+        In case of multiple values with the same key, they are assigned as a list to the key.
+        If a key is starting with 'nsslapd-', this will removed from the key.
+        The values are mangled with the method mangle_value().
+        """
         result = {}
 
         for line in the_list:
@@ -33,7 +52,7 @@ class FilterModule(object):
 
     # ------------------
     def mangle_value(self, value):
-
+        """Tape cast the given value to a boolean, integer of float value, if it is looking so."""
         if self.re_int.match(value):
             return int(value)
         if self.re_float.match(value):
diff --git a/filter_plugins/compare_lc_list.py b/filter_plugins/compare_lc_list.py
new file mode 100644 (file)
index 0000000..7d1db78
--- /dev/null
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+@summary: Ansible filter module of filter 'compare_lc_list'.
+
+@author: Frank Brehm
+@contact: frank@brehm-online.com
+@copyright: © 2024 by Frank Brehm, Berlin
+"""
+
+try:
+    from collections.abc import Sequence
+except ImportError:
+    from collections import Sequence
+
+# =============================================================================
+class FilterModule(object):
+    """A filter module object."""
+
+    # ------------------
+    def filters(self):
+        """Return all usable filter methods from this class."""
+        return {
+            'compare_lc_list': self.compare_lc_list,
+            'bool_to_on_off': self.bool_to_on_off,
+        }
+
+    # ------------------
+    def compare_lc_list(self, list_one, list_two):
+        """Compare two lists with case-insensitive and position independend items."""
+        if not isinstance(list_one, Sequence) or hasattr(list_one, 'strip'):
+            list_one = [list_one]
+
+        if not isinstance(list_two, Sequence) or hasattr(list_two, 'strip'):
+            list_two = [list_two]
+
+        if len(list_one) != len(list_two):
+            return False
+
+        list_one_lc = []
+        for item in list_one:
+            list_one_lc.append(str(item).lower())
+        list_one_lc.sort()
+
+        list_two_lc = []
+        for item in list_two:
+            list_two_lc.append(str(item).lower())
+        list_one_lc.sort()
+
+        if list_one_lc == list_two_lc:
+            return True
+
+        return False
+
+    # ------------------
+    def bool_to_on_off(self, value):
+        """Translate the given value to on or off respective."""
+        if value:
+            return 'on'
+        return 'off'
+
+
+# =============================================================================
+
+# vim: ts=4 et list
index 8f08ba0fc7ae4f56fc66498c0ddf70e3224ed273..25a179c0edbbe33c997f782a349351fc8da38ca9 100644 (file)
@@ -31,5 +31,8 @@
       include_role:
         name: '389ds-config-logging'
 
+    - name: "Configure all necessay plugins of the 389ds LDAP server."
+      include_role:
+        name: 389ds-config-plugins
 
 # vim: filetype=yaml
diff --git a/roles/389ds-config-plugins/tasks/main.yaml b/roles/389ds-config-plugins/tasks/main.yaml
new file mode 100644 (file)
index 0000000..c1acbef
--- /dev/null
@@ -0,0 +1,7 @@
+---
+
+- name: "Configuring the 389ds memberOf-Plugin."
+  include_tasks: 'memberof.yaml'
+  when: (ds389_plugin_memberof_config | bool) == true
+
+# vim: filetype=yaml
diff --git a/roles/389ds-config-plugins/tasks/memberof.yaml b/roles/389ds-config-plugins/tasks/memberof.yaml
new file mode 100644 (file)
index 0000000..244e4ad
--- /dev/null
@@ -0,0 +1,116 @@
+---
+
+- name: 'Get the current configuration of the memberOf-Plugin.'
+  ansible.builtin.shell: "dsconf {{ slapd_instance | quote }} plugin memberof show | grep -P -i '^(memberof|nsslapd-pluginEnabled)' | sed -e 's/^memberof//i' -e 's/nsslapd-plugin//i' | tr '[:upper:]' '[:lower:]' | sort || true"
+  register: plugin_memberof
+  changed_when: false
+  check_mode: false
+
+- name: 'Show raw memberof attribute config.'
+  debug:
+    var: plugin_memberof
+    verbosity: 3
+
+- name: "Set variable plugin_memberof_config"
+  set_fact:
+    plugin_memberof_config: "{{ plugin_memberof.stdout_lines | cfg_389ds_to_dict }}"
+
+- name: "Show config hash:"
+  debug:
+    var: plugin_memberof_config
+    verbosity: 0
+
+- name: 'Predefine variable exec_set to false'
+  set_fact:
+    exec_set: false
+
+- name: 'Check for attr.'
+  set_fact:
+    exec_set: true
+  when: '"attr" not in plugin_memberof_config or plugin_memberof_config["attr"] != ( ds389_plugin_memberof_attr | lower )'
+
+- name: 'Check for groupattrs not set.'
+  set_fact:
+    exec_set: true
+  when: '"groupattr" not in plugin_memberof_config'
+
+- name: 'Check for groupattrs.'
+  set_fact:
+    exec_set: true
+  when: '"groupattr" in plugin_memberof_config and (plugin_memberof_config["groupattr"] | compare_lc_list(ds389_plugin_memberof_groupattrs) != true)'
+
+- name: 'Check for allbackends.'
+  set_fact:
+    exec_set: true
+  when: '"allbackends" not in plugin_memberof_config or plugin_memberof_config["allbackends"] != ds389_plugin_memberof_allbackends'
+
+- name: 'Check for skipnested.'
+  set_fact:
+    exec_set: true
+  when: '"skipnested" not in plugin_memberof_config or plugin_memberof_config["skipnested"] != ds389_plugin_memberof_skipnested'
+
+- name: "Has the memberOf-Plugin to be configured:"
+  debug:
+    var: exec_set
+
+- name: "Configure the memberof plugin, if necessary."
+  when: exec_set == true
+  block:
+
+    - name: "Init var plugin_memberof_cmd."
+      set_fact:
+        plugin_memberof_cmd: "dsconf {{ slapd_instance | quote }} plugin memberof set"
+
+    - name: "Add attr to plugin_memberof_cmd."
+      set_fact:
+        plugin_memberof_cmd: "{{ plugin_memberof_cmd }} --attr {{ ds389_plugin_memberof_attr }}"
+
+    - name: "Add groupattrs to plugin_memberof_cmd."
+      set_fact:
+        plugin_memberof_cmd: "{{ plugin_memberof_cmd }} --groupattr {{ ds389_plugin_memberof_groupattrs | join(' ') }}"
+
+    - name: "Add allbackends to plugin_memberof_cmd."
+      set_fact:
+        plugin_memberof_cmd: "{{ plugin_memberof_cmd }} --allbackends {{ ds389_plugin_memberof_allbackends | bool_to_on_off }}"
+
+    - name: "Add skipnested to plugin_memberof_cmd."
+      set_fact:
+        plugin_memberof_cmd: "{{ plugin_memberof_cmd }} --skipnested {{ ds389_plugin_memberof_skipnested | bool_to_on_off }}"
+
+    - name: "Add suffixes as scope."
+      when: "ds389_plugin_memberof_scopes | length < 1"
+      block:
+
+        - name: "Retrieve all backends"
+          ansible.builtin.shell: "dsconf '{{ slapd_instance }}' backend suffix list"
+          register: get_backend_suffixes
+          changed_when: false
+          check_mode: false
+
+        - name: "Set scopes from suffixes list"
+          no_log: true
+          set_fact:
+            scopes: "{{ get_backend_suffixes.stdout_lines | map('regex_replace', '\\s+\\(.+\\)\\s*$', '') | list }}"
+
+    - name: "Add scopes from config."
+      when: "ds389_plugin_memberof_scopes | length >= 1"
+      block:
+
+        - name: "Set scopes from config."
+          set_fact:
+            scopes: "{{ ds389_plugin_memberof_scopes }}"
+
+    - name: "Add scopes to plugin_memberof_cmd."
+      set_fact:
+        plugin_memberof_cmd: "{{ plugin_memberof_cmd }} --scope {{ scopes | map('quote') | join(' ') }}"
+
+    - name: "Show the command to execute:"
+      debug:
+        var: plugin_memberof_cmd
+        verbosity: 0
+
+    - name: "Finally configure the memberof plugin."
+      ansible.builtin.shell: "{{ plugin_memberof_cmd }}"
+
+
+# vim: filetype=yaml
diff --git a/roles/389ds-config-plugins/vars/main.yaml b/roles/389ds-config-plugins/vars/main.yaml
new file mode 100644 (file)
index 0000000..957a02c
--- /dev/null
@@ -0,0 +1,17 @@
+---
+
+ds389_plugin_memberof_config: true
+ds389_plugin_memberof_attr: 'memberOf'
+ds389_plugin_memberof_groupattrs:
+  - 'member'
+  - 'uniqueMember'
+ds389_plugin_memberof_allbackends: true
+ds389_plugin_memberof_skipnested: false
+
+# Later do eval, how to maintain
+ds389_plugin_memberof_scopes: []
+ds389_plugin_memberof_escapes: []
+ds389_plugin_memberof_auto_add_oc: ~
+
+
+# vim: filetype=yaml