X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=lib%2Fcommon-functions.sh;h=709dbf97437ac05db724b85697c59022b33105cb;hb=605342b46095341c9301456c81e354c73e2197eb;hp=1e55aa18dffa0c9cec75e7cdc15d84d5bee436ae;hpb=bd2faa0275917ef18606f781f462d33387d2532a;p=apex.git diff --git a/lib/common-functions.sh b/lib/common-functions.sh index 1e55aa18..709dbf97 100644 --- a/lib/common-functions.sh +++ b/lib/common-functions.sh @@ -1,362 +1,48 @@ #!/usr/bin/env bash +############################################################################## +# Copyright (c) 2015 Tim Rozet (Red Hat), Dan Radez (Red Hat) and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + # Common Functions used by OPNFV Apex # author: Tim Rozet (trozet@redhat.com) -##find ip of interface -##params: interface name -function find_ip { - ip addr show $1 | grep -Eo '^\s+inet\s+[\.0-9]+' | awk '{print $2}' -} - -##finds subnet of ip and netmask -##params: ip, netmask -function find_subnet { - IFS=. read -r i1 i2 i3 i4 <<< "$1" - IFS=. read -r m1 m2 m3 m4 <<< "$2" - printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))" -} - -##verify subnet has at least n IPs -##params: subnet mask, n IPs -function verify_subnet_size { - IFS=. read -r i1 i2 i3 i4 <<< "$1" - num_ips_required=$2 - - ##this function assumes you would never need more than 254 - ##we check here to make sure - if [ "$num_ips_required" -ge 254 ]; then - echo -e "\n\n${red}ERROR: allocating more than 254 IPs is unsupported...Exiting${reset}\n\n" - return 1 - fi - - ##we just return if 3rd octet is not 255 - ##because we know the subnet is big enough - if [ "$i3" -ne 255 ]; then - return 0 - elif [ $((254-$i4)) -ge "$num_ips_required" ]; then - return 0 - else - echo -e "\n\n${red}ERROR: Subnet is too small${reset}\n\n" - return 1 - fi -} - -##finds last usable ip (broadcast minus 1) of a subnet from an IP and netmask -## Warning: This function only works for IPv4 at the moment. -##params: ip, netmask -function find_last_ip_subnet { - IFS=. read -r i1 i2 i3 i4 <<< "$1" - IFS=. read -r m1 m2 m3 m4 <<< "$2" - IFS=. read -r s1 s2 s3 s4 <<< "$((i1 & m1)).$((i2 & m2)).$((i3 & m3)).$((i4 & m4))" - printf "%d.%d.%d.%d\n" "$((255 - $m1 + $s1))" "$((255 - $m2 + $s2))" "$((255 - $m3 + $s3))" "$((255 - $m4 + $s4 - 1))" -} - -##increments subnet by a value -##params: ip, value -##assumes low value -function increment_subnet { - IFS=. read -r i1 i2 i3 i4 <<< "$1" - printf "%d.%d.%d.%d\n" "$i1" "$i2" "$i3" "$((i4 | $2))" -} - -##finds netmask of interface -##params: interface -##returns long format 255.255.x.x -function find_netmask { - ifconfig $1 | grep -Eo 'netmask\s+[\.0-9]+' | awk '{print $2}' +##converts subnet mask to prefix +##params: subnet mask +function prefix2mask { + # Number of args to shift, 255..255, first non-255 byte, zeroes + set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0 + [ $1 -gt 1 ] && shift $1 || shift + echo ${1-0}.${2-0}.${3-0}.${4-0} } -##finds short netmask of interface -##params: interface -##returns short format, ex: /21 -function find_short_netmask { - echo "/$(ip addr show $1 | grep -Eo '^\s+inet\s+[\/\.0-9]+' | awk '{print $2}' | cut -d / -f2)" -} - -##increments next IP -##params: ip -##assumes a /24 subnet -function next_ip { - baseaddr="$(echo $1 | cut -d. -f1-3)" - lsv="$(echo $1 | cut -d. -f4)" - if [ "$lsv" -ge 254 ]; then - return 1 - fi - ((lsv++)) - echo $baseaddr.$lsv -} - -##subtracts a value from an IP address -##params: last ip, ip_count -##assumes ip_count is less than the last octect of the address -subtract_ip() { - IFS=. read -r i1 i2 i3 i4 <<< "$1" - ip_count=$2 - if [ $i4 -lt $ip_count ]; then - echo -e "\n\n${red}ERROR: Can't subtract $ip_count from IP address $1 Exiting${reset}\n\n" - exit 1 - fi - printf "%d.%d.%d.%d\n" "$i1" "$i2" "$i3" "$((i4 - $ip_count ))" -} - -##check if IP is in use -##params: ip -##ping ip to get arp entry, then check arp -function is_ip_used { - ping -c 5 $1 > /dev/null 2>&1 - arp -n | grep "$1 " | grep -iv incomplete > /dev/null 2>&1 -} - -##find next usable IP -##params: ip -function next_usable_ip { - new_ip=$(next_ip $1) - while [ "$new_ip" ]; do - if ! is_ip_used $new_ip; then - echo $new_ip - return 0 - fi - new_ip=$(next_ip $new_ip) - done - return 1 -} - -##increment ip by value -##params: ip, amount to increment by -##increment_ip $next_private_ip 10 -function increment_ip { - baseaddr="$(echo $1 | cut -d. -f1-3)" - lsv="$(echo $1 | cut -d. -f4)" - incrval=$2 - lsv=$((lsv+incrval)) - if [ "$lsv" -ge 254 ]; then - return 1 - fi - echo $baseaddr.$lsv -} - -##finds gateway on system -##params: interface to validate gateway on (optional) -##find_gateway em1 -function find_gateway { - local gw gw_interface - if [ -z "$1" ]; then - return 1 - fi - gw=$(ip route | grep default | awk '{print $3}') - gw_interface=$(ip route get $gw | awk '{print $3}') - if [ -n "$1" ]; then - if [ "$gw_interface" == "$1" ]; then - echo ${gw} - fi - fi -} - -##finds subnet in CIDR notation for interface -##params: interface to find CIDR -function find_cidr { - local cidr network ip netmask short_mask - if [ -z "$1" ]; then - return 1 - fi - ip=$(find_ip $1) - netmask=$(find_netmask $1) - if [[ -z "$ip" || -z "$netmask" ]]; then - return 1 - fi - network=$(find_subnet ${ip} ${netamsk}) - short_mask=$(find_short_netmask $1) - if [[ -z "$network" || -z "$short_mask" ]]; then - return 1 - fi - cidr="${subnet}'\'${short_mask}" - echo ${cidr} -} - -##finds block of usable IP addresses for an interface -##simply returns at the moment the correct format -##after first 20 IPs, and leave 20 IPs at end of subnet (for floating ips, etc) -##params: interface to find IP -function find_usable_ip_range { - local interface_ip subnet_mask first_block_ip last_block_ip - if [ -z "$1" ]; then - return 1 - fi - interface_ip=$(find_ip $1) - subnet_mask=$(find_netmask $1) - if [[ -z "$interface_ip" || -z "$subnet_mask" ]]; then - return 1 - fi - interface_ip=$(increment_ip ${interface_ip} 20) - first_block_ip=$(next_usable_ip ${interface_ip}) - if [ -z "$first_block_ip" ]; then +##find ip of interface +##params: interface name, address family +function find_ip { + local af + if [[ -z "$1" ]]; then return 1 fi - last_block_ip=$(find_last_ip_subnet ${interface_ip} ${subnet_mask}) - if [ -z "$last_block_ip" ]; then - return 1 + if [[ -z "$2" ]]; then + af=4 else - last_block_ip=$(subtract_ip ${last_block_ip} 21) - echo "${first_block_ip},${last_block_ip}" + af=$2 fi -} - -##generates usable IP range in correct format based on CIDR -##assumes the first 20 IPs are used (by instack or otherwise) -##params: cidr -function generate_usable_ip_range { - local first_ip first_block_ip last_block_ip - #first_ip=$(ipcalc -nb $1 | grep HostMin: | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") - first_ip=$(ipcalc -nmpb $1 | grep NETWORK= | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") - first_ip=$(increment_ip ${first_ip} 1) - first_block_ip=$(increment_ip ${first_ip} 20) - #last_block_ip=$(ipcalc -nb $1 | grep HostMax: | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") - last_block_ip=$(ipcalc -nmpb $1 | grep BROADCAST= | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") - last_block_ip=$(subtract_ip ${last_block_ip} 1) - if [[ -z "$first_block_ip" || -z "$last_block_ip" ]]; then - return 1 - else - last_block_ip=$(subtract_ip ${last_block_ip} 21) - echo "${first_block_ip},${last_block_ip}" - fi -} - -##find the instack IP address -##finds first usable IP on subnet -##params: interface -function find_provisioner_ip { - local interface_ip - if [ -z "$1" ]; then - return 1 - fi - interface_ip=$(find_ip $1) - if [ -z "$interface_ip" ]; then - return 1 - fi - echo $(increment_ip ${interface_ip} 1) -} - -##generates instack IP address based on CIDR -##params: cidr -function generate_provisioner_ip { - local provisioner_ip - #provisioner_ip=$(ipcalc -nb $1 | grep HostMin: | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") - provisioner_ip=$(ipcalc -nmpb $1 | grep NETWORK= | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") - if [ -z "$provisioner_ip" ]; then - return 1 - fi - provisioner_ip=$(increment_ip ${provisioner_ip} 1) - echo "$provisioner_ip" -} - -##finds the dhcp range available via interface -##uses first 8 IPs, after 2nd IP -##params: interface -function find_dhcp_range { - local dhcp_range_start dhcp_range_end interface_ip - if [ -z "$1" ]; then - return 1 - fi - interface_ip=$(find_ip $1) - if [ -z "$interface_ip" ]; then - return 1 - fi - dhcp_range_start=$(increment_ip ${interface_ip} 2) - dhcp_range_end=$(increment_ip ${dhcp_range_start} 8) - echo "${dhcp_range_start},${dhcp_range_end}" -} - -##generates the dhcp range available via CIDR -##uses first 8 IPs, after 1st IP -##params: cidr -function generate_dhcp_range { - local dhcp_range_start dhcp_range_end first_ip - #first_ip=$(ipcalc -nb $1 | grep HostMin: | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") - first_ip=$(ipcalc -nmpb $1 | grep NETWORK= | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") - if [ -z "$first_ip" ]; then - return 1 - fi - first_ip=$(increment_ip ${first_ip} 1) - dhcp_range_start=$(increment_ip ${first_ip} 1) - dhcp_range_end=$(increment_ip ${dhcp_range_start} 8) - echo "${dhcp_range_start},${dhcp_range_end}" -} - -##finds the introspection range available via interface -##uses 8 IPs, after the first 10 IPs -##params: interface -function find_introspection_range { - local inspect_range_start inspect_range_end interface_ip - if [ -z "$1" ]; then - return 1 - fi - interface_ip=$(find_ip $1) - if [ -z "$interface_ip" ]; then - return 1 - fi - inspect_range_start=$(increment_ip ${interface_ip} 10) - inspect_range_end=$(increment_ip ${inspect_range_start} 8) - echo "${inspect_range_start},${inspect_range_end}" -} - -##generate the introspection range available via CIDR -##uses 8 IPs, after the first 10 IPs -##params: cidr -function generate_introspection_range { - local inspect_range_start inspect_range_end first_ip - #first_ip=$(ipcalc -nb $1 | grep HostMin: | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") - first_ip=$(ipcalc -nmpb $1 | grep NETWORK= | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") - if [ -z "$first_ip" ]; then - return 1 - fi - first_ip=$(increment_ip ${first_ip} 1) - inspect_range_start=$(increment_ip ${first_ip} 10) - inspect_range_end=$(increment_ip ${inspect_range_start} 8) - echo "${inspect_range_start},${inspect_range_end}" -} - -##finds the floating ip range available via interface -##uses last 20 IPs of a subnet, minus last IP -##params: interface -function find_floating_ip_range { - local float_range_start float_range_end interface_ip subnet_mask - if [ -z "$1" ]; then - return 1 - fi - interface_ip=$(find_ip $1) - subnet_mask=$(find_netmask $1) - if [[ -z "$interface_ip" || -z "$subnet_mask" ]]; then - return 1 - fi - float_range_end=$(find_last_ip_subnet ${interface_ip} ${subnet_mask}) - float_range_end=$(subtract_ip ${float_range_end} 1) - float_range_start=$(subtract_ip ${float_range_end} 19) - echo "${float_range_start},${float_range_end}" -} - -##generate the floating range available via CIDR -##uses last 20 IPs of subnet, minus last IP -##params: cidr -function generate_floating_ip_range { - local float_range_start float_range_end last_ip - #last_ip=$(ipcalc -nb $1 | grep HostMax: | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") - last_ip=$(ipcalc -nmpb $1 | grep BROADCAST= | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") - if [ -z "$last_ip" ]; then - return 1 - fi - last_ip=$(subtract_ip ${last_ip} 2) - float_range_start=$(subtract_ip ${last_ip} 19) - float_range_end=${last_ip} - echo "${float_range_start},${float_range_end}" + python3 -B $LIB/python/apex_python_utils.py find-ip -i $1 -af $af } ##attach interface to OVS and set the network config correctly ##params: bride to attach to, interface to attach, network type (optional) -##public indicates attaching to a public interface +##external indicates attaching to a external interface function attach_interface_to_ovs { local bridge interface - local if_ip if_mask if_gw if_file ovs_file + local if_ip if_mask if_gw if_file ovs_file if_prefix + local if_metric if_dns1 if_dns2 if [[ -z "$1" || -z "$2" ]]; then return 1 @@ -376,16 +62,25 @@ function attach_interface_to_ovs { if_ip=$(sed -n 's/^IPADDR=\(.*\)$/\1/p' ${if_file}) if_mask=$(sed -n 's/^NETMASK=\(.*\)$/\1/p' ${if_file}) if_gw=$(sed -n 's/^GATEWAY=\(.*\)$/\1/p' ${if_file}) + if_metric=$(sed -n 's/^METRIC=\(.*\)$/\1/p' ${if_file}) + if_dns1=$(sed -n 's/^DNS1=\(.*\)$/\1/p' ${if_file}) + if_dns2=$(sed -n 's/^DNS2=\(.*\)$/\1/p' ${if_file}) else echo "ERROR: ifcfg file missing for ${interface}" return 1 fi + if [ -z "$if_mask" ]; then + # we can look for PREFIX here, then convert it to NETMASK + if_prefix=$(sed -n 's/^PREFIX=[^0-9]*\([0-9][0-9]*\)[^0-9]*$/\1/p' ${if_file}) + if_mask=$(prefix2mask ${if_prefix}) + fi + if [[ -z "$if_ip" || -z "$if_mask" ]]; then - echo "ERROR: IPADDR or NETMASK missing for ${interface}" + echo "ERROR: IPADDR or NETMASK/PREFIX missing for ${interface}" return 1 - elif [[ -z "$if_gw" && "$3" == "public_network" ]]; then - echo "ERROR: GATEWAY missing for ${interface}, which is public" + elif [[ -z "$if_gw" && "$3" == "external" ]]; then + echo "ERROR: GATEWAY missing for ${interface}, which is external" return 1 fi @@ -401,7 +96,7 @@ ONBOOT=yes OVS_BRIDGE=${bridge} PROMISC=yes" > ${if_file} - if [ -z ${if_gw} ]; then + # create bridge cfg echo "DEVICE=${bridge} DEVICETYPE=ovs @@ -413,17 +108,24 @@ TYPE=OVSBridge PROMISC=yes PEERDNS=no" > ${ovs_file} - else - echo "DEVICE=${bridge} -DEVICETYPE=ovs -IPADDR=${if_ip} -NETMASK=${if_mask} -BOOTPROTO=static -ONBOOT=yes -TYPE=OVSBridge -PROMISC=yes -GATEWAY=${if_gw} -PEERDNS=no" > ${ovs_file} + if [ -n "$if_gw" ]; then + echo "GATEWAY=${if_gw}" >> ${ovs_file} + fi + + if [ -n "$if_metric" ]; then + echo "METRIC=${if_metric}" >> ${ovs_file} + fi + + if [[ -n "$if_dns1" || -n "$if_dns2" ]]; then + sed -i '/PEERDNS/c\PEERDNS=yes' ${ovs_file} + + if [ -n "$if_dns1" ]; then + echo "DNS1=${if_dns1}" >> ${ovs_file} + fi + + if [ -n "$if_dns2" ]; then + echo "DNS2=${if_dns2}" >> ${ovs_file} + fi fi sudo systemctl restart network @@ -436,7 +138,8 @@ function detach_interface_from_ovs { local bridge local port_output ports_no_orig local net_path - local if_ip if_mask if_gw + local if_ip if_mask if_gw if_prefix + local if_metric if_dns1 if_dns2 net_path=/etc/sysconfig/network-scripts/ if [[ -z "$1" ]]; then @@ -458,18 +161,25 @@ function detach_interface_from_ovs { elif [ -e ${net_path}/ifcfg-${line}.orig ]; then mv -f ${net_path}/ifcfg-${line}.orig ${net_path}/ifcfg-${line} elif [ -e ${net_path}/ifcfg-${bridge} ]; then - if_ip=$(sed -n 's/^IPADDR=\(.*\)$/\1/p' ${if_file}) - if_mask=$(sed -n 's/^NETMASK=\(.*\)$/\1/p' ${if_file}) - if_gw=$(sed -n 's/^GATEWAY=\(.*\)$/\1/p' ${if_file}) + if_ip=$(sed -n 's/^IPADDR=\(.*\)$/\1/p' ${net_path}/ifcfg-${bridge}) + if_mask=$(sed -n 's/^NETMASK=\(.*\)$/\1/p' ${net_path}/ifcfg-${bridge}) + if_gw=$(sed -n 's/^GATEWAY=\(.*\)$/\1/p' ${net_path}/ifcfg-${bridge}) + if_metric=$(sed -n 's/^METRIC=\(.*\)$/\1/p' ${net_path}/ifcfg-${bridge}) + if_dns1=$(sed -n 's/^DNS1=\(.*\)$/\1/p' ${net_path}/ifcfg-${bridge}) + if_dns2=$(sed -n 's/^DNS2=\(.*\)$/\1/p' ${net_path}/ifcfg-${bridge}) + + if [ -z "$if_mask" ]; then + if_prefix=$(sed -n 's/^PREFIX=[^0-9]*\([0-9][0-9]*\)[^0-9]*$/\1/p' ${net_path}/ifcfg-${bridge}) + if_mask=$(prefix2mask ${if_prefix}) + fi if [[ -z "$if_ip" || -z "$if_mask" ]]; then - echo "ERROR: IPADDR or NETMASK missing for ${bridge} and no .orig file for interface ${line}" + echo "ERROR: IPADDR or PREFIX/NETMASK missing for ${bridge} and no .orig file for interface ${line}" return 1 fi - if [ -z ${if_gw} ]; then - # create if cfg - echo "DEVICE=${line} + # create if cfg + echo "DEVICE=${line} IPADDR=${if_ip} NETMASK=${if_mask} BOOTPROTO=static @@ -477,16 +187,25 @@ ONBOOT=yes TYPE=Ethernet NM_CONTROLLED=no PEERDNS=no" > ${net_path}/ifcfg-${line} - else - echo "DEVICE=${line} -IPADDR=${if_ip} -NETMASK=${if_mask} -BOOTPROTO=static -ONBOOT=yes -TYPE=Ethernet -NM_CONTROLLED=no -GATEWAY=${if_gw} -PEERDNS=no" > ${net_path}/ifcfg-${line} + + if [ -n "$if_gw" ]; then + echo "GATEWAY=${if_gw}" >> ${net_path}/ifcfg-${line} + fi + + if [ -n "$if_metric" ]; then + echo "METRIC=${if_metric}" >> ${net_path}/ifcfg-${line} + fi + + if [[ -n "$if_dns1" || -n "$if_dns2" ]]; then + sed -i '/PEERDNS/c\PEERDNS=yes' ${net_path}/ifcfg-${line} + + if [ -n "$if_dns1" ]; then + echo "DNS1=${if_dns1}" >> ${net_path}/ifcfg-${line} + fi + + if [ -n "$if_dns2" ]; then + echo "DNS2=${if_dns2}" >> ${net_path}/ifcfg-${line} + fi fi break else @@ -501,6 +220,10 @@ PEERDNS=no" > ${net_path}/ifcfg-${line} sudo sed -i 's/IPADDR=.*//' ${net_path}/ifcfg-${bridge} sudo sed -i 's/NETMASK=.*//' ${net_path}/ifcfg-${bridge} sudo sed -i 's/GATEWAY=.*//' ${net_path}/ifcfg-${bridge} + sudo sed -i 's/DNS1=.*//' ${net_path}/ifcfg-${bridge} + sudo sed -i 's/DNS2=.*//' ${net_path}/ifcfg-${bridge} + sudo sed -i 's/METRIC=.*//' ${net_path}/ifcfg-${bridge} + sudo sed -i 's/PEERDNS=.*//' ${net_path}/ifcfg-${bridge} sudo systemctl restart network } @@ -524,3 +247,62 @@ iptables -A FORWARD -s ${external_cidr} -m state --state ESTABLISHED,RELATED -j service iptables save EOI } + +# Interactive prompt handler +# params: step stage, ex. deploy, undercloud install, etc +function prompt_user { + while [ 1 ]; do + echo -n "Would you like to proceed with ${1}? (y/n) " + read response + if [ "$response" == 'y' ]; then + return 0 + elif [ "$response" == 'n' ]; then + return 1 + else + continue + fi + done +} + +##checks if prefix exists in string +##params: string, prefix +##usage: contains_prefix "deploy_setting_launcher=1" "deploy_setting" +contains_prefix() { + local mystr=$1 + local prefix=$2 + if echo $mystr | grep -E "^$prefix.*$" > /dev/null; then + return 0 + else + return 1 + fi +} + +##verify internet connectivity +#params: none +function verify_internet { + if ping -c 2 $ping_site > /dev/null; then + if ping -c 2 $dnslookup_site > /dev/null; then + echo "${blue}Internet connectivity detected${reset}" + return 0 + else + echo "${red}Internet connectivity detected, but DNS lookup failed${reset}" + return 1 + fi + else + echo "${red}No internet connectivity detected${reset}" + return 1 + fi +} + +##tests if overcloud nodes have external connectivity +#params:none +function test_overcloud_connectivity { + for node in $(undercloud_connect stack ". stackrc && nova list" | grep -Eo "controller-[0-9]+|compute-[0-9]+" | tr -d -) ; do + if ! overcloud_connect $node "ping -c 2 $ping_site > /dev/null"; then + echo "${blue}Node ${node} was unable to ping site ${ping_site}${reset}" + return 1 + fi + done + echo "${blue}Overcloud external connectivity OK${reset}" +} +