---
# name/path
- name: Stat the LUKS device, if encrypted
  stat:
    path: "{{ storage_test_volume._device }}"
    follow: true
  register: storage_test_luks_dev
  when: storage_test_volume.encryption

- name: Ensure cryptsetup is present
  package:
    name: cryptsetup
    state: present
    use: "{{ (__storage_is_ostree | d(false)) |
             ternary('ansible.posix.rhel_rpm_ostree', omit) }}"

- name: Collect LUKS info for this volume
  command: cryptsetup luksDump {{ storage_test_volume._raw_device }}
  register: luks_dump
  when: storage_test_volume.encryption and _storage_test_volume_present
  changed_when: false

- name: Verify the presence/absence of the LUKS device node
  assert:
    that: _storage_test_volume_present | ternary(
      storage_test_luks_dev.stat.exists and storage_test_luks_dev.stat.isblk,
      not storage_test_luks_dev.stat.exists)
    msg: >-
      Incorrect device node presence for volume {{ storage_test_volume.name }}
  when: storage_test_volume.encryption

- name: Verify that the raw device is the same as the device if not encrypted
  assert:
    that: __dev_ne_raw == (storage_test_volume.encryption | bool)
    msg: >-
      Encryption not managed correctly for volume
      {{ storage_test_volume.name }}:
      {{ __dev_ne_raw }} {{ storage_test_volume.encryption | bool }}
  vars:
    __dev_ne_raw: "{{
      (storage_test_volume._device != storage_test_volume._raw_device) |
      bool }}"
  when: _storage_test_volume_present

- name: Make sure we got info about the LUKS volume if encrypted
  assert:
    that: storage_test_volume._device in storage_test_blkinfo.info
    msg: Failed to gather info about volume '{{ storage_test_volume.name }}'
  when: _storage_test_volume_present and storage_test_volume.encryption

- name: Verify the LUKS volume's device type if encrypted
  assert:
    that: storage_test_blkinfo.info[storage_test_volume._device].type == 'crypt'
  when: _storage_test_volume_present and storage_test_volume.encryption

- name: Check LUKS version
  assert:
    that: luks_dump.stdout is search(__pattern, multiline=True)
    msg: Wrong LUKS version for volume {{ storage_test_volume.name }}
  vars:
    __ver: "{{ storage_test_volume.encryption_luks_version |
      replace('luks', '') }}"
    __pattern: "^Version:\\s+{{ __ver }}$"
  when:
    - _storage_test_volume_present
    - storage_test_volume.encryption
    - storage_test_volume.encryption_luks_version

- name: Check LUKS key size
  assert:
    that: luks_dump.stdout is search(__pattern, multiline=True)
    msg: Wrong key size for volume {{ storage_test_volume.name }}
  vars:
    __pattern: >-
      ^MK bits:\s+{{ storage_test_volume.encryption_key_size }}$
  when:
    - _storage_test_volume_present
    - storage_test_volume.encryption
    - storage_test_volume.encryption_key_size

- name: Check LUKS cipher
  assert:
    that: luks_dump.stdout is search(__pattern, multiline=True)
    msg: Wrong cipher for volume {{ storage_test_volume.name }}
  vars:
    __cipher: "{{ storage_test_volume.encryption_cipher.split('-')[1:] |
      join('-') }}"
    __pattern: "^Cipher mode:\\s+{{ __cipher }}$"
  when:
    - _storage_test_volume_present
    - storage_test_volume.encryption
    - storage_test_volume.encryption_cipher

- name: Set test variables
  set_fact:
    _storage_test_expected_crypttab_entries: "{{
      (storage_test_volume.encryption and _storage_test_volume_present) |
      ternary(1, 0) }}"
    _storage_test_crypttab_entries: "{{ storage_test_crypttab.stdout_lines |
      map('regex_search', '^' + storage_test_volume._device |
          basename + ' .*$') |
      select('string') | list }}"
    _storage_test_expected_crypttab_key_file: "{{
      storage_test_volume.encryption_key or '-' }}"

- name: Check for /etc/crypttab entry
  assert:
    that: _storage_test_crypttab_entries | length ==
      _storage_test_expected_crypttab_entries | int
    msg: >-
      Incorrect number of crypttab entries found for volume
      {{ storage_test_volume.name }}

- name: Validate the format of the crypttab entry
  assert:
    that: _storage_test_crypttab_entries[0].split() | length >= 3
    msg: >-
      Incorrectly formatted crypttab line for volume
      {{ storage_test_volume.name }}
  when: _storage_test_expected_crypttab_entries | int == 1

- name: Check backing device of crypttab entry
  assert:
    that: _storage_test_crypttab_entries[0].split()[1] ==
      storage_test_volume._raw_device
    msg: >-
      Incorrect backing device in crypttab entry for volume
      {{ storage_test_volume.name }}
  when: _storage_test_expected_crypttab_entries | int == 1

- name: Check key file of crypttab entry
  assert:
    that: _storage_test_crypttab_entries[0].split()[2] ==
      _storage_test_expected_crypttab_key_file
    msg: >-
      Incorrect key file in crypttab entry for volume
      {{ storage_test_volume.name }}
  when: _storage_test_expected_crypttab_entries | int == 1

- name: Clear test variables
  set_fact:
    _storage_test_expected_crypttab_entries: null
    _storage_test_crypttab_entries: null
    _storage_test_expected_crypttab_key_file: null
