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

---

# /*----------------------------------------------------------------------------8
# |                                                                            |
# |         Playbook for preparing for SAP specific OS configuration tasks     |
# |                                                                            |
# +------------------------------------4--------------------------------------*/

- hosts:                               localhost
  name:                                "SAP OS configuration playbook: - Initialization"
  gather_facts:                        true
  vars_files:
    - vars/ansible-input-api.yaml                               # API Input template with defaults

  tasks:
    - name:                            "OS configuration playbook: - Ensure jmespath is installed in the playbook python"
      ansible.builtin.pip:
        name:                          jmespath
        state:                         present
      tags:
        - always

    - name:                            "SAP OS configuration playbook: - Create Progress folder"
      ansible.builtin.file:
        path:                          "{{ _workspace_directory }}/.progress"
        state:                         directory
        mode:                          0755
      tags:
        - always

    - name:                            "SAP OS configuration playbook: - Remove sap-os-install-done flag"
      ansible.builtin.file:
        path:                          "{{ _workspace_directory }}/.progress/sap-os-configuration-done"
        state:                          absent
      tags:
        - always

    - name:                            Include 0.3.sap-installation-media-storage-details role
      ansible.builtin.include_role:
        name:                          roles-misc/0.3.sap-installation-media-storage-details
      when:                            not is_run_with_infraCreate_only
      vars:
        tier:                          bom_download
      tags:
        - always

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

# /*----------------------------------------------------------------------------8
# |                                                                            |
# |         Playbook for performing SAP specific OS configuration tasks        |
# |                                                                            |
# +------------------------------------4--------------------------------------*/

- hosts:                               "{{ sap_sid | upper }}_SCS :
                                        {{ sap_sid | upper }}_DB  :
                                        {{ sap_sid | upper }}_ERS :
                                        {{ sap_sid | upper }}_PAS :
                                        {{ sap_sid | upper }}_APP :
                                        {{ sap_sid | upper }}_WEB :
                                        {{ sap_sid | upper }}_OBSERVER_DB"

  name:                                OS - SAP specific configuration
  remote_user:                         "{{ orchestration_ansible_user }}"
  gather_facts:                        true                                    # Important to collect hostvars information
  any_errors_fatal:                    true
  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:                            "SAP OS Configuration - Linux based systems"
      become:                          true
      become_user:                     "root"
      block:

        - name:                        "SAP OS configuration playbook: - Set sapos tier fact"
          ansible.builtin.set_fact:
            tier:                      sapos                                     # Actions for HANA DB Serve
          tags:
            - always

        - name:                        "SAP OS configuration playbook: - Retrieve Subscription ID, Resource Group Name and Virtual Machine name"
          ansible.builtin.uri:
            url:                       http://169.254.169.254/metadata/instance?api-version=2021-02-01
            use_proxy:                 false
            headers:
              Metadata:                true
          register: azure_metadata
          tags:
            - always

        - name:                        "SAP OS configuration playbook: - : Extract Subscription ID, Resource Group Name and Virtual Machine name"
          ansible.builtin.set_fact:
            subscription_id:           "{{ azure_metadata.json.compute.subscriptionId }}"
            resource_group_name:       "{{ azure_metadata.json.compute.resourceGroupName }}"
            vm_name:                   "{{ azure_metadata.json.compute.name }}"
          tags:
            - always

        - name:                        "SAP OS configuration playbook: - Set sapos storage account facts"
          ansible.builtin.set_fact:
            sapbits_location_base_path: "{{ hostvars.localhost.sapbits_location_base_path }}"
            sa_enabled:                 true
          when:
            - not is_run_with_infraCreate_only
            - hostvars.localhost.sapbits_location_base_path is defined
          tags:
            - always
            - is_run_with_infraCreate_only

        - name:                        "SAP OS configuration playbook: - Set sapos storage account facts"
          ansible.builtin.set_fact:
            sapbits_sas_token:          "{{ hostvars.localhost.sapbits_sas_token }}"
          when:
            - not is_run_with_infraCreate_only
            - hostvars.localhost.sapbits_sas_token is defined
          tags:
            - always
            - is_run_with_infraCreate_only

        - name:                        "SAP OS configuration playbook: - Set sapos storage account facts"
          ansible.builtin.set_fact:
            sapbits_sas_token:          "{{ hostvars.localhost.sapbits_sas_token }}"
          when:
            - not is_run_with_infraCreate_only
            - hostvars.localhost.sapbits_sas_token is defined
          tags:
            - always
            - is_run_with_infraCreate_only

        - name:                        "SAP OS configuration playbook: - Get the IP information from instance meta data service"
          ansible.builtin.uri:
            url:                       http://169.254.169.254/metadata/instance/network?api-version=2021-02-01
            use_proxy:                 false
            headers:
              Metadata:                true
          register: azure_network_metadata
          tags:
            - always

        # - name:                        "SAP OS configuration playbook: - Filter out the values for IPAddresses in json format"
        #   ansible.builtin.set_fact:
        #     private_ips_info:          "{{ azure_network_metadata.json.ipv4.ipAddress }}"

        - name:                        "SAP OS configuration playbook: - Convert ips to list"
          ansible.builtin.set_fact:
            ipadd:                     "{{ azure_network_metadata.json | json_query('interface[*].ipv4.ipAddress[*].privateIpAddress') | flatten(levels=1) | default([]) | list }}"
          tags:
            - always

        # we do not need to add the same assertion for subnet_cidr_client as it is
        # calculated for specific deployment scenarios.
        - name:                        "SAP OS configuration playbook: - Set the subnet_cidr_client fact"
          ansible.builtin.set_fact:
            subnet_cidr_client:        "{{ subnet_cidr_client | default(azure_network_metadata.json.interface[0].ipv4.subnet[0].address + '/' + azure_network_metadata.json.interface[0].ipv4.subnet[0].prefix) }}"
          when:
            - platform == 'HANA'
            - database_scale_out
            - not database_high_availability
          tags:
            - always

        # add assertion to validate if ipadd is not empty and has at least one ip address
        - name:                        "SAP OS configuration playbook: - Assert if IP Address is not empty"
          ansible.builtin.assert:
            that:
              - ipadd is defined
              - ipadd | type_debug != 'NoneType'
              - ipadd | length > 0
          tags:
            - always

        # The variable ipaddr only has the values of the IP addresses of the this
        # host in the play. This causes the IP addresses to repeat in the hosts file.
        # Since ipadd is already set as a fact, we can use it directly in the
        # hosts file. We do not need to set ipaddr to ipadd.
        # vars:
        #   ipaddr:                    "{{ ipadd }}"
        - name:                        "SAP OS configuration playbook: - Create hosts file"
          ansible.builtin.include_role:
            name:                      roles-sap-os/2.4-hosts-file
          tags:
            - 2.4-hosts-file

        - name:                        "SAP OS configuration playbook: - Ensure the repositories are registered"
          ansible.builtin.include_role:
            name:                      roles-os/1.3-repository
          tags:
            - 1.3-repository

        - name:                        "SAP OS configuration playbook: - Configure accounts"
          ansible.builtin.include_role:
            name:                      roles-os/1.11-accounts
          tags:
            - 1.11-accounts

        - name:                        "SAP OS configuration playbook: - Ensure the packages are registered"
          ansible.builtin.include_role:
            name:                      roles-os/1.4-packages
          tags:
            - 1.4-packages

        - name:                        "SAP OS configuration playbook: - Ensure the High Availability packages are registered"
          when:
            - scs_high_availability or database_high_availability
            - node_tier in ['scs', 'ers', 'hana', 'db2']
          ansible.builtin.include_role:
            name:                      roles-os/1.4-packages
          tags:
            - 1.4-packages
          vars:
            tier:                      ha

        - name:                        "SAP OS configuration playbook: - Ensure the packages required for SYBASE are registered"
          when:
            - platform == 'SYBASE'
          ansible.builtin.include_role:
            name:                      roles-os/1.4-packages
          tags:
            - 1.4-packages
          vars:
            tier:                      sybase

        - name:                        "SAP OS configuration playbook: - Configure volume groups, logical volumes and file systems"
          ansible.builtin.include_role:
            name:                      roles-os/1.5-disk-setup
          when:                        node_tier not in ["oracle-multi-sid", "oracle-asm"]
          tags:
            - 1.5-disk-setup

        - name:                        "SAP OS configuration playbook: - Configure volume groups, logical volumes and file systems"
          ansible.builtin.include_role:
            name:                      roles-os/1.5.1.1-disk-setup-asm-sap
          when:
            - node_tier == "oracle-asm"
          tags:
            - 1.5.1.1-disk-setup-asm-sap

        - name:                        "SAP OS configuration playbook: - Configure the disks for Oracle Multi SID"
          ansible.builtin.include_role:
            name:                      roles-os/1.5.2-disk-setup-ora-multi-sid
          when:                        node_tier == "oracle-multi-sid"
          tags:
            - 1.5.2-disk-setup-ora-multi-sid

        - name:                        "SAP OS configuration playbook: - Configure the kernel parameters"
          ansible.builtin.include_role:
            name:                      roles-os/1.9-kernelparameters
          tags:
            - 1.9-kernelparameters

        - name:                        "SAP OS configuration playbook: - Create SAP users/groups"
          ansible.builtin.include_role:
            name:                      roles-sap-os/2.5-sap-users
          tags:
            - 2.5-sap-users

        - name:                        "SAP OS configuration playbook: - Ensure the services are configured"
          ansible.builtin.include_role:
            name:                      roles-os/1.16-services
          tags:
            - 1.16-services

        - name:                        "SAP OS configuration playbook: - Ensure the High Availability services are configured"
          when:
            - scs_high_availability or database_high_availability
            - node_tier in ['scs', 'ers', 'hana', 'db2']
          ansible.builtin.include_role:
            name:                      roles-os/1.16-services
          tags:
            - 1.16-services
          vars:
            tier:                      ha

        - name:                        "SAP OS configuration playbook: - Configurations according to SAP Notes"
          ansible.builtin.include_role:
            name:                      roles-sap-os/2.10-sap-notes
          tags:
            - 2.10-sap-notes

        - name:                        "SAP OS configuration playbook: - configure exports"
          ansible.builtin.include_role:
            name:                      roles-sap-os/2.3-sap-exports
          tags:
            - 2.3-sap-exports

        - name:                        "SAP OS configuration playbook: - Mount the file systems"
          ansible.builtin.include_role:
            name:                      roles-sap-os/2.6-sap-mounts
          tags:
            - 2.6-sap-mounts

        - name:                        "SAP OS configuration playbook: - directory permissions"
          ansible.builtin.include_role:
            name:                      roles-sap-os/2.2-sapPermissions
          tags:
            - 2.2-sapPermissions

      when:
        - ansible_os_family != "Windows"

    - name:                            "SAP OS configuration - Windows based systems"
      block:
        - name:                        "SAP OS configuration playbook: - Calculating the domain value from {{ domain_name }}"
          ansible.builtin.set_fact:
            domain:                    "{{ domain_name | split('.') | first }}"
            cacheable:                 true
          when:
            - domain_name is defined
            - domain_name | type_debug != 'NoneType'
            - domain_name | trim | length > 1
            - domain is not defined

        - name:                        'SAP OS Configuration playbook: - calculate domain account'
          ansible.builtin.set_fact:
            sql_svc_account_name:      '{% if hostvars.localhost.sqlsvc_account is defined %}{{ hostvars.localhost.sqlsvc_account }}{% else %}{{ win_sql_svc_account }}{% endif %}'
            cacheable:                 true
          when:
            - hostvars.localhost.sqlsvc_account is defined or win_sql_svc_account is defined
            - sql_svc_account_name is not defined

        - name:                        "SAP OS configuration playbook: - Set sapos tier fact"
          ansible.builtin.set_fact:
            tier:                      sapos                                     # Actions for HANA DB Serve
          tags:
            - always

        - name:                                'SAP OS configuration playbook: - Calculating the domain service account names'
          ansible.builtin.set_fact:
            domain_sqlsvc_account:            '{{ sql_svc_account_name }}@{{ domain_name }}'
          when:
            - domain_name is defined
            - domain_sqlsvc_account is not defined

        - name:                        "SAP OS configuration playbook: - Add local groups and Permissions"
          ansible.builtin.include_role:
            name:                      roles-sap-os/windows/2.5-sap-users
          vars:
            winadm_password:           "{{ hostvars.localhost.winadm_password }}"
            domain_service_password:   "{{ hostvars.localhost.adsvc_password }}"
            domain_service_account:    "{{ hostvars.localhost.adsvc_account }}"

        - name:                        "SAP OS configuration playbook: - Sharing Data Folder"
          ansible.builtin.include_role:
            name:                      roles-sap-os/windows/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 }}"
            sql_svc_account:           "{{ domain_sqlsvc_account }}"

        - name:                        "SAP OS configuration playbook: - Mounting Shared Folder"
          ansible.builtin.include_role:
            name:                      roles-sap-os/windows/2.6-sap-mounts
          vars:
            domain_user_password:      "{{ hostvars.localhost.winadm_password }}"

      when: ansible_os_family == "Windows"

# /*----------------------------------------------------------------------------8
# |                                                                            |
# |     Logging for performing SAP specific OS configuration tasks             |
# |                                                                            |
# +------------------------------------4--------------------------------------*/

    - name:                            "SAP OS configuration playbook: - Create sap-os-install-done flag"
      delegate_to:                     localhost
      become:                          false
      ansible.builtin.file:
        path:                          "{{ _workspace_directory }}/.progress/sap-os-configuration-done"
        state:                         touch
        mode:                          0755

...
# /*----------------------------------------------------------------------------8
# |                                    END                                      |
# +------------------------------------4--------------------------------------*/
