diff --git a/defaults/main.yaml b/defaults/main.yaml index 513f20d..de44f2a 100644 --- a/defaults/main.yaml +++ b/defaults/main.yaml @@ -16,6 +16,7 @@ patroni_postgresql_system_locale: "en_US.UTF-8" patroni_postgresql_system_language: "{{ patroni_postgresql_system_locale }}" # Patroni superuser auth +patroni_superuser_db: "postgres" patroni_superuser_username: "postgres" patroni_superuser_password: "postgres" @@ -48,9 +49,9 @@ patroni_dcs_type: "consul" ## WAL-G backup and restore options patroni_wal_g_install: false patroni_wal_g_restore_from_backup: false -patroni_wal_g_pitr: 'latest' -patroni_wal_g_restore_backup_name: 'LATEST' -patroni_wal_g_pg_binary_name: 'wal-g-pg' +patroni_wal_g_pitr: "" +patroni_wal_g_restore_backup_name: "LATEST" +patroni_wal_g_pg_binary: "/usr/bin/wal-g-pg" patroni_wal_g_config_name: ".walg.json" patroni_wal_g_restore_config_name: ".walg-restore.json" patroni_restore_script: "{{ patroni_postgresql_home_dir }}/restore.sh" @@ -66,6 +67,9 @@ patroni_wal_g_create_replica_methods: patroni_basebackup_create_replica_methods: - {option: "max-rate", value: "1000M"} - {option: "checkpoint", value: "fast"} +patroni_recovery_target_time: "" +patroni_recovery_target_action: "promote" +patroni_recovery_target_timeline: "latest" # More examples # patroni_postgresql_restore_command: "pgbackrest --stanza={{ pgbackrest_stanza }} archive-get %f %p" # restore WAL-s using pgbackrest @@ -111,8 +115,8 @@ patroni_postgresql_dynamic_parameters: {} patroni_postgresql_backup_parameters: postgresql: parameters: - archive_command: "{{ patroni_postgresql_archive_command if patroni_wal_g_install else 'cd .' }}" - restore_command: "{{ patroni_postgresql_restore_command if patroni_wal_g_install else 'cd .' }}" + archive_command: "{{ patroni_postgresql_archive_command if patroni_wal_g_backup_enable else 'cd .' }}" + restore_command: "{{ patroni_postgresql_restore_command if patroni_wal_g_backup_enable else 'cd .' }}" # postgresql parameters to bootstrap dcs (are parameters for example) patroni_postgresql_max_connections: "1000" diff --git a/tasks/Debian/wal_g_install.yaml b/tasks/Debian/wal_g_install.yaml index b57a71d..e95ccdd 100644 --- a/tasks/Debian/wal_g_install.yaml +++ b/tasks/Debian/wal_g_install.yaml @@ -1,11 +1,4 @@ -- name: Add WAL-G to patroni_create_replica_methods - set_fact: - patroni_create_replica_methods: "{{ patroni_create_replica_methods + [ 'wal_g' ] }}" - when: patroni_wal_g_install - - name: Include WAL-G role ansible.builtin.include_role: name: wal-g-pg - vars: - wal_g_pg: yes when: patroni_wal_g_install diff --git a/tasks/RedHat/wal_g_install.yaml b/tasks/RedHat/wal_g_install.yaml index b57a71d..e95ccdd 100644 --- a/tasks/RedHat/wal_g_install.yaml +++ b/tasks/RedHat/wal_g_install.yaml @@ -1,11 +1,4 @@ -- name: Add WAL-G to patroni_create_replica_methods - set_fact: - patroni_create_replica_methods: "{{ patroni_create_replica_methods + [ 'wal_g' ] }}" - when: patroni_wal_g_install - - name: Include WAL-G role ansible.builtin.include_role: name: wal-g-pg - vars: - wal_g_pg: yes when: patroni_wal_g_install diff --git a/tasks/config.yaml b/tasks/config.yaml index 56042de..b3ba219 100644 --- a/tasks/config.yaml +++ b/tasks/config.yaml @@ -31,6 +31,13 @@ path: "/etc/patroni/{{ patroni_config_name }}" register: patroni_config_file_exists_result +- name: Add WAL-G to patroni_create_replica_methods + set_fact: + patroni_create_replica_methods: "{{ patroni_create_replica_methods + [ 'wal_g' ] }}" + when: + - patroni_wal_g_install + - patroni_wal_g_backup_enable + - name: Propagate Patroni config copy: content: "{{ patroni_config_combined | to_nice_yaml }}" diff --git a/tasks/main.yaml b/tasks/main.yaml index 2979159..88871db 100644 --- a/tasks/main.yaml +++ b/tasks/main.yaml @@ -71,6 +71,10 @@ register: patroni_enable_and_start tags: patroni, patroni_start +- name: Include reset {{ patroni_superuser_username }} password after restore + include_tasks: reset-password-after-restore.yaml + when: patroni_wal_g_restore_from_backup + - name: Dynamic Patroni configuration include_tasks: dynamic_config.yaml tags: patroni_dynamic_configure diff --git a/tasks/reset-password-after-restore.yaml b/tasks/reset-password-after-restore.yaml new file mode 100644 index 0000000..6e131b5 --- /dev/null +++ b/tasks/reset-password-after-restore.yaml @@ -0,0 +1,41 @@ +--- +- name: Reset {{ patroni_superuser_username }} password after restore + block: + - name: Wait for Patroni leader + vars: + _query: 'json.members[].role' + ansible.builtin.uri: + url: "{{ 'https://' if patroni_ssl else 'http://' }}{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}:{{ patroni_restapi_listen_port }}/cluster" + method: GET + body_format: json + status_code: + - 200 + - 503 + register: patroni_role + until: patroni_role | json_query(_query) | regex_findall('leader') | count > 0 + retries: 100 + delay: 10 + + - name: Get Patroni nodes roles + ansible.builtin.uri: + url: "{{ 'https://' if patroni_ssl else 'http://' }}{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}:{{ patroni_restapi_listen_port }}" + method: GET + body_format: json + status_code: + - 200 + - 503 + register: patroni_role + + - name: Set fact about roles + set_fact: + role: "{{ patroni_role.json.role }}" + + - name: Reset {{ patroni_superuser_username }} password after restore + become_user: "{{ postgresql_user }}" + community.postgresql.postgresql_query: + db: "{{ patroni_superuser_db }}" + query: ALTER USER {{ patroni_superuser_username }} with password '{{ patroni_superuser_password }}'; + when: + - "hostvars[inventory_hostname]['role'] == 'master'" + rescue: + - include_tasks: /reset-password-after-restore.yaml diff --git a/templates/patroni.yaml.j2 b/templates/patroni.yaml.j2 index 215a1a7..93ee934 100644 --- a/templates/patroni.yaml.j2 +++ b/templates/patroni.yaml.j2 @@ -60,9 +60,12 @@ bootstrap: command: {{ patroni_restore_script }} no_params: True recovery_conf: - recovery_target_action: promote - recovery_target_timeline: {{ patroni_wal_g_pitr }} restore_command: {{ patroni_cluster_restore_command }} + recovery_target_action: {{ patroni_recovery_target_action }} + recovery_target_timeline: {{ patroni_recovery_target_timeline }} +{% if patroni_wal_g_pitr | length > 0 %} + recovery_target_time: {{ patroni_wal_g_pitr }} +{% endif %} {% endif %} {% if patroni_cluster_bootstrap_method == 'pg_probackup' %} pg_probackup: @@ -97,12 +100,12 @@ bootstrap: use_slots: true parameters: {{ patroni_postgresql_parameters_combined }} - initdb: # List options to be passed on to initdb + initdb: - encoding: {{ patroni_postgresql_encoding }} - locale: {{ patroni_postgresql_locale }} - data-checksums - pg_hba: # Add following lines to pg_hba.conf after running 'initdb' + pg_hba: {% if patroni_ssl|bool %} {% for host in groups[patroni_play_group] %} - hostssl all all {{ hostvars[host]['ansible_host'] }}/32 {{ patroni_postgresql_password_encryption_algorithm }} @@ -121,7 +124,6 @@ bootstrap: - hostssl all all 0.0.0.0/0 {{ patroni_postgresql_password_encryption_algorithm }} - host replication replicator 0.0.0.0/0 {{ patroni_postgresql_password_encryption_algorithm }} - postgresql: listen: 0.0.0.0:{{ patroni_postgresql_port }} connect_address: {{ hostvars[inventory_hostname]['ansible_host'] }}:{{ patroni_postgresql_port }} diff --git a/vars/RedHat.yaml b/vars/RedHat.yaml index d5c611a..996bd98 100644 --- a/vars/RedHat.yaml +++ b/vars/RedHat.yaml @@ -21,7 +21,7 @@ patroni_config_name: "patroni.yml" # PostgreSQL variables patroni_postgresql_package_name: "postgresql" patroni_postgresql_package: "{{ patroni_postgresql_package_name }}-{{ patroni_postgresql_version }}" -patroni_postgresql_data_dir: "{{ patroni_postgresql_home_dir }}/{{ patroni_postgresql_major_version }}/data" +patroni_postgresql_data_dir: "{{ patroni_postgresql_home_dir }}/{{ patroni_postgresql_major_version }}/{{ patroni_postgresql_cluster_name }}" patroni_postgresql_wal_dir: "" patroni_postgresql_cluster_name: "data" patroni_postgresql_conf_dir: "{{ patroni_postgresql_data_dir }}"