---
- name: Test host to host tunnel with custom PSK
  hosts: all
  tags:
    - tests::no_serialization
  vars_files:
    - './vars/main.yml'
  vars:
    __vpn_num_hosts: 2
    __vpn_leftid: leftid_for_testing
    __vpn_rightid: rightid_for_testing
    __vpn_shared_key: shared_key_for_testing
    __vpn_ike: ike_string_for_testing
    __vpn_esp: esp_string_for_testing
    __vpn_ikelifetime: 15h
    __vpn_salifetime: 16h
    __vpn_type: tunnel_type_for_testing
    __vpn_retransmit_timeout: 10s
    __vpn_dpddelay: 30s
    __vpn_dpdtimeout: 31s
    __vpn_dpdaction: restart
    __vpn_leftupdown: leftupdown --option=value
    __vpn_leftupdown_expected: '"leftupdown --option=value"'
    vpn_ensure_openssl: false
  tasks:
    - name: Set up test environment
      include_tasks: tasks/setup_test.yml

    - name: Add extra options to check
      set_fact:
        __new_vpn_connections: "{{ __new_vpn_connections | d([]) + [new_tunnel] | list }}"
      loop: "{{ vpn_connections }}"
      vars:
        __tunnel_params:
          auto: start
          shared_key_content: "{{ __vpn_shared_key }}"
          ike: "{{ __vpn_ike }}"
          esp: "{{ __vpn_esp }}"
          ikelifetime: "{{ __vpn_ikelifetime }}"
          salifetime: "{{ __vpn_salifetime }}"
          type: "{{ __vpn_type }}"
          retransmit_timeout: "{{ __vpn_retransmit_timeout }}"
          dpddelay: "{{ __vpn_dpddelay }}"
          dpdtimeout: "{{ __vpn_dpdtimeout }}"
          dpdaction: "{{ __vpn_dpdaction }}"
          leftupdown: "{{ __vpn_leftupdown }}"
        new_hosts:
          mainhost.local: "{{ __dict }}"
          host01.local: "{{ __dict }}"
          host02.local: "{{ __dict }}"
        new_tunnel: "{{ item | combine(__tunnel_params) | combine({'hosts': new_hosts}) }}"
        __dict:
          leftid: "{{ __vpn_leftid }}"
          rightid: "{{ __vpn_rightid }}"

    - name: Reset vpn_connections
      set_fact:
        vpn_connections: "{{ __new_vpn_connections }}"

    - name: Use vpn role
      include_role:
        name: linux-system-roles.vpn
        public: true

    - name: Assert file existence
      include_tasks: tasks/assert_conf_secrets_files_exist.yml

    - name: Reset success flag
      set_fact:
        __vpn_success: true

    - name: Get and store conf files
      slurp:
        src: "/etc/ipsec.d/{{ inventory_hostname }}-to-{{ item }}.conf"
      register: __vpn_register_conf
      loop: "{{ groups['testing'] }}"

    - name: Check that conf file contains correct information
      set_fact:
        __vpn_success: false
      when: >-
        item.content | b64decode is not
        search('left=' + __vpn_main_hostname) or
        item.content | b64decode is not
        search('leftid=@' + __vpn_leftid) or
        item.content | b64decode is not
        search('right=host0' + (idx + 1) | string + '.local') or
        item.content | b64decode is not
        search('rightid=@' + __vpn_rightid) or
        item.content | b64decode is not
        search('ikev2=insist') or
        item.content | b64decode is not
        search('authby=secret') or
        item.content | b64decode is not
        search('auto=start') or
        item.content | b64decode is not
        search('ike=' + __vpn_ike) or
        item.content | b64decode is not
        search('esp=' + __vpn_esp) or
        item.content | b64decode is not
        search('ikelifetime=' + __vpn_ikelifetime) or
        item.content | b64decode is not
        search('salifetime=' + __vpn_salifetime) or
        item.content | b64decode is not
        search('type=' + __vpn_type) or
        item.content | b64decode is not
        search('retransmit-timeout=' + __vpn_retransmit_timeout) or
        item.content | b64decode is not
        search('dpddelay=' + __vpn_dpddelay) or
        item.content | b64decode is not
        search('dpdtimeout=' + __vpn_dpdtimeout) or
        item.content | b64decode is not
        search('dpdaction=' + __vpn_dpdaction) or
        item.content | b64decode is not
        search('leftupdown=' + __vpn_leftupdown_expected)
      loop: '{{ __vpn_register_conf.results }}'
      loop_control:
        index_var: idx

    - name: Assert success for conf files
      assert:
        that: __vpn_success | d(false)
        msg: Found errors in .conf files

    - name: Get and store secrets files
      slurp:
        src: "/etc/ipsec.d/{{ inventory_hostname }}-to-{{ item }}.secrets"
      register: __vpn_register_secrets
      loop: "{{ groups['testing'] }}"

    - name: Check that secrets file contains correct information
      set_fact:
        __vpn_success: false
      when: >-
        item.content | b64decode |
        regex_search('^@' + __vpn_leftid + ' @' + __vpn_rightid +
        ' : PSK "' + __vpn_shared_key + '"',
        multiline=True) | d() | length == 0
      loop: '{{ __vpn_register_secrets.results }}'
      loop_control:
        index_var: idx

    - name: Assert success for secrets files
      assert:
        that: __vpn_success | d(false)
        msg: Found errors in .conf files

    - name: Check the firewall and the selinux port status
      include_tasks: tasks/check_firewall_selinux.yml

    - name: Cleanup
      include_tasks: tasks/cleanup.yml
      tags:
        - tests::cleanup
