#!/bin/bash # # Author: Georg Voell - georg.voell@standby.cloud # Version: @(#)vip-management 3.2.1 25.09.2024 (c)2024 Standby.cloud # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ # # This script can be used free of charge. Use it as is or customize as needed. It is not guaranteed to be # error free and you will not be reimbursed for any damage it may cause. # #@ Add or delete secondary private IP (Virtual IP) #@ Docs: https://docs.oracle.com/en-us/iaas/Content/Network/Tasks/managingIPaddresses.htm #@ #@Usage: vip-management [options] action [ipv4] #@ Options: -h, --help : Displays helptext. #@ -v, --version : Displays the version of the script. #@ Action: #@ status: Show current state (default). #@ add: Attach ipv4 to instance. #@ delete: Detach ipv4 from instance. #@ route: Add ipv4 to default gateway. #@ start: Start network manager profile and check route. #@ stop: Stop network manager profile and if needed vip routing. #@ ipv4: #@ A valid IPv4 that is not used somewhere else #@ #@Examples: #@ vip-management add 10.0.1.50 #@ Create a second interface using private IP (from primary VNIC). #@ vip-management route #@ Add vip to default route. #@ vip-management delete #@ Delete the second interface. # # Exit codes: # 01: Unknown or wrong parameter and only LINUX supported and script needs to be executed with ROOT privileges. # 02: Unknown action. # 03: No 'ifconfig' or 'ip' in PATH. # 04: No suitable interface found in 'ifconfig'. # 05: No IPv4 found in interface. # 06: VIP already defined (add) or does not exists (delete) # 07: No VIP attached # 08: Error while deleting or adding vip # 09: Error while changing route # 99: User interrupt. # # See also: # **install-scripts**(1) # # Update history: # # V 3.0.0 14.05.2021 New version # V 3.0.1 21.05.2021 Try sudo if user isn't root # V 3.0.2 22.05.2021 New action: show # V 3.1.0 05.06.2023 New copyright # V 3.2.0 09.09.2024 New minor version: Options # V 3.2.1 25.09.2024 Use nmcli with OEL8 and OEL9 # # Find executable bash library and source it lib=`which lib.bash 2>/dev/null | sed 's|^no 'lib.bash' in .*||'` if [ "$lib" != "" ]; then source "$lib" else # lib.bash was not in PATH - try to find it in script path progdir=`readlink -f "$0" 2>/dev/null` if [ "$progdir" = "" ]; then progdir=`dirname "$0" 2>/dev/null` else progdir=`dirname "$progdir" 2>/dev/null` fi if [ -r "${progdir}/lib.bash" ]; then source "${progdir}/lib.bash" else echo "Unexpected error: Unable to locate bash library 'lib.bash'." exit 1 fi fi # Needed by the some functions readonly bitArray=(0 128 192 224 240 248 252 254 255) readonly vnicURL="http://169.254.169.254/opc/v2/vnics" readonly vipURL="http://169.254.169.254/opc/v2/instance/freeformTags/VIP" readonly configFilenames="/etc/sysconfig/network-scripts/ifcfg" # Convert CIDR to Netmask function CidrToNetmask() { local cidr=${1} local netmask=0 local stat=1 if [ "$cidr" != "" ]; then if [ $cidr -ge 0 -a $cidr -lt 33 ]; then netmask=$(( 0xffffffff ^ ((1 << (32 - $cidr)) - 1) )) stat=$? fi fi if [ $stat -eq 0 ]; then echo "$(( (netmask >> 24) & 0xff )).$(( (netmask >> 16) & 0xff )).$(( (netmask >> 8) & 0xff )).$(( netmask & 0xff ))" fi return $stat } # Convert Netmask to CIDR function NetmaskToCidr() { local netmask=${1} local found=false local cidr=0 local octet=0 local binbits=0 local ibase=0 local len=0 local i=0 local stat=1 if [ "$netmask" != "" ]; then if [ "$netmask" = "0.0.0.0" ]; then stat=0 else netmask=`echo "$netmask" | sed 's|\.| |g'` len=`echo "$netmask" | wc -w` if [ $len -eq 4 ]; then len=${#bitArray[@]} for octet in $netmask; do i=0 found=false while [ $i -lt $len ]; do # Check if octet is valid (containing in bitArray) if [ "$octet" = "${bitArray[$i]}" ]; then found=true fi let i++ done if [ "$found" = true ]; then binbits=$(echo "obase=2; ibase=10; ${octet}"| bc | sed 's|0||g') stat=$? if [ $stat -eq 0 ]; then cidr=$(expr $cidr + ${#binbits}) fi else return 1 fi done fi fi fi if [ $stat -eq 0 ]; then echo "$cidr" fi return $stat } function VnicsFromInstance() { local stat=1 if [ "$jq" != "" ]; then transfer --quiet --auth "$vnicURL" | norm-json --quiet > $scratchfile stat=$? if [ $stat -eq 0 ]; then # printf '%s\t%s\t%s\t%s\t%s\t%s\n' "macAddr" "privateIp" "subnetCidrBlock" "virtualRouterIp" "vlanTag" "vnicId" printf '%s\t%s\t%s\t%s\t%s\n' "macAddr" "privateIp" "subnetCidrBlock" "virtualRouterIp" "vlanTag" cat $scratchfile | $jq -r '(.[] | [.macAddr, .privateIp, .subnetCidrBlock, .virtualRouterIp, .vlanTag, .vnicId]) | @tsv' stat=$? fi fi return $stat } function SplitDefaultRoute() { local result="" local line="" local key="" local via="" local dev="" local proto="" local src="" local metric="" local comment="" if [ "$ip" != "" ]; then result=`"$ip" route show 2>/dev/null | grep '^default ' | sed 's|^default ||'` if [ "$result" != "" ]; then for key in via dev proto src metric; do result=`echo "$result" | sed 's|'$key' |'$key'=|g'` done printf '%s\t%s\t%s\t%s\t%s\t%s\n' "via" "dev" "proto" "src" "metric" "viprouted" while read -r line; do line=`echo "$line" | tr ' ' '\n' | grep '='` via=`echo "$line" | grep '^via=' | cut -d'=' -f2` dev=`echo "$line" | grep '^dev=' | cut -d'=' -f2` proto=`echo "$line" | grep '^proto=' | cut -d'=' -f2` src=`echo "$line" | grep '^src=' | cut -d'=' -f2` metric=`echo "$line" | grep '^metric=' | cut -d'=' -f2` if [ "$comment" = "" ]; then if [ "$usedvip" != "" -a "$src" = "$usedvip" ]; then comment="yes" else comment="no" fi fi printf '%s\t%s\t%s\t%s\t%s\t%s\n' "$via" "$dev" "$proto" "$src" "$metric" "$comment" done < <(echo "$result") fi fi } function GetInterfaces() { local result="" local line="" local key="" local link="" local dev="" local mtu="" local qdisc="" local state="" local group="" local qlen="" if [ "$ip" != "" ]; then result=`"$ip" a s | grep ': <' | sed 's|^.: |dev=|g' | tr -d ':'` for key in mtu qdisc state group qlen; do result=`echo "$result" | sed 's|'$key' |'$key'=|g'` done printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "link" "dev" "mtu" "qdisc" "state" "group" "qlen" while read -r line; do line=`echo "$line" | tr ' ' '\n' | grep '='` dev=`echo "$line" | grep '^dev=' | cut -d'=' -f2` link=`"$ip" a s "$dev" | grep 'link/' | tr -s ' ' | cut -d' ' -f3 | toupper` mtu=`echo "$line" | grep '^mtu=' | cut -d'=' -f2` qdisc=`echo "$line" | grep '^qdisc=' | cut -d'=' -f2` state=`echo "$line" | grep '^state=' | cut -d'=' -f2` group=`echo "$line" | grep '^group=' | cut -d'=' -f2` qlen=`echo "$line" | grep '^qlen=' | cut -d'=' -f2` printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "$link" "$dev" "$mtu" "$qdisc" "$state" "$group" "$qlen" done < <(echo "$result") fi } function GetIPs() { local interface=${1} local result="" local line="" local key="" local inet="" local brd="" local scope="" local comment="" if [ "$ip" != "" -a "" != "$interface" ]; then result=`"$ip" a s "$interface" | grep 'inet '` for key in inet brd scope; do result=`echo "$result" | sed 's|'$key' |'$key'=|g'` done printf '%s\t%s\t%s\t%s\n' "inet" "brd" "scope" "comment" while read -r line; do line=`echo "$line" | tr ' ' '\n' | grep '='` inet=`echo "$line" | grep '^inet=' | cut -d'=' -f2` brd=`echo "$line" | grep '^brd=' | cut -d'=' -f2` scope=`echo "$line" | grep '^scope=' | cut -d'=' -f2` comment="" result=`echo "$inet" | cut -d'/' -f1` if [ "$result" = "$lip" ]; then comment="primary" else if [ "$result" = "$usedvip" ]; then comment="vip" fi fi printf '%s\t%s\t%s\t%s\n' "$inet" "$brd" "$scope" "$comment" done < <(echo "$result") fi } # Manipulate network interface config file function ConfigFile() { local action=${1} # Could be show, create, delete or change local interface=${2} # Network interface e.g. ens3 or enp0s5 local defroute=${3} # yes or no local pip=${4} # Primary IP local vip=${5} # Virtual IP address local netmask=${6} # e.g. 255.255.255.0 local gateway=${7} # Network gateway (ip) local broadcast=${8} # Broadcast ip - could be empty local filename="" local bp="" local dr="" local ob="" local name="" local stat=1 if [ "$interface" != "" ]; then filename="${configFilenames}-${interface}:vip" case "$action" in show) if [ -r "$filename" ]; then printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "DEVICE" "BOOTPROTO" "PRIMIP" "IPADDR" "NETMASK" "BROADCAST" "GATEWAY" "DEFROUTE" "ONBOOT" "ORIGINAL" interface=`grep '^DEVICE=' "$filename" | cut -d'=' -f2 | tr -d '"'` bp=`grep '^BOOTPROTO=' "$filename" | cut -d'=' -f2` pip=`grep '^PRIMIP=' "$filename" | cut -d'=' -f2` vip=`grep '^IPADDR=' "$filename" | cut -d'=' -f2` netmask=`grep '^NETMASK=' "$filename" | cut -d'=' -f2` broadcast=`grep '^BROADCAST=' "$filename" | cut -d'=' -f2` gateway=`grep '^GATEWAY=' "$filename" | cut -d'=' -f2` dr=`grep '^DEFROUTE=' "$filename" | cut -d'=' -f2` ob=`grep '^ONBOOT=' "$filename" | cut -d'=' -f2` name=`grep '^ORIGINAL=' "$filename" | cut -d'=' -f2 | tr -d '"'` printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "$interface" "$bp" "$pip" "$vip" "$netmask" "$broadcast" "$gateway" "$dr" "$ob" "$name" stat=$? fi ;; create) printf 'DEVICE="%s:vip"\n' "$interface" > "$filename" 2>/dev/null stat=$? if [ $stat -eq 0 ]; then printf 'BOOTPROTO=static\n' >> "$filename" printf 'PRIMIP=%s\n' "$pip" >> "$filename" printf 'IPADDR=%s\n' "$vip" >> "$filename" printf 'NETMASK=%s\n' "$netmask" >> "$filename" if [ "$broadcast" != "" ]; then printf 'BROADCAST=%s\n' "$broadcast" >> "$filename" fi printf 'GATEWAY=%s\n' "$gateway" >> "$filename" printf 'DEFROUTE=%s\n' "$defroute" >> "$filename" printf 'ONBOOT=yes\n' >> "$filename" fi ;; delete) if [ -f "$filename" ]; then rm -f "$filename" 2>/dev/null stat=$? fi ;; change) if [ -r "$filename" ]; then if [ "$defroute" = "yes" ]; then cat "$filename" | sed 's|^DEFROUTE=no$|DEFROUTE=yes|' > $scratchfile else cat "$filename" | sed 's|^DEFROUTE=yes$|DEFROUTE=no|' > $scratchfile fi mv -f $scratchfile "$filename" 2>/dev/null stat=$? fi ;; esac fi return $stat } # Add an additional parameter to network interface config file function AddToConfigFile() { local paramname=${1} # Could be ORIGINAL or something else local interface=${2} # Network interface e.g. ens3 or enp0s5 local param=${3} # Value of the parameter local stat=1 if [ "$interface" != "" -a "$paramname" != "" ]; then paramname=`echo "$paramname" | toupper` filename="${configFilenames}-${interface}:vip" cat "$filename" | grep -v "^${paramname}=" > $scratchfile mv -f $scratchfile "$filename" 2>/dev/null stat=$? if [ $stat -eq 0 ]; then printf '%s="%s"\n' "$paramname" "$param" >> "$filename" 2>/dev/null stat=$? fi fi return $stat } # Replace default route function ReplaceRoute() { local iface=${1} local gateway=${2} local src=${3} local usedsrc="" local result="" local proto="" local metric="" local protostr="" local metricstr="" local lines=0 local stat=1 if [ "$ip" != "" -a "$iface" != "" -a "$gateway" != "" -a "$src" != "" ]; then # Check if we have more then one default route and delete all but the last one result=`"$ip" route show | grep '^default '` lines=`echo "$result" | wc -l` if [ $lines -eq 0 ]; then # No default route - create one $ip route add default via $gateway dev $iface src $src 2>/dev/null stat=$? else if [ $lines -gt 1 ]; then # To many default routes - delete the first one result=`echo "$result" | head -n 1` $ip route delete $result 2>/dev/null stat=$? fi # Replace last default route with new IP result=`SplitDefaultRoute | tail -n 1` if [ "$result" != "" ]; then gateway=`echo "$result" | cut -d$'\t' -f1` iface=`echo "$result" | cut -d$'\t' -f2` proto=`echo "$result" | cut -d$'\t' -f3` usedsrc=`echo "$result" | cut -d$'\t' -f4` metric=`echo "$result" | cut -d$'\t' -f5` if [ "$usedsrc" != "$src" ]; then if [ "$proto" != "" ]; then protostr="proto $proto" fi if [ "$metric" != "" ]; then metricstr="metric $metric" fi $ip route replace default via $gateway dev $iface $protostr src $src $metricstr 2>/dev/null stat=$? fi fi fi fi return $stat } # Add a second IP as a Virtual IP function AddVIP() { local interface=${1} local pip=${2} local vip=${3} local netmask=${4} local gateway=${5} local broadcast=${6} local name="" local result="" local cidr=0 local stat=0 # Create entry in ifconfig if [ "$ip" != "" -a "$interface" != "" -a "$vip" != "" -a "$netmask" != "" ]; then cidr=`NetmaskToCidr "$netmask"` if [ "$broadcast" != "" ]; then "$ip" addr add "${vip}/${cidr}" dev "$interface" label "${interface}:vip" broadcast "$broadcast" stat=$? else "$ip" addr add "${vip}/${cidr}" dev "$interface" label "${interface}:vip" stat=$? fi # Create file to make it persitent abfter reboot if [ $stat -eq 0 ]; then ConfigFile create "$interface" "no" "$pip" "$vip" "$netmask" "$gateway" "$broadcast" stat=$? if [ $stat -eq 0 ]; then # Create a link for reboot ln -s $script /etc/rc.d/init.d 2>/dev/null ln -s ../init.d/${progstr} /etc/rc.d/rc3.d/S80${progstr} 2>/dev/null # Use nmcli if using Oracle Linux 8+ if [ $vers -ge 8 -a "$nmcli" != "" ]; then # Get name of current active profile name=`"$nmcli" --get-values name con show --active | head -n 1` if [ "$name" != "" ]; then # Save original network profile name AddToConfigFile "ORIGINAL" "$interface" "$name" # Make sure, network manager notice the changes # result=`"$nmcli" con reload 2>/dev/null` # stat=$? # Clone current profile result=`"$nmcli" con clone "$name" "${interface}-vip"` stat=$? if [ $stat -eq 0 ]; then # Add vip to cloned profile result=`"$nmcli" con mod "${interface}-vip" +ipv4.addresses ${vip}/$cidr` stat=$? if [ $stat -eq 0 ]; then result=`"$nmcli" --terse con show | grep "^${interface}-vip:"` stat=$? if [ "$result" != "" ]; then # Start cloned profile result=`"$nmcli" --wait 3 con up "${interface}-vip"` stat=$? fi fi fi fi fi # Display success if [ $stat -eq 0 ]; then printf "\nVIP '%s' added to interface '%s'.\n" "$vip" "$interface" else exitcode=8 errormsg $exitcode "Error while adding VIP '$vip' to interface '$iface'." fi fi fi fi } # Delete the second IP (Virtual IP) function DeleteVIP() { local interface=${1} local vip=${2} local netmask=${3} local name=${4} local result="" local cidr=0 local stat=1 # Create entry in ifconfig if [ "$interface" != "" -a "$vip" != "" -a "$netmask" != "" ]; then # Delete file to make it persistent after reboot ConfigFile delete "$interface" stat=$? if [ $stat -eq 0 ]; then # Delete link for reboot rm -f /etc/rc.d/init.d/${progstr} 2>/dev/null rm -f /etc/rc.d/rc3.d/S80${progstr} 2>/dev/null stat=$? fi if [ $vers -ge 8 -a "$nmcli" != "" ]; then result=`"$nmcli" --terse con show --active | grep "^${interface}-vip:"` stat=$? if [ "$result" != "" ]; then result=`"$nmcli" --wait 2 con down "${interface}-vip" 2>/dev/null` stat=$? fi result=`"$nmcli" --terse con show | grep "^${interface}-vip:"` stat=$? if [ "$result" != "" ]; then result=`"$nmcli" con delete "${interface}-vip" 2>/dev/null` stat=$? # Wait a few seconds for the profile to change sleep 3 fi fi # Delete the VIP from interface if [ "$ifconfig" != "" -a "$ip" != "" ]; then result=`"$ifconfig" "${interface}:vip" | grep "inet $vip"` if [ "$result" != "" ]; then cidr=`NetmaskToCidr "$netmask"` "$ip" addr del "${vip}/${cidr}" dev "${interface}:vip" stat=$? fi fi if [ $stat -eq 0 ]; then if [ $vers -ge 8 -a "$nmcli" != "" -a "$name" != "" ]; then # Make sure, network manager notice the changes result=`"$nmcli" con reload 2>/dev/null` stat=$? result=`"$nmcli" --terse con show | grep "^${name}:"` if [ "$result" != "" ]; then # Activate original profile if [ "$name" != "" ]; then result=`"$nmcli" --wait 3 con up "$name" 2>/dev/null` stat=$? fi fi fi fi if [ $stat -eq 0 ]; then # Display success printf "\nVIP '%s' deleted from interface '%s'.\n" "$vip" "$interface" else exitcode=8 errormsg $exitcode "Error while deleting VIP '$vip' from interface '$iface'." fi fi } # Preset action="" vip="" # Check parameters: Loop until all parameters are used up while [ $# -gt 0 ]; do pname=${1} case "$pname" in -v | --version) shift showversion=true ;; -h | --help) shift showhelp=true ;; *) shift paramck=`echo "$pname" | grep '^-'` # Types don't begin with '-' if [ "$paramck" != "" ]; then errstr="Unknown option '$pname'." else if [ "$action" = "" ]; then action=`echo "$pname" | tolower` else if [ "$vip" = "" ]; then vip="$pname" else errstr="VIP was already specified '$vip'. Unknown additional parameter: '$pname'." fi fi fi esac done # Get infos about the platform result=`get-platform --output keys` id=`echo "$result" | grep '^id:' | cut -d':' -f2` vers=`echo "$result" | grep '^version_main:' | cut -d':' -f2` gateway=`echo "$result" | grep '^gateway:' | cut -d':' -f2` iface=`echo "$result" | grep '^interface:' | cut -d':' -f2` ifup=`echo "$result" | grep '^up:' | cut -d':' -f2` lip=`echo "$result" | grep '^ip_v4:' | cut -d':' -f2` # Check if we are running on Linux if [ "$id" != "ol" ]; then errstr="This script only supports Oracle Linux." else # Plausibility check if [ "$action" = "" ]; then action="status" elif [ "$action" = "add" -a "$vip" = "" ]; then errstr="Parameter action needs a virtual ip as second paramater." fi fi # Display help or error message DisplayHelp ### Main if [ "$USER" != "root" ]; then # Try sudo check-sudo stat=$? if [ $stat -eq 0 ]; then sudo --preserve-env=PATH "$script" "$action" "$vip" else exitcode=1 errormsg $exitcode "Need to be root." fi else ifconfig=`filecheck -x ifconfig` jq=`filecheck -x jq` ip=`filecheck -x ip` nmcli=`filecheck -x nmcli` if [ "$ip" = "" ]; then exitcode=3 errormsg $exitcode "No 'ip' in PATH." else if [ "$iface" = "" -o "$ifup" = false ]; then exitcode=4 errormsg $exitcode "No suitable interface found." else if [ "$lip" = "" ]; then exitcode=5 errormsg $exitcode "No IPv4 found in interface '$iface'." else result=`ConfigFile show "$iface" | tail -n 1` if [ "$result" != "" ]; then lip=`echo "$result" | cut -d$'\t' -f3` usedvip=`echo "$result" | cut -d$'\t' -f4` netmask=`echo "$result" | cut -d$'\t' -f5` broadcast=`echo "$result" | cut -d$'\t' -f6` gateway=`echo "$result" | cut -d$'\t' -f7` viproute=`echo "$result" | cut -d$'\t' -f8` original=`echo "$result" | cut -d$'\t' -f10` else usedvip="" viproute=no result=`GetIPs "$iface" | grep "^${lip}/"` netmask=`echo "$result" | cut -d$'\t' -f1 | cut -d'/' -f2` netmask=`CidrToNetmask "$netmask"` broadcast=`echo "$result" | cut -d$'\t' -f2` fi case "$action" in status) printf "\nVNICs on instance:\n\n" VnicsFromInstance | print-table printf "\nDefined interfaces:\n\n" GetInterfaces | print-table printf "\nPlan:\n\n" printf " Primary interface: '%s'\n" "$iface" printf " Primary IP: '%s'\n" "$lip" if [ "$usedvip" != "" ]; then printf " Used VIP: '%s'\n" "$usedvip" else result=`transfer --quiet --auth "$vipURL" | head -n 1` stat=$? if [ $stat -ne 0 -o "$result" = "" ]; then result="" fi if [ "$result" != "" ]; then printf " Suggested VIP '%s' not used.\n" "$result" else echo " VIP not used." fi fi if [ "$viproute" = "yes" ]; then echo " VIP attached to default route." else echo " VIP not attached to default route." fi printf "\nPrivate ip_v4 on interface '%s':\n\n" "$iface" GetIPs "$iface" | print-table printf "\nDefault route:\n\n" SplitDefaultRoute | print-table ;; start) if [ "$usedvip" != "" ]; then # Startup network manager profile if [ $vers -ge 8 -a "$nmcli" != "" ]; then stat=1 i=0 while [ $stat -ne 0 -a $i -lt 10 ]; do sleep 1 let i++ result=`"$nmcli" --terse con show --active | grep "^${iface}-vip:"` stat=$? if [ "$result" = "" ]; then # We don't use the right profile - check if it exists and then start it result=`"$nmcli" --terse con show | grep "^${iface}-vip:"` if [ "$result" != "" ]; then result=`"$nmcli" con up "${iface}-vip" 2>/dev/null` stat=$? fi fi done fi if [ "$viproute" = "yes" ]; then ReplaceRoute $iface $gateway $usedvip stat=$? if [ $stat -ne 0 ]; then exitcode=9 errormsg $exitcode "Error while changing default route for interface '$iface'." fi fi else exitcode=7 errormsg $exitcode "No VIP attached to interface '$iface'." fi ;; stop) if [ "$usedvip" != "" ]; then if [ "$viproute" = "yes" ]; then ReplaceRoute $iface $gateway $lip stat=$? if [ $stat -ne 0 ]; then exitcode=9 errormsg $exitcode "Error while changing default route for interface '$iface'." fi fi # Startup network manager profile if [ $vers -ge 8 -a "$nmcli" != "" ]; then stat=1 i=0 while [ $stat -ne 0 -a $i -lt 10 ]; do sleep 1 let i++ result=`"$nmcli" --terse con show --active | grep "^${iface}-vip:"` stat=$? if [ "$result" != "" ]; then # We don't use the right profile - check if it exists and then start it # result=`"$nmcli" --terse con show | grep "^${iface}-vip:"` result=`"$nmcli" --terse con show | grep "^${original}:"` if [ "$result" != "" ]; then # result=`"$nmcli" con down "${iface}-vip" 2>/dev/null` result=`"$nmcli" con up "$original" 2>/dev/null` stat=$? fi fi done fi else exitcode=7 errormsg $exitcode "No VIP attached to interface '$iface'." fi ;; route) if [ "$usedvip" != "" ]; then if [ "$vip" = "$usedvip" -o "$vip" = "" ]; then ReplaceRoute $iface $gateway $usedvip stat=$? if [ $stat -ne 0 ]; then exitcode=9 errormsg $exitcode "Error while changing default route for interface '$iface'." else if [ "$viproute" = "no" ]; then ConfigFile change "$iface" "yes" fi fi else ReplaceRoute $iface $gateway $vip stat=$? if [ $stat -ne 0 ]; then exitcode=9 errormsg $exitcode "Error while changing default route for interface '$iface'." else if [ "$viproute" = "yes" ]; then ConfigFile change "$iface" "no" fi fi fi printf "\nDefault route:\n\n" SplitDefaultRoute | print-table else exitcode=7 errormsg $exitcode "No VIP attached to interface '$iface'." fi ;; add) if [ "$vip" = "$lip" ]; then exitcode=6 errormsg $exitcode "Primary IP on interface '${iface}' can't be used as VIP." else if [ "$usedvip" != "" ]; then exitcode=6 errormsg $exitcode "VIP for '$iface' already defined: '$usedvip'." else AddVIP "$iface" "$lip" "$vip" "$netmask" "$gateway" "$broadcast" fi fi ;; delete) if [ "$usedvip" = "" ]; then exitcode=7 errormsg $exitcode "No VIP attached to interface '$iface'." else # defroute=`ConfigFile show "$iface" | print-table DEFROUTE --output plain` if [ "$viproute" = "yes" ]; then ReplaceRoute $iface $gateway $lip stat=$? if [ $stat -ne 0 ]; then exitcode=9 errormsg $exitcode "Error while changing default route for interface '$iface'." fi fi DeleteVIP "$iface" "$usedvip" "$netmask" "$original" fi ;; *) exitcode=2 errormsg $exitcode "Unknown action: '$action'." esac fi fi fi fi # Cleanup and exit Cleanup exit $exitcode