---
- name: Test LUKS pool
  hosts: localhost
  become: true
  vars:
    luks_version: 'luks2'
    mount_location: '/opt/test1'
    mount_location_2: '/opt/test2'
    testfile: "{{ mount_location }}/quux"
    testfile_location_2: "{{ mount_location_2 }}/quux"
    volume_size: '5g'
    __luks_cipher: "{{ (__luks_cipher_env == '') |
      ternary('aes-xts-plain64', __luks_cipher_env) }}"
    __luks_cipher_env: "{{ lookup('env', 'SYSTEM_ROLES_LUKS_CIPHER') }}"
  tags:
    - tests::lvm

  tasks:
    - name: Enable FIPS mode
      when:
        - lookup("env", "SYSTEM_ROLES_TEST_FIPS") == "true"
        - ansible_facts["os_family"] == "RedHat"
        - ansible_facts["distribution_major_version"] | int > 7
      block:
        - name: Enable FIPS mode
          command: fips-mode-setup --enable
          changed_when: false

        - name: Reboot
          reboot:
            test_command: fips-mode-setup --check

    - name: Enable FIPS mode
      when:
        - lookup("env", "SYSTEM_ROLES_TEST_FIPS") == "true"
        - ansible_facts["os_family"] == "RedHat"
        - ansible_facts["distribution_major_version"] | int == 7
      block:
        - name: Ensure dracut-fips
          package:
            name: dracut-fips
            state: present
            use: "{{ (__storage_is_ostree | d(false)) |
                     ternary('ansible.posix.rhel_rpm_ostree', omit) }}"

        - name: Configure boot for FIPS
          changed_when: false
          shell: |
            set -euxo pipefail
            mv -v /boot/initramfs-$(uname -r).img{,.bak}
            dracut
            kernel=$(grubby --default-kernel)
            grubby --update-kernel=$kernel --args=fips=1

        - name: Reboot
          reboot:
            test_command: grep 1 /proc/sys/crypto/fips_enabled

    - name: Run the role
      include_role:
        name: linux-system-roles.storage

    - name: Mark tasks to be skipped
      set_fact:
        storage_skip_checks:
          - blivet_available
          - service_facts

    - name: Get unused disks
      include_tasks: get_unused_disk.yml
      vars:
        min_size: "{{ volume_size }}"
        max_return: 1

    ##
    ## LVM Pool
    ##

    - name: Test for correct handling of new encrypted pool w/ no key
      include_tasks: verify-role-failed.yml
      vars:
        __storage_failed_regex: encrypted pool.*missing key
        __storage_failed_msg: >-
          Unexpected behavior w/ encrypted pool w/ no key
        __storage_failed_params:
          storage_pools:
            - name: foo
              type: lvm
              disks: "{{ unused_disks }}"
              encryption: true
              volumes:
                - name: test1
                  mount_point: "{{ mount_location }}"
                  size: 4g


    - name: Mark tasks to be skipped
      set_fact:
        storage_skip_checks:
          - blivet_available
          - "{{ (lookup('env',
                        'SYSTEM_ROLES_REMOVE_CLOUD_INIT') in ['', 'false']) |
                ternary('packages_installed', '') }}"
          - service_facts
    - debug:
        msg: "{{ storage_skip_checks }}"

    - name: shell check
      shell:
        lsblk
      register: shell_output
    - debug:
        msg: "{{ shell_output }}"
    

    - name: Test key file handling
      block:
        - name: Create a key file
          tempfile:
            prefix: storage_test
            suffix: lukskey
          register: storage_test_key_file
          changed_when: false

        - name: Write the key into the key file
          copy:
            dest: "{{ storage_test_key_file.path }}"
            content: veryveryveryveryverysecureindeed
            mode: "0600"
          changed_when: false

        - name: Create an encrypted lvm pool using a key file
          include_role:
            name: linux-system-roles.storage
          vars:
            storage_pools:
              - name: foo
                type: lvm
                disks: "{{ unused_disks }}"
                encryption: true
                encryption_key: "{{ storage_test_key_file.path }}"
                encryption_luks_version: "{{ luks_version }}"
                encryption_key_size: 512
                volumes:
                  - name: test2
                    mount_point: "{{ mount_location }}"
                    size: 4g
        - name: shell check
          shell:
            lsblk
          register: shell_output
        - debug:
            msg: "{{ shell_output }}"

        - name: Verify role results
          include_tasks: verify-role-results.yml

      always:
        - name: Remove the key file
          file:
            path: "{{ storage_test_key_file.path }}"
            state: absent
          changed_when: false

    - name: Create test file
      import_tasks: create-test-file.yml



    - name: Remove the encryption layer
      include_role:
        name: linux-system-roles.storage
      vars:
        storage_safe_mode: false
        storage_pools:
          - name: foo
            type: lvm
            disks: "{{ unused_disks }}"
            encryption: false
            encryption_password: yabbadabbadoo
            volumes:
              - name: test1
                mount_point: "{{ mount_location }}"
                size: 4g
    - name: output
      shell: lsblk
      register: shell_output
    - debug:
        msg: "{{ shell_output }}"

    - name: Verify role results
      include_tasks: verify-role-results.yml



    - name: output
      shell: lsblk
      register: shell_output
    - debug:
        msg: "{{ shell_output }}"

    - name: Create test file
      import_tasks: create-test-file.yml

    - name: Add encryption to the pool
      include_role:
        name: linux-system-roles.storage
      vars:
        storage_safe_mode: false
        storage_pools:
          - name: foo
            type: lvm
            disks: "{{ unused_disks }}"
            encryption: true
            encryption_password: yabbadabbadoo
            encryption_luks_version: "{{ luks_version }}"
            encryption_key_size: 256
            encryption_cipher: "{{ __luks_cipher }}"
            volumes:
              - name: test6
                mount_point: "{{ mount_location }}"
                size: 4g

    - name: output
      shell: lsblk
      register: shell_output
    - debug:
        msg: "{{ shell_output }}"


    - name: Verify role results
      include_tasks: verify-role-results.yml



    - name: Create test file
      import_tasks: create-test-file.yml

    - name: Change the mountpoint, leaving encryption in place
      include_role:
        name: linux-system-roles.storage
      vars:
        storage_pools:
          - name: foo
            type: lvm
            disks: "{{ unused_disks }}"
            volumes:
              - name: test7
                mount_point: "{{ mount_location_2 }}"

    - name: output
      shell: lsblk
      register: shell_output

    - debug:
        msg: "{{ shell_output }}"


    - name: Assert to implicitly preserve encryption on existing pool
      assert:
        that: blivet_output.pools[0].encryption
        msg: Failed to implicitly preserve encryption on existing pool.

    - name: Verify data preservation
      import_tasks: verify-data-preservation.yml
      vars:
        testfile: "{{ testfile_location_2 }}"

    - name: Verify role results
      include_tasks: verify-role-results.yml

    - name: Clean up
      include_role:
        name: linux-system-roles.storage
      vars:
        storage_volumes:
          - name: foo
            type: disk
            disks: "{{ unused_disks }}"
            state: absent

    - name: Verify role results
      include_tasks: verify-role-results.yml
