# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

---

# /*---------------------------------------------------------------------------8
# |                                                                            |
# |                       Prepare for SAP PAS Install                          |
# |                                                                            |
# +------------------------------------4--------------------------------------*/

- hosts:                               localhost
  name:                                "PAS Installation Playbook: - Initialization"
  gather_facts:                        true
  vars_files:
    - vars/ansible-input-api.yaml                               # API Input template with defaults

  tasks:

    - name:                            "PAS Installation Playbook: - Create Progress folder"
      ansible.builtin.file:
        path:                          "{{ _workspace_directory }}/.progress"
        state:                         directory
        mode:                          0755

    - name:                            "PAS Installation Playbook: - Remove pas-install-done flag"
      ansible.builtin.file:
        path:                          "{{ _workspace_directory }}/.progress/pas-install-done"
        state:                          absent


    - name:                            "PAS Installation Playbook: - Set pas fact"
      ansible.builtin.set_fact:
        tier:                          pas

    - name:                            "PAS Installation Playbook: - Read/Create passwords"
      ansible.builtin.include_role:
        name:                          roles-misc/0.1-passwords
        public:                        true
      tags:
        - 0.1-passwords

    - name:                            "OS configuration playbook: - Read password"
      ansible.builtin.include_role:
        name:                          roles-misc/0.1-passwords
        tasks_from:                    windows.yaml
        public:                        true
      when: platform == "SQLSERVER"
      tags:
        - 0.1-win-passwords

    - name:                            "PAS Installation Playbook: - Read/Create key vault secrets"
      ansible.builtin.include_role:
        name:                          roles-misc/0.2-kv-secrets
        public:                        true
      vars:
        operation:                     fencing
      tags:
                                       - 0.2-kv-secrets

    - name:                            "PAS Installation Playbook: - Read storage account details"
      ansible.builtin.include_role:
        name:                          roles-misc/0.3.sap-installation-media-storage-details
        public:                        true
      vars:
        tier:                          pas
      tags:
        - kv-sap-installation-media-storage-details

# /*---------------------------------------------------------------------------8
# |                                                                            |
# |                       Playbook for SAP OS USERS and Groups Creation        |
# |                                                                            |
# +------------------------------------4--------------------------------------*/

- hosts:                               "{{ sap_sid | upper }}_PAS"

  name:                                SAP Generic OS Groups and User Creation
  serial:                              1
  remote_user:                         "{{ orchestration_ansible_user }}"
  gather_facts:                        true                                    # Important to collect hostvars information
  vars_files:
    - vars/ansible-input-api.yaml                                              # API Input template with defaults

  tasks:
    - name:                            "PAS Installation Playbook: Define this SID"
      ansible.builtin.set_fact:
        this_sid:
          {
              'sid':          '{{ sap_sid | upper }}',
              'dbsid_uid':    '{{ hdbadm_uid }}',
              'sidadm_uid':   '{{ UIDs[ platform ].uid }}',
              'ascs_inst_no': '{{ scs_instance_number }}',
              'pas_inst_no':  '{{ pas_instance_number }}',
              'app_inst_no':  '{{ app_instance_number }}'
          }

    - name:                            "PAS Installation Playbook: - Set 'pas' tier facts"
      ansible.builtin.set_fact:
        all_sids:                      "{% if MULTI_SIDS is defined %}{{ MULTI_SIDS }}{% else %}{{ all_sids | default([]) + [this_sid] }}{% endif %}"

    - name:                            "Generic Users and Groups for SAP Installation"
      ansible.builtin.include_role:
        name:                          roles-sap-os/2.5-sap-users
        tasks_from:                    user_nw.yaml
        apply:
          tags:
            - 2.5-sap-users
          become:                      true
          become_user:                 root
      vars:
        scs_instance_number:           "{{ sid_to_be_deployed.ascs_inst_no }}"
        tier:                          generic
        main_password:                 "{{ hostvars.localhost.sap_password }}"
        sapbits_location_base_path:    "{{ hostvars.localhost.sapbits_location_base_path }}"
        sapbits_sas_token:             "{{ hostvars.localhost.sapbits_sas_token }}"
      loop:                            "{{ all_sids }}"
      loop_control:
        loop_var:                      sid_to_be_deployed
      when:
        - ansible_os_family != "Windows"
      tags:
        - 2.5-sap-users


# /*---------------------------------------------------------------------------8
# |                                                                            |
# |                       Playbook for SAP PAS Install                         |
# |                                                                            |
# +------------------------------------4--------------------------------------*/


- hosts:                               "{{ sap_sid | upper }}_PAS  :
                                        {{ sap_sid | upper }}_SCS :
                                        {{ sap_sid | upper }}_DB"

  name:                                "PAS Installation Playbook"
  remote_user:                         "{{ orchestration_ansible_user }}"
  gather_facts:                        true                                    # Important to collect hostvars information
  vars_files:
    - vars/ansible-input-api.yaml                                              # API Input template with defaults
# -------------------------------------+---------------------------------------8
#
# Build the list of tasks to be executed in order here.
#
# -------------------------------------+---------------------------------------8

  tasks:

    - name:                            "PAS Installation Playbook: - Set 'pas' tier facts"
      ansible.builtin.set_fact:
        tier:                          pas
        main_password:                 "{{ hostvars.localhost.sap_password }}"
        sapbits_location_base_path:    "{{ hostvars.localhost.sapbits_location_base_path }}"
        sapbits_sas_token:             "{{ hostvars.localhost.sapbits_sas_token }}"
        pas_file_path:                 INSTALL/DISTRIBUTED/ABAP/APP1
        always_upload_jinja_templates: false
        sa_enabled:                    true
      tags:
        - always

    - name:                            "PAS Installation Playbook: Define this SID"
      ansible.builtin.set_fact:
        this_sid:
          {
                'sid':          '{{ sap_sid | upper }}',
                'dbsid_uid':    '{{ hdbadm_uid }}',
                'sidadm_uid':   '{{ UIDs[ platform ].uid }}',
                'ascs_inst_no': '{{ scs_instance_number }}',
                'pas_inst_no':  '{{ pas_instance_number }}',
                'app_inst_no':  '{{ app_instance_number }}'
          }

    - name:                            "PAS Installation Playbook: Define list of SIDs"
      ansible.builtin.set_fact:
        all_sids:                      "{% if MULTI_SIDS is defined %}{{ MULTI_SIDS }}{% else %}{{ all_sids | default([]) + [this_sid] }}{% endif %}"
      when:
        - "'pas' in supported_tiers"

# -------------------------------------+---------------------------------------8
# Role: 5.2-PAS Installation
#
# Description:
#
# -------------------------------------+---------------------------------------8

    - name:                            "PAS Installation Playbook: - Run PAS Installation on Linux"
      when:
        - "'pas' in supported_tiers"
        - ansible_os_family != "Windows"
      become:                          true
      block:

        - name:                        "PAS Installation Playbook: - Assertions"
          block:
            - name:                    "PAS Installation Playbook: - Show instance numbers"
              ansible.builtin.debug:
                msg:
                  - "pas_instance_number: {{ pas_instance_number }}"
                  - "scs_instance_number: {{ scs_instance_number }}"

            - name:                    "PAS Installation Playbook: - Assert instance numbers"
              ansible.builtin.assert:
                that:
                  - "pas_instance_number is defined"
                  - "scs_instance_number != pas_instance_number"
                fail_msg:              "Please ensure that the scs_instance_number is different from the pas_instance_number"
          when:                        (ansible_play_hosts_all | length) <= 2

        - name:                        Run the PAS installation Playbook
          block:
            - name:                            "Backward Compatibility - Check required Database HA variables"
              ansible.builtin.set_fact:
                database_high_availability:    "{{ db_high_availability | default(false) }}"
              when:
                - db_high_availability is defined
                - database_high_availability is not defined

            - name:                        "PAS Installation playbook: - Determine if part of high availablity deployment"
              ansible.builtin.set_fact:
                is_ha:                      "{{ database_high_availability | default(false) }}"
              tags:
                - always

            - name:                        "PAS Installation playbook: - Ensure the kernel parameters are set"
              ansible.builtin.include_role:
                name:                      roles-os/1.9-kernelparameters
              when:                        is_ha
              tags:
                - 1.9-kernelparameters

            - name:                    "PAS Installation Playbook - Install: Include 2.6-sap-mounts role"
              ansible.builtin.include_role:
                name:                  roles-sap-os/2.6-sap-mounts
              tags:
                - 2.6-sap-mounts

            - name:                    "PAS Installation Playbook: - Install SAPInst"
              ansible.builtin.include_role:
                name:                  roles-sap/5.2-pas-install
              vars:
                instance_number:       "{% if pas_instance_number is defined %}{{ pas_instance_number }}{% else %}00{% endif %}"
              loop:                    "{{ all_sids }}"
              loop_control:
                loop_var:              sid_to_be_deployed

            - name:                    "PAS Installation Playbook: - Create pas-install-done flag"
              delegate_to:             localhost
              become:                  false
              ansible.builtin.file:
                path:                  "{{ _workspace_directory }}/.progress/pas-install-done"
                state:                 touch
                mode:                  0755
              when:
                - pas_already_installed is defined or (pas_installation.rc is defined and pas_installation.rc == 0)
          always:
            - name:                    "PAS Installation Playbook: - Get the Error lines from installation output"
              ansible.builtin.set_fact:
                error_lines:           "{{ error_lines | default([]) + [item] }}"
              with_items:              "{{ pas_installation.stdout_lines }}"
              when:
                - pas_installation.stdout_lines is defined
                - '"ERROR" in item'

            - name:                    "PAS Installation Playbook: - Run post installation routines"
              ansible.builtin.include_role:
                name:                  roles-sap/7.0.0-post-install
              vars:
                suffix:                "_PAS"
                prefix:                "{{ bom.product_ids.pas.replace('.', '/').replace('/ABAP', '').replace('/PD', '').split(':')[1] }}"
                path:                  'INSTALL/DISTRIBUTED/{{ pas_bom_instance_type }}/APP1'
                tier:                  'pas'
                this_sid:              "{{ sid_to_be_deployed.sid | upper }}"
                work_log_component_name: "D{{ pas_instance_number }}"
              loop:                    "{{ all_sids }}"
              loop_control:
                loop_var:              sid_to_be_deployed

            - name:                    "PAS Installation Playbook: - Show errors from PAS installation"
              ansible.builtin.debug:
                msg:                   "{{ error_lines }}"
              when:
                - error_lines is defined

          tags:
            - 5.2-pas-install
    - name:                            "PAS Installation Playbook: - Run PAS Installation on Windows"
      when:
        - "'pas' in supported_tiers"
        - ansible_os_family == "Windows"
      block:

        - name:                        "PAS Installation Playbook: - Assertions"
          block:
            - name:                    "PAS Installation Playbook: - Show instance numbers"
              ansible.builtin.debug:
                msg:
                  - "pas_instance_number: {{ pas_instance_number }}"
                  - "scs_instance_number: {{ scs_instance_number }}"
                  - "{{ ansible_play_hosts_all | length }} hosts in inventory"

            - name:                    "PAS Installation Playbook: - Assert instance numbers"
              ansible.builtin.assert:
                that:
                  - "pas_instance_number is defined"
                  - "scs_instance_number != pas_instance_number"
                fail_msg:              "Please ensure that the scs_instance_number is different from the pas_instance_number"

          when:                        (ansible_play_hosts_all | length) <= 2

        - name:                        "PAS Installation Playbook: - Ensure Sharing Data Folder"
          ansible.builtin.include_role:
            name:                      roles-sap-os/windows/2.3-sap-exports
          tags:
            - 2.3-sap-exports
          vars:
            winadm_password:           "{{ hostvars.localhost.winadm_password }}"
            domain_service_password:   "{{ hostvars.localhost.adsvc_password }}"
            domain_service_account:    "{{ hostvars.localhost.adsvc_account }}"
            domain_user_password:      "{{ hostvars.localhost.winadm_password }}"
            sql_svc_account:           "{% if hostvars.localhost.sqlsvc_account is defined %}{{ hostvars.localhost.sqlsvc_account }}{% else %}{{ win_sql_svc_account }}{% endif %}"
            tier:                      app_tier

        - name:                        Run the PAS installation Playbook
          block:
            - name:                    "PAS Installation - Add packages"
              ansible.builtin.include_role:
                name:                  roles-os/windows/1.4-packages
              tags:
                - 1.4-packages
              vars:
                winadm_password:           "{{ hostvars.localhost.winadm_password }}"
                domain_service_password:   "{{ hostvars.localhost.adsvc_password }}"
                domain_service_account:    "{{ hostvars.localhost.adsvc_account }}"
                domain_user_password:      "{{ hostvars.localhost.winadm_password }}"
                tier:                      app_tier

            - name:                    "PAS Installation Playbook: - Install using SAPInst"
              ansible.builtin.include_role:
                name:                  roles-sap/windows/5.2-pas-install
              vars:
                instance_number:       "{% if pas_instance_number is defined %}{{ pas_instance_number }}{% else %}00{% endif %}"
                domain_user_password:  "{{ hostvars.localhost.winadm_password }}"
                svc_password:          "{{ hostvars.localhost.svcadm_password }}"
              loop:                    "{{ all_sids }}"
              loop_control:
                loop_var:              sid_to_be_deployed

            - name:                    "PAS Installation Playbook: - Create pas-install-done flag"
              delegate_to:             localhost
              become:                  false
              ansible.builtin.file:
                path:                  "{{ _workspace_directory }}/.progress/pas-install-done"
                state:                 touch
                mode:                  0755
              when:
                - pas_already_installed is defined or (pas_installation.rc is defined and pas_installation.rc == 0)

          always:
            - name:                    "PAS Installation Playbook: - Get the Error lines from installation output"
              ansible.builtin.set_fact:
                error_lines:           "{{ error_lines | default([]) + [item] }}"
              with_items:              "{{ pas_installation.stdout_lines }}"
              when:
                - pas_installation.stdout_lines is defined
                - '"ERROR" in item'
                - pas_installation.rc > 0

            - name:                    "PAS Installation Playbook: - Run post installation routines"
              ansible.builtin.include_role:
                name:                  roles-sap/windows/7.0.0-post-install
              vars:
                suffix:                "_PAS"
                tier:                  'pas'

            - name:                    "PAS Installation Playbook: - Show errors from PAS installation"
              ansible.builtin.debug:
                msg:                   "{{ error_lines }}"
              when:
                - error_lines is defined

            - name:                    "SCS Install: Rename sapinst_logs Folder with TimeStamp"
              ansible.windows.win_shell: |
                                        Rename-Item -Path .\sapinst_logs -NewName "sapinst_logs_$(get-date -f yyyy_MM_dd_HH_mm_ss)"
              args:
                chdir:                 '{{ log_dir_windows }}'
                removes:               '{{ log_dir_windows }}\sapinst_logs'
              register:                sapinst_log_name
              failed_when:             sapinst_log_name.rc > 0
              when:
                - ansible_os_family == "Windows"

          tags:
            - 5.2-pas-install


# /*---------------------------------------------------------------------------8
# |                                                                            |
# |                       Playbook for Reseting the DB2 parameters             |
# |  2570458 - DB6: Depooling report RUTPOADAPT fails with SQL -912            |
# +------------------------------------4--------------------------------------*/
- hosts:                               "{{ sap_sid | upper }}_DB"

  name:                                "Resetting the DB2 LOCK escalationparameters"
  serial:                              1
  gather_facts:                        true
  vars_files:
    - vars/ansible-input-api.yaml                               # API Input template with defaults

  tasks:
    # 2570458 - DB6: Depooling report RUTPOADAPT fails with SQL -912
    - name:                            "Check if LOCK variable is set for PAS"
      ansible.builtin.stat:
        path:                          /etc/sap_deployment_automation/lock_escalation_false.txt
      register:                        db2_lock_escalation
      when:
        - platform == "DB2"

    # 2570458 - DB6: Depooling report RUTPOADAPT fails with SQL -912
    - name:                            "Set LOCK variable for PAS"
      become:                          true
      become_user:                     db2{{ db_sid | lower }}
      ansible.builtin.shell:           db2set DB2_AVOID_LOCK_ESCALATION=
      args:
        executable:                    /bin/csh
      when:
        - platform == "DB2"
        - db2_lock_escalation.stat.exists
