From f74fdc277b6e8ff69b510e0a43057d2565fd791d Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Fri, 13 Dec 2024 18:06:10 +0100 Subject: [PATCH] Working on playbook playbooks/enable-ldap-server-replication.yaml + role 389ds-enable-replication --- inventory/dpx-ldap-dev1.yaml | 1 + inventory/dpx-ldap-prd.yaml | 1 + inventory/dpx-ldap-test.yaml | 1 + inventory/spk-ldap-live.yaml | 1 + inventory/spk-ldap-stage.yaml | 1 + playbooks/enable-ldap-server-replication.yaml | 22 ++++- plugins/filter/filter.py | 9 ++ .../389ds-disable-replication/tasks/main.yaml | 2 +- .../389ds-enable-replication/tasks/check.yaml | 77 +++++++++++++++++ .../389ds-enable-replication/tasks/main.yaml | 50 +++++++++++ .../tasks/suffix.yaml | 85 +++++++++++++++++++ roles/389ds-enable-replication/vars/main.yaml | 6 ++ 12 files changed, 251 insertions(+), 5 deletions(-) create mode 100644 roles/389ds-enable-replication/tasks/check.yaml create mode 100644 roles/389ds-enable-replication/tasks/main.yaml create mode 100644 roles/389ds-enable-replication/tasks/suffix.yaml create mode 100644 roles/389ds-enable-replication/vars/main.yaml diff --git a/inventory/dpx-ldap-dev1.yaml b/inventory/dpx-ldap-dev1.yaml index f585565..4c592ce 100644 --- a/inventory/dpx-ldap-dev1.yaml +++ b/inventory/dpx-ldap-dev1.yaml @@ -22,6 +22,7 @@ all: replication_manager_dn: 'cn=Replication Manager,cn=config' replication_manager_password_file: '/root/.private/dirserv-repl-mngr-pwd.txt' replication_manager_idle_timeout: 0 + ds389_replication_role: supplier ldaps_validate_certs: false # ds389_plugin_attr_uniq_purge: false ds389_plugin_attr_uniq_attributes: diff --git a/inventory/dpx-ldap-prd.yaml b/inventory/dpx-ldap-prd.yaml index c57fdf4..f87cff3 100644 --- a/inventory/dpx-ldap-prd.yaml +++ b/inventory/dpx-ldap-prd.yaml @@ -23,6 +23,7 @@ all: replication_manager_password_file: '/root/.private/dirserv-repl-mngr-pwd.txt' replication_manager_idle_timeout: 0 ldaps_validate_certs: false + ds389_replication_role: supplier ds389_plugin_attr_uniq_purge: false ds389_plugin_attr_uniq_attributes: 'uid': diff --git a/inventory/dpx-ldap-test.yaml b/inventory/dpx-ldap-test.yaml index c1118ff..23d81c7 100644 --- a/inventory/dpx-ldap-test.yaml +++ b/inventory/dpx-ldap-test.yaml @@ -22,6 +22,7 @@ all: replication_manager_dn: 'cn=Replication Manager,cn=config' replication_manager_password_file: '/root/.private/dirserv-repl-mngr-pwd.txt' replication_manager_idle_timeout: 0 + ds389_replication_role: supplier ldaps_validate_certs: false # ds389_plugin_attr_uniq_purge: false ds389_plugin_attr_uniq_attributes: diff --git a/inventory/spk-ldap-live.yaml b/inventory/spk-ldap-live.yaml index 866a638..e79c716 100644 --- a/inventory/spk-ldap-live.yaml +++ b/inventory/spk-ldap-live.yaml @@ -33,6 +33,7 @@ all: subtrees: - 'dc=spk,dc=pixelpark,dc=net' ds389_plugin_account_policy_config: false + ds389_replication_role: supplier # Temporary # ds389_logging_config: false diff --git a/inventory/spk-ldap-stage.yaml b/inventory/spk-ldap-stage.yaml index d735b16..bc88321 100644 --- a/inventory/spk-ldap-stage.yaml +++ b/inventory/spk-ldap-stage.yaml @@ -33,6 +33,7 @@ all: subtrees: - 'dc=spk,dc=pixelpark,dc=net' ds389_plugin_account_policy_config: false + ds389_replication_role: supplier # Temporary # ds389_logging_config: false diff --git a/playbooks/enable-ldap-server-replication.yaml b/playbooks/enable-ldap-server-replication.yaml index 25329e4..022280b 100644 --- a/playbooks/enable-ldap-server-replication.yaml +++ b/playbooks/enable-ldap-server-replication.yaml @@ -4,7 +4,7 @@ gather_facts: false vars_prompt: - name: ldap_server - prompt: "On wich LDAP server should replication be enabled" + prompt: "To wich LDAP server should should the complete replica be mirrord (a.k.a. replication init - leave empty to skip it)" private: false tasks: @@ -18,7 +18,15 @@ ansible.builtin.set_fact: found_ldapserver: false - - name: "Searching for LDAP server '{{ ldapserver_to_enable }}' ..." + - name: 'Actions, if no ldapserver_to_enable was set.' + when: ldapserver_to_enable is empty + block: + + - name: "End play because ldapserver_to_enable was not set." + ansible.builtin.meta: end_play + when: ("No LDAP server set, where the replica should be mirrored to." | warn_me()) + + - name: "Searching for LDAP server {{ ldapserver_to_enable | quote }} ..." ansible.builtin.set_fact: found_ldapserver: true when: "item == ldapserver_to_enable" @@ -28,12 +36,13 @@ - name: "Fail for non LDAP server." ansible.builtin.fail: - msg: "The given host '{{ ldapserver_to_enable }}' is not a valid LDAP server." + msg: "The given host {{ ldapserver_to_enable | quote }} is not a valid LDAP server." when: found_ldapserver == false - name: "Initial checks for the HAProxy." hosts: haproxy_servers gather_facts: false + any_errors_fatal: true tasks: @@ -41,9 +50,10 @@ include_role: name: haproxy-check-initial -- name: "Enabling Replication on a particular LDAP server." +- name: "Enabling Replication on all LDAP servers." hosts: ldap_servers gather_facts: false + any_errors_fatal: true tasks: @@ -64,5 +74,9 @@ var: ldapserver_to_enable verbosity: 0 + - name: "Enable replica on all backends." + include_role: + name: '389ds-enable-replication' + # vim: filetype=yaml diff --git a/plugins/filter/filter.py b/plugins/filter/filter.py index e34de3c..6b9fed9 100644 --- a/plugins/filter/filter.py +++ b/plugins/filter/filter.py @@ -10,6 +10,8 @@ import re +from ansible.utils.display import Display + try: from collections.abc import Sequence except ImportError: @@ -32,6 +34,7 @@ class FilterModule(object): 'compare_lc_list': self.compare_lc_list, 'bool_to_on_off': self.bool_to_on_off, 'bool_to_yes_no': self.bool_to_yes_no, + 'warn_me': self.warn_filter, } # ------------------ @@ -118,6 +121,12 @@ class FilterModule(object): return 'yes' return 'no' + # ------------------ + def warn_filter(self, message, **kwargs): + """Emit a warning.""" + Display().warning(message) + return message + # ============================================================================= diff --git a/roles/389ds-disable-replication/tasks/main.yaml b/roles/389ds-disable-replication/tasks/main.yaml index 94ef5b6..31fddfb 100644 --- a/roles/389ds-disable-replication/tasks/main.yaml +++ b/roles/389ds-disable-replication/tasks/main.yaml @@ -35,7 +35,7 @@ verbosity: 0 - name: "Finally remove replication from suffix {{ suffix | quote }}." - ansible.builtin.shell: "dsconf {{ slapd_instance | quote }} disable --suffix {{ suffix | quote }}" + ansible.builtin.shell: "dsconf {{ slapd_instance | quote }} replication disable --suffix {{ suffix | quote }}" when: suffix_is_replicated == true # vim: filetype=yaml diff --git a/roles/389ds-enable-replication/tasks/check.yaml b/roles/389ds-enable-replication/tasks/check.yaml new file mode 100644 index 0000000..20ebec2 --- /dev/null +++ b/roles/389ds-enable-replication/tasks/check.yaml @@ -0,0 +1,77 @@ +--- + +# Checking all preferences for replication + +- name: "Check existence of replication Id of host." + ansible.builtin.fail: + msg: "No replica Id for host {{ inventory_hostname | quote }} given." + when: replica_id is empty + +- name: "Convert replication Id of host to int." + ansible.builtin.set_fact: + replica_id: "{{ replica_id | int }}" + +- name: "Current replication Id of host:" + debug: + var: replica_id + verbosity: 0 + +- name: "Checking value of replication Id of host." + ansible.builtin.fail: + msg: "Invalid value for replication Id {{ replica_id }} - must be greater than 0 and less or equal then {{ max_replication_id }}." + when: (replica_id | int) <= 0 or (replica_id | int) >= max_replication_id + +- name: "Checking replication Id of host to those of other hosts." + ansible.builtin.fail: + msg: "Replication Id {{ replica_id }} also used on host {{ other_host | quote }}." + when: other_host != inventory_hostname and hostvars[other_host].replica_id == replica_id + loop: "{{ groups['ldap_servers'] }}" + loop_control: + loop_var: other_host + +- name: "Define replication role of this host, if not given." + set_fact: + ds389_replication_role: "{{ ds389_default_replication_role }}" + when: ds389_replication_role is empty + +- name: "Checking replication role of this host." + ansible.builtin.fail: + msg: "Wrong replication role '{{ ds389_replication_role }}', must be one of .'supplier', 'hub' or 'consumer'" + when: "ds389_replication_role not in ['supplier', 'hub', 'consumer']" + +- name: "Replication role of this host:" + debug: + var: ds389_replication_role + verbosity: 0 + +- name: "Checking replication Bind DN" + ansible.builtin.fail: + msg: "Bind DN of replication manager not set." + when: replication_manager_dn is empty + +- name: "Checking existence of variable replication_manager_password_file." + ansible.builtin.fail: + msg: "Password file replication_manager_password_file not set." + when: replication_manager_password_file is empty + +- name: "Get file stat of Replication manager password file ..." + ansible.builtin.stat: + path: "{{ replication_manager_password_file }}" + register: repl_mngr_password_file + +- name: "File stat of Replication manager password file: " + debug: + var: repl_mngr_password_file + verbosity: 3 + +- name: "Check existence of Replication manager password file." + ansible.builtin.fail: + msg: "The Replication manager password file {{ replication_manager_password_file | quote }} does not exists." + when: repl_mngr_password_file.stat.exists != true + +- name: "Checking, whether Replication manager password file is a regular file." + ansible.builtin.fail: + msg: "The path {{ replication_manager_password_file | quote }} for the Replication manager password file is not a regular file." + when: repl_mngr_password_file.stat.isreg != true + +# vim: filetype=yaml diff --git a/roles/389ds-enable-replication/tasks/main.yaml b/roles/389ds-enable-replication/tasks/main.yaml new file mode 100644 index 0000000..7fbbefd --- /dev/null +++ b/roles/389ds-enable-replication/tasks/main.yaml @@ -0,0 +1,50 @@ +--- + +- name: "Checking all preferences for replication..." + include_tasks: 'check.yaml' + +- name: "Get a list of all replicated Suffixes." + ansible.builtin.shell: "dsconf {{ slapd_instance | quote }} replication list" + check_mode: false + changed_when: false + register: list_of_replicated_suffixes + +- name: "Show current list_of_replicated_suffixes" + debug: + var: list_of_replicated_suffixes + verbosity: 2 + +- name: "Retrieve all backends from {{ ldapserver_to_disable | quote }}." + ansible.builtin.shell: "dsconf {{ slapd_instance | quote }} backend suffix list" + register: backend_suffix_list + changed_when: false + check_mode: false + +- name: "Show current backend_suffix_list" + debug: + var: backend_suffix_list + verbosity: 2 + +- name: "Set backend variable" + no_log: true + set_fact: + suffix_names: "{{ backend_suffix_list.stdout_lines | map('regex_replace', '\\s+\\(.+\\)\\s*$', '') | list }}" + backend_names: "{{ backend_suffix_list.stdout_lines | map('regex_replace', '^.*\\((.+)\\)\\s*$', '\\1') | list }}" + +- name: "Set suffixes dict" + no_log: true + set_fact: + suffixes: "{{ dict( suffix_names | zip(backend_names) ) }}" + +- name: "Show current suffixes" + debug: + var: suffixes + verbosity: 0 + +- name: "Enable replication for particular suffix." + include_tasks: 'suffix.yaml' + vars: + suffix: "{{ item.key }}" + loop: "{{ suffixes | dict2items | list }}" + +# vim: filetype=yaml diff --git a/roles/389ds-enable-replication/tasks/suffix.yaml b/roles/389ds-enable-replication/tasks/suffix.yaml new file mode 100644 index 0000000..14cca42 --- /dev/null +++ b/roles/389ds-enable-replication/tasks/suffix.yaml @@ -0,0 +1,85 @@ +--- + +# Enabling replication for a particular suffix + +- name: "Ensure enabled replication for particular suffix." + debug: + var: suffix + verbosity: 0 + +- name: "Get a list of all replicated Suffixes." + ansible.builtin.shell: "dsconf {{ slapd_instance | quote }} replication list" + check_mode: false + changed_when: false + register: list_of_replicated_suffixes + +- name: "Show current list_of_replicated_suffixes" + debug: + var: list_of_replicated_suffixes + verbosity: 2 + +- name: "Set fact suffix_is_replicated." + no_log: true + set_fact: + suffix_is_replicated: false + +- name: "Searching for suffix {{ suffix | quote }} in the list of replicated suffixes." + set_fact: + suffix_is_replicated: true + when: ( this_line | regex_replace('^\\s*') | regex_replace('\\s*$') ) == suffix + loop: "{{ list_of_replicated_suffixes.stdout_lines }}" + loop_control: + loop_var: this_line + +- name: "Check existing replication." + when: suffix_is_replicated == true + block: + + - name: "Get current replication Id." + ansible.builtin.shell: "dsconf {{ slapd_instance | quote }} replication get --suffix {{ suffix | quote }} | \ + grep -P -i '^nsDS5ReplicaId:' | sed -e 's/^nsDS5ReplicaId:[ ]*//i'" + check_mode: false + changed_when: false + register: get_cur_replication_id + + - name: "Show get_cur_replication_id" + debug: + var: get_cur_replication_id + verbosity: 2 + + - name: "Set fact cur_replication_id." + set_fact: + cur_replication_id: "{{ get_cur_replication_id.stdout | int }}" + + - name: "Show cur_replication_id" + debug: + var: cur_replication_id + verbosity: 1 + + - name: "Check current replication Id against the configured one" + ansible.builtin.fail: + msg: "The configured replication Id {{ replica_id | int }} does not match the existing \ + replication Id {{ cur_replication_id | int ]] of suffix {{ suffix | quote }}." + when: (replica_id | int) != (cur_replication_id | int) + +- name: "Enable relication." + when: suffix_is_replicated == false + block: + + - name: "Define command for enabling replication." + set_fact: + cmd_enable_replica: "dsconf {{ slapd_instance | quote }} replication enable --suffix {{ suffix | quote }} \ + --role {{ ds389_replication_role | quote }} \ + --replica-id {{ replica_id | int }} \ + --bind-dn {{ replication_manager_dn | quote }} \ + --bind-passwd-file {{ replication_manager_password_file | quote }}" + + - name: "Command for enabling replication:" + debug: + var: cmd_enable_replica + verbosity: 0 + + - name: "Finally enabling replication." + ansible.builtin.shell: "{{ cmd_enable_replica }}" + +# vim: filetype=yaml diff --git a/roles/389ds-enable-replication/vars/main.yaml b/roles/389ds-enable-replication/vars/main.yaml new file mode 100644 index 0000000..d3ad3e7 --- /dev/null +++ b/roles/389ds-enable-replication/vars/main.yaml @@ -0,0 +1,6 @@ +--- + +max_replication_id: 32767 +ds389_default_replication_role: 'supplier' + +# vim: filetype=yaml -- 2.39.5