Merge "Introduce multinode tempest job"

This commit is contained in:
Zuul 2025-01-17 10:37:56 +00:00 committed by Gerrit Code Review
commit f90262e7d3
12 changed files with 799 additions and 17 deletions

@ -39,7 +39,11 @@ function configure_frr {
sudo install -d -o $STACK_USER $FRR_CONF_DIR
# Configure frr daemons
sudo install -o root -g root -m 644 $OVN_BGP_AGENT_DIR/etc/frr/* $FRR_CONF_DIR/
if [[ "$FRR_USE_BFD" == "True" ]]; then
sudo install -o root -g root -m 644 $OVN_BGP_AGENT_DIR/etc/frr_with_bfd/* $FRR_CONF_DIR/
else
sudo install -o root -g root -m 644 $OVN_BGP_AGENT_DIR/etc/frr/* $FRR_CONF_DIR/
fi
}

@ -12,6 +12,7 @@ FRR_CONF_DIR=${FRR_CONF_DIR:-/etc/frr}
FRR_SYSTEMD_SERVICE="frr.service"
FRR_CONF_FILE=$FRR_CONF_DIR/frr.conf
FRR_DAEMON_CONF_FILE=$FRR_CONF_DIR/daemons
FRR_USE_BFD=$(trueorfalse False FRR_USE_BFD)
# Defaults
OVN_BGP_AGENT_DIR=$DEST/ovn-bgp-agent

42
etc/frr_with_bfd/daemons Normal file

@ -0,0 +1,42 @@
bgpd=yes
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=no
pimd=no
ldpd=no
nhrpd=no
eigrpd=no
babeld=no
sharpd=no
pbrd=no
bfdd=yes
fabricd=no
vrrpd=no
pathd=no
#
# If this option is set the /etc/init.d/frr script automatically loads
# the config via "vtysh -b" when the servers are started.
# Check /etc/pam.d/frr if you intend to use "vtysh"!
#
vtysh_enable=yes
zebra_options=" -A 127.0.0.1 -s 90000000"
bgpd_options=" -A 127.0.0.1"
ospfd_options=" -A 127.0.0.1"
ospf6d_options=" -A ::1"
ripd_options=" -A 127.0.0.1"
ripngd_options=" -A ::1"
isisd_options=" -A 127.0.0.1"
pimd_options=" -A 127.0.0.1"
ldpd_options=" -A 127.0.0.1"
nhrpd_options=" -A 127.0.0.1"
eigrpd_options=" -A 127.0.0.1"
babeld_options=" -A 127.0.0.1"
sharpd_options=" -A 127.0.0.1"
pbrd_options=" -A 127.0.0.1"
staticd_options="-A 127.0.0.1"
bfdd_options=" -A 127.0.0.1"
fabricd_options="-A 127.0.0.1"
vrrpd_options=" -A 127.0.0.1"

69
etc/frr_with_bfd/frr.conf Normal file

@ -0,0 +1,69 @@
frr version 7.0
frr defaults traditional
hostname devstack
log file /var/log/frr/frr.log debugging
log timestamp precision 3
service integrated-vtysh-config
line vty
debug bfd peer
debug bfd network
debug bfd zebra
debug bgp graceful-restart
debug bgp neighbor-events
debug bgp updates
debug bgp update-groups
router bgp 64999
bgp router-id 172.24.4.1
bgp log-neighbor-changes
bgp graceful-shutdown
no bgp default ipv4-unicast
no bgp ebgp-requires-policy
neighbor uplink peer-group
neighbor uplink remote-as internal
neighbor uplink password f00barZ
neighbor leaf0-port interface peer-group uplink
neighbor leaf1-port interface peer-group uplink
neighbor uplink bfd
neighbor uplink bfd profile devstack
address-family ipv4 unicast
redistribute connected
neighbor uplink activate
neighbor uplink allowas-in origin
neighbor uplink prefix-list only-host-prefixes out
exit-address-family
address-family ipv6 unicast
redistribute connected
neighbor uplink activate
neighbor uplink allowas-in origin
neighbor uplink prefix-list only-host-prefixes out
exit-address-family
ip prefix-list only-default permit 0.0.0.0/0
ip prefix-list only-host-prefixes permit 0.0.0.0/0 ge 32
route-map rm-only-default permit 10
match ip address prefix-list only-default
set src 172.24.4.1
ip protocol bgp route-map rm-only-default
ipv6 prefix-list only-default permit ::/0
ipv6 prefix-list only-host-prefixes permit ::/0 ge 128
route-map rm-only-default permit 11
match ipv6 address prefix-list only-default
set src 2001:db8::2
ipv6 protocol bgp route-map rm-only-default
ip nht resolve-via-default
bfd
profile devstack
detect-multiplier 10
transmit-interval 500
receive-interval 500

@ -0,0 +1,171 @@
- name: Install dependencies on all nodes
hosts: leafs,spine
tasks:
- name: Install openvswitch
become: true
ansible.builtin.package:
name: "openvswitch-switch"
state: present
- name: Figure out VXLAN endpoints
hosts: controller,leafs,spine
tasks:
- name: Set local IP for VXLAN tunnels
ansible.builtin.set_fact:
vxlan_local_ip: "{{ nodepool.private_ipv4 | ipv4 | default(nodepool.public_ipv4) }} "
- name: Create tunnels between the controller and the leafs
hosts: controller
vars:
base_subnet: "172.18"
spine_base_subnet: "172.19"
tasks:
- name: Create local.sh script to create tunnels
vars:
# todo: get this from a variable
top_dir: "/opt/stack/devstack"
become: true
copy:
dest: "{{ top_dir }}/local.sh"
owner: stack
group: stack
mode: '0755'
content: |
#!/bin/bash
set -e
function configure_vxlan_endpoint() {
local loop_index=$1
local remote_ip=$2
local local_ip={{ vxlan_local_ip }}
local tunnel_iface=leaf${loop_index}-tunnel
local port_iface=leaf${loop_index}-port
local vlan_tag=100${loop_index}
sudo ovs-vsctl add-port br-infra $tunnel_iface -- \
set Interface $tunnel_iface type=vxlan options:remote_ip=$remote_ip \
options:key=1000${loop_index} options:local_ip=$local_ip -- \
set Port $tunnel_iface tag=$vlan_tag -- \
add-port br-infra $port_iface -- \
set Interface $port_iface type=internal -- \
set Port $port_iface tag=$vlan_tag
sudo ip addr add {{ base_subnet }}.${loop_index}.1/30 dev $port_iface
sudo ip link set dev $port_iface up
sudo iptables -I INPUT 1 -s {{ base_subnet }}.${loop_index}.0/30 -j ACCEPT
sudo iptables -I FORWARD 1 -i $port_iface -j ACCEPT
# Add routes to the spine too since we cannot use default
sudo ip route add {{ spine_base_subnet }}.${loop_index}.0/30 nexthop via {{ base_subnet }}.${loop_index}.2 dev $port_iface
}
sudo ovs-vsctl --may-exist add-br br-infra
{% for leaf in groups['leafs'] %}
configure_vxlan_endpoint {{ loop.index0 }} {{ hostvars[leaf].vxlan_local_ip }}
{% endfor %}
sudo iptables -I FORWARD 1 -i br-ex -j ACCEPT
# When FRR started before the peer interfaces did not exist
sudo systemctl restart frr
- name: "Create VXLAN tunnel from {{ item.1 }} to the controller"
ansible.builtin.shell: |
set -e
tunnel_iface=controller-tunnel
port_iface=controller-port
local_ip={{ hostvars[item.1].vxlan_local_ip }}
remote_ip={{ vxlan_local_ip }}
vlan_tag=100{{ item.0 }}
ovs-vsctl --may-exist add-br br-infra -- \
add-port br-infra $tunnel_iface -- \
set Interface $tunnel_iface type=vxlan options:remote_ip=$remote_ip \
options:key=1000{{ item.0 }} options:local_ip=$local_ip -- \
set Port $tunnel_iface tag=$vlan_tag -- \
add-port br-infra $port_iface -- \
set Interface $port_iface type=internal -- \
set Port $port_iface tag=$vlan_tag
ip addr add {{ base_subnet }}.{{ item.0 }}.2/30 dev $port_iface
ip link set dev $port_iface up
iptables -I INPUT 1 -s {{ base_subnet }}.{{ item.0 }}.0/30 -j ACCEPT
iptables -I FORWARD 1 -i $port_iface -j ACCEPT
with_indexed_items: "{{ groups['leafs'] }}"
delegate_to: "{{ item.1 }}"
become: true
- name: Create tunnels between the spine and the leafs
hosts: spine
vars:
base_subnet: "172.19"
become: true
tasks:
- name: "Create VXLAN tunnels from the spine to {{ item.1 }}"
ansible.builtin.shell: |
set -e
tunnel_iface=leaf{{ item.0 }}-tunnel
port_iface=leaf{{ item.0 }}-port
local_ip={{ vxlan_local_ip }}
remote_ip={{ hostvars[item.1].vxlan_local_ip }}
vlan_tag=100{{ item.0 }}
ovs-vsctl --may-exist add-br br-infra -- \
add-port br-infra $tunnel_iface -- \
set Interface $tunnel_iface type=vxlan options:remote_ip=$remote_ip \
options:key=1001{{ item.0 }} options:local_ip=$local_ip -- \
set Port $tunnel_iface tag=$vlan_tag -- \
add-port br-infra $port_iface -- \
set Interface $port_iface type=internal -- \
set Port $port_iface tag=$vlan_tag
ip addr add {{ base_subnet }}.{{ item.0 }}.1/30 dev $port_iface
ip link set dev $port_iface up
iptables -I INPUT 1 -s {{ base_subnet }}.{{ item.0 }}.0/30 -j ACCEPT
iptables -I FORWARD 1 -i $port_iface -j ACCEPT
with_indexed_items: "{{ groups['leafs'] }}"
- name: "Create VXLAN tunnel from {{ item.1 }} to the spine"
ansible.builtin.shell: |
set -e
tunnel_iface=spine-tunnel
port_iface=spine-port
local_ip={{ hostvars[item.1].vxlan_local_ip }}
remote_ip={{ vxlan_local_ip }}
vlan_tag=1001
ovs-vsctl --may-exist add-br br-infra -- \
add-port br-infra $tunnel_iface -- \
set Interface $tunnel_iface type=vxlan options:remote_ip=$remote_ip \
options:key=1001{{ item.0 }} options:local_ip=$local_ip -- \
set Port $tunnel_iface tag=$vlan_tag -- \
add-port br-infra $port_iface -- \
set Interface $port_iface type=internal -- \
set Port $port_iface tag=$vlan_tag
ip addr add {{ base_subnet }}.{{ item.0 }}.2/30 dev $port_iface
ip link set dev $port_iface up
iptables -I INPUT 1 -s {{ base_subnet }}.{{ item.0 }}.0/30 -j ACCEPT
iptables -I FORWARD 1 -i $port_iface -j ACCEPT
with_indexed_items: "{{ groups['leafs'] }}"
delegate_to: "{{ item.1 }}"
- name: Configure the spine switch
hosts: spine
roles:
- spine
- name: Configure the leafs switches
hosts: leafs
roles:
- leaf

131
roles/leaf/tasks/main.yml Normal file

@ -0,0 +1,131 @@
---
- name: Workaround router advertisement packets polluting routing tables
become: true
ansible.builtin.shell:
cmd: |
for i in $(ls /proc/sys/net/ipv6/conf/*/forwarding); do echo 1 > $i; done
changed_when: false
- name: Register interfaces
ansible.builtin.shell:
cmd: "ls -1 /proc/sys/net/ipv4/conf/*/rp_filter | cut -d/ -f7"
register: interfaces
changed_when: false
- name: Disable reverse path forwarding validation
become: true
ansible.posix.sysctl:
name: "net.ipv4.conf.{{ item }}.rp_filter"
value: "0"
sysctl_set: true
sysctl_file: /etc/sysctl.d/99-sysctl.conf
state: present
reload: true
loop: "{{ interfaces.stdout_lines }}"
register: result
retries: 3
timeout: 60
until: result is not failed
- name: Disable reverse path forwarding validation
become: true
ansible.posix.sysctl:
name: "{{ item.key }}"
value: "{{ item.value }}"
sysctl_set: true
sysctl_file: /etc/sysctl.d/99-sysctl.conf
state: present
reload: true
with_dict:
net.ipv4.conf.all.rp_filter: '0'
net.ipv4.conf.default.rp_filter: '0'
register: result
retries: 3
timeout: 60
until: result is not failed
- name: Set IPv4 forwarding
become: true
ansible.posix.sysctl:
name: net.ipv4.ip_forward
value: '1'
sysctl_set: true
sysctl_file: /etc/sysctl.d/90-network.conf
state: present
reload: true
- name: Set IPv6 forwarding
become: true
ansible.posix.sysctl:
name: net.ipv6.conf.all.forwarding
value: '1'
sysctl_set: true
sysctl_file: /etc/sysctl.d/90-network.conf
state: present
reload: true
- name: Check installed packages
ansible.builtin.package_facts:
manager: auto
- name: Install frr
become: true
ansible.builtin.package:
name: frr
state: present
- name: Enable FRR BGP daemon
become: true
ansible.builtin.lineinfile:
path: /etc/frr/daemons
regexp: "^bgpd="
line: "bgpd=yes"
owner: frr
group: frr
mode: '640'
- name: Enable FRR BFD daemon
become: true
ansible.builtin.lineinfile:
path: /etc/frr/daemons
regexp: "^bfdd="
line: "bfdd=yes"
owner: frr
group: frr
mode: '640'
- name: Enable retain option of zebra
become: true
ansible.builtin.lineinfile:
path: /etc/frr/daemons
regexp: "^zebra_options="
line: "zebra_options=\" -A 127.0.0.1 -s 90000000 -r \""
owner: frr
group: frr
mode: '640'
- name: Configure FRR
become: true
ansible.builtin.template:
src: frr.conf.j2
dest: /etc/frr/frr.conf
owner: frr
group: frr
mode: '640'
- name: Enable FRR Zebra daemon
become: true
ansible.builtin.lineinfile:
path: /etc/frr/daemons
regexp: "^zebra="
line: "zebra=yes"
owner: frr
group: frr
mode: '640'
- name: Enable and start FRR
become: true
ansible.builtin.service:
name: frr
enabled: true
state: restarted

@ -0,0 +1,77 @@
hostname {{ ansible_hostname }}
log file /var/log/frr/frr.log
service integrated-vtysh-config
line vty
frr version 7.0
debug bfd peer
debug bfd network
debug bfd zebra
debug bgp graceful-restart
debug bgp neighbor-events
debug bgp updates
debug bgp update-groups
router bgp 64999
bgp log-neighbor-changes
bgp graceful-shutdown
bgp graceful-restart
bgp graceful-restart notification
bgp graceful-restart restart-time 60
bgp graceful-restart preserve-fw-state
! bgp long-lived-graceful-restart stale-time 15
neighbor downlink peer-group
neighbor downlink remote-as internal
neighbor downlink bfd
neighbor downlink bfd profile devstack
neighbor downlink password f00barZ
! neighbor downlink capability extended-nexthop
neighbor controller-port interface peer-group downlink
neighbor uplink peer-group
neighbor uplink remote-as external
neighbor uplink bfd
neighbor uplink bfd profile devstack
! neighbor uplink capability extended-nexthop
neighbor spine-port interface peer-group uplink
address-family ipv4 unicast
redistribute connected
neighbor downlink route-reflector-client
neighbor downlink next-hop-self
neighbor downlink prefix-list only-host-prefixes out
neighbor uplink allowas-in origin
neighbor uplink prefix-list only-default-host-prefixes in
exit-address-family
address-family ipv6 unicast
redistribute connected
neighbor downlink activate
neighbor downlink route-reflector-client
neighbor downlink next-hop-self
neighbor uplink activate
neighbor uplink allowas-in origin
neighbor uplink prefix-list only-default-host-prefixes in
exit-address-family
address-family l2vpn evpn
neighbor uplink activate
neighbor uplink allowas-in origin
neighbor downlink activate
neighbor downlink route-reflector-client
exit-address-family
ip prefix-list only-host-prefixes permit 0.0.0.0/0 ge 32
ipv6 prefix-list only-host-prefixes permit ::/0 ge 128
ip nht resolve-via-default
bfd
profile devstack
detect-multiplier 10
transmit-interval 500
receive-interval 500

131
roles/spine/tasks/main.yml Normal file

@ -0,0 +1,131 @@
---
- name: Workaround router advertisement packets polluting routing tables
become: true
ansible.builtin.shell:
cmd: |
for i in $(ls /proc/sys/net/ipv6/conf/*/forwarding); do echo 1 > $i; done
changed_when: false
- name: Register interfaces
ansible.builtin.shell:
cmd: "ls -1 /proc/sys/net/ipv4/conf/*/rp_filter | cut -d/ -f7"
register: interfaces
changed_when: false
- name: Disable reverse path forwarding validation
become: true
ansible.posix.sysctl:
name: "net.ipv4.conf.{{ item }}.rp_filter"
value: "0"
sysctl_set: true
sysctl_file: /etc/sysctl.d/99-sysctl.conf
state: present
reload: true
loop: "{{ interfaces.stdout_lines }}"
register: result
retries: 3
timeout: 60
until: result is not failed
- name: Disable reverse path forwarding validation
become: true
ansible.posix.sysctl:
name: "{{ item.key }}"
value: "{{ item.value }}"
sysctl_set: true
sysctl_file: /etc/sysctl.d/99-sysctl.conf
state: present
reload: true
with_dict:
net.ipv4.conf.all.rp_filter: '0'
net.ipv4.conf.default.rp_filter: '0'
register: result
retries: 3
timeout: 60
until: result is not failed
- name: Set IPv4 forwarding
become: true
ansible.posix.sysctl:
name: net.ipv4.ip_forward
value: '1'
sysctl_set: true
sysctl_file: /etc/sysctl.d/90-network.conf
state: present
reload: true
- name: Set IPv6 forwarding
become: true
ansible.posix.sysctl:
name: net.ipv6.conf.all.forwarding
value: '1'
sysctl_set: true
sysctl_file: /etc/sysctl.d/90-network.conf
state: present
reload: true
- name: Check installed packages
ansible.builtin.package_facts:
manager: auto
- name: Install frr
become: true
ansible.builtin.package:
name: frr
state: present
- name: Enable FRR BGP daemon
become: true
ansible.builtin.lineinfile:
path: /etc/frr/daemons
regexp: "^bgpd="
line: "bgpd=yes"
owner: frr
group: frr
mode: '640'
- name: Enable FRR BFD daemon
become: true
ansible.builtin.lineinfile:
path: /etc/frr/daemons
regexp: "^bfdd="
line: "bfdd=yes"
owner: frr
group: frr
mode: '640'
- name: Enable retain option of zebra
become: true
ansible.builtin.lineinfile:
path: /etc/frr/daemons
regexp: "^zebra_options="
line: "zebra_options=\" -A 127.0.0.1 -s 90000000 -r \""
owner: frr
group: frr
mode: '640'
- name: Configure FRR
become: true
ansible.builtin.template:
src: frr.conf.j2
dest: /etc/frr/frr.conf
owner: frr
group: frr
mode: '640'
- name: Enable FRR Zebra daemon
become: true
ansible.builtin.lineinfile:
path: /etc/frr/daemons
regexp: "^zebra="
line: "zebra=yes"
owner: frr
group: frr
mode: '640'
- name: Enable and start FRR
become: true
ansible.builtin.service:
name: frr
enabled: true
state: restarted

@ -0,0 +1,53 @@
hostname {{ ansible_hostname }}
log file /var/log/frr/frr.log
service integrated-vtysh-config
line vty
frr version 7.0
debug bfd peer
debug bfd network
debug bfd zebra
debug bgp graceful-restart
debug bgp neighbor-events
debug bgp updates
debug bgp update-groups
router bgp 65000
bgp log-neighbor-changes
bgp graceful-shutdown
neighbor downlink peer-group
neighbor downlink remote-as external
neighbor downlink bfd
neighbor downlink bfd profile devstack
! neighbor downlink capability extended-nexthop
neighbor leaf0-port interface peer-group downlink
neighbor leaf1-port interface peer-group downlink
address-family ipv4 unicast
redistribute connected
neighbor downlink prefix-list only-host-prefixes in
exit-address-family
address-family ipv6 unicast
redistribute connected
neighbor downlink activate
neighbor downlink prefix-list only-host-prefixes in
exit-address-family
address-family l2vpn evpn
neighbor downlink activate
exit-address-family
ip prefix-list only-host-prefixes permit 0.0.0.0/0 ge 32
ipv6 prefix-list only-host-prefixes permit ::/0 ge 128
ip nht resolve-via-default
bfd
profile devstack
detect-multiplier 10
transmit-interval 500
receive-interval 500

@ -9,10 +9,11 @@
check:
jobs:
- openstack-tox-functional-with-sudo
- ovn-bgp-agent-tempest-plugin-multinode:
voting: false
experimental:
jobs:
- openstack-tox-py310-with-oslo-master
- ovn-bgp-agent-tempest-plugin
periodic-weekly:
jobs:
- openstack-tox-py310

@ -0,0 +1,117 @@
- nodeset:
name: ovn-bgp-agent-four-node-jammy
nodes:
- name: controller
label: ubuntu-jammy
- name: leaf-1
label: ubuntu-jammy
- name: leaf-2
label: ubuntu-jammy
- name: spine
label: ubuntu-jammy
groups:
- name: controller
nodes:
- controller
- name: subnode
nodes:
- spine
- name: leafs
nodes:
- leaf-1
- leaf-2
- name: tempest
nodes:
- spine
- job:
name: ovn-bgp-agent-tempest-plugin-multinode
parent: neutron-tempest-plugin-ovn
nodeset: ovn-bgp-agent-four-node-jammy
timeout: 10800
post-timeout: 9600
required-projects:
- openstack/devstack
- openstack/ovn-bgp-agent
vars:
devstack_localrc:
ENABLE_TLS: True
OVN_BUILD_FROM_SOURCE: True
OVN_BRANCH: v24.03.4
OVS_BRANCH: v3.3.3
FRR_USE_BFD: True
devstack_plugins:
ovn-bgp-agent: https://opendev.org/openstack/ovn-bgp-agent
devstack_services:
tls-proxy: true
tempest: false
devstack_local_conf:
post-config:
"/$NEUTRON_CORE_PLUGIN_CONF":
ovn:
enable_distributed_floating_ip: True
pre-run: playbooks/configure_bgp_networking.yaml
group-vars:
subnode:
devstack_localrc:
LIBS_FROM_GIT: neutron-tempest-plugin
OVN_BUILD_FROM_SOURCE: False
Q_PLUGIN: "noop"
SERVICES_FOR_TEMPEST: neutron,nova,keystone,glance
devstack_plugins:
neutron-tempest-plugin: https://opendev.org/openstack/neutron-tempest-plugin
devstack_services:
tls-proxy: true
tempest: true
etcd3: false
mysql: false
c-api: false
c-bak: false
c-sch: false
c-vol: false
cinder: false
n-api: false
n-api-meta: false
n-cond: false
n-cpu: false
n-novnc: false
n-sch: false
placement-api: false
br-ex-tcpdump: false
br-int-flows: false
q-ovn-metadata-agent: false
q-ovn-agent: false
ovn-controller: false
ovn-northd: false
ovs-vswitchd: false
ovsdb-server: false
neutron-dns: false
neutron-log: false
neutron-qos: false
neutron-segments: false
neutron-trunk: false
neutron-uplink-status-propagation: false
neutron-network-segment-range: false
neutron-port-forwarding: false
neutron-conntrack-helper: false
neutron-tag-ports-during-bulk-creation: false
neutron-ndp-proxy: false
neutron-subnet-external-network: false
neutron-port-trusted-vif: false
devstack_local_conf:
post-config: {}
test-config:
$TEMPEST_CONFIG:
service_available:
neutron: True
nova: True
glance: True
key: True
neutron_plugin_options:
firewall_driver: ovn
tempest_test_regex: "^neutron_tempest_plugin.scenario"
tempest_exclude_regex: "\
(^neutron_tempest_plugin.scenario.test_port_forwardings)|\
(^neutron_tempest_plugin.scenario.test_multiple_gws)"

@ -1,15 +0,0 @@
- job:
name: ovn-bgp-agent-tempest-plugin
parent: neutron-tempest-plugin-ovn
timeout: 10800
required-projects:
- openstack/devstack
- openstack/ovn-bgp-agent
- openstack/neutron-tempest-plugin
vars:
devstack_localrc:
ENABLE_TLS: True
devstack_plugins:
ovn-bgp-agent: https://git.openstack.org/openstack/ovn-bgp-agent
devstack_services:
tls-proxy: true