# Playbook for Ansible to scan for PFSA-2022-013

# This playbook must be started from the main folder to access the dynamic data-dir inventory.
# start with:
# ansible-playbook playbooks/PFSA-2022-013/main.yml --diff --limit $hostname
# For legacy Systems use:
# ansible-playbook playbooks/PFSA-2022-013/main.yml --diff --exta-vars "legacy=true" --limit $hostname
# With this playbook we do not use the --check parameter!

- name: scan PFSA-2022-013
  gather_facts: no
  hosts: all
  ignore_unreachable: yes
  order: sorted

  tasks:

#Zope Test - error expected on servers without zope
  - name: test if zope is running
    shell: curl http://localhost:9081/PerFact/DB_Utils/VERSION
    register: curl_result
    ignore_errors: true

  - debug:
      msg: "Auf diesem System läuft kein zope. Das Playbook endet für diesen Host"
    when: curl_result.stdout | length == 0

  - name: end host when no zope is running
    ansible.builtin.meta: end_host
    when: curl_result.stdout | length == 0

#End playbook on host when patch already installed - expected error when the patch is not installed
  - name: check if patch is already installed
    shell: git log --oneline | grep "T235186"
    args:
      chdir: /opt/perfact/dbutils-zoperepo
    register: check_output
    become: yes
    become_method: su
    become_user: perfact
    ignore_errors: true

  - debug:
      msg: "Der Patch ist auf diesem System bereits installiert. Das Playbook endet für diesen Host"
    when: check_output.stdout | length > 0

  - name: end playbook when patch is already installed
    ansible.builtin.meta: end_host
    when: check_output.stdout | length > 0

#Gather facts to compare the package versions
  - name: gather the package facts
    ansible.builtin.package_facts:
      manager: auto

#End playbook on host when old perfact-dbutils version is installed
  - when: ansible_facts.packages['perfact-dbutils-zope4'][0].version is defined
    block:
      - debug:
          msg: "Auf diesem System ist keine unterstützte Version von dbutils installiert. Das Playbook endet für diesen Host"
        when: ansible_facts.packages['perfact-dbutils-zope4'][0].version is version('4.1.4', '<')

      - name: end playbook when dbutils-zope4 < 4.1.4
        ansible.builtin.meta: end_host
        when: ansible_facts.packages['perfact-dbutils-zope4'][0].version is version('4.1.4', '<')

  - when: ansible_facts.packages['perfact-dbutils-zope2'][0].version is defined
    block:
      - debug:
          msg: "Auf diesem System ist keine unterstützte Version von dbutils installiert. Das Playbook endet für diesen Host"
        when: ansible_facts.packages['perfact-dbutils-zope2'][0].version is version('4.1.0', '<')

      - name: end playbook when dbutils-zope2 < 4.1.0
        ansible.builtin.meta: end_host
        when: ansible_facts.packages['perfact-dbutils-zope2'][0].version is version('4.1.0', '<')

  - debug:
      msg: "Auf diesem System ist kein dbutils installiert. Das Playbook endet für diesen Host"
    when: >
      ansible_facts.packages['perfact-dbutils-zope4'][0].version is not defined and
      ansible_facts.packages['perfact-dbutils-zope2'][0].version is not defined

  - name: end playbook when no dbutils-zope is installed
    ansible.builtin.meta: end_host
    when: >
      ansible_facts.packages['perfact-dbutils-zope4'][0].version is not defined and
      ansible_facts.packages['perfact-dbutils-zope2'][0].version is not defined

  - when: legacy is defined and legacy | bool
    block:
    #Copies the legacy patchfile to /tmp/
      - name: copy patchfile
        copy: src=PFSA-2022-013-legacy.patch dest=/tmp/

    #Check if default site is WebApp or customer name
      - name: default site check
        shell: grep "default_site" /opt/perfact/dbutils-zoperepo/__root__/__meta__ | cut -d "'" -f 12
        register: default_site

    #If default site is customer name, change WebApp to customer name in the legacy patch file
      - name: change default site to customer name
        shell: sed -i -e 's@__root__/PerFact/WebApp/@__root__/PerFact/{{ default_site.stdout }}/@g' /tmp/PFSA-2022-013-legacy.patch
        when: default_site.stdout != 'WebApp'

    #Executes security patch and checks if it is installed correctly
      - name: Install and check if the patch is installed
        block:
          - name: execute patch
            shell: zodbsync exec "git am /tmp/PFSA-2022-013-legacy.patch || git am --abort"
            become: yes
            become_method: su
            become_user: perfact

          - name: check if patch is installed
            shell: git log -n 1 --oneline | grep "T235186"
            args:
              chdir: /opt/perfact/dbutils-zoperepo
            register: test_output
            become: yes
            become_method: su
            become_user: perfact
          - debug:
              msg: "Patch erfolgreich eingespielt!"
            when: test_output.stdout | length > 0

    #Remove patchfile
      - name: remove patchfile
        ansible.builtin.file:
          path: /tmp/PFSA-2022-013-legacy.patch
          state: absent

    #End Host after Installation of legacy Patch
      - name: End Play for this Host
        ansible.builtin.meta: end_host

#Copies the patchfile to /tmp/
  - name: copy patchfile
    copy: src=PFSA-2022-013.patch dest=/tmp/

#Check if default site is WebApp or customer name
  - name: default site check
    shell: grep "default_site" /opt/perfact/dbutils-zoperepo/__root__/__meta__ | cut -d "'" -f 12
    register: default_site

#If default site is customer name, change WebApp to customer name in the patch file
  - name: change default site to customer name
    shell: sed -i -e 's@__root__/PerFact/WebApp/@__root__/PerFact/{{ default_site.stdout }}/@g' /tmp/PFSA-2022-013.patch
    when: default_site.stdout != 'WebApp'

#Executes security patch and checks if it is installed correctly
  - name: Install and check if the patch is installed
    block:
      - name: execute patch
        shell: zodbsync exec "git am /tmp/PFSA-2022-013.patch || git am --abort"
        become: yes
        become_method: su
        become_user: perfact

      - name: check if patch is installed
        shell: git log -n 1 --oneline | grep "T235186"
        args:
          chdir: /opt/perfact/dbutils-zoperepo
        register: test_output
        become: yes
        become_method: su
        become_user: perfact
      - debug:
          msg: "Patch erfolgreich eingespielt!"
        when: test_output.stdout | length > 0

#Remove patchfile
  - name: remove patchfile
    ansible.builtin.file:
      path: /tmp/PFSA-2022-013.patch
      state: absent
