X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=lib%2Fcommon-functions.sh;h=6b259ac1f7a4d5f9390c77d00c45edd7395428a3;hb=88e800cde8e61acb05b60bff5997cb843ec6e133;hp=055d7fa2632a20b1a61e518748425351571795fa;hpb=9a11a203fa228cad7a86ebf2cb28ae834d17decd;p=apex.git diff --git a/lib/common-functions.sh b/lib/common-functions.sh index 055d7fa2..6b259ac1 100644 --- a/lib/common-functions.sh +++ b/lib/common-functions.sh @@ -2,315 +2,23 @@ # Common Functions used by OPNFV Apex # author: Tim Rozet (trozet@redhat.com) +##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} +} + ##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}' -} - -##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 - 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 - 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 - 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 - return 1 - fi - last_block_ip=$(find_last_ip_subnet ${interface_ip} ${subnet_mask}) - if [ -z "$last_block_ip" ]; then - return 1 - else - last_block_ip=$(subtract_ip ${last_block_ip} 20) - echo "${first_block_ip},${last_block_ip}" - 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_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]+") - if [[ -z "$first_block_ip" || -z "$last_block_ip" ]]; then - return 1 - else - last_block_ip=$(subtract_ip ${last_block_ip} 20) - 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 - 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]+") -} - -##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 - 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]+") - if [ -z "$first_ip" ]; then - return 1 - fi - 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 - 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]+") - if [ -z "$first_ip" ]; then - return 1 - fi - 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 -##params: interface -function find_floating_ip_range { - local float_range_start float_range_end interface_ip subnet_mask - interface_ip=$(find_ip $1) - subnet_mask=$(find_netmask $1) - if [[ -z "$interface_ip" || -z "$subnet_mask" ]]; then + if [[ -z "$1" ]]; then return 1 fi - float_range_end=$(find_last_ip_subnet ${interface_ip} ${subnet_mask}) - 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 -##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]+") - if [ -z "$last_ip" ]; then - return 1 - fi - float_range_start=$(subtract_ip ${last_ip} 19) - float_range_end=${last_ip} - echo "${float_range_start},${float_range_end}" + python3.4 -B $LIB/python/apex-python-utils.py find-ip -i $1 } ##attach interface to OVS and set the network config correctly @@ -318,7 +26,8 @@ function generate_floating_ip_range { ##public indicates attaching to a public 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 @@ -338,13 +47,22 @@ 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=\(.*\)$/\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" @@ -353,36 +71,46 @@ function attach_interface_to_ovs { # move old config file to .orig mv -f ${if_file} ${if_file}.orig - echo "DEVICE=${interface}, -TYPE=OVSPort, -PEERDNS=no, -BOOTPROTO=static, -NM_CONTROLLED=no, -ONBOOT=yes, -OVS_BRIDGE=${bridge}, + echo "DEVICE=${interface} +DEVICETYPE=ovs +TYPE=OVSPort +PEERDNS=no +BOOTPROTO=static +NM_CONTROLLED=no +ONBOOT=yes +OVS_BRIDGE=${bridge} PROMISC=yes" > ${if_file} - if [ -z ${if_gw} ]; then + # create bridge cfg - echo "DEVICE=${bridge}, -IPADDR=${if_ip}, -NETMASK=${if_mask}, -BOOTPROTO=static, -ONBOOT=yes, -TYPE=OVSBridge, -PROMISC=yes, + echo "DEVICE=${bridge} +DEVICETYPE=ovs +IPADDR=${if_ip} +NETMASK=${if_mask} +BOOTPROTO=static +ONBOOT=yes +TYPE=OVSBridge +PROMISC=yes PEERDNS=no" > ${ovs_file} - else - echo "DEVICE=${bridge}, -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 @@ -395,7 +123,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 @@ -417,35 +146,51 @@ 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}, -IPADDR=${if_ip}, -NETMASK=${if_mask}, -BOOTPROTO=static, -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}, + # create if cfg + echo "DEVICE=${line} +IPADDR=${if_ip} +NETMASK=${if_mask} +BOOTPROTO=static +ONBOOT=yes +TYPE=Ethernet +NM_CONTROLLED=no 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 @@ -455,8 +200,51 @@ PEERDNS=no" > ${net_path}/ifcfg-${line} done <<< "$port_output" - # now remove the bridge ifcfg file - rm -f ${net_path}/ifcfg-${bridge} + # modify the bridge ifcfg file + # to remove IP params + 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 } + +# Update iptables rule for external network reach internet +# for virtual deployments +# params: external_cidr +function configure_undercloud_nat { + local external_cidr + if [[ -z "$1" ]]; then + return 1 + else + external_cidr=$1 + fi + + ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" <