---
- block:
  - name: Make sure we're not already using Docker swarm
    docker_swarm:
      state: absent
      force: true

  - name: Try to get docker_swarm_info when docker is not running in swarm mode
    docker_swarm_info:
    ignore_errors: yes
    register: output

  - name: assert failure when called when swarm is not in use or not run on mamager node
    assert:
      that:
         - 'output is failed'
         - 'output.msg == "Error running docker swarm module: must run on swarm manager node"'
         - 'output.can_talk_to_docker == true'
         - 'output.docker_swarm_active == false'
         - 'output.docker_swarm_manager == false'
         - 'output.swarm_unlock_key is not defined'

  - name: Create a Swarm cluster
    docker_swarm:
      state: present
      advertise_addr: "{{ansible_default_ipv4.address | default('127.0.0.1')}}"
    register: output

  - name: assert changed when create a new swarm cluster
    assert:
      that:
         - 'output is changed'
         - 'output.actions[0] | regex_search("New Swarm cluster created: ")'
         - 'output.swarm_facts.JoinTokens.Manager'
         - 'output.swarm_facts.JoinTokens.Worker'

  - name: Try to get docker_swarm_info when docker is running in swarm mode and as manager
    docker_swarm_info:
    register: output

  - name: assert creding docker swarm facts
    assert:
      that:
         - 'output.swarm_facts.JoinTokens.Manager'
         - 'output.swarm_facts.JoinTokens.Worker'
         - 'output.swarm_facts.ID'
         - 'output.can_talk_to_docker == true'
         - 'output.docker_swarm_active == true'
         - 'output.docker_swarm_manager == true'
         - 'output.swarm_unlock_key is not defined'

  - name: Try to get docker_swarm_info and list of nodes when docker is running in swarm mode and as manager
    docker_swarm_info:
      nodes: yes
    register: output

  - name: assert reding swarm facts with list of nodes option
    assert:
      that:
         - 'output.swarm_facts.JoinTokens.Manager'
         - 'output.swarm_facts.JoinTokens.Worker'
         - 'output.swarm_facts.ID'
         - 'output.nodes[0].ID is string'
         - 'output.can_talk_to_docker == true'
         - 'output.docker_swarm_active == true'
         - 'output.docker_swarm_manager == true'
         - 'output.swarm_unlock_key is not defined'

  - name: Get local docker node name
    set_fact:
      localnodename:  "{{ output.nodes[0].Hostname }}"


  - name: Try to get docker_swarm_info and verbose list of nodes when docker is running in swarm mode and as manager
    docker_swarm_info:
      nodes: yes
      verbose_output: yes
    register: output

  - name: assert reading swarm facts with list of nodes and versbose output options
    assert:
      that:
         - 'output.swarm_facts.JoinTokens.Manager'
         - 'output.swarm_facts.JoinTokens.Worker'
         - 'output.swarm_facts.ID'
         - 'output.nodes[0].ID is string'
         - 'output.nodes[0].CreatedAt'
         - 'output.can_talk_to_docker == true'
         - 'output.docker_swarm_active == true'
         - 'output.docker_swarm_manager == true'
         - 'output.swarm_unlock_key is not defined'

  - name: Try to get docker_swarm_info and list of nodes with filters providing existing node name
    docker_swarm_info:
      nodes: yes
      nodes_filters:
        name: "{{ localnodename }}"
    register: output

  - name: assert reading reading swarm facts and using node filter (random node name)
    assert:
      that:
         - 'output.swarm_facts.JoinTokens.Manager'
         - 'output.swarm_facts.JoinTokens.Worker'
         - 'output.swarm_facts.ID'
         - 'output.nodes | length == 1'
         - 'output.can_talk_to_docker == true'
         - 'output.docker_swarm_active == true'
         - 'output.docker_swarm_manager == true'
         - 'output.swarm_unlock_key is not defined'

  - name: Create random name
    set_fact:
      randomnodename: "{{ 'node-%0x' % ((2**32) | random) }}"

  - name: Try to get docker_swarm_info and list of nodes with filters providing non-existing random node name
    docker_swarm_info:
      nodes: yes
      nodes_filters:
        name: "{{ randomnodename }}"
    register: output

  - name: assert reading reading swarm facts and using node filter (random node name)
    assert:
      that:
         - 'output.swarm_facts.JoinTokens.Manager'
         - 'output.swarm_facts.JoinTokens.Worker'
         - 'output.swarm_facts.ID'
         - 'output.nodes | length == 0'
         - 'output.can_talk_to_docker == true'
         - 'output.docker_swarm_active == true'
         - 'output.docker_swarm_manager == true'
         - 'output.swarm_unlock_key is not defined'

  - name: Try to get docker_swarm_info and swarm_unlock_key on non a unlocked swarm
    docker_swarm_info:
      unlock_key: yes
    register: output
    ignore_errors: yes

  - name: assert reading swarm facts and non existing swarm unlock key
    assert:
      that:
        - 'output.swarm_unlock_key is none'
        - 'output.can_talk_to_docker == true'
        - 'output.docker_swarm_active == true'
        - 'output.docker_swarm_manager == true'
    when: docker_py_version is version('2.7.0', '>=')
  - assert:
      that:
        - output is failed
        - "('version is ' ~ docker_py_version ~ ' ') in output.msg"
        - "'Minimum version required is 2.7.0 ' in output.msg"
    when: docker_py_version is version('2.7.0', '<')

  - name: Update swarm cluster to be locked
    docker_swarm:
      state: present
      advertise_addr: "{{ansible_default_ipv4.address | default('127.0.0.1')}}"
      autolock_managers: true
    register: autolock_managers_update_output
    ignore_errors: yes

  - name: Try to get docker_swarm_info and swarm_unlock_key
    docker_swarm_info:
      unlock_key: yes
    register: output
    ignore_errors: yes

  - name: assert reading swarm facts and swarm unlock key
    assert:
      that:
        - 'output.swarm_unlock_key is string'
        - 'output.swarm_unlock_key == autolock_managers_update_output.swarm_facts.UnlockKey'
        - 'output.can_talk_to_docker == true'
        - 'output.docker_swarm_active == true'
        - 'output.docker_swarm_manager == true'
    when: docker_py_version is version('2.7.0', '>=')
  - assert:
      that:
        - output is failed
        - "('version is ' ~ docker_py_version ~ ' ') in output.msg"
        - "'Minimum version required is 2.7.0 ' in output.msg"
    when: docker_py_version is version('2.7.0', '<')

  always:
  - name: Cleanup
    docker_swarm:
      state: absent
      force: true
