update for el9

This commit is contained in:
Neil Hanlon 2023-04-23 22:14:38 -04:00
parent 803bb21868
commit 129b0c5d3a
Signed by: neil
GPG Key ID: 705BC21EC3C70F34
13 changed files with 172 additions and 307 deletions

View File

@ -1,5 +1,4 @@
warn_list: warn_list:
- internal-error - internal-error
- syntax-check
skip_list: skip_list:
- '204' - '204'

View File

@ -1,7 +1,7 @@
--- ---
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.4.0 rev: v4.4.0
hooks: hooks:
- id: trailing-whitespace - id: trailing-whitespace
- id: end-of-file-fixer - id: end-of-file-fixer
@ -12,24 +12,22 @@ repos:
- id: pretty-format-json - id: pretty-format-json
- id: detect-private-key - id: detect-private-key
- repo: local # - repo: local
hooks: # hooks:
- id: ansible-lint # # - id: ansible-lint
name: Ansible-lint # name: Ansible-lint
description: This hook runs ansible-lint. # description: This hook runs ansible-lint.
entry: ansible-lint --force-color # entry: ansible-lint --force-color
language: python # language: python
# do not pass files to ansible-lint, see: # # do not pass files to ansible-lint, see:
# https://github.com/ansible/ansible-lint/issues/611 # # https://github.com/ansible/ansible-lint/issues/611
pass_filenames: false # pass_filenames: false
always_run: true # always_run: true
- repo: https://github.com/adrienverge/yamllint.git - repo: https://github.com/adrienverge/yamllint.git
rev: v1.26.0 rev: v1.31.0
hooks: hooks:
- id: yamllint - id: yamllint
files: \.(yaml|yml)$ files: \.(yaml|yml)$
types: [file, yaml] types: [file, yaml]
entry: yamllint entry: yamllint
exclude: '^ansible/playbooks/files/lxc_install_dnf.yml$'

View File

@ -66,7 +66,7 @@ no_log = False
log_path = tmp/ansible.log log_path = tmp/ansible.log
known_hosts = tmp/known_hosts known_hosts = tmp/known_hosts
roles_path = roles/local:roles/public roles_path = roles/local:roles/public
collections_paths = collections collections_paths = collections/local:collections/public
remote_user=root remote_user=root
[inventory] [inventory]

View File

@ -54,8 +54,9 @@
tags: images tags: images
# yamllint disable rule:braces # yamllint disable rule:braces
loop: loop:
- { name: 'cirros', filename: 'http://download.cirros-cloud.net/0.5.1/cirros-0.5.1-x86_64-disk.img', properties: {cpu_arch: x86_64, distro: cirros}} # - { name: 'cirros', filename: 'http://download.cirros-cloud.net/0.5.1/cirros-0.5.1-x86_64-disk.img', properties: {cpu_arch: x86_64, distro: cirros, protected: true}}
- { name: 'rockylinux85', filename: 'https://dl.rockylinux.org/pub/rocky/8/images/Rocky-8-GenericCloud-8.5-20211114.2.x86_64.qcow2', properties: {cpu_arch: x86_64, distro: rocky}} - { name: 'rockylinux86', filename: 'https://dl.rockylinux.org/pub/rocky/8/images/Rocky-8-GenericCloud.latest.x86_64.qcow2', properties: {cpu_arch: x86_64, distro: rocky}}
- { name: 'rockylinux90', filename: 'https://dl.rockylinux.org/pub/rocky/9/images/Rocky-9-GenericCloud.latest.x86_64.qcow2', properties: {cpu_arch: x86_64, distro: rocky}}
# yamllint enable rule:braces # yamllint enable rule:braces
post_tasks: post_tasks:

View File

@ -1,135 +0,0 @@
#!/bin/bash
MGMT_SUBNET='172.29.220'
VXLAN_SUBNET='172.29.224'
STORAGE_SUBNET='172.29.228'
iface_mgmt=$(ip addr | grep $MGMT_SUBNET | awk '{print $NF}')
iface_vxlan=$(ip addr | grep $VXLAN_SUBNET | awk '{print $NF}')
iface_storage=$(ip addr | grep $STORAGE_SUBNET | awk '{print $NF}')
if [[ -z "${iface_mgmt}" ]]; then
echo "can't find mgmt interface"
else
echo "mgmt interface is: ${iface_mgmt}"
fi
if [[ -z "${iface_vxlan}" ]]; then
echo "can't find vxlan interface"
else
echo "vxlan interface is: ${iface_vxlan}"
fi
if [[ -z "${iface_storage}" ]]; then
echo "can't find storage interface"
else
echo "storage interface is: ${iface_storage}"
fi
if [[ -z "${iface_mgmt}" && ( -z "${iface_vxlan}" || -z "${iface_storage}" ) ]]; then
echo "Stopping. Only a mgmt interface found. Need at least one of vxlan or storage"
exit 1
fi
HOSTNAME="$(hostname)"
hostpart=''
if [[ "$HOSTNAME" =~ "infra" ]]; then
let hostpart='5'
cat << EOF > ifcfg-br-mgmt\:10
DEVICE=br-mgmt:10
ONPARENT=on
IPADDR=${MGMT_SUBNET}.10
PREFIX=22
EOF
cat << EOF > ifcfg-br-mgmt\:11
DEVICE=br-mgmt:11
ONPARENT=on
IPADDR=${MGMT_SUBNET}.11
PREFIX=22
EOF
fi
if [[ "${HOSTNAME}" =~ "compute" ]]; then
let hostpart='6'
fi
if [[ "${HOSTNAME}" =~ "storage1" ]]; then
let hostpart='7'
fi
if [[ "${HOSTNAME}" =~ "storage2" ]]; then
let hostpart='8'
fi
if [[ "${HOSTNAME}" =~ "storage3" ]]; then
let hostpart='9'
fi
if [[ ! -z "${iface_mgmt}" ]]; then
cat << EOF > ifcfg-br-mgmt
BOOTPROTO=none
DEVICE=br-mgmt
NM_CONTROLLED=no
IPADDR=${MGMT_SUBNET}.${hostpart}
NETMASK=255.255.252.0
ONBOOT=yes
TYPE=Bridge
USERCTL=no
EOF
cat << EOF > ifcfg-${iface_mgmt}
TYPE=Ethernet
DEVICE=${iface_mgmt}
ONBOOT=yes
BRIDGE=br-mgmt
HWADDR=$(ip link show ${iface_mgmt} | awk '/link\/ether/{print $2}')
EOF
fi
if [[ "${HOSTNAME}" =~ "storage" || ! -z "${iface_storage}" ]]; then
cat << EOF > ifcfg-br-storage
BOOTPROTO=none
DEVICE=br-storage
IPADDR=${STORAGE_SUBNET}.${hostpart}
NETMASK=255.255.252.0
NM_CONTROLLED=no
ONBOOT=yes
TYPE=Bridge
USERCTL=no
EOF
cat << EOF > ifcfg-${iface_storage}
TYPE=Ethernet
DEVICE=${iface_storage}
ONBOOT=yes
BRIDGE=br-storage
HWADDR=$(ip link show ${iface_storage} | awk '/link\/ether/{print $2}')
EOF
fi
if [[ ! -z "${iface_vxlan}" ]]; then
cat << EOF > ifcfg-br-vxlan
BOOTPROTO=none
DEVICE=br-vxlan
IPADDR=${VXLAN_SUBNET}.${hostpart}
NETMASK=255.255.252.0
NM_CONTROLLED=no
ONBOOT=yes
TYPE=Bridge
USERCTL=no
EOF
cat << EOF > ifcfg-${iface_vxlan}
TYPE=Ethernet
DEVICE=${iface_vxlan}
ONBOOT=yes
BRIDGE=br-vxlan
HWADDR=$(ip link show ${iface_vxlan} | awk '/link\/ether/{print $2}')
EOF
fi

View File

@ -5,16 +5,17 @@ cidr_networks:
storage: 172.29.228.0/22 storage: 172.29.228.0/22
used_ips: used_ips:
- "172.29.220.1,172.29.220.50" - "172.29.220.1"
- "172.29.224.1,172.29.224.50" - "172.29.224.1"
- "172.29.228.1,172.29.228.50" - "172.29.228.1"
- "172.29.232.1"
global_overrides: global_overrides:
# The internal and external VIP should be different IPs, however they # The internal and external VIP should be different IPs, however they
# do not need to be on separate networks. # do not need to be on separate networks.
external_lb_vip_address: 172.29.220.10 external_lb_vip_address: 172.29.220.100
internal_lb_vip_address: 172.29.220.11 internal_lb_vip_address: "{{ bootstrap_host_public_address | default(ansible_facts['default_ipv4']['address']) }}"
management_bridge: "br-mgmt" management_bridge: "br-mgmt"
provider_networks: provider_networks:
- network: - network:
@ -27,6 +28,14 @@ global_overrides:
- all_containers - all_containers
- hosts - hosts
is_container_address: true is_container_address: true
- network:
container_bridge: "br-external"
container_type: "veth"
container_interface: "eth12"
type: "flat"
net_name: "external"
group_binds:
- neutron_linuxbridge_agent
- network: - network:
container_bridge: "br-vxlan" container_bridge: "br-vxlan"
container_type: "veth" container_type: "veth"
@ -52,13 +61,15 @@ global_overrides:
x-infra-hosts: &x-infra-hosts x-infra-hosts: &x-infra-hosts
infra1: infra1:
ip: 172.29.220.5 ip: 172.29.220.10
x-compute-hosts: &x-compute-hosts x-compute-hosts: &x-compute-hosts
compute1: compute1:
ip: 172.29.220.6 ip: 172.29.220.20
compute2:
ip: 172.29.220.21
x-storage-hosts: &x-storage-hosts x-storage-hosts: &x-storage-hosts
storage1: storage1:
ip: 172.29.220.7 ip: 172.29.220.30
container_vars: container_vars:
cinder_backends: cinder_backends:
limit_container_types: cinder_volume limit_container_types: cinder_volume
@ -66,7 +77,7 @@ x-storage-hosts: &x-storage-hosts
volume_group: cinder-volumes volume_group: cinder-volumes
volume_driver: cinder.volume.drivers.lvm.LVMVolumeDriver volume_driver: cinder.volume.drivers.lvm.LVMVolumeDriver
volume_backend_name: LVM_iSCSI volume_backend_name: LVM_iSCSI
iscsi_ip_address: "172.29.228.7" iscsi_ip_address: "172.29.228.10"
## ##
## Infrastructure ## Infrastructure

View File

@ -1,57 +0,0 @@
diff --git a/run_tests.sh b/run_tests.sh
index 48ce6583b..5fffe12b6 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -54,7 +54,7 @@ source /etc/os-release || source /usr/lib/os-release
# Figure out the appropriate package install command
case ${ID,,} in
*suse*) pkg_mgr_cmd="zypper -n in" ;;
- centos|rhel|fedora) pkg_mgr_cmd="dnf install -y" ;;
+ rocky|rhel|fedora) pkg_mgr_cmd="dnf install -y" ;;
ubuntu|debian) pkg_mgr_cmd="apt-get install -y" ;;
# Gentoo needs to have version set since it's rolling
gentoo) pkg_mgr_cmd="emerge --jobs=4"; VERSION="rolling" ;;
diff --git a/scripts/bootstrap-ansible.sh b/scripts/bootstrap-ansible.sh
index 49a122a00..c464ffe72 100755
--- a/scripts/bootstrap-ansible.sh
+++ b/scripts/bootstrap-ansible.sh
@@ -71,7 +71,7 @@ determine_distro
# Install the base packages
case ${DISTRO_ID} in
- centos|rhel)
+ rocky|rhel)
dnf -y install \
git curl autoconf gcc gcc-c++ nc \
python3 python3-devel libselinux-python3 \
diff --git a/scripts/scripts-library.sh b/scripts/scripts-library.sh
index 742366cde..8d5ec1db2 100755
--- a/scripts/scripts-library.sh
+++ b/scripts/scripts-library.sh
@@ -212,7 +212,7 @@ function setup_ara {
function run_dstat {
if [ "$GATE_EXIT_RUN_DSTAT" == true ]; then
case ${DISTRO_ID} in
- centos|rhel)
+ rocky|rhel)
dnf -y install dstat
;;
ubuntu)
@@ -261,7 +261,7 @@ function log_instance_info {
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get -y install iproute2 net-tools
;;
- centos|rhel)
+ rocky|rhel)
dnf -y install iproute
;;
esac
@@ -336,7 +336,7 @@ function get_instance_info {
determine_distro
case ${DISTRO_ID} in
- centos|rhel|fedora|opensuse)
+ rocky|rhel|fedora|opensuse)
rpm -qa | sort > \
"/openstack/log/instance-info/host_packages_info_${TS}.log" || true
;;

View File

@ -4,4 +4,4 @@ lxc_hosts_container_build_command: "dnf --assumeyes --installroot=/var/lib/machi
lxc_container_map: lxc_container_map:
distro: "{{ hostvars[physical_host]['ansible_facts']['distribution'] | lower }}" distro: "{{ hostvars[physical_host]['ansible_facts']['distribution'] | lower }}"
arch: "{{ lxc_architecture_mapping.get( hostvars[physical_host]['ansible_facts']['architecture'] | lower ) }}" arch: "{{ lxc_architecture_mapping.get( hostvars[physical_host]['ansible_facts']['architecture'] | lower ) }}"
release: "{{ hostvars[pyhsical_host]['ansible_facts']['distribution_major_version'] }}" release: "{{ hostvars[physical_host]['ansible_facts']['distribution_major_version'] }}"

View File

@ -2,9 +2,11 @@
# Installs everything on hosts # Installs everything on hosts
# #
- name: Bootstrap nodes for distributed OSA installation - name: Bootstrap nodes for distributed OSA installation
hosts: "{{ host | default('infra1,compute1,storage1') }}" hosts: "{{ host | default('infra1,compute1,compute2,storage1') }}"
become: true become: true
vars:
handlers: handlers:
- import_tasks: handlers/main.yml - import_tasks: handlers/main.yml
@ -26,19 +28,37 @@
tasks: tasks:
- name: Initialize nodes - name: Initialize nodes
import_tasks: tasks/init-nodes.yml tags:
- init
args:
apply:
tags:
- init
include_tasks: tasks/init-nodes.yml
- name: Reboot - name: Reboot
import_tasks: tasks/reboot.yml import_tasks: tasks/reboot.yml
when: reboot | default(true) | bool when: reboot | default(true) | bool
- name: Setup infra hosts - name: Setup infra hosts
import_tasks: tasks/infra-host.yml include_tasks: tasks/infra-host.yml
when: tag.find("infra") != -1 or aio_install | default(false) | bool # when on an infra tagged host tags:
- infrastructure
args:
apply:
tags:
- infrastructure
when: tag.find("infra") != -1 or aio_install | default(false) | bool
- name: Setup storage hosts - name: Setup storage hosts
import_tasks: tasks/storage-host.yml include_tasks: tasks/storage-host.yml
when: tag.find("storage") != -1 # when on an storage tagged host tags:
- storage
args:
apply:
tags:
- storage
when: tag.find("storage") != -1
post_tasks: post_tasks:
- name: Touching run file that ansible has ran here - name: Touching run file that ansible has ran here

View File

@ -12,11 +12,11 @@
block: block:
- name: Copy template to etc - name: Copy template to etc
ansible.builtin.copy: ansible.builtin.copy:
remote_src: yes remote_src: true
src: /opt/openstack-ansible/etc/openstack_deploy/ src: /opt/openstack-ansible/etc/openstack_deploy/
dest: /etc/openstack_deploy dest: /etc/openstack_deploy
directory_mode: yes directory_mode: true
force: no force: false
- name: Copy distributed openstack configs - name: Copy distributed openstack configs
ansible.builtin.copy: ansible.builtin.copy:
@ -35,17 +35,6 @@
creates: /etc/openstack_deploy/user_secrets.yml.tar creates: /etc/openstack_deploy/user_secrets.yml.tar
when: aio_install is undefined | default(false) when: aio_install is undefined | default(false)
#- import_tasks: tasks/python3-lxc.yml
#- name:
# copy:
# content: ""
# dest: /usr/share/lxc/config/rockylinux.common.conf
# mode: '0644'
# owner: root
# group: root
# tags: python3-lxc
- name: "[AIO] Deploy and setup configuration / bootstrap" - name: "[AIO] Deploy and setup configuration / bootstrap"
when: aio_install | default('false') | bool when: aio_install | default('false') | bool
block: block:
@ -60,7 +49,7 @@
chdir: /opt/openstack-ansible/ chdir: /opt/openstack-ansible/
creates: /etc/openstack_deploy/ creates: /etc/openstack_deploy/
environment: environment:
SCENARIO: "{{ SCENARIO | default('aio_metal') }}" SCENARIO: "{{ SCENARIO | default('aio_lxc') }}"
tags: tags:
- bootstrap - bootstrap
- aio - aio
@ -77,36 +66,9 @@
dest: /etc/openstack_deploy/ dest: /etc/openstack_deploy/
mode: '0644' mode: '0644'
with_items: with_items:
- user_lxc
- user_galera - user_galera
- user_debug
tags: config tags: config
- name: manually patch lxc_hosts role to bring in powertools repo
ansible.builtin.copy:
src: "files/{{ item }}.yml"
dest: /etc/ansible/roles/lxc_hosts/tasks/
mode: '0644'
with_items:
- lxc_install_dnf
tags: config,patch
- name: manually patch os_nova role to kill powervmtools and futures== requiresments
ansible.builtin.copy:
src: "files/{{ item }}"
dest: /tmp/
mode: '0644'
with_items:
- os_nova.patch
tags: config,patch
- name: patch the thing
args:
chdir: /etc/ansible/roles/os_nova/
creates: /etc/ansible/roles/os_nova/.patched
ansible.builtin.shell: 'patch -p1 < /tmp/os_nova.patch && touch .patched'
- name: Disable SSH Agent Forwarding - name: Disable SSH Agent Forwarding
lineinfile: lineinfile:
dest: /etc/ssh/sshd_config dest: /etc/ssh/sshd_config

View File

@ -2,9 +2,9 @@
- name: Disable Firewalld - name: Disable Firewalld
ansible.builtin.systemd: ansible.builtin.systemd:
name: firewalld.service name: firewalld.service
masked: yes masked: true
enabled: no enabled: false
force: yes force: true
state: stopped state: stopped
tags: services tags: services
@ -20,12 +20,24 @@
state: latest state: latest
tags: packages tags: packages
- name: remove curl
ansible.builtin.dnf:
name: "curl"
state: absent
tags: packages
- name: add curl-minimal
ansible.builtin.dnf:
name: "curl-minimal"
state: latest
tags: packages
- name: Generate SSH key - name: Generate SSH key
block: block:
- name: Create ssh key for root - name: Create ssh key for root
ansible.builtin.user: ansible.builtin.user:
name: root name: root
generate_ssh_key: yes generate_ssh_key: true
ssh_key_bits: 4096 ssh_key_bits: 4096
ssh_key_file: .ssh/id_rsa ssh_key_file: .ssh/id_rsa
register: sshkey_register register: sshkey_register
@ -36,7 +48,7 @@
fetch: fetch:
src: "~/.ssh/id_rsa.pub" src: "~/.ssh/id_rsa.pub"
dest: "files/buffer/infra-id_rsa.pub" dest: "files/buffer/infra-id_rsa.pub"
flat: yes flat: true
when: sshkey_register.ssh_public_key != "" when: sshkey_register.ssh_public_key != ""
register: sshkey_fetch register: sshkey_fetch
@ -54,23 +66,12 @@
notify: notify:
- restart_sshd - restart_sshd
- name: Copy interface.sh script to host - name: Setup network
ansible.builtin.copy: include_tasks: tasks/setup-network.yml
src: 'files/interfaces.sh' when: aio_install is undefined or not aio_install # don't run when AIO
dest: '/root/interfaces.sh'
mode: 0744
owner: 'root'
group: 'root'
when: aio_install is undefined or not aio_install
tags:
- interfaces
- name: Generate ifcfg files
shell: /root/interfaces.sh
args: args:
chdir: /etc/sysconfig/network-scripts/ apply:
creates: /etc/sysconfig/network-scripts/ifcfg-br-mgmt tags: interfaces
when: aio_install is undefined or not aio_install
tags: tags:
- interfaces - interfaces
@ -83,24 +84,23 @@
- wget - wget
- chrony - chrony
- openssh-server - openssh-server
#- python3-devel
- sudo - sudo
- patch # temporary
state: latest state: latest
tags: packages tags: packages
- name: Clone repository - name: Clone repository
ansible.builtin.git: ansible.builtin.git:
#repo: https://opendev.org/openstack/openstack-ansible.git
repo: https://review.opendev.org/openstack/openstack-ansible repo: https://review.opendev.org/openstack/openstack-ansible
#single_branch: yes
dest: /opt/openstack-ansible dest: /opt/openstack-ansible
version: 'master' version: stable/zed
# version: 'b958c02eeed355484be12db736ed81a047f7d7c0'
# refspec: 'refs/changes/81/852181/2'
tags: repos tags: repos
- name: Create ssh key for root - name: Create ssh key for root
ansible.builtin.user: ansible.builtin.user:
name: root name: root
generate_ssh_key: yes generate_ssh_key: true
ssh_key_bits: 4096 ssh_key_bits: 4096
ssh_key_file: .ssh/id_rsa ssh_key_file: .ssh/id_rsa
register: sshkey_register register: sshkey_register
@ -111,7 +111,7 @@
fetch: fetch:
src: "~/.ssh/id_rsa.pub" src: "~/.ssh/id_rsa.pub"
dest: "files/buffer/infra-id_rsa.pub" dest: "files/buffer/infra-id_rsa.pub"
flat: yes flat: true
when: sshkey_register.ssh_public_key != "" when: sshkey_register.ssh_public_key != ""
register: sshkey_fetch register: sshkey_fetch
when: tag.find("infra") != -1 or aio_install | default(false) when: tag.find("infra") != -1 or aio_install | default(false)
@ -137,16 +137,6 @@
when: tag.find("infra") == -1 and sshkey_fetch | default(false) when: tag.find("infra") == -1 and sshkey_fetch | default(false)
tags: sshkey tags: sshkey
#- name: Setup a hosts file for the static deployment
# ansible.builtin.lineinfile:
# dest: /etc/hosts
# line: "{{ hostvars[ansible_fqdn]['ansible_br_mgmt']['ipv4']['address'] }} {{ ansible_hostname }}"
# when:
# - hostvars[ansible_fqdn]['ansible_br_mgmt'] is defined
# - hostvars[ansible_fqdn]['ansible_br_mgmt']['ipv4']['address'] is defined
# tags: debug123
- name: Disable cloud init from future runs - name: Disable cloud init from future runs
file: file:
path: /etc/cloud/cloud-init.disabled path: /etc/cloud/cloud-init.disabled

View File

@ -0,0 +1,39 @@
---
- include_vars: common-network.yml
- name: Remove cloud-init cruft
ignore_errors: true
community.general.nmcli:
state: absent
conn_name: "{{ item }}"
loop:
- cloud-init enp6s0
- cloud-init enp7s0
- cloud-init enp8s0
- cloud-init enp9s0
- name: Create network bridges
community.general.nmcli:
stp: true
type: bridge
conn_name: "{{ 'Bridge-' + item.key }}"
state: present
ifname: "{{ network_bridges[item.key] }}"
method4: manual
ip4: "{{ network_cidrs[item.key] | ansible.utils.ipmath(host_cidr_octets[inventory_hostname]) }}/{{ network_cidrs[item.key] | split('/') | last }}"
method6: ignore
autoconnect: true
loop: "{{ network_interfaces[inventory_hostname] | dict2items }}"
- name: Enslave network interfaces to bridges
community.general.nmcli:
type: bridge-slave
conn_name: "{{ 'Slave-' + item.value }}"
state: present
ifname: "{{ item.value }}"
master: "{{ network_bridges[item.key] }}"
autoconnect: true
mtu: 1450
method4: manual
hairpin: false
loop: "{{ network_interfaces[inventory_hostname] | dict2items }}"

View File

@ -0,0 +1,37 @@
---
network_interfaces:
infra1:
management: enp7s0
tunnel: enp6s0
storage: enp8s0
external: enp9s0
compute1:
management: enp6s0
tunnel: enp7s0
storage: enp8s0
external: enp9s0
compute2:
management: enp7s0
tunnel: enp6s0
storage: enp8s0
external: enp9s0
storage1:
management: enp7s0
storage: enp6s0
network_bridges:
management: br-mgmt
tunnel: br-tunnel
storage: br-storage
external: br-ext
network_cidrs:
management: 172.29.220.0/22
tunnel: 172.29.224.0/22
storage: 172.29.228.0/22
external: 172.29.232.0/22
host_cidr_octets:
infra1: 10
infra2: 11
compute1: 20
compute2: 21
storage1: 30
storage2: 31