---
- name: 'Deploy a VM in check-mode with template_id'
  one_vm:
    template_id: '{{ one_template_id }}'
  register: deployed_vm1
  check_mode: yes

- name: Check if deployment in check-mode with template_id returns 'changed'
  assert:
    that:
      - deployed_vm1 is changed
    msg: Check mode doesn't return as 'changed' when deploying in check-mode with specified template_id

- name: Deploy a VM in check-mode with template_name
  one_vm:
    template_name: '{{ one_template_name }}'
  register: deployed_vm2
  check_mode: yes

- name: Check if deployment in check-mode with template_name returns 'changed'
  assert:
    that:
      - deployed_vm2 is changed
    msg: Check mode doesn't return as 'changed' when deploying in check-mode with specified template_name

- name: Deploy a VM in check-mode with non-existent template_name
  one_vm:
    template_name: 'unknown'
  register: template_bad
  failed_when: not template_bad is failed

- name: Check if it fails if we try to access a non-existent VM in check-mode
  one_vm:
    instance_ids: non-existent-vm-{{ ansible_date_time.iso8601_basic_short }}
  register: vm_missing
  failed_when: not vm_missing is failed
  check_mode: yes

- name: Check if it fails if we try to access a non-existent VM
  one_vm:
    instance_ids: non-existent-vm-{{ ansible_date_time.iso8601_basic_short }}
  register: vm_missing
  failed_when: not vm_missing is failed

- block:
    - name: Deploy a VM with networks, memory and cpu
      one_vm:
        template_id: '{{ one_template_id }}'
        networks: '{{ one_networks_good }}'
        memory: '{{ one_memory }}'
        cpu: '{{ one_cpu }}'
      register: deployed_vm

    - name: Verify deploying of the VM
      assert:
        that:
          - deployed_vm is changed
          - deployed_vm.instances_ids|length == 1
          - deployed_vm.instances|length == 1
          - deployed_vm.instances[0].vm_id == deployed_vm.instances_ids[0]
          - deployed_vm.instances[0].networks|length == one_networks_good|length
          - deployed_vm.instances[0].memory == "4096 MB"
          - deployed_vm.instances[0].cpu == "{{ one_cpu }}"
          - deployed_vm.instances[0].state == "ACTIVE"
          - deployed_vm.instances[0].lcm_state == "RUNNING"

    - name: Delete a VM in check-mode
      one_vm:
        instance_ids: '{{ deployed_vm.instances[0].vm_id }}'
        state: absent
      register: delete_vm
      check_mode: yes

    - name: Check if delete in check-mode returns 'changed'
      assert:
        that: delete_vm is changed

    - name: Wait for the VM to become RUNNING
      one_vm:
        attributes:
          name: '{{ deployed_vm.instances[0].vm_name }}'
        state: running

  always:
    - name: Delete the VM
      one_vm:
        instance_ids:
          - '{{ deployed_vm.instances[0].vm_id }}'
        state: absent
        hard: yes
      register: delete_vm

- name: Check if deletion has done
  assert:
    that:
      - delete_vm is changed
      - delete_vm.instances_ids|length == 1
      - delete_vm.instances_ids[0] == deployed_vm.instances_ids[0]
    msg: 'Deletion has not done'

- name: Delete the VM again to test idempotence
  one_vm:
    instance_ids:
      - '{{ deployed_vm.instances[0].vm_id }}'
    state: absent
  register: delete_vm_idempotent

- name: Check if deletion is idempotent
  assert:
    that:
      - not delete_vm_idempotent is changed
    msg: 'Deletion is not idempotent'

- name: Delete a non-existent VM
  one_vm:
    instance_ids:
     - non-existent-vm-{{ ansible_date_time.iso8601_basic_short }}
    state: absent
  register: delete_non_existent_vm

- name: Check if deletion is not executed
  assert:
    that:
      - not delete_non_existent_vm is changed
    msg: 'Deletion is bad, task has deleted non existent VM'

- block:
    - name: Set the unique name of the VM
      set_fact:
        vm_unique_name: test-vm-name-{{ ansible_date_time.iso8601_basic_short }}

    - name: Try to deploy an unique VM with exact_count but without count_attributes and count_labels
      one_vm:
        template_id: '{{ one_template_id }}'
        attributes:
          name: '{{ vm_unique_name }}'
        exact_count: 1
      register: one_exact_count_without_count_attrs
      failed_when: not one_exact_count_without_count_attrs is failed

    - name: Deploy an unique VM in check mode
      one_vm:
        template_id: '{{ one_template_id }}'
        attributes:
          name: '{{ vm_unique_name }}'
        exact_count: 1
        count_attributes:
          name: '{{ vm_unique_name }}'
      register: unique_vm_check_mode
      check_mode: yes

    - name: Check if deployment in check-mode returns as 'changed'
      assert:
        that:
          - unique_vm_check_mode is changed
        msg: 'Deploying an unique VM, that does not exist, in check-mode should return as changed.'

    - name: Really deploy an unique VM
      one_vm:
        template_id: '{{ one_template_id }}'
        attributes:
          name: '{{ vm_unique_name }}'
        exact_count: 1
        count_attributes:
          name: '{{ vm_unique_name }}'
      register: unique_vm

    - name: Verify deploying with unique name
      assert:
        that:
          - unique_vm is changed
          - unique_vm.instances_ids|length == 1
          - unique_vm.instances|length == 1
          - unique_vm.instances[0].vm_name == "{{ vm_unique_name }}"
        msg: Deployment of the unique VM doesn't return as 'changed'

    - name: Deploy an unique VM again to check idempotence
      one_vm:
        template_id: '{{ one_template_id }}'
        attributes:
          name: '{{ vm_unique_name }}'
        exact_count: 1
        count_attributes:
          name: '{{ vm_unique_name }}'
      register: unique_vm_idempotent

    - name: Check idempotence of deployment with unique name
      assert:
        that:
          - not unique_vm_idempotent is changed
        msg: Deployment with unique name isn't idempotent

  always:
    - name: Delete the unique VM
      one_vm:
        instance_ids:
          - '{{ unique_vm.tagged_instances[0].vm_id }}'
        state: absent
        hard: yes

- name: Try to deploy a VM with incorrect networks
  one_vm:
    template_name: '{{ one_template_name }}'
    networks: '{{ one_networks_bad }}'
  register: vm_with_bad_networks
  failed_when: not vm_with_bad_networks is failed

- name: Try to deploy a VM with incorrect memory size
  one_vm:
    template_name: '{{ one_template_name }}'
    memory: '{{ one_incorrect_memory }}'
  register: vm_with_bad_memory_param
  failed_when: not vm_with_bad_memory_param is failed

- name: Try to deploy a VM with incorrect disk size
  one_vm:
    template_name: '{{ one_template_name }}'
    disk_size: '{{ one_incorrect_disk_size }}'
  register: vm_with_bad_disk_size_param
  failed_when: not vm_with_bad_disk_size_param is failed

- name: Try to deploy a VM, with disk size, whose template has more than one DISK
  one_vm:
    template_name: '{{ one_template_name_with_2_disks }}'
    disk_size: '{{ one_disk_size }}'
  register: vm_with_disk_size_and_more_disks
  failed_when: not vm_with_disk_size_and_more_disks is failed

- name: Try to deploy a VM with incorrect name's format
  one_vm:
    template_name: '{{ one_template_name }}'
    attributes:
      name: 'foo#Vm###'
  register: vm_with_bad_name
  failed_when: not vm_with_bad_name is failed

- name: Try to deploy a VM with incorrect name's format
  one_vm:
    template_name: '{{ one_template_name }}'
    attributes:
      name: '###'
  register: vm_with_bad_name
  failed_when: not vm_with_bad_name is failed

- block:
    - name: Deploy a VM and wait for it to become RUNNING
      one_vm:
        template_id: '{{ one_template_id }}'
      register: vm_register

    - name: Power-off the VM and wait for it to become POWEROFF
      one_vm:
        instance_ids:
          - '{{ vm_register.instances[0].vm_id }}'
        state: poweredoff
        hard: yes
      register: power_off_vm

    - name: Check if VM went down properly
      assert:
        that:
          - power_off_vm is changed
          - power_off_vm.instances|length == 1
          - power_off_vm.instances[0].state == "POWEROFF"
        msg: Power-off of the VM doesn't work

    - name: Power-off the VM again to check idempotence
      one_vm:
        instance_ids:
          - '{{ vm_register.instances[0].vm_id }}'
        state: poweredoff
      register: power_off_vm_idempotent

    - name: Check if power-off is idempotent
      assert:
        that:
          - not power_off_vm_idempotent is changed
        msg: Power-off of the VM is not idempotent

    - name: Run a VM again in check-mode
      one_vm:
        instance_ids:
          - '{{ vm_register.instances[0].vm_id }}'
        state: running
      register: run_vm_check_mode
      check_mode: yes

    - name: Check if running in check-mode returns as 'changed'
      assert:
        that:
          - run_vm_check_mode is changed

    - name: Run a VM and wait for it to become RUNNING
      one_vm:
        instance_ids:
          - '{{ vm_register.instances[0].vm_id }}'
        state: running
      register: run_vm

    - name: Check if VM is running again
      assert:
        that:
          - run_vm is changed
          - run_vm.instances_ids|length == 1
          - run_vm.instances_ids[0] == vm_register.instances[0].vm_id
          - run_vm.instances|length == 1
          - run_vm.instances[0].state == "ACTIVE"
          - run_vm.instances[0].lcm_state == "RUNNING"

    - name: Reboot the running VM
      one_vm:
        instance_ids:
          - '{{ vm_register.instances[0].vm_id }}'
        state: rebooted
      register: reboot_running_vm

    - name: Check if reboot returns as changed
      assert:
        that:
          - reboot_running_vm is changed
        msg: Reboot should be done anyway

    - name: Power-off the VM and wait for it to become POWEROFF
      one_vm:
        instance_ids:
          - '{{ vm_register.instances[0].vm_id }}'
        state: poweredoff
        hard: yes

    - name: Reboot the extinguished VM and wait for it to become RUNNING
      one_vm:
        instance_ids:
          - '{{ vm_register.instances[0].vm_id }}'
        state: rebooted
      register: reboot_extinguished_vm

    - name: Check if reboot started VM again
      assert:
        that:
          - reboot_extinguished_vm is changed
          - reboot_extinguished_vm.instances|length == 1
          - reboot_extinguished_vm.instances[0].state == "ACTIVE"
          - reboot_extinguished_vm.instances[0].lcm_state == "RUNNING"
        msg: Rebooting the extinguished VM should run it

  always:
    - name: Delete the VM
      one_vm:
        instance_ids:
          - '{{ vm_register.instances[0].vm_id }}'
        state: absent
        hard: yes

- block:
    - name: Deploy 2 VMs with attributes in check-mode
      one_vm:
        template_id: '{{ one_template_id }}'
        attributes:
          name: aero
          key: value
        count: 2
      register: deploy_vms_with_count_check_mode
      check_mode: yes

    - name: Check if deployment in check-mode returns as 'changed'
      assert:
        that:
          - deploy_vms_with_count_check_mode is changed

    - name: Deploy 2 VMs with attributes
      one_vm:
        template_id: '{{ one_template_id }}'
        attributes:
          name: aero
          key: value
        count: 2
      register: deploy_vms_with_count

    - name: Check if deployment in returns as 'changed'
      assert:
        that:
          - deploy_vms_with_count is changed
          - deploy_vms_with_count.instances_ids|length == 2
          - deploy_vms_with_count.instances|length == 2
          - deploy_vms_with_count.tagged_instances|length == 0
          - deploy_vms_with_count.instances[0].vm_name == "aero"
          - deploy_vms_with_count.instances[1].vm_name == "aero"

    - name: Deploy 2 VMs with attributes to check it is not idempotent
      one_vm:
        template_id: '{{ one_template_id }}'
        attributes:
          name: aero
          key: value
        count: 2
      register: deploy_vms_with_count_check_idempotence

    - name: Check if deployment with count is not idempotent
      assert:
        that:
          - deploy_vms_with_count_check_idempotence is changed
          - deploy_vms_with_count_check_idempotence.instances_ids|length == 2
          - deploy_vms_with_count_check_idempotence.instances|length == 2

  always:
    - name: Delete all VMs
      one_vm:
        instance_ids: '{{ deploy_vms_with_count.instances_ids | union(deploy_vms_with_count_check_idempotence.instances_ids) }}'
        state: absent
        hard: yes
      register: delete_all_vms

    - name: Verify deletion
      assert:
        that:
          - delete_all_vms is changed
          - delete_all_vms.instances_ids|length == 4
          - delete_all_vms.instances|length == 4
          - delete_all_vms.tagged_instances|length == 0

- block:
    - name: Set VMs indexed format name
      set_fact:
        vms_indexed_name: 'aero-##'

    - name: Terminate all VMs with name's format 'aero-##'
      one_vm:
        template_id: '{{ one_template_id }}'
        count_attributes:
          name: '{{ vms_indexed_name }}'
        hard: yes
        exact_count: 0

    - name: Terminate all VMs with name's format 'aero-##' again to check-idempotence
      one_vm:
        template_id: '{{ one_template_id }}'
        count_attributes:
          name: '{{ vms_indexed_name }}'
        hard: yes
        exact_count: 0

    - name: Terminate all VMs with name's format 'aero'
      one_vm:
        template_id: '{{ one_template_id }}'
        exact_count: 0
        count_attributes:
          name: aero
        hard: yes

    - name: Fetch all VMs with name's format 'aero-##'
      one_vm:
        attributes:
          name: '{{ vms_indexed_name }}'
      register: all_aero_vms
      failed_when: all_aero_vms.instances_ids|length > 0

    - name: Deploy exact 3 instances with name's format 'aero-##'
      one_vm:
        template_id: '{{ one_template_id }}'
        attributes:
          name: '{{ vms_indexed_name }}'
        exact_count: 3
        count_attributes:
          name: '{{ vms_indexed_name }}'
      register: vms_with_hash

    - name: Deploy exact 2 instances with name's format 'aero'
      one_vm:
        template_id: '{{ one_template_id }}'
        attributes:
          name: aero
        exact_count: 2
        count_attributes:
          name: aero
      register: vms_without_hash

    - name: Fetch all VMs with name's format 'aero-#'
      one_vm:
        attributes:
          name: aero-#
      register: all_aero_vms_with_hash

    - name: Check there are exactly 3 instances with name's format 'aero-#'
      assert:
        that:
          - not all_aero_vms_with_hash is changed
          - all_aero_vms_with_hash.instances|length == 3

    - name: Decrement count of 'aero-#' instances
      one_vm:
        template_id: '{{ one_template_id }}'
        exact_count: 2
        count_attributes:
          name: aero-#
      register: aero_vms_with_hash_decremented

    - name: Check if we terminated oldest one VM
      assert:
        that:
          - aero_vms_with_hash_decremented is changed
          - aero_vms_with_hash_decremented.instances_ids|length == 1
          - vms_with_hash.instances_ids|min == aero_vms_with_hash_decremented.instances_ids[0]

    - name: Deploy new one with name's format 'aero-#'
      one_vm:
        template_id: '{{ one_template_id }}'
        attributes:
          name: 'aero-#'
      register: new_vm_with_hash

    - name: Check if new VM has index 0
      assert:
        that:
          - new_vm_with_hash is changed
          - new_vm_with_hash.instances_ids|length == 1
          - new_vm_with_hash.instances|length == 1
          - new_vm_with_hash.tagged_instances|length == 0
          - new_vm_with_hash.instances[0].vm_name|regex_replace('(\d+)$','\1')|int == 0

  always:
    - name: Terminate all VMs with name's format 'aero-##'
      one_vm:
        template_id: '{{ one_template_id }}'
        count_attributes:
          name: '{{ vms_indexed_name }}'
        exact_count: 0
        hard: yes

    - name: Terminate all VMs with name's format 'aero'
      one_vm:
        template_id: '{{ one_template_id }}'
        count_attributes:
          name: aero
        exact_count: 0
        hard: yes

- block:
    - name: Try to create negative count of VMs
      one_vm:
        template_id: '{{ one_template_id }}'
        count: -3
      register: negative_count_of_vms
      failed_when: not negative_count_of_vms is failed

    - name: Verify the fail message
      assert:
        that:
          - negative_count_of_vms.msg == "`count` has to be grater than 0"

    - name: Try to use hard parameter for running state
      one_vm:
        instance_ids:
          - 123
          - 456
        hard: yes
        state: running
      register: hard_with_running
      failed_when: not hard_with_running is failed

    - name: Try to use count with count_attributes/count_labels
      one_vm:
        template_id: '{{ one_template_id }}'
        count: 2
        count_attributes:
          key: val
        count_labels:
          - foo
      register: use_count_with_count_attrs
      failed_when: not use_count_with_count_attrs is failed

    - name: Terminate all VMs with label 'foo'
      one_vm:
        template_id: '{{ one_template_id }}'
        count_labels:
          - foo
        exact_count: 0
        hard: yes

    - name: Deploy exact 3 VMs with label 'foo'
      one_vm:
        template_id: '{{ one_template_id }}'
        labels:
          - foo
        exact_count: 3
        count_labels:
          - foo
      register: vms_with_foo_label

    - name:
      assert:
        that:
          - vms_with_foo_label is changed
          - vms_with_foo_label.tagged_instances|length == 3
          - vms_with_foo_label.tagged_instances[0].labels|length == 1
          - vms_with_foo_label.tagged_instances[0].labels[0] == "foo"

    - name: Try to use ids with exact_count and check if it fails
      one_vm:
        instance_ids: '{{ vms_with_foo_label.instances_ids }}'
        exact_count: 2
      register: failed_ids_and_exact_count
      failed_when: not failed_ids_and_exact_count is failed

    - name: Set special label for a new instance
      set_fact:
        vm_spec_label: spec-label-{{ ansible_date_time.iso8601_basic_short }}

    - name: Add a new instance in the group of instances with label 'foo'
      one_vm:
        template_id: '{{ one_template_id }}'
        labels:
          - foo
          - '{{ vm_spec_label }}'
        exact_count: 4
        count_labels:
          - foo
      register: new_vm_with_label

    - name: Fetch all instances with special label
      one_vm:
        labels:
          - '{{ vm_spec_label }}'
      register: vm_with_special_label

    - name: Check there is only one VM with the special label
      assert:
        that:
          - not vm_with_special_label is changed
          - vm_with_special_label.instances_ids|length == 1
          - vm_with_special_label.instances_ids[0] == new_vm_with_label.instances_ids[0]

  always:
    - name: Fetch all VMs with label 'foo'
      one_vm:
        labels:
          - foo
      register: all_foo_instances

    - name: Terminate all VMs with label 'foo'
      one_vm:
        instance_ids: '{{ all_foo_instances.instances_ids }}'
        state: absent
        hard: yes
      when: all_foo_instances.instances_ids|length > 0

- block:
    - name: Fetch all VMs with 'foo_app' key
      one_vm:
        attributes:
          foo_app:
      register: foo_app_instances

    - name: Terminate all VMs with 'foo_app' key
      one_vm:
        instance_ids: '{{ foo_app_instances.instances_ids }}'
        state: absent
        hard: yes
      when: foo_app_instances.instances_ids|length > 0

    - name: Terminate all instances with name's format 'aeroXYZ-##' to test name parsing later
      one_vm:
        template_id: '{{ one_template_id }}'
        exact_count: 0
        count_attributes:
          name: 'aeroXYZ-##'
        hard: yes

    - name: Deploy 2 instances with attributes
      one_vm:
        template_id: '{{ one_template_id }}'
        attributes:
          name: 'aero-###'
          foo_app: foo
        count: 2

    - name: Deploy 2 instances with different value for attribute
      one_vm:
        template_id: '{{ one_template_id }}'
        attributes:
          name: 'aero-###'
          foo_app: bar
        count: 2

    - name: Get all instances with attribute's key
      one_vm:
        attributes:
          foo_app:
      register: all_foo_app_vms

    - name: Check there are 4 VMs with 'foo_app' key
      assert:
        that:
          - all_foo_app_vms.instances|length == 4

    - name: Decrement count of VMs with 'foo_app' key
      one_vm:
        template_id: '{{ one_template_id }}'
        exact_count: 2
        count_attributes:
          foo_app:
      register: foo_app_vms

      # instances list contains affected instances
      # tagged_instances list contains the remaining instances with the appropriate attributes
    - name: Check are there 2 elements in instances list and 2 elements in tagged_instances list
      assert:
        that:
          - foo_app_vms is changed
          - foo_app_vms.instances|length == 2
          - foo_app_vms.tagged_instances|length == 2

    - name: Fetch all instances with name's format 'aeroXYZ-##' to check parsing
      one_vm:
        attributes:
          name: 'aeroXYZ-##'
      register: check_there_are_no_vms
      failed_when: check_there_are_no_vms.instances_ids|length > 0

  always:
    - name: Fetch all VMs with 'foo_app' key
      one_vm:
        attributes:
          foo_app:
      register: foo_app_instances

    - name: Terminate all VMs with 'foo_app' key
      one_vm:
        instance_ids: '{{ foo_app_instances.instances_ids }}'
        state: absent
        hard: yes
      when: foo_app_instances.instances_ids|length > 0

- block:
    - name: Set labels list
      set_fact:
        labels_list:
           - bar1
           - bar2

    - name: Deploy an instance with name 'app1', attribute 'foo app' and labels 'bar1' and 'bar2'
      one_vm:
        template_id: '{{ one_template_id }}'
        attributes:
          name: app1
          foo: app
        labels: '{{ labels_list }}'
      register: instance_with_labels

    - name: Fetch the current instance
      one_vm:
        attributes:
          name: app1
          foo: app
        labels: '{{ labels_list }}'
      register: current_instance

    - name: Check that the instance is fetched
      assert:
        that: current_instance.instances|length == 1
        msg: There is no instance

    - name: Check that labels are set correctly
      assert:
        that: instance_with_labels.instances[0].labels|difference(labels_list)|length == 0
        msg: Labels are not correct

    - name: Check that name is correct
      assert:
        that: instance_with_labels.instances[0].vm_name == 'app1'
        msg: The instance name is incorrect

  always:
    - name: Terminate the instance
      one_vm:
        instance_ids: '{{ instance_with_labels.instances_ids }}'
        state: absent
        hard: yes

- name: Try to use letters for ids option
  one_vm:
    instance_ids:
      - asd
      - 123
    state: running
  register: ids_with_letters
  failed_when: not ids_with_letters is failed

- name: Try to use letters for ids option when terminate vms
  one_vm:
    instance_ids:
      - asd
      - 123
    state: absent
  register: ids_with_letters
  failed_when: ids_with_letters is failed

- name: Try to use restricted attributes when deploying
  one_vm:
    template_id: '{{ one_template_id }}'
    attributes:
      disk: 34 GB
      template: foo
  register: restricted_attributes
  failed_when: not restricted_attributes is failed

- name: Verify the fail message
  assert:
    that:
      - restricted_attributes.msg == "Restricted attribute `DISK` cannot be used when filtering VMs."

- block:
    - name: Deploy VM and set its mode
      one_vm:
        template_id: '{{ one_template_id }}'
        mode: 640
      register: deployed_vm

    - name: Check if mode is set correctly
      assert:
        that:
          - deployed_vm is changed
          - deployed_vm.instances|length == 1
          - deployed_vm.instances[0].mode == "640"

    - name: Set VM permissions to 660
      one_vm:
        instance_ids: '{{ deployed_vm.instances_ids }}'
        mode: 660
      register: deployed_vm

    - name: Check if mode is set correctly
      assert:
        that:
          - deployed_vm is changed
          - deployed_vm.instances|length == 1
          - deployed_vm.instances[0].mode == "660"

    - name: Set 660 permissions againt to check idempotence
      one_vm:
        instance_ids: '{{ deployed_vm.instances_ids[0] }}'
        mode: 660
      register: chmod_idempotent

    - name: Check if chmod is idempotent
      assert:
        that:
          - chmod_idempotent is not changed
        msg: 'Permissions changing is not idempotent'

    - name: Try to set permissions incorectly
      one_vm:
        instance_ids: '{{ deployed_vm.instances_ids[0] }}'
        mode: 8983
      register: chmod_failed
      failed_when: not chmod_failed is failed

    - name: Try to set permissions incorectly
      one_vm:
        instance_ids: '{{ deployed_vm.instances_ids[0] }}'
        mode: 64a
      register: chmod_failed
      failed_when: not chmod_failed is failed

    - name: Set 664 permissions
      one_vm:
        instance_ids: '{{ deployed_vm.instances_ids[0] }}'
        mode: 664
      register: vm_chmod

    - name: Verify permissions changing
      assert:
        that:
          - vm_chmod is changed
          - vm_chmod.instances|length == 1
          - vm_chmod.instances[0].mode == "664"
        msg: 'Permissions changing is failed'

    - name: Deploy 2 VMs with label 'test-mode' and mode 640
      one_vm:
        template_id: '{{ one_template_id }}'
        count_labels:
          - test-mode
        exact_count: 2
        mode: 640
      register: deployed_vm2

    - name: Verify VMs permissions
      assert:
        that:
          - deployed_vm2 is changed
          - deployed_vm2.instances|length == 2
          - deployed_vm2.instances[0].mode == "640"
          - deployed_vm2.instances[1].mode == "640"

    - name: Change permissions of first VM
      one_vm:
        instance_ids: '{{ deployed_vm2.instances_ids[0] }}'
        mode: 644
      register: chmod_vm1

    - name: Verify VM permissions
      assert:
        that:
          - chmod_vm1 is changed
          - chmod_vm1.instances|length == 1
          - chmod_vm1.instances[0].mode == "644"

    - name: Change permissions on both VMs
      one_vm:
        instance_ids: '{{ deployed_vm2.instances_ids }}'
        mode: 644
      register: deployed_vm2

    - name: Verify VMs permissions
      assert:
        that:
          - deployed_vm2 is changed
          - deployed_vm2.instances|length == 2
          - deployed_vm2.instances[0].mode == "644"
          - deployed_vm2.instances[1].mode == "644"

    - name: Change VMs permissions using the label
      one_vm:
        labels:
          - test-mode
        mode: 664
      register: label_chmod

    - name: Verify VMs permissions
      assert:
        that:
          - label_chmod is changed
          - label_chmod.instances|length == 2
          - label_chmod.instances[0].mode == "664"
          - label_chmod.instances[1].mode == "664"

    - name: Deploy 2 more VMs with label 'test-mode' and mode 640
      one_vm:
        template_id: '{{ one_template_id }}'
        count_labels:
          - test-mode
        exact_count: 4
        mode: 640
      register: deployed_vm4

    - name: Verify VMs permissions
      assert:
        that:
          - deployed_vm4 is changed
          - deployed_vm4.tagged_instances|length == 4
          - deployed_vm4.tagged_instances[0].mode == "640"
          - deployed_vm4.tagged_instances[1].mode == "640"
          - deployed_vm4.tagged_instances[2].mode == "640"
          - deployed_vm4.tagged_instances[3].mode == "640"

    - name: Terminate 2 VMs with label 'test-mode' and set mode 660 on remaining VMs
      one_vm:
        template_id: '{{ one_template_id }}'
        count_labels:
          - test-mode
        exact_count: 2
        mode: 660
      register: terminate_vm4

    - name: Verify VMs permissions
      assert:
        that:
          - terminate_vm4 is changed
          - terminate_vm4.instances|length == 2 # 2 removed
          - terminate_vm4.tagged_instances|length == 2 # 2 remaining with label test-mode
          - terminate_vm4.instances[0].mode == "640"
          - terminate_vm4.instances[1].mode == "640"
          - terminate_vm4.tagged_instances[0].mode == "660"
          - terminate_vm4.tagged_instances[1].mode == "660"

  always:
    - name: Delete VM
      one_vm:
        instance_ids: '{{ deployed_vm.instances_ids }}'
        state: absent
        hard: yes

    - name: Delete VMs
      one_vm:
        instance_ids: '{{ deployed_vm4.instances_ids }}'
        state: absent
        hard: yes
  tags: test-chmod

- block:
    - name: Deploy VM
      one_vm:
        template_id: '{{ one_template_id }}'
      register: deployed_vm

    - name: Change VM's group
      one_vm:
        instance_ids: '{{ deployed_vm.instances_ids }}'
        group_id: 1
      register: changed_group

    - name: Verify group changing
      assert:
        that:
          - deployed_vm is changed
          - changed_group is changed
          - deployed_vm.instances|length == 1
          - changed_group.instances|length == 1
          - changed_group.instances[0].owner_id == deployed_vm.instances[0].owner_id
          - changed_group.instances[0].group_id != deployed_vm.instances[0].group_id

    - name: Try to set non-existent group
      one_vm:
        instance_ids: '{{ deployed_vm.instances_ids }}'
        group_id: -999
      register: changed_group
      failed_when: changed_group is not failed

  always:
    - name: Delete VM
      one_vm:
        instance_ids: '{{ deployed_vm.instances_ids }}'
        state: absent
        hard: yes
  tags: test-chown

- name: Test images creation
  block:
    - name: Set fact image name
      set_fact:
        image_name: test-image-name-{{ ansible_date_time.iso8601_basic_short }}

    - name: Deploy VM
      one_vm:
        template_id: '{{ one_template_id }}'
        labels:
          - test-image
        attributes:
          name: test-vm-image
      register: vm_image

    - name: Try to use disk_saveas option with labels and attributes
      one_vm:
        labels:
          - test-image
        attributes:
          name: test-vm-image
        disk_saveas:
          name: '{{ image_name }}'
      register: save_disk_labels
      failed_when: not save_disk_labels is failed

    - name: Try to save disk in running state to check if it will fail
      one_vm:
        instance_ids: '{{ vm_image.instances_ids }}'
        disk_saveas:
          name: '{{ image_name }}'
      register: disk_save_as_running
      failed_when: not disk_save_as_running

    - name: Verify the fail message
      assert:
        that:
          - disk_save_as_running.msg == "'disksaveas' option can be used only when the VM is in 'POWEROFF' state"

    - name: Try to save disk without specified image name
      one_vm:
        instance_ids: '{{ vm_image.instances_ids }}'
        disk_saveas: {}
      register: disk_save_without_name
      failed_when: not disk_save_without_name is failed

    - name: Try to save disk of non-existent VM
      one_vm:
        attributes:
          name: test-vm-{{ ansible_date_time.iso8601_basic_short }}
        disk_saveas:
          name: '{{ image_name }}'
      register: disk_save_no_vm
      failed_when: not disk_save_no_vm is failed

    - name: Save disk of powered-off VM in check-mode
      one_vm:
        instance_ids: '{{ vm_image.instances_ids }}'
        state: poweredoff
        hard: yes
        disk_saveas:
          name: '{{ image_name }}'
      check_mode: yes
      register: vm_disk_saveas_check_mode

    - name: Check if disk saving in check-mode is returned as 'changed'
      assert:
        that:
          - vm_disk_saveas_check_mode is changed

    - name: Check that image doesn't exist
      one_image:
        name: '{{ image_name }}'
      failed_when: no

    - name: Save disk of powered-off VM
      one_vm:
        instance_ids: '{{ vm_image.instances_ids }}'
        state: poweredoff
        hard: yes
        disk_saveas:
          name: '{{ image_name }}'
      register: vm_disk_saveas

    - name: Check if disk saving is returned as 'changed'
      assert:
        that:
          - vm_disk_saveas is changed

    - name: Check if image is created
      one_image:
        name: '{{ image_name }}'

    - name: Try to save disk again with the same name
      one_vm:
        instance_ids: '{{ vm_image.instances_ids }}'
        disk_saveas:
          name: '{{ image_name }}'
      register: disk_save_as_fail
      failed_when: not disk_save_as_fail is failed

  always:
    - name: Delete the image
      one_image:
        name: '{{ image_name }}'
        state: absent

    - name: Delete the VM
      one_vm:
        instance_ids: '{{ vm_image.instances_ids }}'
        state: absent
        hard: yes
  tags: test-image
