--- /dev/null
+---
+
+# Sets the port number of the replica
+ds389_repl_agmt_port: 389
+
+# Sets the replication connection protocol: LDAP, LDAPS, or StartTLS
+# Possible values: 'LDAP', 'LDAPS', 'StartTLS'
+ds389_repl_agmt_conn_proto: 'LDAP'
+
+# Sets the bind method.
+# Possible values: "SIMPLE", "SSLCLIENTAUTH", "SASL/DIGEST", or "SASL/GSSAPI"
+ds389_repl_agmt_bind_method: 'SIMPLE'
+
+# Sets the list of attributes to NOT replicate to the consumer during incremental updates
+ds389_repl_agmt_frac_list:
+ - 'authorityRevocationList'
+ - 'accountUnlockTime'
+ - 'memberOf'
+
+# Sets the list of attributes to NOT replicate during a total initialization
+ds389_repl_agmt_frac_list_total:
+ - 'memberOf'
+
+# Sets a list of attributes that are removed from updates only if the event would otherwise be empty.
+ds389_repl_agmt_strip_list:
+ - 'modifiersName'
+ - 'modifyTimestmap'
+
+# Sets the replication update schedule: 'HHMM-HHMM DDDDDDD' D = 0-6 (Sunday - Saturday).
+# ds389_repl_agmt_schedule: '0500-2100 0123456'
+ds389_repl_agmt_schedule: ~
+
+# Sets the timeout used for replication connections
+ds389_repl_agmt_conn_timeout: 300
+
+# Sets a timeout in seconds on how long to wait before stopping replication when the server is under load
+ds389_repl_agmt_protocol_timeout: 600
+
+# Sets the amount of time in milliseconds the server waits if the consumer is not ready before resending data.
+ds389_repl_agmt_wait_async_results: 3000
+
+# Sets the amount of time in seconds a supplier should wait
+# after a consumer sends back a busy response before making another attempt to acquire access.
+ds389_repl_agmt_busy_wait_time: 300
+
+# Sets the amount of time in seconds a supplier should wait between update sessions.
+ds389_repl_agmt_session_pause_time: ~
+
+# Sets the maximum number of entries and updates sent by a supplier, which are not acknowledged by the consumer.
+ds389_repl_agmt_flow_control_window: ~
+
+# Sets the time in milliseconds to pause after reaching the number of entries and updates set in 'ds389_repl_agmt_flow_control_window'.
+ds389_repl_agmt_flow_control_pause: ~
+
+# vim: filetype=yaml
--- /dev/null
+---
+
+- debug:
+ msg: "Ensuring existence of all necessary replication agreements."
+
+- name: "Retrieve all backends."
+ ansible.builtin.shell: "dsconf {{ slapd_instance | quote }} backend suffix list"
+ register: get_backend_suffix_list
+ changed_when: false
+ check_mode: false
+
+- name: "Show current get_backend_suffix_list"
+ debug:
+ var: get_backend_suffix_list
+ verbosity: 2
+
+- name: "Set backend variable"
+ no_log: true
+ set_fact:
+ suffix_names: "{{ get_backend_suffix_list.stdout_lines | map('regex_replace', '\\s+\\(.+\\)\\s*$', '') | list }}"
+ backend_names: "{{ get_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: 1
+
+- name: "Ensure replication agreements on all suffixes."
+ include_tasks: 'repl-agmts-suffix.yaml'
+ when: item[1] != inventory_hostname
+ vars:
+ suffix: "{{ item[0].key }}"
+ other_host: "{{ item[1] }}"
+ loop: "{{ suffixes | dict2items | product( ansible_play_batch ) | list }}"
+
+# vim: filetype=yaml
--- /dev/null
+---
+
+- debug:
+ msg: "Ensuring existence of replication agreement from {{ inventory_hostname | quote }} \
+ to {{ other_host | quote }} for suffix {{ suffix | quote }}."
+ verbosity: 0
+
+- name: "Set fact agreement_name."
+ set_fact:
+ agreement_name: "{{ slapd_instance }} to {{ other_host }} agreement"
+
+- name: "Show replication agreement name for suffix {{ suffix | quote }}."
+ debug:
+ var: agreement_name
+ verbosity: 0
+
+- name: "Get list of current replication agreements for suffix {{ suffix | quote }}."
+ ansible.builtin.shell: "dsconf {{ slapd_instance | quote }} repl-agmt list --suffix {{ suffix | quote }} | \
+ grep -i '^cn: ' | sed -e 's/^cn:[ ]*//i' -e 's/[ ]*$//'"
+ register: get_repl_agmt_list
+ changed_when: false
+ check_mode: false
+
+- name: "Show current get_repl_agmt_list"
+ debug:
+ var: get_repl_agmt_list
+ verbosity: 2
+
+- name: "Predefine repl_agmt_exists"
+ set_fact:
+ repl_agmt_exists: false
+
+- name: "Search for current replication agreement."
+ set_fact:
+ repl_agmt_exists: true
+ when: (line | lower) == (agreement_name | lower)
+ loop: "{{ get_repl_agmt_list.stdout_lines }}"
+ loop_control:
+ loop_var: line
+
+- name: "Replication agreement already exists."
+ when: repl_agmt_exists == true
+ block:
+
+ - debug:
+ msg: "The replication agreement {{ agreement_name | quote }} is already existing for suffix {{ suffix | quote }}."
+
+- name: "Create replication agreement."
+ # when: repl_agmt_exists != true
+ block:
+
+ - debug:
+ var: hostvars[other_host]
+ verbosity: 3
+
+ - name: "Predefine variables."
+ set_fact:
+ used_port: "{{ ds389_repl_agmt_port }}"
+ used_proto: "{{ ds389_repl_agmt_conn_proto }}"
+ used_frac_list: "{{ ds389_repl_agmt_frac_list }}"
+ used_frac_list_total: "{{ ds389_repl_agmt_frac_list_total }}"
+
+ - name: "Get port from other host."
+ set_fact:
+ used_port: "{{ hostvars[other_host].ds389_repl_agmt_port }}"
+ when: "'ds389_repl_agmt_port' in hostvars[other_host] and hostvars[other_host].ds389_repl_agmt_port is not empty"
+
+ - name: "Get connection protocol from other host."
+ set_fact:
+ used_conn_proto: "{{ hostvars[other_host].ds389_repl_agmt_conn_proto }}"
+ when: "'ds389_repl_agmt_conn_proto' in hostvars[other_host] and hostvars[other_host].ds389_repl_agmt_conn_proto is not empty"
+
+ - name: "Get fractional list from other host."
+ set_fact:
+ used_frac_list: "{{ hostvars[other_host].ds389_repl_agmt_frac_list }}"
+ when: "'ds389_repl_agmt_frac_list' in hostvars[other_host] and hostvars[other_host].ds389_repl_agmt_frac_list is not empty"
+
+ - name: "Get fractional list for total from other host."
+ set_fact:
+ used_frac_list_total: "{{ hostvars[other_host].ds389_repl_agmt_frac_list_total }}"
+ when: "'ds389_repl_agmt_frac_list_total' in hostvars[other_host] and hostvars[other_host].ds389_repl_agmt_frac_list_total is not empty"
+
+ - name: "Define command for creating replication agreement."
+ set_fact:
+ create_cmd: "dsconf {{ slapd_instance | quote }} repl-agmt create --suffix {{ suffix | quote }} \
+ --host {{ other_host | quote }} --port {{ used_port | int }} \
+ --conn-protocol {{ used_conn_proto | quote }} \
+ --bind-dn {{ replication_manager_dn | quote }} \
+ --bind-passwd-file {{ replication_manager_password_file | quote }} \
+ --bind-method {{ ds389_repl_agmt_bind_method | quote }} \
+ --frac-list {{ used_frac_list | map('quote') | join(' ') }} \
+ --frac-list-total {{ used_frac_list_total | map('quote') | join(' ') }}"
+
+ - name: "Add --strip-list to command for creating replication agreement."
+ set_fact:
+ create_cmd: "{{ create_cmd }} --strip-list {{ ds389_repl_agmt_strip_list | map('quote') | join(' ') }}"
+ when: ds389_repl_agmt_strip_list is not empty
+
+ - name: "Add --schedule to command for creating replication agreement."
+ set_fact:
+ create_cmd: "{{ create_cmd }} --schedule {{ ds389_repl_agmt_schedule | quote }}"
+ when: ds389_repl_agmt_schedule is not empty
+
+ - name: "Add --conn-timeout to command for creating replication agreement."
+ set_fact:
+ create_cmd: "{{ create_cmd }} --conn-timeout {{ ds389_repl_agmt_conn_timeout | quote }}"
+ when: ds389_repl_agmt_conn_timeout is not empty
+
+ - name: "Add --protocol-timeout to command for creating replication agreement."
+ set_fact:
+ create_cmd: "{{ create_cmd }} --protocol-timeout {{ ds389_repl_agmt_protocol_timeout | quote }}"
+ when: ds389_repl_agmt_protocol_timeout is not empty
+
+ - name: "Add --wait-async-results to command for creating replication agreement."
+ set_fact:
+ create_cmd: "{{ create_cmd }} --wait-async-results {{ ds389_repl_agmt_wait_async_results | quote }}"
+ when: ds389_repl_agmt_wait_async_results is not empty
+
+ - name: "Add --busy-wait-time to command for creating replication agreement."
+ set_fact:
+ create_cmd: "{{ create_cmd }} --busy-wait-time {{ ds389_repl_agmt_busy_wait_time | quote }}"
+ when: ds389_repl_agmt_busy_wait_time is not empty
+
+ - name: "Add --session-pause-time to command for creating replication agreement."
+ set_fact:
+ create_cmd: "{{ create_cmd }} --session-pause-time {{ cds389_repl_agmt_session_pause_time | quote }}"
+ when: cds389_repl_agmt_session_pause_time is not empty
+
+ - name: "Add --flow-control-window to command for creating replication agreement."
+ set_fact:
+ create_cmd: "{{ create_cmd }} --flow-control-window {{ ds389_repl_agmt_flow_control_window | quote }}"
+ when: ds389_repl_agmt_flow_control_window is not empty
+
+ - name: "Add --flow-control-pause to command for creating replication agreement."
+ set_fact:
+ create_cmd: "{{ create_cmd }} --flow-control-pause {{ ds389_repl_agmt_flow_control_pause | quote }}"
+ when: ds389_repl_agmt_flow_control_pause is not empty
+
+ - name: "Complete command for creating replication agreement."
+ set_fact:
+ create_cmd: "{{ create_cmd }} {{ agreement_name | quote }}"
+
+ - name: "Command for creating replication agreement:"
+ debug:
+ var: create_cmd
+ verbosity: 0
+
+ - name: "Finally create the replication agreement."
+ ansible.builtin.shell: "{{ create_cmd }}"
+
+
+# vim: filetype=yaml