]> Frank Brehm's Git Trees - pixelpark/pp-admin-tools.git/commitdiff
Adding and using Ansible info modules
authorFrank Brehm <frank.brehm@pixelpark.com>
Thu, 19 Dec 2024 15:52:48 +0000 (16:52 +0100)
committerFrank Brehm <frank.brehm@pixelpark.com>
Thu, 19 Dec 2024 15:52:48 +0000 (16:52 +0100)
lib/ansible/ds389_instances_info.py [new file with mode: 0644]
lib/ansible/ds389_logging_info.py [new file with mode: 0644]
playbooks/library [new symlink]
roles/389ds-check-initial/tasks/main.yaml
roles/389ds-config-logging/tasks/config-facility.yaml
roles/389ds-config-logging/tasks/main.yaml

diff --git a/lib/ansible/ds389_instances_info.py b/lib/ansible/ds389_instances_info.py
new file mode 100644 (file)
index 0000000..ccb9891
--- /dev/null
@@ -0,0 +1,116 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+"""
+@summary: Ansible info module for retrieving list of 389ds directory server instances.
+
+@author: Frank Brehm
+@contact: frank.brehm@pixelpark.com
+@copyright: © 2024 by Frank Brehm, Berlin
+"""
+
+# Copyright (c) 2024, Frank Brehm <frank.brehm@pixelpark.com>
+# GNU General Public License v3.0+
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = r"""
+---
+module: ds389_instances_info
+short_description: Retrieve list of 389ds directory server instances
+description:
+  - Get a list of installed instances of a 389ds directory server
+author: "Frank Brehm <frank.brehm@pixelpark.com>"
+extends_documentation_fragment:
+  - community.general.attributes
+  - community.general.attributes.info_module
+options: {}
+
+"""
+
+EXAMPLES = r"""
+# Gather list of instances of 389ds directory server
+- name: Get list of instances of 389ds directory server
+  ds389_instances_info: {}
+  register: ds389_instance_info
+
+"""
+
+RETURN = r"""
+---
+changed: false
+failed: false
+instances:
+  - slapd-dev-ds01
+
+"""
+
+# Standard modules
+import warnings
+from subprocess import run
+
+# Third party modules
+from ansible.module_utils.basic import AnsibleModule
+# from ansible.module_utils.common.text.converters import to_text
+from ansible.module_utils.common.process import get_bin_path
+
+
+# ##############################################################################
+class Ds389InstancesInfo(object):
+    """Class for retrieving list of 389ds directory server instances."""
+
+    encoding = 'utf-8'
+
+    # --------------------------------------------------------------------------
+    def __init__(self):
+        """Initialize the Ds389InstancesInfo object."""
+        pass
+
+    # --------------------------------------------------------------------------
+    def run(self):
+        """Retrieve the list anyhow ..."""
+        try:
+            cmd = get_bin_path('dsctl')
+        except ValueError:
+            return []
+
+        if not cmd:
+            return []
+
+        proc = run([cmd, '-l'], capture_output=True, encoding=self.encoding)
+
+        if proc.stderr:
+            warnings.warn(proc.stderr)
+
+        result = []
+        for line in proc.stdout.splitlines():
+            instance = line.strip()
+            if instance:
+                result.append(instance)
+
+        return result
+
+
+# ##############################################################################
+def main():
+    """Execute main entry function of this module."""
+    global module
+
+    module = AnsibleModule(
+        argument_spec={},
+        supports_check_mode=True,
+    )
+
+    instances = Ds389InstancesInfo().run()
+    module.exit_json(changed=False, instances=instances)
+
+
+# ##############################################################################
+if __name__ == '__main__':
+    main()
+
+# =============================================================================
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list
diff --git a/lib/ansible/ds389_logging_info.py b/lib/ansible/ds389_logging_info.py
new file mode 100644 (file)
index 0000000..be1a647
--- /dev/null
@@ -0,0 +1,277 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+"""
+@summary: Ansible info module for retrieving logging configuration of a 389ds instance.
+
+@author: Frank Brehm
+@contact: frank.brehm@pixelpark.com
+@copyright: © 2024 by Frank Brehm, Berlin
+"""
+
+# Copyright (c) 2024, Frank Brehm <frank.brehm@pixelpark.com>
+# GNU General Public License v3.0+
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = r"""
+---
+module: ds389_logging_info
+short_description: Retrieve logging configuration of a 389ds instance
+description:
+  - Get the logging configuration of an instance of a 389ds directory server
+author: "Frank Brehm <frank.brehm@pixelpark.com>"
+extends_documentation_fragment:
+  - community.general.attributes
+  - community.general.attributes.info_module
+options:
+  instance:
+    type: str
+    description:
+      - The name of the instance, where the logging configuration should be retrieved.
+    required: true
+
+"""
+
+EXAMPLES = r"""
+- name: Get logging configuration of the 389ds directory server
+  ds389_logging_info:
+    instance: slapd-dev-ds21
+  register: ds389_logging_config
+
+"""
+
+RETURN = r"""
+---
+changed: false
+failed: false
+config:
+  access:
+    compress: false
+    level: 256
+    list:
+      - /var/log/dirsrv/slapd-dev-ds21/access.log.20241209-160851
+      - /var/log/dirsrv/slapd-dev-ds21/access.log.20241210-160853
+      - /var/log/dirsrv/slapd-dev-ds21/access.log.20241211-160858
+    logfile: /var/log/dirsrv/slapd-dev-ds21/access.log
+    logbuffering: true
+    logexpirationtime: 1
+    logexpirationtimeunit: 'month'
+    logging-enabled: true
+    logmaxdiskspace: 500
+    logminfreediskspace: 5
+    logrotationsync-enabled: false
+    logrotationsynchour: 0
+    logrotationsyncmin: 0
+    logrotationtime: 1
+    logrotationtimeunit: 'day'
+    maxlogsize: 100
+    maxlogsperdir: 10
+    mode: '600'
+  audit:
+    compress: false
+    display-attrs: ~
+    level: 256
+    list:
+      - /var/log/dirsrv/slapd-dev-ds21/audit.log.20241211-154245
+    logfile: /var/log/dirsrv/slapd-dev-ds21/access.log
+    logbuffering: true
+    logexpirationtime: 1
+    logexpirationtimeunit: 'month'
+    logging-enabled: false
+    logmaxdiskspace: 500
+    logminfreediskspace: 5
+    logrotationsync-enabled: false
+    logrotationsynchour: 0
+    logrotationsyncmin: 0
+    logrotationtime: 1
+    logrotationtimeunit: 'week'
+    maxlogsize: 100
+    maxlogsperdir: 10
+    mode: '600'
+  auditfail:
+    compress: false
+    list: []
+    logfile: /var/log/dirsrv/slapd-dev-ds21/access.log
+    logbuffering: true
+    logexpirationtime: 1
+    logexpirationtimeunit: 'month'
+    logging-enabled: true
+    logmaxdiskspace: 500
+    logminfreediskspace: 5
+    logrotationsync-enabled: false
+    logrotationsynchour: 0
+    logrotationsyncmin: 0
+    logrotationtime: 1
+    logrotationtimeunit: 'week'
+    maxlogsize: 100
+    maxlogsperdir: 10
+    mode: '600'
+  error:
+    compress: false
+    level: 16384
+    list:
+      - /var/log/dirsrv/slapd-dev-ds21/error.log.20241211-174002
+    logfile: /var/log/dirsrv/slapd-dev-ds21/access.log
+    logexpirationtime: 1
+    logexpirationtimeunit: 'month'
+    logging-enabled: true
+    logmaxdiskspace: 500
+    logminfreediskspace: 5
+    logrotationsync-enabled: false
+    logrotationsynchour: 0
+    logrotationsyncmin: 0
+    logrotationtime: 1
+    logrotationtimeunit: 'day'
+    maxlogsize: 100
+    maxlogsperdir: 10
+    mode: '600'
+  security:
+    compress: true
+    level: 256
+    list:
+      - '/var/log/dirsrv/slapd-dev-ds21/security.log.20241210-153222'
+      - '/var/log/dirsrv/slapd-dev-ds21/security.log.20241126-153149'
+      - '/var/log/dirsrv/slapd-dev-ds21/security.log.20241119-153143'
+      - '/var/log/dirsrv/slapd-dev-ds21/security.log.20241112-153127'
+      - '/var/log/dirsrv/slapd-dev-ds21/security.log.20241105-153116'
+      - '/var/log/dirsrv/slapd-dev-ds21/security.log.20241203-153153'
+    logbuffering: true
+    logexpirationtime: 1
+    logexpirationtimeunit: 'month'
+    logfile: '/var/log/dirsrv/slapd-dev-ds21/security.log'
+    logging-enabled: true
+    logmaxdiskspace: 500
+    logminfreediskspace: 5
+    logrotationsync-enabled: false
+    logrotationsynchour: 0
+    logrotationsyncmin: 0
+    logrotationtime: 1
+    logrotationtimeunit: 'week'
+    maxlogsize: 100
+    maxlogsperdir: 10
+    mode: '600'
+
+
+"""
+
+# Standard modules
+import re
+import warnings
+from subprocess import run
+
+# Third party modules
+from ansible.module_utils.basic import AnsibleModule
+# from ansible.module_utils.common.text.converters import to_text
+from ansible.module_utils.common.process import get_bin_path
+
+
+# ##############################################################################
+class Ds389LoggingInfo(object):
+    """Class for retrieving logging configuration of a 389ds directory server instance."""
+
+    encoding = 'utf-8'
+
+    log_facilities = ('access', 'audit', 'auditfail', 'error', 'security')
+
+    # --------------------------------------------------------------------------
+    def __init__(self):
+        """Initialize the Ds389LoggingInfo object."""
+        self.instance = module.params.get('instance')
+
+    # --------------------------------------------------------------------------
+    def run(self):
+        """Retrieve the list anyhow ..."""
+        try:
+            cmd = get_bin_path('dsconf')
+        except ValueError:
+            return {}
+
+        if not cmd:
+            return {}
+
+        proc = run(
+            [cmd, self.instance, 'config', 'get'],
+            capture_output=True, encoding=self.encoding)
+
+        if proc.stderr:
+            warnings.warn(proc.stderr)
+
+        proc.check_returncode()
+
+        pat_logconfig = (
+            r'^nsslapd-(' + '|'.join(self.log_facilities) + r')log(?:-([a-z-]*))?:\s*(\S.*)?')
+        re_logconfig = re.compile(pat_logconfig, re.IGNORECASE)
+        re_int = re.compile(r'^[+-]?\d+$')
+        re_float = re.compile(r'^[+-]?\d+\.\d*$')
+
+        result = {}
+        for line in proc.stdout.splitlines():
+            line = line.strip()
+            m = re_logconfig.match(line)
+            if not m:
+                continue
+            facility = m.group(1).lower()
+            key = m.group(2)
+            value = m.group(3)
+
+            if not key:
+                key = 'logfile'
+            else:
+                key = key.lower()
+
+            if facility not in result:
+                result[facility] = {}
+
+            if key == 'list':
+                if 'list' not in result[facility]:
+                    result[facility]['list'] = []
+                if value:
+                    result[facility]['list'].append(value)
+                continue
+
+            if key != 'mode' and value is not None:
+                if re_int.match(value):
+                    value = int(value)
+                elif re_float.match(value):
+                    value = float(value)
+                elif value in ('yes', 'on', 'true'):
+                    value = True
+                elif value in ('no', 'off', 'false'):
+                    value = False
+                elif value == '':
+                    value = None
+
+            result[facility][key] = value
+
+        return result
+
+
+# ##############################################################################
+def main():
+    """Execute main entry function of this module."""
+    global module
+
+    module = AnsibleModule(
+        argument_spec={
+            'instance': {
+                'type': 'str',
+                'required': True,
+            },
+        },
+        supports_check_mode=True,
+    )
+
+    config = Ds389LoggingInfo().run()
+    module.exit_json(changed=False, config=config)
+
+
+# ##############################################################################
+if __name__ == '__main__':
+    main()
+
+# =============================================================================
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list
diff --git a/playbooks/library b/playbooks/library
new file mode 120000 (symlink)
index 0000000..7ae5bc3
--- /dev/null
@@ -0,0 +1 @@
+../lib/ansible
\ No newline at end of file
index c29caee36998c59a5902bb925f3773a595441e1b..1bb24d13383030438a61b6c5cf3923f29f6f7925 100644 (file)
 - name: "Get the version of the 389ds LDAP server."
   ansible.builtin.set_fact:
     version_389ds: "{{ get_389ds_version.stdout }}"
-    cacheable: true
 
 - name: "Show version of 389ds LDAP server."
   debug:
     var: version_389ds
     verbosity: 0
 
+- name: "Get a list of all 389ds directory server instances."
+  ds389_instances_info: {}
+  register: ds389_instances_info
+
+- set_fact:
+    ds389_instances: "{{ ds389_instances_info.instances }}"
+
+- name: "Show the list of all 389ds directory server instances."
+  debug:
+    var: ds389_instances
+    verbosity: 0
+
 - name: "Fail for non existing 389ds LDAP server."
   ansible.builtin.fail:
     msg: "No 389ds LDAP server found on host '{{ inventory_hostname }}'."
index 03fc655ed55c5fab4e4370aaa2933c29201f45d9..96a5eb250e92f5e6da6e4596c742239210a5d99f 100644 (file)
@@ -1,43 +1,59 @@
 ---
 
-- name: "Get current configuration of config for log facility '{{ log_facility.key }}'."
-  ansible.builtin.shell: "dsconf {{ slapd_instance | quote }} config get | grep -P -i 'nsslapd-{{ log_facility.key }}log' || true"
-  register: config_get
-  changed_when: false
-  check_mode: false
-
-- name: "Show current config_get"
-  debug:
-    var: config_get
-    verbosity: 3
-
-- name: "Generate config hash."
-  when: config_get.stdout is not empty
+- name: "Log facility is existing."
+  when: log_config.facility in ds389_logging_config
   block:
 
-    - name: "Set logging variables"
+    - name: "Set facts for {{ log_config.facility | quote }} logging."
       set_fact:
-        log_config: "{{ config_get.stdout_lines | cfg_389ds_to_dict }}"
+        cur_logfile: "{{ ds389_logging_config[log_config.facility]['logfile'] }}"
+        cur_enabled: "{{ ds389_logging_config[log_config.facility]['logging-enabled'] }}"
+        exp_logfile: "{{ base_logdir }}/slapd-{{ slapd_instance }}/{{ log_config.config.logfile }}"
+        exp_enabled: "{{ log_config.config.enabled }}"
+        config_logfile_key: "nsslapd-{{log_config.facility}}log"
+        facility: "{{ log_config.facility }}"
+
+    - debug:
+        msg: "Current logfile: {{ cur_logfile | quote }}, expected: {{ exp_logfile | quote }}."
+        verbosity: 1
 
-    - name: "Show config hash:"
-      debug:
-        var: log_config
-        verbosity: 2
+    - name: "Replace logfile"
+      when: cur_logfile != exp_logfile
+      block:
 
-    - name: "Set config key for '{{ log_facility.key }}' logfile."
-      set_fact:
-        exp_logfile: "{{ base_logdir }}/slapd-{{ slapd_instance }}/{{ log_facility.value.logfile }}"
-        dict_logfile_key: "{{ log_facility.key }}log"
-        config_logfile_key: "nsslapd-{{ log_facility.key }}log"
+        - name: "Define command for setting logfile."
+          set_fact:
+            cmd_set_logfile: "dsconf {{ slapd_instance | quote }} config replace {{ config_logfile_key }}={{ exp_logfile }}"
+
+        - name: "Show command for setting logfile."
+          debug:
+            var: cmd_set_logfile
+            verbosity: 0
+
+        - name: "Setting new value for {{ log_config.facility }} log to {{ exp_logfile | quote }} ..."
+          ansible.builtin.shell: "{{ cmd_set_logfile }}"
 
-    - name: "Show logfile stuff"
-      debug:
-        msg: "Current logfile: '{{ log_config[dict_logfile_key] }}', expected: '{{ exp_logfile }}'."
+    - debug:
+        msg: "Logging for facility {{ log_config.facility | quote }} is currently enabled: \
+              {{ cur_enabled }}, expected is {{ log_config.config.enabled }}."
         verbosity: 1
 
-    - name: "Setting new value for {{ log_facility.key }} log to '{{ exp_logfile }}' ..."
-      ansible.builtin.shell: "dsconf {{ slapd_instance | quote }} config replace {{ config_logfile_key }}={{ exp_logfile }}"
-      when: log_config[dict_logfile_key] != exp_logfile
+    - name: "Enabling/disabling logging"
+      when: cur_enabled != log_config.config.enabled
+      block:
+
+        - name: "Define command for enabling/disabling logging facility {{ log_config.facility | quote }}."
+          set_fact:
+            cmd_enabling_logging: "dsconf {{ slapd_instance | quote }} config replace \
+                                   nsslapd-{{ log_config.facility }}log-logging-enabled={{ log_config.config.enabled | bool_to_on_off }}"
+
+        - name: "Show command for  enabling/disabling logging facility {{ log_config.facility | quote }}."
+          debug:
+            var: cmd_enabling_logging
+            verbosity: 0
+
+        - name: "Enabling/disabling logging for facility {{ log_config.facility | quote }}."
+          ansible.builtin.shell: "{{ cmd_enabling_logging }}"
 
 
 # vim: filetype=yaml
index 34e4c96394ff0304e4e0500c415ad593c7514bd5..405b2167ab19c3484eba521bcfa5febbc6d00110 100644 (file)
@@ -2,10 +2,28 @@
 
 # Configuring logging of a 389ds LDAP server
 
+- name: "Get logging configuration."
+  ds389_logging_info:
+    instance: "slapd-{{ slapd_instance }}"
+  register: get_logging_info
+
+- name: "Show get_logging_info"
+  debug:
+    var: get_logging_info
+    verbosity: 3
+
+- set_fact:
+    ds389_logging_config: "{{ get_logging_info.config }}"
+
+- name: "Show current logging information:"
+  debug:
+    var: ds389_logging_config
+    verbosity: 1
+
 - name: "Configuring logging facility '{{ log_facility.key }}'."
   include_tasks: 'config-facility.yaml'
-  loop: "{{ logging | dict2items | list }}"
+  loop: "{{ logging | dict2items(key_name='facility', value_name='config') | list }}"
   loop_control:
-    loop_var: log_facility
+    loop_var: log_config
 
 # vim: filetype=yaml