Syntax updates and new tests
[apex.git] / lib / common-functions.sh
1 #!/usr/bin/env bash
2 # Common Functions used by  OPNFV Apex
3 # author: Tim Rozet (trozet@redhat.com)
4
5 ##converts subnet mask to prefix
6 ##params: subnet mask
7 function prefix2mask {
8   # Number of args to shift, 255..255, first non-255 byte, zeroes
9    set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
10    [ $1 -gt 1 ] && shift $1 || shift
11    echo ${1-0}.${2-0}.${3-0}.${4-0}
12 }
13
14 ##find ip of interface
15 ##params: interface name
16 function find_ip {
17   if [[ -z "$1" ]]; then
18     return 1
19   fi
20
21   python3.4 -B $LIB/python/apex_python_utils.py find-ip -i $1
22 }
23
24 ##attach interface to OVS and set the network config correctly
25 ##params: bride to attach to, interface to attach, network type (optional)
26 ##public indicates attaching to a public interface
27 function attach_interface_to_ovs {
28   local bridge interface
29   local if_ip if_mask if_gw if_file ovs_file if_prefix
30   local if_metric if_dns1 if_dns2
31
32   if [[ -z "$1" || -z "$2" ]]; then
33     return 1
34   else
35     bridge=$1
36     interface=$2
37   fi
38
39   if ovs-vsctl list-ports ${bridge} | grep ${interface}; then
40     return 0
41   fi
42
43   if_file=/etc/sysconfig/network-scripts/ifcfg-${interface}
44   ovs_file=/etc/sysconfig/network-scripts/ifcfg-${bridge}
45
46   if [ -e "$if_file" ]; then
47     if_ip=$(sed -n 's/^IPADDR=\(.*\)$/\1/p' ${if_file})
48     if_mask=$(sed -n 's/^NETMASK=\(.*\)$/\1/p' ${if_file})
49     if_gw=$(sed -n 's/^GATEWAY=\(.*\)$/\1/p' ${if_file})
50     if_metric=$(sed -n 's/^METRIC=\(.*\)$/\1/p' ${if_file})
51     if_dns1=$(sed -n 's/^DNS1=\(.*\)$/\1/p' ${if_file})
52     if_dns2=$(sed -n 's/^DNS2=\(.*\)$/\1/p' ${if_file})
53   else
54     echo "ERROR: ifcfg file missing for ${interface}"
55     return 1
56   fi
57
58   if [ -z "$if_mask" ]; then
59     # we can look for PREFIX here, then convert it to NETMASK
60     if_prefix=$(sed -n 's/^PREFIX=\(.*\)$/\1/p' ${if_file})
61     if_mask=$(prefix2mask ${if_prefix})
62   fi
63
64   if [[ -z "$if_ip" || -z "$if_mask" ]]; then
65     echo "ERROR: IPADDR or NETMASK/PREFIX missing for ${interface}"
66     return 1
67   elif [[ -z "$if_gw" && "$3" == "public_network" ]]; then
68     echo "ERROR: GATEWAY missing for ${interface}, which is public"
69     return 1
70   fi
71
72   # move old config file to .orig
73   mv -f ${if_file} ${if_file}.orig
74   echo "DEVICE=${interface}
75 DEVICETYPE=ovs
76 TYPE=OVSPort
77 PEERDNS=no
78 BOOTPROTO=static
79 NM_CONTROLLED=no
80 ONBOOT=yes
81 OVS_BRIDGE=${bridge}
82 PROMISC=yes" > ${if_file}
83
84
85   # create bridge cfg
86   echo "DEVICE=${bridge}
87 DEVICETYPE=ovs
88 IPADDR=${if_ip}
89 NETMASK=${if_mask}
90 BOOTPROTO=static
91 ONBOOT=yes
92 TYPE=OVSBridge
93 PROMISC=yes
94 PEERDNS=no" > ${ovs_file}
95
96   if [ -n "$if_gw" ]; then
97     echo "GATEWAY=${if_gw}" >> ${ovs_file}
98   fi
99
100   if [ -n "$if_metric" ]; then
101     echo "METRIC=${if_metric}" >> ${ovs_file}
102   fi
103
104   if [[ -n "$if_dns1" || -n "$if_dns2" ]]; then
105     sed -i '/PEERDNS/c\PEERDNS=yes' ${ovs_file}
106
107     if [ -n "$if_dns1" ]; then
108       echo "DNS1=${if_dns1}" >> ${ovs_file}
109     fi
110
111     if [ -n "$if_dns2" ]; then
112       echo "DNS2=${if_dns2}" >> ${ovs_file}
113     fi
114   fi
115
116   sudo systemctl restart network
117 }
118
119 ##detach interface from OVS and set the network config correctly
120 ##params: bridge to detach from
121 ##assumes only 1 real interface attached to OVS
122 function detach_interface_from_ovs {
123   local bridge
124   local port_output ports_no_orig
125   local net_path
126   local if_ip if_mask if_gw if_prefix
127   local if_metric if_dns1 if_dns2
128
129   net_path=/etc/sysconfig/network-scripts/
130   if [[ -z "$1" ]]; then
131     return 1
132   else
133     bridge=$1
134   fi
135
136   # if no interfaces attached then return
137   if ! ovs-vsctl list-ports ${bridge} | grep -Ev "vnet[0-9]*"; then
138     return 0
139   fi
140
141   # look for .orig ifcfg files  to use
142   port_output=$(ovs-vsctl list-ports ${bridge} | grep -Ev "vnet[0-9]*")
143   while read -r line; do
144     if [ -z "$line" ]; then
145       continue
146     elif [ -e ${net_path}/ifcfg-${line}.orig ]; then
147       mv -f ${net_path}/ifcfg-${line}.orig ${net_path}/ifcfg-${line}
148     elif [ -e ${net_path}/ifcfg-${bridge} ]; then
149       if_ip=$(sed -n 's/^IPADDR=\(.*\)$/\1/p' ${net_path}/ifcfg-${bridge})
150       if_mask=$(sed -n 's/^NETMASK=\(.*\)$/\1/p' ${net_path}/ifcfg-${bridge})
151       if_gw=$(sed -n 's/^GATEWAY=\(.*\)$/\1/p' ${net_path}/ifcfg-${bridge})
152       if_metric=$(sed -n 's/^METRIC=\(.*\)$/\1/p' ${net_path}/ifcfg-${bridge})
153       if_dns1=$(sed -n 's/^DNS1=\(.*\)$/\1/p' ${net_path}/ifcfg-${bridge})
154       if_dns2=$(sed -n 's/^DNS2=\(.*\)$/\1/p' ${net_path}/ifcfg-${bridge})
155
156       if [ -z "$if_mask" ]; then
157         if_prefix=$(sed -n 's/^PREFIX=[^0-9]*\([0-9][0-9]*\)[^0-9]*$/\1/p' ${net_path}/ifcfg-${bridge})
158         if_mask=$(prefix2mask ${if_prefix})
159       fi
160
161       if [[ -z "$if_ip" || -z "$if_mask" ]]; then
162         echo "ERROR: IPADDR or PREFIX/NETMASK missing for ${bridge} and no .orig file for interface ${line}"
163         return 1
164       fi
165
166       # create if cfg
167       echo "DEVICE=${line}
168 IPADDR=${if_ip}
169 NETMASK=${if_mask}
170 BOOTPROTO=static
171 ONBOOT=yes
172 TYPE=Ethernet
173 NM_CONTROLLED=no
174 PEERDNS=no" > ${net_path}/ifcfg-${line}
175
176       if [ -n "$if_gw" ]; then
177         echo "GATEWAY=${if_gw}" >> ${net_path}/ifcfg-${line}
178       fi
179
180       if [ -n "$if_metric" ]; then
181         echo "METRIC=${if_metric}" >> ${net_path}/ifcfg-${line}
182       fi
183
184       if [[ -n "$if_dns1" || -n "$if_dns2" ]]; then
185         sed -i '/PEERDNS/c\PEERDNS=yes' ${net_path}/ifcfg-${line}
186
187         if [ -n "$if_dns1" ]; then
188           echo "DNS1=${if_dns1}" >> ${net_path}/ifcfg-${line}
189         fi
190
191         if [ -n "$if_dns2" ]; then
192           echo "DNS2=${if_dns2}" >> ${net_path}/ifcfg-${line}
193         fi
194       fi
195       break
196     else
197       echo "ERROR: Real interface ${line} attached to bridge, but no interface or ${bridge} ifcfg file exists"
198       return 1
199     fi
200
201   done <<< "$port_output"
202
203   # modify the bridge ifcfg file
204   # to remove IP params
205   sudo sed -i 's/IPADDR=.*//' ${net_path}/ifcfg-${bridge}
206   sudo sed -i 's/NETMASK=.*//' ${net_path}/ifcfg-${bridge}
207   sudo sed -i 's/GATEWAY=.*//' ${net_path}/ifcfg-${bridge}
208   sudo sed -i 's/DNS1=.*//' ${net_path}/ifcfg-${bridge}
209   sudo sed -i 's/DNS2=.*//' ${net_path}/ifcfg-${bridge}
210   sudo sed -i 's/METRIC=.*//' ${net_path}/ifcfg-${bridge}
211   sudo sed -i 's/PEERDNS=.*//' ${net_path}/ifcfg-${bridge}
212
213   sudo systemctl restart network
214 }
215
216 # Update iptables rule for external network reach internet
217 # for virtual deployments
218 # params: external_cidr
219 function configure_undercloud_nat {
220   local external_cidr
221   if [[ -z "$1" ]]; then
222     return 1
223   else
224     external_cidr=$1
225   fi
226
227   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" <<EOI
228 iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
229 iptables -t nat -A POSTROUTING -s ${external_cidr} -o eth0 -j MASQUERADE
230 iptables -A FORWARD -i eth2 -j ACCEPT
231 iptables -A FORWARD -s ${external_cidr} -m state --state ESTABLISHED,RELATED -j ACCEPT
232 service iptables save
233 EOI
234 }
235
236 # Interactive prompt handler
237 # params: step stage, ex. deploy, undercloud install, etc
238 function prompt_user {
239   while [ 1 ]; do
240     echo -n "Would you like to proceed with ${1}? (y/n) "
241     read response
242     if [ "$response" == 'y' ]; then
243       return 0
244     elif [ "$response" == 'n' ]; then
245       return 1
246     else
247       continue
248     fi
249   done
250 }