openstack-helm-infra/ovn/templates/bin/_ovn-controller-init.sh.tpl
Vladimir Kozhukalov fb90642b18 Update ovn controller init script
- OVN init script must be able to attach an interface
  to the provider network bridge and migrate IP from the
  interface to the bridge exactly like Neutron OVS agent
  init script does it.

- OVN init script sets gateway option to those OVN controller
  instances which are running on nodes with l3-agent=enabled
  label.

Change-Id: I24345c1f85c1e75af6e804f09d35abf530ddd6b4
2024-03-21 16:03:51 -05:00

149 lines
5.3 KiB
Smarty

#!/bin/bash -xe
# Copyright 2023 VEXXHOST, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
function get_ip_address_from_interface {
local interface=$1
local ip=$(ip -4 -o addr s "${interface}" | awk '{ print $4; exit }' | awk -F '/' 'NR==1 {print $1}')
if [ -z "${ip}" ] ; then
exit 1
fi
echo ${ip}
}
function get_ip_prefix_from_interface {
local interface=$1
local prefix=$(ip -4 -o addr s "${interface}" | awk '{ print $4; exit }' | awk -F '/' 'NR==1 {print $2}')
if [ -z "${prefix}" ] ; then
exit 1
fi
echo ${prefix}
}
function migrate_ip_from_nic {
src_nic=$1
bridge_name=$2
# Enabling explicit error handling: We must avoid to lose the IP
# address in the migration process. Hence, on every error, we
# attempt to assign the IP back to the original NIC and exit.
set +e
ip=$(get_ip_address_from_interface ${src_nic})
prefix=$(get_ip_prefix_from_interface ${src_nic})
bridge_ip=$(get_ip_address_from_interface "${bridge_name}")
bridge_prefix=$(get_ip_prefix_from_interface "${bridge_name}")
ip link set ${bridge_name} up
if [[ -n "${ip}" && -n "${prefix}" ]]; then
ip addr flush dev ${src_nic}
if [ $? -ne 0 ] ; then
ip addr add ${ip}/${prefix} dev ${src_nic}
echo "Error while flushing IP from ${src_nic}."
exit 1
fi
ip addr add ${ip}/${prefix} dev "${bridge_name}"
if [ $? -ne 0 ] ; then
echo "Error assigning IP to bridge "${bridge_name}"."
ip addr add ${ip}/${prefix} dev ${src_nic}
exit 1
fi
elif [[ -n "${bridge_ip}" && -n "${bridge_prefix}" ]]; then
echo "Bridge '${bridge_name}' already has IP assigned. Keeping the same:: IP:[${bridge_ip}]; Prefix:[${bridge_prefix}]..."
elif [[ -z "${bridge_ip}" && -z "${ip}" ]]; then
echo "Interface and bridge have no ips configured. Leaving as is."
else
echo "Interface ${src_nic} has invalid IP address. IP:[${ip}]; Prefix:[${prefix}]..."
exit 1
fi
set -e
}
# Detect tunnel interface
tunnel_interface="{{- .Values.network.interface.tunnel -}}"
if [ -z "${tunnel_interface}" ] ; then
# search for interface with tunnel network routing
tunnel_network_cidr="{{- .Values.network.interface.tunnel_network_cidr -}}"
if [ -z "${tunnel_network_cidr}" ] ; then
tunnel_network_cidr="0/0"
fi
# If there is not tunnel network gateway, exit
tunnel_interface=$(ip -4 route list ${tunnel_network_cidr} | awk -F 'dev' '{ print $2; exit }' \
| awk '{ print $1 }') || exit 1
fi
ovs-vsctl set open . external_ids:ovn-encap-ip="$(get_ip_address_from_interface ${tunnel_interface})"
# Configure system ID
set +e
ovs-vsctl get open . external-ids:system-id
if [ $? -eq 1 ]; then
ovs-vsctl set open . external-ids:system-id="$(uuidgen)"
fi
set -e
# Configure OVN remote
{{- if empty .Values.conf.ovn_remote -}}
{{- $sb_svc_name := "ovn-ovsdb-sb" -}}
{{- $sb_svc := (tuple $sb_svc_name "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup") -}}
{{- $sb_port := (tuple "ovn-ovsdb-sb" "internal" "ovsdb" . | include "helm-toolkit.endpoints.endpoint_port_lookup") -}}
{{- $sb_service_list := list -}}
{{- range $i := until (.Values.pod.replicas.ovn_ovsdb_sb | int) -}}
{{- $sb_service_list = printf "tcp:%s-%d.%s:%s" $sb_svc_name $i $sb_svc $sb_port | append $sb_service_list -}}
{{- end }}
ovs-vsctl set open . external-ids:ovn-remote="{{ include "helm-toolkit.utils.joinListWithComma" $sb_service_list }}"
{{- else -}}
ovs-vsctl set open . external-ids:ovn-remote="{{ .Values.conf.ovn_remote }}"
{{- end }}
# Configure OVN values
ovs-vsctl set open . external-ids:rundir="/var/run/openvswitch"
ovs-vsctl set open . external-ids:ovn-encap-type="{{ .Values.conf.ovn_encap_type }}"
ovs-vsctl set open . external-ids:ovn-bridge="{{ .Values.conf.ovn_bridge }}"
ovs-vsctl set open . external-ids:ovn-bridge-mappings="{{ .Values.conf.ovn_bridge_mappings }}"
GW_ENABLED=$(cat /tmp/gw-enabled/gw-enabled)
if [[ ${GW_ENABLED} == enabled ]]; then
ovs-vsctl set open . external-ids:ovn-cms-options={{ .Values.conf.onv_cms_options_gw_enabled }}
else
ovs-vsctl set open . external-ids:ovn-cms-options={{ .Values.conf.ovn_cms_options }}
fi
# Configure hostname
{{- if .Values.pod.use_fqdn.compute }}
ovs-vsctl set open . external-ids:hostname="$(hostname -f)"
{{- else }}
ovs-vsctl set open . external-ids:hostname="$(hostname)"
{{- end }}
# Create bridges and create ports
# handle any bridge mappings
# /tmp/auto_bridge_add is one line json file: {"br-ex1":"eth1","br-ex2":"eth2"}
for bmap in `sed 's/[{}"]//g' /tmp/auto_bridge_add | tr "," "\n"`
do
bridge=${bmap%:*}
iface=${bmap#*:}
ovs-vsctl --may-exist add-br $bridge -- set bridge $bridge protocols=OpenFlow13
if [ -n "$iface" ] && [ "$iface" != "null" ] && ( ip link show $iface 1>/dev/null 2>&1 );
then
ovs-vsctl --may-exist add-port $bridge $iface
migrate_ip_from_nic $iface $bridge
fi
done