---
- hosts: localhost
  gather_facts: yes  # Required for ansible_date_time
  tasks:

  - name: NEGATIVE test -> Create file system named {{ auto_prefix }}fs under a pool that does not exist
    infini_fs:
      name: "{{ auto_prefix }}fs"
      size: 1GB
      pool: "{{ auto_prefix }}pool_missing"
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"
    register: result
    failed_when: "'pool_missing' not in result.msg"
    when: not ansible_check_mode

  - name: POSITIVE test -> Create pool {{ auto_prefix }}pool
    infini_pool:
      name: "{{ auto_prefix }}pool"
      size: 1TB
      vsize: 1TB
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Stat pool {{ auto_prefix }}pool
    infini_pool:
      name: "{{ auto_prefix }}pool"
      state: stat
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Create file system named {{ auto_prefix }}fs under pool {{ auto_prefix }}pool
    infini_fs:
      name: "{{ auto_prefix }}fs"
      size: 1GB
      pool: "{{ auto_prefix }}pool"
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Stat file system named {{ auto_prefix }}fs under pool {{ auto_prefix }}pool
    infini_fs:
      name: "{{ auto_prefix }}fs"
      pool: "{{ auto_prefix }}pool"
      state: stat
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Export file system {{ auto_prefix }}fs
    infini_export:
      name: "/{{ auto_prefix }}export"
      filesystem: "{{ auto_prefix }}fs"
      client_list:
        - client: "*"
          access: "RO"
          no_root_squash: True
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Stat file system export {{ auto_prefix }}export
    infini_export:
      name: "/{{ auto_prefix }}export"
      filesystem: "{{ auto_prefix }}fs"
      state: stat
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: NEGATIVE test -> Export file system {{ auto_prefix }}fs that does not exist
    infini_export:
      name: "/{{ auto_prefix }}export_missing"
      filesystem: "{{ auto_prefix }}fs_missing"
      client_list:
        - client: "*"
          access: "RO"
          no_root_squash: True
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"
    register: result
    failed_when: "not result.msg | regex_search('File system.*not found')"
    when: not ansible_check_mode

  - name: POSITIVE test -> Create export client for export /{{ auto_prefix }}export
    infini_export_client:
      export: "/{{ auto_prefix }}export"
      client: "20.20.20.20"
      state: present
      access_mode: "RO"
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  # TODO - stat export client

  - name: NEGATIVE test -> Create export client for export that does not exist
    infini_export_client:
      export: "/{{ auto_prefix }}export_missing"
      client: 20.20.20.20
      state: present
      access_mode: "RO"
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"
    register: result
    failed_when: "not result.msg | regex_search('Export.*not found')"
    when: not ansible_check_mode

  - name: NEGATIVE test -> Create volume {{ auto_prefix }}vol_in_pool_missing under pool that does not exist
    infini_vol:
      name: "{{ auto_prefix }}vol_in_pool_missing"
      size: 1GB
      pool: "{{ auto_prefix }}pool_missing"
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"
    register: result
    failed_when: "'Pool not found' not in result.msg"
    # failed_when: "'pool_missing' not in result.msg"
    when: not ansible_check_mode

  - name: POSITIVE test -> Create thin volume {{ auto_prefix }}vol under pool {{ auto_prefix }}pool
    infini_vol:
      name: "{{ auto_prefix }}vol"
      size: 1GB
      pool: "{{ auto_prefix }}pool"
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Create thick volume {{ auto_prefix }}vol_thick under pool {{ auto_prefix }}pool
    infini_vol:
      name: "{{ auto_prefix }}vol_thick"
      size: 1GB
      pool: "{{ auto_prefix }}pool"
      thin_provision: false
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Stat volume {{ auto_prefix }}vol under pool {{ auto_prefix }}pool
    infini_vol:
      name: "{{ auto_prefix }}vol"
      pool: "{{ auto_prefix }}pool"
      state: stat
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Create snapshot {{ auto_prefix }}vol_snap from volume {{ auto_prefix }}vol
    infini_vol:
      name: "{{ auto_prefix }}vol_snap"
      state: present
      volume_type: snapshot
      parent_volume_name: "{{ auto_prefix }}vol"
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: DEBUG test -> Find the current date-time (WARNING - Time marks when the playbook gathered facts)
    debug:
      var=ansible_date_time.iso8601_micro

  - name: POSITIVE test -> Create and lock for 2 minutes snapshot {{ auto_prefix }}vol_snap_locked from volume {{ auto_prefix }}vol
    infini_vol:
      name: "{{ auto_prefix }}vol_snap_locked"
      state: present
      volume_type: snapshot
      parent_volume_name: "{{ auto_prefix }}vol"
      snapshot_lock_expires_at: "{{ ansible_date_time.iso8601_micro | to_datetime(fmt) | delta_time(minutes=2) }}"
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"
    vars:
      fmt: "%Y-%m-%dT%H:%M:%S.%fZ"

  - name: POSITIVE test -> Extend lock to 3 minutes for {{ auto_prefix }}vol_snap_locked without refresh
    infini_vol:
      name: "{{ auto_prefix }}vol_snap_locked"
      state: present
      volume_type: snapshot
      parent_volume_name: "{{ auto_prefix }}vol"
      snapshot_lock_expires_at: "{{ ansible_date_time.iso8601_micro | to_datetime(fmt) | delta_time(minutes=3) }}"
      snapshot_lock_only: true
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"
    vars:
      fmt: "%Y-%m-%dT%H:%M:%S.%fZ"

  - name: NEGATIVE test -> Attempt to extend lock without refresh on a snapshot that does not exist.
    infini_vol:
      name: "{{ auto_prefix }}vol_snap_locked_missing"
      state: present
      volume_type: snapshot
      parent_volume_name: "{{ auto_prefix }}vol"
      snapshot_lock_expires_at: "{{ ansible_date_time.iso8601_micro | to_datetime(fmt) | delta_time(minutes=3) }}"
      snapshot_lock_only: true
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"
    register: result
    failed_when: "not result.msg | regex_search('Snapshot does not exist. Cannot comply')"
    vars:
      fmt: "%Y-%m-%dT%H:%M:%S.%fZ"

  - name: NEGATIVE test -> Attempt to create snapshot locked for 31 days, 31 days exceeds 30 day maximum lock time enforced by infini_vol module (not api)
    infini_vol:
      name: "{{ auto_prefix }}vol_snap_locked_too_long"
      state: present
      volume_type: snapshot
      parent_volume_name: "{{ auto_prefix }}vol"
      snapshot_lock_expires_at: "{{ ansible_date_time.iso8601_micro | to_datetime(fmt) | delta_time(days=31) }}"
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"
    register: result
    failed_when: "not result.msg | regex_search('snapshot_lock_expires_at exceeds.*days in the future')"
    vars:
      fmt: "%Y-%m-%dT%H:%M:%S.%fZ"

  - name: NEGATIVE test -> Attempt to remove locked snapshot {{ auto_prefix }}vol_snap_locked
    infini_vol:
      name: "{{ auto_prefix }}vol_snap_locked"
      state: absent
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"
    register: result
    failed_when: "'Cannot delete snapshot. Locked' not in result.msg"

  - name: POSITIVE test -> Wait for lock on {{ auto_prefix }}vol_snap_locked to expire
    pause:
      seconds: 181
      prompt: Waiting for {{ auto_prefix }}vol_snap_locked to expire

  - name: POSITIVE test -> Remove snapshot {{ auto_prefix }}vol_snap_locked with expired lock
    infini_vol:
      name: "{{ auto_prefix }}vol_snap_locked"
      state: absent
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Create host {{ auto_prefix }}host
    infini_host:
      name: "{{ auto_prefix }}host"
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  # Second host used for testing infini_cluster
  - name: POSITIVE test -> Create host {{ auto_prefix }}host2
    infini_host:
      name: "{{ auto_prefix }}host2"
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Stat host {{ auto_prefix }}host
    infini_host:
      name: "{{ auto_prefix }}host"
      state: stat
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Add one wwns port to {{ auto_prefix }}host
    infini_port:
      host: PSUS_ANSIBLE_host
      state: present
      wwns:
        - "21:00:00:24:ff:78:69:e4"
      # iqns: []
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Add a second wwn port plus two iscsi ports to {{ auto_prefix }}host
    infini_port:
      host: PSUS_ANSIBLE_host
      state: present
      wwns:
        - "21:00:00:24:ff:78:69:e5"
      iqns:
        - "iqn.1998-01.com.vmware:5d2f90f6-1987-c06c-4d2f-246e9602d5e0-aaaaaaaa"
        - "iqn.1998-01.com.vmware:5d2f90f6-1987-c06c-4d2f-246e9602d5e0-bbbbbbbb"
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Stat ports on {{ auto_prefix }}host
    infini_port:
      host: PSUS_ANSIBLE_host
      state: stat
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Stat host {{ auto_prefix }}host after ports added
    infini_host:
      name: "{{ auto_prefix }}host"
      state: stat
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: NEGATIVE test -> Map volume {{ auto_prefix }}vol to host that does not exist
    infini_map:
      host: "{{ auto_prefix }}host_missing"
      volume: "{{ auto_prefix }}vol"
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"
    register: result
    failed_when: "not result.msg | regex_search('Host.*not found')"
    when: not ansible_check_mode

  - name: POSITIVE test -> Map volume {{ auto_prefix }}vol to host {{ auto_prefix }}host
    infini_map:
      host: "{{ auto_prefix }}host"
      volume: "{{ auto_prefix }}vol"
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Stat map of volume {{ auto_prefix }}vol to host {{ auto_prefix }}host
    infini_map:
      host: "{{ auto_prefix }}host"
      volume: "{{ auto_prefix }}vol"
      state: stat
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Remove mapping of volume {{ auto_prefix }}vol from host {{ auto_prefix }}host
    infini_map:
      host: "{{auto_prefix }}host"
      volume: "{{auto_prefix }}vol"
      state: absent
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Map volume {{ auto_prefix }}vol to host {{ auto_prefix }}host using lun 0
    infini_map:
      host: "{{ auto_prefix }}host"
      volume: "{{ auto_prefix }}vol"
      lun: 0
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Stat map of volume {{ auto_prefix }}vol to host {{ auto_prefix }}host using lun 0
    infini_map:
      host: "{{ auto_prefix }}host"
      volume: "{{ auto_prefix }}vol"
      state: stat
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"
    register: check_lun
    tags:
      - dev

  - name: ASSERT test -> Check lun 0 set
    assert:
      that:
        - check_lun.volume_lun == 0
    tags:
      - dev

  - name: POSITIVE test -> Create user {{ auto_prefix }}pool_admin_user with pool_admin role managing pool {{ auto_prefix }}pool
    infini_user:
      user_name: "{{ auto_prefix }}pool_admin_user"
      user_email: "{{ auto_prefix }}pool_admin_user@example.com"
      user_password: "secret1"
      user_role: "pool_admin"
      user_enabled: "true"
      user_pool: "{{ auto_prefix }}pool"
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Disable user {{ auto_prefix }}pool_admin_user
    infini_user:
      user_name: "{{ auto_prefix }}pool_admin_user"
      user_email: "{{ auto_prefix }}pool_admin_user@example.com"
      user_password: "secret1"
      user_role: "pool_admin"
      user_enabled: "false"
      user_pool: "{{ auto_prefix }}pool"
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Stat user {{ auto_prefix }}pool_admin_user
    infini_user:
      user_name: "{{ auto_prefix }}pool_admin_user"
      state: stat
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Reset password for user {{ auto_prefix }}pool_admin_user
    infini_user:
      user_name: "{{ auto_prefix }}pool_admin_user"
      user_password: "secret_new"
      state: reset_password
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Create user {{ auto_prefix }}admin_user with admin role
    infini_user:
      user_name: "{{ auto_prefix }}admin_user"
      user_email: "{{ auto_prefix }}admin_user@example.com"
      user_password: "secret2"
      user_role: "admin"
      user_enabled: "true"
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Create user {{ auto_prefix }}read_only_user with read_only role
    infini_user:
      user_name: "{{ auto_prefix }}read_only_user"
      user_email: "{{ auto_prefix }}read_only_user@example.com"
      user_password: "secret3"
      user_role: "read_only"
      user_enabled: "true"
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Create cluster {{ auto_prefix }}cluster with two hosts
    infini_cluster:
      name: "{{ auto_prefix }}cluster"
      cluster_hosts:
        - host_name: "{{ auto_prefix }}host"
          host_cluster_state: present
        - host_name: "{{ auto_prefix }}host2"
          host_cluster_state: present
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Remove {{ auto_prefix }}host from cluster {{ auto_prefix }}cluster. Leave {{ auto_prefix }}host2.
    infini_cluster:
      name: "{{ auto_prefix }}cluster"
      cluster_hosts:
        - host_name: "{{ auto_prefix }}host"
          host_cluster_state: absent
        - host_name: "{{ auto_prefix }}host2"
          host_cluster_state: present
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: POSITIVE test -> Re-add {{ auto_prefix }}host to cluster {{ auto_prefix }}cluster. Remove {{ auto_prefix }}host2.
    infini_cluster:
      name: "{{ auto_prefix }}cluster"
      cluster_hosts:
        - host_name: "{{ auto_prefix }}host"
          host_cluster_state: present
        - host_name: "{{ auto_prefix }}host2"
          host_cluster_state: absent
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: IDEMPOTENT test -> Re-add {{ auto_prefix }}host to cluster {{ auto_prefix }}cluster again. Remove {{ auto_prefix }}host2 again.
    infini_cluster:
      name: "{{ auto_prefix }}cluster"
      cluster_hosts:
        - host_name: "{{ auto_prefix }}host"
          host_cluster_state: present
        - host_name: "{{ auto_prefix }}host2"
          host_cluster_state: absent
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"

  - name: NEGATIVE test -> Attempt to add {{ auto_prefix }}host to cluster {{ auto_prefix }}cluster with missing host_cluster_state key:value
    infini_cluster:
      name: "{{ auto_prefix }}cluster"
      cluster_hosts:
        - host_name: "{{ auto_prefix }}host"
          # host_cluster_state: present
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"
    register: result
    failed_when: "'require host_name and host_cluster_state' not in result.msg"

  - name: NEGATIVE test -> Attempt to add {{ auto_prefix }}host to cluster {{ auto_prefix }}cluster with an unsupported key:value
    infini_cluster:
      name: "{{ auto_prefix }}cluster"
      cluster_hosts:
        - host_name: "{{ auto_prefix }}host"
          host_cluster_state: present
          host_unknown_key: unknown_value
      state: present
      user: "{{ user }}"
      password: "{{ password }}"
      system: "{{ system }}"
    register: result
    failed_when: "'require host_name and host_cluster_state' not in  result.msg"
