--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+../lib/ansible
\ No newline at end of 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 }}'."
---
-- 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
# 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