Merge "CI: Refactor VXLAN overlay setup"
This commit is contained in:
commit
8829c5aa72
72
roles/multi-node-managed-addressing/tasks/main.yml
Normal file
72
roles/multi-node-managed-addressing/tasks/main.yml
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
---
|
||||||
|
# Not all variables have sensible defaults, let's ensure these are set.
|
||||||
|
- name: Ensure mandatory variables are defined
|
||||||
|
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
|
||||||
|
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 | ipaddr('broadcast') }}"
|
||||||
|
command: ip address add {{ managed_network_cidr }} broadcast {{ managed_network_broadcast_address }} dev {{ managed_interface_name }}
|
||||||
|
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
|
||||||
|
command: ip address add {{ managed_interface_address }}/{{ managed_network_prefix_length }} dev {{ managed_interface_name }}
|
||||||
|
when: managed_network_address_family == 'ipv6'
|
||||||
|
|
||||||
|
- name: Accept traffic on the managed network (IN)
|
||||||
|
become: true
|
||||||
|
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
|
||||||
|
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
|
||||||
|
command: ip -o address show tentative dev {{ managed_interface_name }}
|
||||||
|
register: tentative_addresses
|
||||||
|
until: tentative_addresses.stdout == ''
|
||||||
|
retries: 30
|
||||||
|
delay: 2
|
||||||
|
when:
|
||||||
|
- managed_network_address_family == 'ipv6'
|
||||||
|
|
||||||
|
- name: Ping across the managed network
|
||||||
|
vars:
|
||||||
|
ping_command: "{{ 'ping' if managed_network_address_family == 'ipv4' else 'ping6' }}"
|
||||||
|
command: "{{ ping_command }} -c1 {{ hostvars[item].managed_interface_address }}"
|
||||||
|
with_inventory_hostnames: all
|
5
roles/multi-node-vxlan-overlay/defaults/main.yml
Normal file
5
roles/multi-node-vxlan-overlay/defaults/main.yml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
# NOTE(yoctozepto): CI VXLAN overlay must use a different port than
|
||||||
|
# neutron-openvswitch-agent which defaults to 4789.
|
||||||
|
# Hence using port 4790 by default.
|
||||||
|
vxlan_dstport: 4790
|
50
roles/multi-node-vxlan-overlay/tasks/main.yml
Normal file
50
roles/multi-node-vxlan-overlay/tasks/main.yml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
# Not all variables have sensible defaults, let's ensure these are set.
|
||||||
|
- name: Ensure mandatory variables are defined
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- vxlan_interface_name is defined
|
||||||
|
- vxlan_vni is defined
|
||||||
|
|
||||||
|
# We have had cases where the nodepool private IP address is not assigned,
|
||||||
|
# which causes hard to diagnose errors later on. Catch it early.
|
||||||
|
- name: Assert that the nodepool private IPv4 address is assigned
|
||||||
|
assert:
|
||||||
|
that: nodepool.private_ipv4 in ansible_all_ipv4_addresses
|
||||||
|
fail_msg: >-
|
||||||
|
The nodepool private IP address {{ nodepool.private_ipv4 }} is not assigned
|
||||||
|
|
||||||
|
- name: Set VXLAN interface facts
|
||||||
|
set_fact:
|
||||||
|
tunnel_local_address: "{{ nodepool.private_ipv4 }}"
|
||||||
|
|
||||||
|
- name: Create VXLAN interface
|
||||||
|
become: true
|
||||||
|
command: ip link add {{ vxlan_interface_name }} type vxlan id {{ vxlan_vni }} local {{ tunnel_local_address }} dstport {{ vxlan_dstport }}
|
||||||
|
|
||||||
|
- name: Set VXLAN interface MTU
|
||||||
|
become: true
|
||||||
|
vars:
|
||||||
|
# Find the parent interface
|
||||||
|
parent_interface: >-
|
||||||
|
{{ ansible_interfaces |
|
||||||
|
map('extract', ansible_facts) |
|
||||||
|
selectattr('ipv4.address', 'defined') |
|
||||||
|
selectattr('ipv4.address', 'equalto', tunnel_local_address) |
|
||||||
|
first }}
|
||||||
|
# Allow 50 bytes overhead for VXLAN headers.
|
||||||
|
mtu: "{{ parent_interface.mtu | int - 50 }}"
|
||||||
|
command: ip link set {{ vxlan_interface_name }} mtu {{ mtu }}
|
||||||
|
|
||||||
|
# emulate BUM by multiplicating traffic to unicast targets
|
||||||
|
- name: Add fdb entries for BUM traffic
|
||||||
|
become: true
|
||||||
|
vars:
|
||||||
|
dest_ip: "{{ hostvars[item].tunnel_local_address }}"
|
||||||
|
command: bridge fdb append 00:00:00:00:00:00 dev {{ vxlan_interface_name }} dst {{ dest_ip }}
|
||||||
|
with_inventory_hostnames: all
|
||||||
|
when: item != inventory_hostname
|
||||||
|
|
||||||
|
- name: Bring VXLAN interface up
|
||||||
|
become: true
|
||||||
|
command: ip link set {{ vxlan_interface_name }} up
|
119
tests/pre.yml
119
tests/pre.yml
@ -6,20 +6,22 @@
|
|||||||
roles:
|
roles:
|
||||||
- bindep
|
- bindep
|
||||||
- multi-node-firewall
|
- multi-node-firewall
|
||||||
|
- role: multi-node-vxlan-overlay
|
||||||
|
vars:
|
||||||
|
vxlan_interface_name: "{{ api_interface_name }}"
|
||||||
|
vxlan_vni: 10001
|
||||||
|
- role: multi-node-managed-addressing
|
||||||
|
vars:
|
||||||
|
managed_interface_name: "{{ api_interface_name }}"
|
||||||
|
managed_network_prefix: "{{ api_network_prefix }}"
|
||||||
|
managed_network_prefix_length: "{{ api_network_prefix_length }}"
|
||||||
|
managed_network_address_family: "{{ address_family }}"
|
||||||
tasks:
|
tasks:
|
||||||
# TODO(mnasiadka): Remove once infra merges virtualenv fixes
|
# TODO(mnasiadka): Remove once infra merges virtualenv fixes
|
||||||
- name: Upgrade virtualenv package
|
- name: Upgrade virtualenv package
|
||||||
command: python3 -m pip install -U virtualenv
|
command: python3 -m pip install -U virtualenv
|
||||||
become: True
|
become: True
|
||||||
|
|
||||||
# We have had cases where the nodepool private IP address is not assigned,
|
|
||||||
# which causes hard to diagnose errors later on. Catch it early.
|
|
||||||
- name: Assert that the nodepool private IPv4 address is assigned
|
|
||||||
assert:
|
|
||||||
that: nodepool.private_ipv4 in ansible_all_ipv4_addresses
|
|
||||||
fail_msg: >-
|
|
||||||
The nodepool private IP address {{ nodepool.private_ipv4 }} is not assigned
|
|
||||||
|
|
||||||
- name: Install dbus for debian system
|
- name: Install dbus for debian system
|
||||||
apt: name=dbus
|
apt: name=dbus
|
||||||
when:
|
when:
|
||||||
@ -48,107 +50,6 @@
|
|||||||
name: "{{ inventory_hostname }}"
|
name: "{{ inventory_hostname }}"
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
# NOTE(yoctozepto): start VXLAN interface config
|
|
||||||
|
|
||||||
- name: Set VXLAN interface facts
|
|
||||||
set_fact:
|
|
||||||
api_interface_address: "{{ api_network_prefix }}{{ groups['all'].index(inventory_hostname) + 1 }}"
|
|
||||||
api_interface_tunnel_vni: 10001
|
|
||||||
tunnel_local_address: "{{ nodepool.private_ipv4 }}"
|
|
||||||
|
|
||||||
# NOTE(yoctozepto): CI VXLAN must use a different port than neutron-openvswitch-agent
|
|
||||||
# which defaults to 4789 (the default is used in CI)
|
|
||||||
# hence using port 4790
|
|
||||||
- name: Create VXLAN interface
|
|
||||||
become: true
|
|
||||||
command: ip link add {{ api_interface_name }} type vxlan id {{ api_interface_tunnel_vni }} local {{ tunnel_local_address }} dstport 4790
|
|
||||||
|
|
||||||
- name: Set VXLAN interface MTU
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
# Find the parent interface
|
|
||||||
parent_interface: >-
|
|
||||||
{{ ansible_interfaces |
|
|
||||||
map('extract', ansible_facts) |
|
|
||||||
selectattr('ipv4.address', 'defined') |
|
|
||||||
selectattr('ipv4.address', 'equalto', tunnel_local_address) |
|
|
||||||
first }}
|
|
||||||
# Allow 50 bytes overhead for VXLAN headers.
|
|
||||||
mtu: "{{ parent_interface.mtu | int - 50 }}"
|
|
||||||
command: ip link set {{ api_interface_name }} mtu {{ mtu }}
|
|
||||||
|
|
||||||
# emulate BUM by multiplicating traffic to unicast targets
|
|
||||||
- name: Add fdb entries for BUM traffic
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
dest_ip: "{{ hostvars[item].tunnel_local_address }}"
|
|
||||||
command: bridge fdb append 00:00:00:00:00:00 dev {{ api_interface_name }} dst {{ dest_ip }}
|
|
||||||
with_inventory_hostnames: all
|
|
||||||
when: item != inventory_hostname
|
|
||||||
|
|
||||||
- name: Add IPv4 address for VXLAN network
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
api_network_cidr: "{{ api_interface_address }}/{{ api_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
|
|
||||||
api_network_broadcast_address: "{{ api_network_cidr | ipaddr('broadcast') }}"
|
|
||||||
command: ip address add {{ api_network_cidr }} broadcast {{ api_network_broadcast_address }} dev {{ api_interface_name }}
|
|
||||||
when: address_family == 'ipv4'
|
|
||||||
|
|
||||||
# NOTE(yoctozepto): IPv6 has no broadcast address, let's not create confusion by setting it
|
|
||||||
- name: Add IPv6 address for VXLAN network
|
|
||||||
become: true
|
|
||||||
command: ip address add {{ api_interface_address }}/{{ api_network_prefix_length }} dev {{ api_interface_name }}
|
|
||||||
when: address_family == 'ipv6'
|
|
||||||
|
|
||||||
- name: Accept traffic on the VXLAN network (IN)
|
|
||||||
become: true
|
|
||||||
iptables:
|
|
||||||
state: present
|
|
||||||
action: insert
|
|
||||||
chain: INPUT
|
|
||||||
ip_version: "{{ address_family }}"
|
|
||||||
in_interface: "{{ api_interface_name }}"
|
|
||||||
jump: ACCEPT
|
|
||||||
|
|
||||||
# NOTE(yoctozepto): the default policy is ACCEPT but it is nicer to get statistics
|
|
||||||
- name: Accept traffic on the VXLAN network (OUT)
|
|
||||||
become: true
|
|
||||||
iptables:
|
|
||||||
state: present
|
|
||||||
action: insert
|
|
||||||
chain: OUTPUT
|
|
||||||
ip_version: "{{ address_family }}"
|
|
||||||
out_interface: "{{ api_interface_name }}"
|
|
||||||
jump: ACCEPT
|
|
||||||
|
|
||||||
- name: Bring VXLAN interface up
|
|
||||||
become: true
|
|
||||||
command: ip link set {{ api_interface_name }} up
|
|
||||||
|
|
||||||
# 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 VXLAN are no longer tentative
|
|
||||||
become: true
|
|
||||||
command: ip -o address show tentative dev {{ api_interface_name }}
|
|
||||||
register: tentative_addresses
|
|
||||||
until: tentative_addresses.stdout == ''
|
|
||||||
retries: 30
|
|
||||||
delay: 2
|
|
||||||
when:
|
|
||||||
- address_family == 'ipv6'
|
|
||||||
|
|
||||||
- name: Ping across VXLAN
|
|
||||||
vars:
|
|
||||||
ping_command: "{{ 'ping' if address_family == 'ipv4' else 'ping6' }}"
|
|
||||||
command: "{{ ping_command }} -c1 {{ hostvars[item].api_interface_address }}"
|
|
||||||
with_inventory_hostnames: all
|
|
||||||
|
|
||||||
# NOTE(yoctozepto): CentOS 7 image uses myhostname plugin for NSS
|
# NOTE(yoctozepto): CentOS 7 image uses myhostname plugin for NSS
|
||||||
# which creates issues with IPv6-only deployment by providing
|
# which creates issues with IPv6-only deployment by providing
|
||||||
# an IPv4 address for the current hostname (affects rabbitmq)
|
# an IPv4 address for the current hostname (affects rabbitmq)
|
||||||
|
Loading…
Reference in New Issue
Block a user