diff --git a/tasks/main.yml b/tasks/main.yml index b9b81bc0..2060f3b9 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -32,50 +32,45 @@ - vpn_ensure_openssl | d(true) - not "/usr/bin/openssl" is exists - - name: Enforce default auth method as needed + - name: Ensure __vpn_connections_fixed is defined and empty set_fact: - vpn_connections: | - {% for tunnel in vpn_connections %} - {% set _ = tunnel.__setitem__( - "auth_method", tunnel.auth_method | d(vpn_auth_method) - ) %} - {% endfor %} - {{ vpn_connections }} + __vpn_connections_fixed: [] + - name: Add missing fields to tunnel items + set_fact: + __vpn_connections_fixed: "{{ __vpn_connections_fixed | + union([item | combine(fixed_item) | combine(_host_item)]) | list }}" + loop: "{{ vpn_connections }}" + vars: + fixed_item: + auth_method: "{{ item.auth_method | d(vpn_auth_method) }}" + opportunistic: "{{ item.opportunistic | d(vpn_opportunistic) }}" + _hosts: "{{ item.hosts if item.hosts | d({}) | length > 1 + else (item.hosts | combine(_host)) if item.hosts | d({}) | length == 1 + else {} }}" + _host_item: "{{ {'hosts': _hosts} if _hosts | length > 0 else {} }}" + _host: "{{ {inventory_hostname: ''} }}" + no_log: true + + # any tunnel definition that is not an opportunistic tunnel should have + # hosts defined and not be empty - name: Make sure that the hosts list is not empty vars: - # noqa jinja[spacing] - failure: >- - {% for tunnel in vpn_connections %} - {%- if not tunnel.opportunistic | d(vpn_opportunistic) -%} - {%- if not 'hosts' in tunnel or not tunnel.hosts -%} - True - {%- endif -%} - {%- endif -%} - {% endfor %} + count_not_opps: "{{ __vpn_connections_fixed | selectattr('opportunistic') | + list | length }}" + count_has_hosts: "{{ __vpn_connections_fixed | rejectattr('opportunistic') | + selectattr('hosts', 'defined') | selectattr('hosts') | list | length }}" fail: msg: list of hosts is empty for one or more tunnels - when: '"True" in failure' - - - name: Make sure there is at least one pair of hosts in each connection - set_fact: - vpn_connections: | - {% set new_vpn_connections = [] %} - {% for tunnel in vpn_connections %} - {% if not tunnel.opportunistic | d(vpn_opportunistic) %} - {% if tunnel.hosts | length == 1 %} - {% set _ = tunnel.hosts.update({inventory_hostname: null}) %} - {% endif %} - {% endif %} - {% set _ = new_vpn_connections.append(tunnel) %} - {% endfor %} - {{ new_vpn_connections }} + when: + - __vpn_connections_fixed | length > 0 + - count_not_opps == count_has_hosts - name: Ensure cert_names are populated when auth_method is cert vars: # noqa jinja[spacing] failure: >- - {% for tunnel in vpn_connections %} + {% for tunnel in __vpn_connections_fixed %} {% if tunnel.auth_method == 'cert' %} {% if tunnel.opportunistic | d(vpn_opportunistic) %} {% for host in ansible_play_hosts %} @@ -93,42 +88,24 @@ {% endfor %} {% endif %} {% endif %} + {% else %} + False {% endfor %} fail: msg: cert_name is missing or empty for one or more hosts in a tunnel when: '"True" in failure' - - name: Generate PSKs or use provided shared_key_content - no_log: true + - name: Reset __vpn_psks set_fact: - # noqa jinja[spacing] - __vpn_psks: | - {% set __vpn_psks = {} %} - {% for tunnel in vpn_connections %} - {% if not tunnel.opportunistic | d(vpn_opportunistic) %} - {% set __vpn_idx = loop.index0 %} - {% if tunnel.auth_method == 'psk' %} - {% set _ = __vpn_psks.__setitem__(__vpn_idx, {}) %} - {% for host1, host2 in tunnel.hosts.keys() | combinations(2) %} - {% if not host1 in __vpn_psks[__vpn_idx] %} - {% set _ = __vpn_psks[__vpn_idx].__setitem__(host1, {}) %} - {% endif %} - {% if not host2 in __vpn_psks[__vpn_idx] %} - {% set _ = __vpn_psks[__vpn_idx].__setitem__(host2, {}) %} - {% endif %} - {% if 'shared_key_content' in tunnel %} - {% set val = {'pre_shared_key':tunnel['shared_key_content']} %} - {% else %} - {% set psk = lookup('lines', 'openssl rand -base64 48') %} - {% set val = {'pre_shared_key':psk} %} - {%- endif -%} - {% set _ = __vpn_psks[__vpn_idx][host1].__setitem__(host2, val) %} - {% set _ = __vpn_psks[__vpn_idx][host2].__setitem__(host1, val) %} - {% endfor %} - {% endif %} - {% endif %} - {% endfor %} - {{ __vpn_psks }} + __vpn_psks: [] + + - name: Get PSKs for each tunnel + include_tasks: vpn_get_psks_for_tunnel.yml + loop: "{{ __vpn_connections_fixed }}" + loop_control: + loop_var: tunnel + index_var: tunnel_idx + no_log: true # The run_once host might not be the first one in hostvars - we do not have # a good way to know which host in hostvars was the run_once, and it might @@ -144,20 +121,10 @@ - name: Build host-to-host tunnels vars: - tunnels: | - {% set unique_tunnels = [] %} - {% for tunnel in vpn_connections %} - {% if not tunnel.opportunistic | d(vpn_opportunistic) %} - {% if inventory_hostname in tunnel.hosts %} - {% for node in tunnel.hosts %} - {% if node != inventory_hostname %} - {% set _ = unique_tunnels.append(node) %} - {% endif %} - {% endfor %} - {% endif %} - {% endif %} - {% endfor %} - {{ unique_tunnels | unique }} + tunnels: "{{ __vpn_connections_fixed | rejectattr('opportunistic') | + selectattr('hosts', 'contains', inventory_hostname) | map(attribute='hosts') | + map('dict2items') | flatten | map(attribute='key') | + flatten | reject('match', '^' ~ inventory_hostname ~ '$') | unique | list }}" block: - name: Create ipsec.conf files template: @@ -174,6 +141,7 @@ loop: "{{ tunnels }}" - name: Create ipsec.secrets files + no_log: true template: src: "{{ vpn_provider }}-host-to-host.secrets.j2" dest: "/etc/ipsec.d/{{ inventory_hostname }}-to-{{ item.item }}.secrets" @@ -186,7 +154,7 @@ - name: Build opportunistic configuration include_tasks: tasks/mesh_conf.yml when: conn.opportunistic | d(vpn_opportunistic) - loop: "{{ vpn_connections }}" + loop: "{{ __vpn_connections_fixed }}" loop_control: loop_var: conn no_log: true diff --git a/tasks/mesh_conf.yml b/tasks/mesh_conf.yml index 8db036eb..633cb7c7 100644 --- a/tasks/mesh_conf.yml +++ b/tasks/mesh_conf.yml @@ -1,66 +1,65 @@ --- -# yamllint disable rule:line-length -- name: Set current IP fact for each host - set_fact: - current_ip: "{{ ansible_default_ipv4.address | d(ansible_default_ipv6.address) }}" +- name: Set mesh configuration + vars: + conn_policies: "{{ conn.policies | selectattr('cidr', 'match', '^default$') | map(attribute='policy') | join(',') }}" + pol_default: "{{ vpn_default_policy if conn_policies | length == 0 else conn_policies }}" + block: + - name: Set current IP fact for each host + set_fact: + __vpn_current_ip: "{{ ansible_default_ipv4.address | d(ansible_default_ipv6.address) }}" -- name: Set IP with prefix register - shell: |- - set -euo pipefail - ip addr show | grep {{ current_ip }} | awk '{print $2}' - register: - ip_with_prefix_register - changed_when: false + - name: Set IP with prefix register + shell: |- + set -euo pipefail + ip addr show | grep {{ __vpn_current_ip }} | awk '{print $2}' + register: __vpn_ip_with_prefix_register + changed_when: false -- name: Set net CIDR fact - set_fact: - current_subnet: "{{ ip_with_prefix_register.stdout | vpn_ipaddr('subnet') }}" + - name: Set net CIDR fact + set_fact: + __vpn_current_subnet: "{{ __vpn_ip_with_prefix_register.stdout | vpn_ipaddr('subnet') }}" -- name: Set policies fact - set_fact: - policies: "{{ conn.policies | rejectattr('cidr', 'match', '^default$') | list }}" + - name: Set policies fact + set_fact: + __vpn_policies: "{{ conn.policies | rejectattr('cidr', 'match', '^default$') | list }}" -- name: Apply the default policy as needed - delegate_to: localhost - run_once: true - vars: - # noqa jinja[spacing] - pol_default: >- - {% set pol = conn.policies | selectattr('cidr', 'match', '^default$') | map(attribute='policy') | join(',') %} - {%- if pol | length == 0 -%}{{ vpn_default_policy }}{%- else -%}{{ pol }}{%- endif -%} - set_fact: - policies: | - {% for node in ansible_play_hosts %} - {% set node_in_pol = {'flag': false} %} - {% for policy in policies %} - {% if hostvars[node].current_ip | vpn_ipaddr(policy.cidr) | vpn_ipaddr('bool') %} - {% if node_in_pol.update({'flag': true}) %}{% endif %} - {% endif %} - {% endfor %} - {% if not node_in_pol.flag | bool %} - {% set new_pol = {} %} - {% set _ = new_pol.__setitem__('policy', pol_default) %} - {% set _ = new_pol.__setitem__('cidr', hostvars[node].current_subnet) %} - {% set _ = policies.append(new_pol) %} - {% endif %} - {% endfor %} - {{ policies | unique }} + - name: Apply the default policy as needed + set_fact: + __new_vpn_policies: "{{ __new_vpn_policies | d([]) + new_policy_or_empty | list }}" + delegate_to: localhost + run_once: true + loop: "{{ the_product }}" + vars: + the_product: "{{ policy_cidrs | product(node_ips_subnets) | list }}" + in_subnet: "{{ item.1.0 | vpn_ipaddr(item.0) | vpn_ipaddr('bool') }}" + new_policy: + policy: "{{ pol_default }}" + cidr: "{{ item.1.1 }}" + new_policy_or_empty: "{{ [new_policy] if not in_subnet else [] }}" + policy_cidrs: "{{ __vpn_policies | map(attribute='cidr') | list }}" + node_ips: "{{ ansible_play_hosts | map('extract', hostvars, '__vpn_current_ip') | list }}" + node_subnets: "{{ ansible_play_hosts | map('extract', hostvars, '__vpn_current_subnet') | list }}" + node_ips_subnets: "{{ node_ips | zip(node_subnets) | list }}" + + - name: Reset policies to include the added ones above + set_fact: + __vpn_policies: "{{ __vpn_policies + __new_vpn_policies | unique | list }}" -- name: Write tunnel policies for each network - template: - src: 'policy.j2' - dest: "/etc/ipsec.d/policies/{{ item }}" - mode: '0644' - loop: "{{ policies | map(attribute='policy') | unique | list }}" - notify: - - __vpn_handler_enable_start_vpn - - __vpn_handler_init_mesh_conns + - name: Write tunnel policies for each network + template: + src: 'policy.j2' + dest: "/etc/ipsec.d/policies/{{ item }}" + mode: '0644' + loop: "{{ __vpn_policies | map(attribute='policy') | unique | list }}" + notify: + - __vpn_handler_enable_start_vpn + - __vpn_handler_init_mesh_conns -- name: Deploy opportunistic configuration to each node - template: - src: "{{ vpn_provider }}-mesh.conf.j2" - dest: "/etc/ipsec.d/mesh.conf" - mode: '0644' - notify: - - __vpn_handler_enable_start_vpn - - __vpn_handler_init_mesh_conns + - name: Deploy opportunistic configuration to each node + template: + src: "{{ vpn_provider }}-mesh.conf.j2" + dest: "/etc/ipsec.d/mesh.conf" + mode: '0644' + notify: + - __vpn_handler_enable_start_vpn + - __vpn_handler_init_mesh_conns diff --git a/tasks/vpn_get_psks_for_tunnel.yml b/tasks/vpn_get_psks_for_tunnel.yml new file mode 100644 index 00000000..7ae9d88f --- /dev/null +++ b/tasks/vpn_get_psks_for_tunnel.yml @@ -0,0 +1,21 @@ +- name: Generate PSKs when not opportunistic and using psk + when: + - not tunnel.opportunistic + - tunnel.auth_method == "psk" + block: + - name: Reset __vpn_host_pairs + set_fact: + __vpn_host_pairs: [] + + - name: Generate host list for PSKs + set_fact: + __vpn_host_pairs: "{{ __vpn_host_pairs | d([]) + [{'host_pairs': item, 'pre_shared_key': pre_shared_key}] | list }}" + loop: "{{ tunnel.hosts | d({}) | dict2items | flatten | map(attribute='key') | combinations(2) | list }}" + vars: + pre_shared_key: "{{ tunnel.shared_key_content | d(lookup('lines', 'openssl rand -base64 48')) }}" + no_log: true + + - name: Generate PSKs or use provided shared_key_content + set_fact: + __vpn_psks: "{{ __vpn_psks | d({}) | combine({tunnel_idx: __vpn_host_pairs}) }}" + no_log: true diff --git a/templates/libreswan-host-to-host.conf.j2 b/templates/libreswan-host-to-host.conf.j2 index e1ede7d9..636b20c6 100644 --- a/templates/libreswan-host-to-host.conf.j2 +++ b/templates/libreswan-host-to-host.conf.j2 @@ -1,7 +1,7 @@ #jinja2: lstrip_blocks: True {{ ansible_managed | comment }} {{ "system_role:vpn" | comment(prefix="", postfix="") }} -{% for tunnel in vpn_connections %} +{% for tunnel in __vpn_connections_fixed %} {% if item in tunnel.hosts %} {% set otherhost = tunnel.hosts[item].hostname | d((hostvars[item] | d({})).ansible_host | d(item)) %} {% set rightid = tunnel.hosts[item].rightid | d(otherhost) %} diff --git a/templates/libreswan-host-to-host.secrets.j2 b/templates/libreswan-host-to-host.secrets.j2 index 714c6115..c0947d1c 100644 --- a/templates/libreswan-host-to-host.secrets.j2 +++ b/templates/libreswan-host-to-host.secrets.j2 @@ -1,19 +1,21 @@ #jinja2: lstrip_blocks: True {{ ansible_managed | comment }} {{ "system_role:vpn" | comment(prefix="", postfix="") }} -{% for tunnel in vpn_connections %} +{% for tunnel in __vpn_connections_fixed %} {% set __vpn_idx = loop.index0 %} {% if tunnel.auth_method == 'psk' %} {% for host, val in tunnel.hosts.items() %} {% if host == inventory_hostname or host == ansible_host %} -{% for otherhost, otherval in __vpn_psks[__vpn_idx][host].items() %} -{% if otherhost == item.item %} +{% for host_pairs_key in __vpn_psks[__vpn_idx] %} +{% set host_pairs = host_pairs_key['host_pairs'] %} +{% set pre_shared_key = host_pairs_key['pre_shared_key'] %} +{% if (host_pairs[0] == item.item and host_pairs[1] == host) or (host_pairs[1] == item.item and host_pairs[0] == host) %} {% set thishost = host %} {% set host = tunnel.hosts[host].hostname | d((hostvars[host] | d({})).ansible_host | d(host)) %} {% set leftid = tunnel.hosts[thishost].leftid | d(host) %} -{% set otherhost = tunnel.hosts[otherhost].hostname | d((hostvars[otherhost] | d({})).ansible_host | d(otherhost)) %} +{% set otherhost = tunnel.hosts[item.item].hostname | d((hostvars[item.item] | d({})).ansible_host | d(item.item)) %} {% set rightid = tunnel.hosts[item.item].rightid | d(otherhost) %} -{{ host | vpn_ipaddr | ternary('','@') }}{{ leftid }} {{ otherhost | vpn_ipaddr | ternary('','@') }}{{ rightid }} : PSK "{{ otherval['pre_shared_key'] }}" +{{ host | vpn_ipaddr | ternary('','@') }}{{ leftid }} {{ otherhost | vpn_ipaddr | ternary('','@') }}{{ rightid }} : PSK "{{ pre_shared_key }}" {% endif %} {% endfor %} {% endif %} diff --git a/templates/policy.j2 b/templates/policy.j2 index 3f3f993c..c3993f33 100644 --- a/templates/policy.j2 +++ b/templates/policy.j2 @@ -1,6 +1,6 @@ {{ ansible_managed | comment }} {{ "system_role:vpn" | comment(prefix="", postfix="") }} -{% for policy in policies %} +{% for policy in __vpn_policies %} {% if policy.policy == item %} {{ policy.cidr }} {% endif %} diff --git a/tests/tasks/add_hosts.yml b/tests/tasks/add_hosts.yml index 99cd066d..b808dcb0 100644 --- a/tests/tasks/add_hosts.yml +++ b/tests/tasks/add_hosts.yml @@ -4,23 +4,15 @@ name: "{{ 'host%02x.local' | format(item) }}" groups: testing cert_name: "{{ __vpn_dynamic_hosts_sample_cert }}" - current_ip: "{{ __vpn_dynamic_hosts_sample_ip }}" - current_subnet: "{{ __vpn_dynamic_hosts_sample_cidr }}" + __vpn_current_ip: "{{ __vpn_dynamic_hosts_sample_ip }}" + __vpn_current_subnet: "{{ __vpn_dynamic_hosts_sample_cidr }}" loop: "{{ range(1, __vpn_num_hosts + 1) | list }}" - name: Create mock vpn_connections set_fact: - vpn_connections: | - {% set vpn_connections = [] %} - {% set myhosts = {} %} - {% for host in (ansible_play_batch + groups['testing'] + [inventory_hostname]) | unique %} - {% if '/' in host %} - {% set _ = myhosts.__setitem__(__vpn_main_hostname, "") %} - {% else %} - {% set _ = myhosts.__setitem__(host, "") %} - {% endif %} - {% endfor %} - {% set empty_host = {} %} - {% set _ = empty_host.__setitem__('hosts', myhosts) %} - {% set _ = vpn_connections.append(empty_host) %} - {{ vpn_connections }} + vpn_connections: + - hosts: "{{ myhosts }}" + vars: + myhosts: "{{ dict(hostlist | product(['']) | list) }}" + hostlist: "{{ (ansible_play_batch + groups['testing'] + [inventory_hostname]) | unique | + map('regex_replace', '^.*/.*', __vpn_main_hostname) | list }}" diff --git a/tests/tasks/check_header.yml b/tests/tasks/check_header.yml index 607320f0..efcac838 100644 --- a/tests/tasks/check_header.yml +++ b/tests/tasks/check_header.yml @@ -9,8 +9,8 @@ - name: Check for presence of ansible managed header, fingerprint assert: that: - - ansible_managed in content + - __ansible_managed in content - __fingerprint in content vars: content: "{{ (__file_content | d(__content)).content | b64decode }}" - ansible_managed: "{{ lookup('template', 'get_ansible_managed.j2') }}" + __ansible_managed: "{{ lookup('template', 'get_ansible_managed.j2') }}" diff --git a/tests/tasks/cleanup.yml b/tests/tasks/cleanup.yml index 2e7daff8..8f2ac89d 100644 --- a/tests/tasks/cleanup.yml +++ b/tests/tasks/cleanup.yml @@ -27,18 +27,10 @@ - name: Clean up files vars: - tunnels: | - {% set unique_tunnels = [] %} - {% for connection in vpn_connections | d([]) %} - {% if inventory_hostname in connection.hosts %} - {% for node in connection.hosts %} - {% if node != inventory_hostname %} - {% set _ = unique_tunnels.append(node) %} - {% endif %} - {% endfor %} - {% endif %} - {% endfor %} - {{ unique_tunnels | unique }} + tunnels: "{{ __vpn_connections_fixed | rejectattr('opportunistic') | + selectattr('hosts', 'contains', inventory_hostname) | map(attribute='hosts') | + map('dict2items') | flatten | map(attribute='key') | + flatten | reject('match', '^' ~ inventory_hostname ~ '$') | unique | list }}" block: - name: Remove ipsec.conf files file: diff --git a/tests/tasks/fixup_hosts.yml b/tests/tasks/fixup_hosts.yml new file mode 100644 index 00000000..6b50570e --- /dev/null +++ b/tests/tasks/fixup_hosts.yml @@ -0,0 +1,18 @@ +--- +- name: Init __hosts + set_fact: + __hosts: "{{ tunnel.hosts }}" + +- name: Set __tunnel_hosts + set_fact: + __hosts: "{{ __hosts | combine({item.key: __cert}) }}" + loop: "{{ tunnel.hosts | dict2items | list }}" + loop_control: + index_var: host_idx + vars: + __cert: + cert_name: "{{ 'cert%d' | format(host_idx) }}" + +- name: Update __tunnel_hosts + set_fact: + __tunnel_hosts: "{{ __tunnel_hosts | combine({tunnel_idx: __hosts}) }}" diff --git a/tests/tests_defaults_vars.yml b/tests/tests_defaults_vars.yml index d46b0918..b195a05d 100644 --- a/tests/tests_defaults_vars.yml +++ b/tests/tests_defaults_vars.yml @@ -6,14 +6,21 @@ include_role: name: linux-system-roles.vpn public: true + - name: Assert that the role declares all parameters in defaults assert: - that: "{{ item }} is defined" - loop: - - vpn_provider - - vpn_auth_method - - vpn_regen_keys - - vpn_connections + that: vpn_vars_vals | length == vpn_vars | length + vars: + vpn_vars: + - vpn_provider + - vpn_auth_method + - vpn_regen_keys + - vpn_connections + - vpn_opportunistic + - vpn_default_policy + - vpn_manage_firewall + - vpn_manage_selinux + vpn_vars_vals: "{{ lookup('vars', *vpn_vars) }}" - name: Check the firewall and the selinux port status include_tasks: tasks/check_firewall_selinux.yml diff --git a/tests/tests_host_to_host_cert.yml b/tests/tests_host_to_host_cert.yml index ee69321c..78015b40 100644 --- a/tests/tests_host_to_host_cert.yml +++ b/tests/tests_host_to_host_cert.yml @@ -10,19 +10,35 @@ - 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: - vpn_connections: | - {% for tunnel in vpn_connections %} - {% set _ = tunnel.__setitem__("auth_method", "cert") %} - {% set _ = tunnel.__setitem__("auto", "start") %} - {% set _ = tunnel.__setitem__("name", "tunnel%d" | format(loop.index)) %} - {% for host in tunnel.hosts %} - {% set temp_dict = {'cert_name': 'cert' + loop.index | string} %} - {% set _ = tunnel.hosts.__setitem__(host, temp_dict) %} - {% endfor %} - {% endfor %} - {{ vpn_connections }} + __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: diff --git a/tests/tests_host_to_host_psk.yml b/tests/tests_host_to_host_psk.yml index 1fb5bcac..7a9187c9 100644 --- a/tests/tests_host_to_host_psk.yml +++ b/tests/tests_host_to_host_psk.yml @@ -15,11 +15,10 @@ - name: Add extra options to check set_fact: - vpn_connections: | - {% for tunnel in vpn_connections %} - {% set _ = tunnel.__setitem__("auto", "start") %} - {% endfor %} - {{ vpn_connections }} + vpn_connections: "{{ vpn_connections | map('combine', fixed_item) | list }}" + vars: + fixed_item: + auto: start - name: Use vpn role include_role: diff --git a/tests/tests_host_to_host_psk_custom.yml b/tests/tests_host_to_host_psk_custom.yml index 953aa371..674e4226 100644 --- a/tests/tests_host_to_host_psk_custom.yml +++ b/tests/tests_host_to_host_psk_custom.yml @@ -28,14 +28,8 @@ - name: Add extra options to check set_fact: - vpn_connections: | - {% for tunnel in vpn_connections %} - {% set _ = tunnel.update(__tunnel_params) %} - {% set _ = tunnel["hosts"].__setitem__(__hostmain, __dict) %} - {% set _ = tunnel["hosts"].__setitem__(__host1, __dict) %} - {% set _ = tunnel["hosts"].__setitem__(__host2, __dict) %} - {% endfor %} - {{ vpn_connections }} + __new_vpn_connections: "{{ __new_vpn_connections | d([]) + [new_tunnel] | list }}" + loop: "{{ vpn_connections }}" vars: __tunnel_params: auto: start @@ -50,13 +44,19 @@ dpdtimeout: "{{ __vpn_dpdtimeout }}" dpdaction: "{{ __vpn_dpdaction }}" leftupdown: "{{ __vpn_leftupdown }}" - __hostmain: mainhost.local - __host1: host01.local - __host2: host02.local + 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 diff --git a/tests/tests_host_to_unmanaged_host.yml b/tests/tests_host_to_unmanaged_host.yml index 22e0b270..9aeadd72 100644 --- a/tests/tests_host_to_unmanaged_host.yml +++ b/tests/tests_host_to_unmanaged_host.yml @@ -14,12 +14,16 @@ - name: Add extra options and unmanaged host set_fact: - vpn_connections: | - {% for tunnel in vpn_connections %} - {% set temp_dict = {'hostname': __vpn_unmanaged_hostname} %} - {% set _ = tunnel.hosts.__setitem__(__vpn_unmanaged_host, temp_dict) %} - {% endfor %} - {{ vpn_connections }} + __new_vpn_connections: "{{ __new_vpn_connections | d([]) + [new_tunnel] | list }}" + loop: "{{ vpn_connections }}" + vars: + new_hosts: "{{ item.hosts | + combine({__vpn_unmanaged_host: {'hostname': __vpn_unmanaged_hostname}}) }}" + new_tunnel: "{{ item | combine({'hosts': new_hosts}) }}" + + - name: Reset vpn_connections + set_fact: + vpn_connections: "{{ __new_vpn_connections }}" - name: Use vpn role include_role: diff --git a/tests/tests_mesh_cert.yml b/tests/tests_mesh_cert.yml index 7df3ac17..f8349dbe 100644 --- a/tests/tests_mesh_cert.yml +++ b/tests/tests_mesh_cert.yml @@ -20,18 +20,21 @@ - name: Add extra options to check set_fact: - vpn_connections: | - {% for tunnel in vpn_connections %} - {% set pols = [] %} - {% set private_pol = {"policy": "private", "cidr": __vpn_private_host_cidr} %} - {% set clear_pol = {"policy": "clear", "cidr": __vpn_clear_host_cidr} %} - {% set _ = pols.append(private_pol) %} - {% set _ = pols.append(clear_pol) %} - {% set _ = tunnel.__setitem__("auth_method", "cert") %} - {% set _ = tunnel.__setitem__("opportunistic", true) %} - {% set _ = tunnel.__setitem__("policies", pols) %} - {% endfor %} - {{ vpn_connections }} + __new_vpn_connections: "{{ __new_vpn_connections | d([]) + [item | combine(new_tunnel)] | list }}" + loop: "{{ vpn_connections }}" + vars: + new_tunnel: + policies: + - policy: private + cidr: "{{ __vpn_private_host_cidr }}" + - policy: clear + cidr: "{{ __vpn_clear_host_cidr }}" + auth_method: cert + opportunistic: true + + - name: Reset vpn_connections + set_fact: + vpn_connections: "{{ __new_vpn_connections }}" - name: Add cert_name fact to controller set_fact: @@ -174,7 +177,7 @@ __vpn_success: false when: >- __vpn_register_private_or_clear['content'] | b64decode - is not search(current_subnet) or + is not search(__vpn_current_subnet) or __vpn_register_private_or_clear['content'] | b64decode is not search(__vpn_dynamic_hosts_sample_cidr) diff --git a/tests/tests_subnet_to_subnet.yml b/tests/tests_subnet_to_subnet.yml index 938dced1..31750199 100644 --- a/tests/tests_subnet_to_subnet.yml +++ b/tests/tests_subnet_to_subnet.yml @@ -19,12 +19,17 @@ - name: Add subnets set_fact: - vpn_connections: | - {% for tunnel in vpn_connections %} - {% set temp_dict = {'subnets': __vpn_subnets} %} - {% set _ = tunnel.hosts.__setitem__('host01.local', temp_dict) %} - {% endfor %} - {{ vpn_connections }} + __new_vpn_connections: "{{ __new_vpn_connections | d([]) + [new_tunnel] | list }}" + loop: "{{ vpn_connections }}" + vars: + new_tunnel: + hosts: + host01.local: + subnets: "{{ __vpn_subnets }}" + + - name: Reset vpn_connections + set_fact: + vpn_connections: "{{ __new_vpn_connections }}" - name: Use vpn role include_role: