# SPDX-License-Identifier: MIT
# Example test inventory:
# all:
#   hosts:
#     managed_host1:
#       ansible_host: <ip_address1>
#       mssql_ha_replica_type: primary
#     managed_host2:
#       ansible_host: <ip_address2>
#       mssql_ha_replica_type: synchronous
#     managed_host3:
#       ansible_host: <ip_address3>
#       mssql_ha_replica_type: witness
---
- name: Verify HA functionality with external clusters and templates
  hosts: all
  tags:
    # this test doesn't work in container builds
    - tests::booted
  vars:
    mssql_debug: true
    mssql_accept_microsoft_odbc_driver_for_sql_server_eula: true
    mssql_accept_microsoft_cli_utilities_for_sql_server_eula: true
    mssql_accept_microsoft_sql_server_standard_eula: true
    mssql_password: "p@55w0rD"
    mssql_edition: Evaluation
    mssql_version: 2022
    mssql_manage_firewall: true
    __mssql_gather_facts_no_log: true
    mssql_manage_selinux: false
    mssql_run_selinux_confined: false
    mssql_ha_configure: true
    mssql_ha_endpoint_port: 5022
    mssql_ha_cert_name: ExampleCert
    mssql_ha_master_key_password: "p@55w0rD1"
    mssql_ha_private_key_password: "p@55w0rD2"
    mssql_ha_reset_cert: false
    mssql_ha_endpoint_name: Example_Endpoint
    mssql_ha_ag_name: ExampleAG
    mssql_ha_db_names:
      - ExampleDB1
      - ExampleDB2
    mssql_ha_ag_cluster_type: external
    mssql_ha_login: ExampleLogin
    mssql_ha_login_password: "p@55w0rD3"
    mssql_ha_virtual_ip: 192.168.124.222
    # ha_cluster doesn't support running against a single host
    mssql_manage_ha_cluster: "{{ ansible_play_hosts_all | length > 1 }}"
    ha_cluster_cluster_name: "{{ mssql_ha_ag_name }}"
    ha_cluster_hacluster_password: "p@55w0rD4"
    ha_cluster_sbd_enabled: true
    ha_cluster_cluster_properties:
      - attrs:
          - name: cluster-recheck-interval
            value: 2min
          - name: start-failure-is-fatal
            value: true
          - name: stonith-enabled
            value: true
          - name: stonith-watchdog-timeout
            value: 10
    ha_cluster_resource_primitives:
      - id: ag_cluster
        agent: ocf:mssql:ag
        instance_attrs:
          - attrs:
              - name: ag_name
                value: "{{ mssql_ha_ag_name }}"
        meta_attrs:
          - attrs:
              - name: failure-timeout
                value: 60s
      - id: virtualip
        agent: ocf:heartbeat:IPaddr2
        instance_attrs:
          - attrs:
              - name: ip
                value: "{{ mssql_ha_virtual_ip }}"
        operations:
          - action: monitor
            attrs:
              - name: interval
                value: 30s
    ha_cluster_resource_clones:
      - resource_id: ag_cluster
        promotable: true
        meta_attrs:
          - attrs:
              - name: notify
                value: true
    ha_cluster_constraints_colocation:
      - resource_leader:
          id: ag_cluster-clone
          role: Promoted
        resource_follower:
          id: virtualip
        options:
          - name: score
            value: INFINITY
    ha_cluster_constraints_order:
      - resource_first:
          id: ag_cluster-clone
          action: promote
        resource_then:
          id: virtualip
          action: start
  tasks:
    - name: Run test in a block to clean up in always
      block:
        - name: This test is applicable in multi-host scenario only
          meta: end_play
          when: ansible_play_hosts_all | length < 3

        - name: Load softdog module for stonith to have at least one watchdog
          command: modprobe softdog
          changed_when: true

        - name: Set facts to create test DBs on primary as a pre task
          set_fact:
            mssql_pre_input_sql_file:
              - create_ExampleDB1.sql
              - create_ExampleDB2.sql
          when: mssql_ha_replica_type == 'primary'

        - name: Set up test environment for the ha_cluster role
          include_role:
            name: fedora.linux_system_roles.ha_cluster
            tasks_from: test_setup.yml

        - name: Test is_contained functionality available on newers SQL version
          when: mssql_version is version('2022', '>=')
          block:
            - name: Run on all hosts to configure contained AG
              vars:
                mssql_ha_ag_is_contained: true
                mssql_ha_ag_reuse_system_db: false
              include_role:
                name: linux-system-roles.mssql
                public: true

            - name: Verify is_contained status
              when: __mssql_ha_is_primary | bool
              include_tasks: tasks/verify_contained.yml
              vars:
                __mssql_is_contained: 1

            - name: Clean up AG
              include_tasks: tasks/cleanup_ag.yml

            - name: Unset create_db facts
              set_fact:
                mssql_pre_input_sql_file: []

            - name: Run with contained=true reuse_system_db=true
              vars:
                mssql_ha_ag_is_contained: true
                mssql_ha_ag_reuse_system_db: true
              include_role:
                name: linux-system-roles.mssql
                public: true

            - name: Verify is_contained status
              when: __mssql_ha_is_primary | bool
              include_tasks: tasks/verify_contained.yml
              vars:
                __mssql_is_contained: 1

            - name: Clean up AG
              include_tasks: tasks/cleanup_ag.yml

        - name: Run with contained=false
          include_role:
            name: linux-system-roles.mssql
          vars:
            mssql_ha_ag_is_contained: false

        - name: Verify is_contained and reuse_system_db status
          include_tasks: tasks/verify_contained.yml
          when:
            - mssql_version is version('2022', '>=')
            - __mssql_ha_is_primary | bool
          vars:
            __mssql_is_contained: 0

        - name: Wait for the cluster to finish configuration
          command: crm_resource --wait
          changed_when: false
          when: mssql_manage_ha_cluster | bool
          register: __mssql_crm_resource_wait
          until: __mssql_crm_resource_wait is success

        - name: Get global pcs status
          command: pcs status
          register: __pcs_status
          changed_when: false

        - name: Print global psc status
          debug:
            var: __pcs_status.stdout
          run_once: true

        - name: Get pcs status for the virtualip resource
          command: pcs status resources virtualip
          register: __pcs_status_virtualip
          changed_when: false

        - name: Print pcs status for the virtualip resource
          debug:
            var: __pcs_status_virtualip.stdout
          run_once: true

        - name: Assert that virtualip is successfully started
          assert:
            that: "'Started' in __pcs_status_virtualip.stdout"

        - name: Move the virtualip resource
          command: >-
            pcs resource
            {% if (ansible_distribution in ['CentOS', 'RedHat']) and
            (ansible_distribution_major_version is version('9', '>=')) %}
            move-with-constraint
            {% else %}
            move
            {% endif %}
            virtualip
          register: __pcs_move
          run_once: true
          changed_when: true

        - name: Wait for the cluster to finish configuration
          command: crm_resource --wait
          changed_when: false
          when: mssql_manage_ha_cluster | bool
          register: __mssql_crm_resource_wait
          until: __mssql_crm_resource_wait is success

        - name: Get global pcs status
          command: pcs status resources
          register: __pcs_status
          changed_when: false

        - name: Print global psc status
          debug:
            var: __pcs_status.stdout
          run_once: true

        - name: Get pcs status for the virtualip resource
          command: pcs status resources virtualip
          register: __pcs_status_virtualip
          changed_when: false

        - name: Print pcs status for the virtualip resource
          debug:
            var: __pcs_status_virtualip.stdout
          run_once: true

        - name: Assert that virtualip is successfully started
          assert:
            that: "'Started' in __pcs_status_virtualip.stdout"

        - name: Clear constraints for the virtualip resource
          command: pcs resource clear virtualip
          changed_when: true
      always:
        - name: Clean up after the role invocation
          include_tasks: tasks/cleanup.yml
