From: Frank Brehm Date: Mon, 2 Dec 2024 17:13:34 +0000 (+0100) Subject: Adding and using role 389ds-config-plugins X-Git-Url: https://git.uhu-banane.net/?a=commitdiff_plain;h=ecd69fbe80af5d2334bc3d97093526ff245eaae4;p=pixelpark%2Fpp-admin-tools.git Adding and using role 389ds-config-plugins --- diff --git a/filter_plugins/cfg_389ds_to_dict.py b/filter_plugins/cfg_389ds_to_dict.py index 71c7715..b13430d 100644 --- a/filter_plugins/cfg_389ds_to_dict.py +++ b/filter_plugins/cfg_389ds_to_dict.py @@ -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 index 0000000..7d1db78 --- /dev/null +++ b/filter_plugins/compare_lc_list.py @@ -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 diff --git a/playbooks/configure-ldap-servers.yaml b/playbooks/configure-ldap-servers.yaml index 8f08ba0..25a179c 100644 --- a/playbooks/configure-ldap-servers.yaml +++ b/playbooks/configure-ldap-servers.yaml @@ -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 index 0000000..c1acbef --- /dev/null +++ b/roles/389ds-config-plugins/tasks/main.yaml @@ -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 index 0000000..244e4ad --- /dev/null +++ b/roles/389ds-config-plugins/tasks/memberof.yaml @@ -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 index 0000000..957a02c --- /dev/null +++ b/roles/389ds-config-plugins/vars/main.yaml @@ -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