---
# yamllint disable rule:line-length
- name: Test host to host tunnel with certificate
  hosts: all
  vars_files:
    - './vars/main.yml'
  vars:
    __vpn_num_hosts: 2
  tasks:
    - name: Set up test environment
      include_tasks: tasks/setup_test.yml

    - name: Reset __tunnel_hosts
      set_fact:
        __tunnel_hosts: {}

    # sets __tunnel_hosts - the hosts element in each tunnel
    - name: Fixup hosts
      include_tasks: tasks/fixup_hosts.yml
      loop: "{{ vpn_connections }}"
      loop_control:
        loop_var: tunnel
        index_var: tunnel_idx

    # need extra task file to iterate over hosts per tunnel
    - name: Add cert options to check
      set_fact:
        __new_vpn_connections: "{{ __new_vpn_connections | d([]) + [item | combine(fixed_item)] | list }}"
      loop: "{{ vpn_connections }}"
      loop_control:
        index_var: loop_idx
      vars:
        fixed_item:
          auth_method: cert
          auto: start
          name: "{{ 'tunnel%d' | format(loop_idx) }}"
          hosts: "{{ item.hosts | combine(__tunnel_hosts[loop_idx]) }}"

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

    - name: Save certname for main host
      set_fact:
        __vpn_main_certname: "{{ vpn_connections[0]['hosts'][__vpn_main_hostname]['cert_name'] }}"

    - 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_main_hostname) or
        item.content | b64decode is not
        search('right=host0' + (idx + 1) | string + '.local') or
        item.content | b64decode is not
        search('rightid=%fromcert') or
        item.content | b64decode is not
        search('ikev2=insist') or
        item.content | b64decode is not
        search('auto=start') or
        item.content | b64decode is not
        search('leftrsasigkey=%cert') or
        item.content | b64decode is not
        search('rightrsasigkey=%cert') or
        item.content | b64decode is not
        search('leftcert=' + __vpn_main_certname)
      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_main_hostname + ' @host0' +
        (idx + 1) | string + '\.local : RSA \"' + __vpn_main_certname + '\"',
        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 .secrets files

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

    - name: Check for ansible_managed, fingerprint in generated files
      include_tasks: tasks/check_header.yml
      loop: "{{ __vpn_register_conf.results + __vpn_register_secrets.results }}"
      loop_control:
        loop_var: __file_content
      vars:
        __fingerprint: "system_role:vpn"

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