aboutsummaryrefslogtreecommitdiff
path: root/roles/multi-node-managed-addressing/tasks/main.yml
blob: 0949746bb9cba5dd22b43c1f81767f20f0a0d44c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
---
# Not all variables have sensible defaults, let's ensure these are set.
- name: Ensure mandatory variables are defined
  ansible.builtin.assert:
    that:
      - managed_interface_name is defined
      - managed_network_prefix is defined
      - managed_network_prefix_length is defined
      - managed_network_address_family is defined

- name: Set managed interface facts
  ansible.builtin.set_fact:
    managed_interface_address: "{{ managed_network_prefix }}{{ groups['all'].index(inventory_hostname) + 1 }}"

- name: Add IPv4 address for managed network
  become: true
  vars:
    managed_network_cidr: "{{ managed_interface_address }}/{{ managed_network_prefix_length }}"
    # NOTE(yoctozepto): we have to compute and explicitly set the broadcast address,
    # otherwise bifrost fails its pre-bootstrap sanity checks due to missing
    # broadcast address as ansible picks up scope ('global') as the interface's
    # broadcast address which fails checks logic
    managed_network_broadcast_address: "{{ managed_network_cidr | ansible.utils.ipaddr('broadcast') }}"
  ansible.builtin.command:
    cmd: ip address add {{ managed_network_cidr }} broadcast {{ managed_network_broadcast_address }} dev {{ managed_interface_name }}
  changed_when: true
  when: managed_network_address_family == 'ipv4'

# NOTE(yoctozepto): IPv6 has no broadcast address, let's not create confusion by setting it
- name: Add IPv6 address for managed network
  become: true
  ansible.builtin.command:
    cmd: ip address add {{ managed_interface_address }}/{{ managed_network_prefix_length }} dev {{ managed_interface_name }}
  changed_when: true
  when: managed_network_address_family == 'ipv6'

- name: Accept traffic on the managed network (IN)
  become: true
  ansible.builtin.iptables:
    state: present
    action: insert
    chain: INPUT
    ip_version: "{{ managed_network_address_family }}"
    in_interface: "{{ managed_interface_name }}"
    jump: ACCEPT

# NOTE(yoctozepto): the default policy is ACCEPT but it is nicer to get statistics
- name: Accept traffic on the managed network (OUT)
  become: true
  ansible.builtin.iptables:
    state: present
    action: insert
    chain: OUTPUT
    ip_version: "{{ managed_network_address_family }}"
    out_interface: "{{ managed_interface_name }}"
    jump: ACCEPT

# NOTE(yoctozepto): IPv6 DAD may delay proper address assignment
# this task will wait until DAD is done and addresses are no longer tentative
# we assign addresses uniquely so DAD can only move it to preferred
# hence we only check whether it's no longer tentative
- name: Ensure IPv6 addresses on the managed interface are no longer tentative
  become: true
  ansible.builtin.command:
    cmd: ip -o address show tentative dev {{ managed_interface_name }}
  changed_when: false
  register: tentative_addresses
  until: tentative_addresses.stdout == ''
  retries: 30
  delay: 2
  when:
    - managed_network_address_family == 'ipv6'

- name: Ping across the managed network
  become: true
  vars:
    ping_command: "{{ 'ping' if managed_network_address_family == 'ipv4' else 'ping6' }}"
  ansible.builtin.command:
    cmd: "{{ ping_command }} -c1 {{ hostvars[item].managed_interface_address }}"
  changed_when: false
  with_inventory_hostnames: all