---
- name: "Ensure needed packages"
  become: true
  package:
    name: pigz

- name: "Create destination backup directory"
  become: true
  ansible.builtin.file:
    path: "{{ backup_dest_dir }}"
    state: directory
    mode: "0755"
    owner: postgres
    group: postgres

- name: "Block: gpg stuff"
  become: true
  become_user: postgres
  block:
    - name: Create temp dir
      ansible.builtin.tempfile:
        state: directory
        suffix: gitcheckout
        path: /tmp
      register: tempdir

    - name: "Checkout repo for gpg communication-keys"
      ansible.builtin.git:
        repo: "{{ backup_communication_keys_repository }}"
        dest: "{{ tempdir.path }}"
        version: master

    # there is no ansible gpg module already in place
    # linting violation needs to be whitelisted
    - name: "Importing stage specific automation gpg-key" # noqa command-instead-of-shell
      shell: "gpg --import {{ tempdir.path }}/{{ backup_communication_keys_stage_gpg_key }}"

- name: "Block: Creating pg_basebackup"
  become: true
  block:
    - name: "Set common variables"
      set_fact:
        backup_file: "{{ backup_dest_dir }}/basebackup_{{ current_date_time }}.tar.gz"
        backup_status_file: "{{ backup_status_file }}_{{ current_date_time }}"
    # there is no ansible module already in place for (pg_basebackup|gpg)
    # so using shell module
    - name: "Creating pg_basebackup ... + doing async check if successful or not"
      become: true
      become_user: postgres
      shell: |
        set -o pipefail
        /usr/bin/pg_basebackup -Ft -X fetch -D - | nice -n {{ postgres_backup_niceness_pigz | default(8) }} pigz -p 2 > {{ backup_file }} && \
        nice -n {{ postgres_backup_niceness_gpg | default(10) }} gpg --encrypt --recipient "{{ backup_gpg_recipient }}" --trust-model always {{ backup_file }} && \
        rm {{ backup_file }}
      args:
        executable: /bin/bash
      async: 3600 # allows duration for task up to 3600sec
      poll: 30 # rechecks every 30sec if task has finished yet
      register: backup_result
      changed_when: false

    - name: "Save output to {{ backup_status_file }}"
      copy:
        content: "{{ backup_result }}"
        dest: "{{ backup_status_file }}"

    - name: "Change ownership of {{ backup_dest_dir }} to {{ backupuser_user_name }}:{{ backupuser_user_name }}"
      ansible.builtin.file:
        path: "{{ backup_dest_dir }}"
        owner: "{{ backupuser_user_name }}"
        group: "{{ backupuser_user_name }}"
        recurse: yes
  rescue:
    - name: "Rescue: Save output to {{ backup_status_file }}_with_failures"
      copy:
        content: "{{ backup_result }}"
        dest: "{{ backup_status_file }}_with_failures"
      when: backup_result.failed

    - name: "Rescue: Delete {{ backup_file }} on failure"
      file:
        path: "{{ backup_file }}"
        state: absent
      when: backup_result.failed

    - name: "Rescue: Sending e-mail to devops team"
      delegate_to: "{{ stage }}-mail-01.smardigo.digital"
      community.general.mail:
        host: "{{ stage }}-mail-01.smardigo.digital"
        port: 25
        from: "noreply@smardigo.digital"
        to: "{{ devops_email_address }}"
        subject: "Backup Postgresql on {{ inventory_hostname }} ( {{ lookup('pipe','date +%Y-%m-%d_%H:%M') }} ) problem report for failed postgresql basebackup"
        body: |
          Dear Sir or Madam
          creation of postgresql basebackup failed on host {{ inventory_hostname }}
          Plz check what happened/ fix it little padawan ;
          kind regards
          your automation-bofh

          Error report below

          ---

          {{ backup_result.stderr }}

          ---
      when: backup_result.failed

    - name: "Rescue: Stop backup because of failure"
      fail:
        msg: "Postgres backup failed. See the status file for more information about what happened."
      when: backup_result.failed
