# SPDX-License-Identifier: MIT
---
- name: Verify edition
  vars:
    __mssql_conf_path: /var/opt/mssql/mssql.conf
  when: __verify_mssql_edition is defined
  block:
    - name: Check if the errorlog file exists and its location
      shell: |
        set -euo pipefail
        errorlog="$(grep '^errorlogfile' {{ __mssql_conf_path }} \
        2>&1 | sed 's\errorlogfile : \\')" || :
        if [ -f "${errorlog}" ]; then
          echo "${errorlog}"
        elif [ -f /var/opt/mssql/log/errorlog ]; then
          echo "/var/opt/mssql/log/errorlog"
        else
          echo ""
        fi
      changed_when: false
      register: __mssql_errorlog

    - name: Check if the set edition matches the existing edition
      shell: |
        errorlog_edition="$(grep -oi '{{ __verify_mssql_edition }} edition' \
        {{ __mssql_errorlog.stdout }})"
        if [ -z "${errorlog_edition}" ]; then
          echo false
        else
          echo true
        fi
      register: __mssql_edition_matches
      changed_when: false

    - name: Verify if the edition matches
      assert:
        that: __mssql_edition_matches.stdout | bool

- name: Verify the setting {{ item.key }}
  with_dict:
    ipaddress: "{{ __verify_mssql_ip_address }}"
    tcpport: "{{ __verify_mssql_tcp_port }}"
    defaultdatadir: "{{ __verify_mssql_datadir }}"
    defaultlogdir: "{{ __verify_mssql_logdir }}"
    enabled: "{{ __verify_mssql_agent_is_enabled }}"
  when: item.value is defined
  include_tasks: mssql_conf_verify.yml
  vars:
    __mssql_conf_setting: "{{ item.key }}"
    __mssql_conf_value: "{{ item.value }}"

- name: Verify mssql_datadir permissions and ownership
  when: __verify_mssql_datadir_mode is defined
  block:
    - name: Get stat of mssql_datadir
      stat:
        path: "{{ __verify_mssql_datadir }}"
      register: __mssql_datadir_stat

    - name: Assert that mssql_datadir has proper permissions and ownership
      assert:
        that:
          - __mssql_datadir_stat.stat.mode == __verify_mssql_datadir_mode
          - __mssql_datadir_stat.stat.gr_name == 'mssql'
          - __mssql_datadir_stat.stat.pw_name == 'mssql'

- name: Verify mssql_logdir permissions and ownership
  when: __verify_mssql_logdir_mode is defined
  block:
    - name: Get stat of mssql_logdir
      stat:
        path: "{{ __verify_mssql_logdir }}"
      register: __mssql_logdir_stat

    - name: Assert that mssql_logdir has proper permissions and ownership
      assert:
        that:
          - __mssql_logdir_stat.stat.mode == __verify_mssql_logdir_mode
          - __mssql_logdir_stat.stat.gr_name == 'mssql'
          - __mssql_logdir_stat.stat.pw_name == 'mssql'

- name: Verify password
  when: __verify_mssql_password is defined
  block:
    - name: Prepare MSSQL and facts for logging in
      vars:
        mssql_password: "{{ __verify_mssql_password }}"
      include_role:
        name: linux-system-roles.mssql
        tasks_from: verify_password
        public: true

    - name: Wait for mssql-server to prepare for client connections
      wait_for:
        path: /var/opt/mssql/log/errorlog
        search_regex: SQL Server is now ready for client connections
        delay: 1

    - name: Check if the set password matches the existing password
      command: "{{ __mssql_sqlcmd_login_cmd }} -Q 'SELECT @@VERSION'"
      changed_when: false
      register: __mssql_test_psw_query
      until: >-
        "TCP Provider: Error code 0x102" not in __mssql_test_psw_query.stdout
        and
        "TCP Provider: Error code 0x102" not in __mssql_test_psw_query.stderr
        and
        "TCP Provider: Error code 0x2749" not in __mssql_test_psw_query.stdout
        and
        "TCP Provider: Error code 0x2749" not in __mssql_test_psw_query.stderr
        and
        "TCP Provider: Timeout error [258]" not in __mssql_test_psw_query.stdout
        and
        "TCP Provider: Timeout error [258]" not in __mssql_test_psw_query.stderr
      retries: 5
      delay: 10

    - name: Set the mssql_password variable to default null
      set_fact:
        mssql_password: null

- name: Verify the package {{ __mssql_server_fts_packages }}
  include_tasks: verify_package.yml
  vars:
    __mssql_verify_package_name: "{{ __mssql_server_fts_packages }}"
    __mssql_verify_package_installed: "{{ __verify_mssql_fts_is_installed }}"
  when: __verify_mssql_fts_is_installed is defined

- name: Verify the package {{ __mssql_powershell_packages }}
  include_tasks: verify_package.yml
  vars:
    __mssql_verify_package_name: "{{ __mssql_powershell_packages }}"
    __mssql_verify_package_installed: >-
      {{ __verify_mssql_powershell_is_installed }}
  when: __verify_mssql_powershell_is_installed is defined

- name: Verify that MSSQL is tuned for FUA
  when: __verify_mssql_is_tuned_for_fua is defined
  block:
    - name: Get the value of the traceflag setting
      shell: grep '^traceflag' {{ __mssql_conf_path }} || true
      changed_when: false
      register: __mssql_conf_get_traceflag

    - name: Verify that the traceflag setting is set to 3979
      assert:
        that: "'3979' in __mssql_conf_get_traceflag.stdout"
      when: __verify_mssql_is_tuned_for_fua | bool

    - name: Verify that the traceflag setting is not set to 3979
      assert:
        that: "'3979' not in __mssql_conf_get_traceflag.stdout"
      when: not __verify_mssql_is_tuned_for_fua | bool

    # alternatewritethrough must be false according to MS docs
    - name: Verify that the alternatewritethrough setting is false
      include_tasks: mssql_conf_verify.yml
      vars:
        __mssql_conf_setting: alternatewritethrough
        __mssql_conf_value: false

    - name: Verify the writethrough setting
      include_tasks: mssql_conf_verify.yml
      vars:
        __mssql_conf_setting: writethrough
        __mssql_conf_value: >-
          {{ true if __verify_mssql_is_tuned_for_fua else false }}

- name: Verify that MSSQL configuration for TSL encryption
  when: __verify_mssql_is_tls_encrypted is defined
  block:
    - name: Verify the tlscert setting
      include_tasks: mssql_conf_verify.yml
      vars:
        __mssql_conf_setting: tlscert
        __mssql_tls_cert: >-
          {{ mssql_tls_cert if mssql_tls_cert is not none else '' }}
        __mssql_conf_value: >-
          {{ '/etc/pki/tls/certs/' ~ __mssql_tls_cert | basename
          if __verify_mssql_is_tls_encrypted
          else '' }}

    - name: Verify the tlskey setting
      include_tasks: mssql_conf_verify.yml
      vars:
        __mssql_conf_setting: tlskey
        __mssql_tls_private_key: >-
          {{ mssql_tls_private_key if mssql_tls_private_key is not none
          else '' }}
        __mssql_conf_value: >-
          {{ '/etc/pki/tls/private/' ~ __mssql_tls_private_key | basename
          if __verify_mssql_is_tls_encrypted
          else '' }}

    - name: Verify the tlsprotocols setting
      include_tasks: mssql_conf_verify.yml
      vars:
        __mssql_conf_setting: tlsprotocols
        __mssql_conf_value: >-
          {{ mssql_tls_version | string if
          __verify_mssql_is_tls_encrypted else '' }}

    - name: Verify the forceencryption setting
      include_tasks: mssql_conf_verify.yml
      vars:
        __mssql_conf_setting: forceencryption
        __mssql_conf_value: >-
          {{ true if __verify_mssql_is_tls_encrypted else false }}

- name: Verify configuration for confined application
  when: __verify_mssql_is_confined is defined
  vars:
    __mssql_verify_package_name: "{{ __mssql_server_selinux_packages }}"
    __mssql_verify_package_installed: "{{ __verify_mssql_is_confined }}"
  include_tasks: verify_package.yml
